openrat-cms

# OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

commit dd7997f6ca754e55d11c9cf1a52cceb2beb75bdc
parent bd07ae8aa64b49996b4858aae2958941d0286cbb
Author: Jan Dankert <develop@jandankert.de>
Date:   Sat, 11 May 2019 02:50:43 +0200

Einbau eines dedizierten Caches. Es ist fraglich, ob dieser Cache überhaupt sinnvoll ist, da beim Anzeigen von BLOBs das HTTP-Caching zum Zuge kommt.

Diffstat:
modules/cms-core/action/FileAction.class.php | 15++++++---------
modules/cms-core/action/PageAction.class.php | 10+++++-----
modules/cms-core/model/File.class.php | 74+++++++++++++++++++++++++++++---------------------------------------------
modules/cms-core/model/Image.class.php | 12+++++-------
modules/cms-core/model/Page.class.php | 78+++++++++++++++++++++++++++++++++---------------------------------------------
modules/cms-core/model/Value.class.php | 61+++++++++++++++++++++++++++++++++++--------------------------
modules/util/ClassUtils.class.php | 3+++
modules/util/FileUtils.class.php | 6+++++-
modules/util/cache/LoaderCache.class.php | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/util/require.php | 2++
modules/wikiparser/renderer/PdfRenderer.class.php | 2+-
11 files changed, 211 insertions(+), 139 deletions(-)

diff --git a/modules/cms-core/action/FileAction.class.php b/modules/cms-core/action/FileAction.class.php @@ -171,21 +171,21 @@ class FileAction extends ObjectAction // Groesse des Bildes in Bytes // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen - header('Content-Length: '.filesize($this->file->tmpfile()) ); + header('Content-Length: '.filesize($this->file->getCache()->getFilename()) ); if ( in_array( getenv('HTTP_ACCEPT'),array('application/php-array','application/php-serialized','application/json','application/xml'))) { $this->setTemplateVar('encoding', 'base64'); - $this->setTemplateVar('value' , base64_encode($this->file->tmpfile()) ); + $this->setTemplateVar('value' , base64_encode($this->file->getCache()->getFilename()) ); } // Unterscheidung, ob PHP-Code in der Datei ausgefuehrt werden soll. elseif ( ( config('publish','enable_php_in_file_content')=='auto' && $this->file->getRealExtension()=='php') || config('publish','enable_php_in_file_content')===true ) // PHP-Code ausfuehren - require( $this->file->tmpfile() ); + require( $this->file->getCache()->getFilename() ); else // PHP-Code nicht ausfuehren, Datei direkt auf die Standardausgabe schreiben - readfile( $this->file->tmpfile() ); + readfile( $this->file->getCache()->getFilename() ); // Maybe we want some gzip-encoding? @@ -216,11 +216,8 @@ class FileAction extends ObjectAction $this->setTemplateVar('size',number_format($this->file->size/1000,0,',','.').' kB' ); $this->setTemplateVar('full_filename',$this->file->full_filename()); - if ( is_file($this->file->tmpfile())) - { - $this->setTemplateVar('cache_filename' ,$this->file->tmpfile()); - $this->setTemplateVar('cache_filemtime',@filemtime($this->file->tmpfile())); - } + $this->setTemplateVar('cache_filename' ,$this->file->getCache()->getFilename()); + $this->setTemplateVar('cache_filemtime',@filemtime($this->file->getCache()->getFilename())); // Alle Seiten mit dieser Datei ermitteln $pages = $this->file->getDependentObjectIds(); diff --git a/modules/cms-core/action/PageAction.class.php b/modules/cms-core/action/PageAction.class.php @@ -332,8 +332,8 @@ class PageAction extends ObjectAction $template = new Template( $this->page->templateid ); $template->load(); - $this->setTemplateVar('template_name',$template->name); - $this->setTemplateVar('tmp_filename',$this->page->tmpfile() ); + $this->setTemplateVar('template_name',$template->name ); + $this->setTemplateVar('tmp_filename' ,$this->page->getCache()->getFilename() ); } @@ -343,7 +343,7 @@ class PageAction extends ObjectAction /** * Austauschen der Vorlage vorbereiten * - * Es wird ein Formualr erzeugt, in dem der Benutzer auswaehlen kann, welche Elemente + * Es wird ein Formualar erzeugt, in dem der Benutzer auswaehlen kann, welche Elemente * in welches Element uebernommen werden sollen */ public function changetemplateselectelementsView() @@ -611,9 +611,9 @@ class PageAction extends ObjectAction // Wenn if ( ( config('publish','enable_php_in_page_content')=='auto' && $this->page->template->extension == 'php') || config('publish','enable_php_in_page_content')===true ) - require( $this->page->tmpfile() ); + require( $this->page->getCache()->getFilename() ); else - readfile( $this->page->tmpfile() ); + readfile( $this->page->getCache()->getFilename() ); exit(); } diff --git a/modules/cms-core/model/File.class.php b/modules/cms-core/model/File.class.php @@ -26,6 +26,7 @@ use cms\publish\PublishShow; use JSqueeze; use Less_Parser; use Logger; +use util\LoaderCache; define('OR_FILE_DEFAULT_MIMETYPE','application/octet-stream'); @@ -70,7 +71,6 @@ class File extends BaseObject public $public = false ; - /** * Konstruktor * @@ -78,16 +78,23 @@ class File extends BaseObject */ function __construct( $objectid='' ) { - global $conf; - - $db = \Session::getDatabase(); - $this->storeValueAsBase64 = $db->conf['base64']; + $this->storeValueAsBase64 = db()->conf['base64']; parent::__construct( $objectid ); $this->isFile = true; - } + } + + /** + * @return LoaderCache + */ + public function getCache() { + $cacheKey = array('db'=>db()->id,'file'=>$this->objectid,'publish'=>\ClassUtils::getSimpleClassName($this->publisher)); + return new LoaderCache( $cacheKey,function() { + return $this->loadValueFromDatabase(); + } ); + } /** * Ermitteln des Dateinamens dieser Datei @@ -363,16 +370,23 @@ EOF } - /** + public function loadValue() + { + if ( filemtime($this->getCache()->getFilename() < $this->lastchangeDate)) + $this->getCache()->invalidate(); + + return $this->getCache()-get(); + } + + + /** * Lesen des Inhaltes der Datei aus der Datenbank. * * @return String Inhalt der Datei */ - public function loadValue() + private function loadValueFromDatabase() { // Read from cache, if cache exist and is not too old. - if ( is_file($this->tmpfile()) && filemtime($this->tmpfile()>=$this->lastchangeDate)) - return implode('',file($this->tmpfile())); // From cache $sql = db()->sql( 'SELECT size,value'. ' FROM {{file}}'. @@ -391,27 +405,16 @@ EOF $this->filterValue(); - // Store in cache. - $f = fopen( $this->tmpfile(),'w' ); - fwrite( $f,$this->value ); - fclose( $f ); - return $this->value; } - public function deleteTmpFile() { - - if ( is_file($this->tmpfile()) ) - @unlink( $this->tmpfile() ); - } - /** * Speichert den Inhalt in der Datenbank. */ function saveValue( $value = '' ) { - $this->deleteTmpFile(); + $this->getCache()->invalidate(); $db = db_connection(); @@ -436,8 +439,7 @@ EOF */ function write() { - if ( !is_file($this->tmpfile()) ) - $this->loadValue(); + $this->getCache()->load(); } @@ -466,30 +468,14 @@ EOF public function publish() { - $this->deleteTmpFile(); - $this->write(); - $this->publisher->copy( $this->tmpfile(),$this->full_filename(),$this->lastchangeDate ); + $this->publisher->copy( $this->getCache()->getFilename(),$this->full_filename(),$this->lastchangeDate ); $this->publisher->publishedObjects[] = $this->getProperties(); } /** - * Ermittelt einen tempor�ren Dateinamen f�r diese Datei. - */ - public function tmpfile() - { - if ( $this->tmpfile == '' ) - { - $db = db_connection(); - $this->tmpfile = \FileUtils::getTempFileName( array('db'=>$db->id,'o'=>$this->objectid,'p'=>intval($this->public)) ); - } - return $this->tmpfile; - } - - - /** * Setzt den Zeitstempel der Datei auf die aktuelle Zeit. * * @see objectClasses/Object#setTimestamp() @@ -497,7 +483,7 @@ EOF function setTimestamp() { - @unlink( $this->tmpfile() ); + $this->getCache()->invalidate(); parent::setTimestamp(); } @@ -578,9 +564,7 @@ EOF } // Store in cache. - $f = fopen( $this->tmpfile(),'w' ); - fwrite( $f,$this->value ); - fclose( $f ); + $this->getCache()->invalidate(); } } diff --git a/modules/cms-core/model/Image.class.php b/modules/cms-core/model/Image.class.php @@ -67,7 +67,7 @@ class Image extends File $this->write(); // Datei schreiben // Bildinformationen ermitteln - $size = getimagesize( $this->tmpfile() ); + $size = getimagesize( $this->getCache()->getFilename() ); // Breite und Hoehe des aktuellen Bildes $this->width = $size[0]; @@ -96,7 +96,7 @@ class Image extends File $this->write(); // Datei schreiben // Bildinformationen ermitteln - $size = getimagesize( $this->tmpfile() ); + $size = getimagesize( $this->getCache()->getFilename() ); // Breite und Hoehe des aktuellen Bildes $oldWidth = $size[0]; @@ -173,7 +173,7 @@ class Image extends File $newImage = &$oldImage; } - ImageGIF($newImage, $this->tmpfile() ); + ImageGIF($newImage, $this->getCache()->getFilename() ); $this->extension = 'gif'; break; @@ -228,7 +228,7 @@ class Image extends File $newHeight,$oldWidth,$oldHeight); } - imagepng( $newImage,$this->tmpfile() ); + imagepng( $newImage,$this->getCache()->getFilename() ); $this->extension = 'png'; break; @@ -237,9 +237,7 @@ class Image extends File throw new \LogicException('unsupported image format "'.$newformat.'", cannot resize'); } - $f = fopen( $this->tmpfile(), "r" ); - $this->value = fread( $f,filesize($this->tmpfile()) ); - fclose( $f ); + $this->getCache()->invalidate(); imagedestroy( $oldImage ); //imagedestroy( $newImage ); diff --git a/modules/cms-core/model/Page.class.php b/modules/cms-core/model/Page.class.php @@ -19,6 +19,7 @@ namespace cms\model; use cms\mustache\Mustache; use cms\publish\PublishPreview;use cms\publish\PublishPublic; use Logger; +use util\LoaderCache; /** @@ -82,16 +83,32 @@ class Page extends BaseObject */ public $value; - function __construct( $objectid='' ) { parent::__construct( $objectid ); $this->isPage = true; $this->publisher = new PublishPreview(); + } + /** + * @return LoaderCache + */ + public function getCache() { + $cacheKey = array('db'=>db()->id, + 'page' =>$this->objectid, + 'language' =>$this->languageid, + 'model' =>$this->modelid, + 'publish' =>\ClassUtils::getSimpleClassName($this->publisher) ); + + return new LoaderCache( $cacheKey,function() { + return $this->generateValue(); + } ); + + } + /** * Ermitteln der Objekt-ID (Tabelle object) anhand der Seiten-ID (Tablle page) * @@ -528,18 +545,24 @@ SQL $val->modelid = $this->modelid; $val->page = $this; $val->generate(); - $val->page = null; + //$val->page = null; $this->values[$elementid] = $val; } } + + public function generate() { + + return $this->getCache()->get(); + } + /** * Erzeugen des Inhaltes der gesamten Seite. * * @return String Inhalt */ - public function generate() + private function generateValue() { global $conf; @@ -563,12 +586,6 @@ SQL setlocale(LC_ALL,''); } - if ( $conf['cache']['enable_cache'] && is_file($this->tmpfile() )) - { - $this->value = implode('',file($this->tmpfile())); - return $this->value; - } - $this->template = new Template( $this->templateid ); $this->template->modelid = $this->modelid; $this->template->load(); @@ -588,7 +605,7 @@ SQL foreach( $elements as $elementId=>$elementName ) { - $data[ $elementName ] = $this->values[$elementId]->value; + $data[ $elementName ] = $this->values[$elementId]->generate(); // The following code is for old template values: @@ -637,14 +654,7 @@ SQL $src = translateutf8tohtml($src); } - $this->value = $src; - - // Store in cache. - $f = fopen( $this->tmpfile(),'w' ); - fwrite( $f,$this->value ); - fclose( $f ); - - return $this->value; + return $src; } @@ -653,8 +663,7 @@ SQL */ public function write() { - if ( !is_file($this->tmpfile())) - $this->generate(); + $this->getCache()->load(); } @@ -681,8 +690,7 @@ SQL $this->modelid = $projectmodelid; $this->load(); - $this->generate(); - $this->write(); + $this->getCache()->load(); // Vorlage ermitteln. $t = new Template( $this->templateid ); @@ -692,8 +700,7 @@ SQL // Nur wenn eine Datei-Endung vorliegt wird die Seite veroeffentlicht if ( !empty($t->extension) ) { - $this->publisher->copy( $this->tmpfile(),$this->full_filename() ); - unlink( $this->tmpfile() ); + $this->publisher->copy( $this->getCache()->getFilename(),$this->full_filename() ); $this->publisher->publishedObjects[] = $this->getProperties(); } } @@ -725,29 +732,10 @@ SQL - /** - * Ermittelt einen tempor�ren Dateinamen f�r diese Seite. - */ - function tmpfile() - { - $db = db_connection(); - $filename = \FileUtils::getTempFileName( array('db'=>$db->id, - 'o' =>$this->objectid, - 'l' =>$this->languageid, - 'm' =>$this->modelid, - 'p' =>\ClassUtils::getSimpleClassName($this->publisher) ) ); - return $filename; - } - - - function setTimestamp() { - $tmpFilename = $this->tmpfile(); - - if ( is_file($tmpFilename) ) - unlink( $tmpFilename); - + $this->getCache()->invalidate(); + parent::setTimestamp(); } diff --git a/modules/cms-core/model/Value.class.php b/modules/cms-core/model/Value.class.php @@ -8,6 +8,7 @@ use \Html; use \Http; use \Transformer; use \Code; +use util\LoaderCache; // OpenRat Content Management System // Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de @@ -160,6 +161,7 @@ class Value { $this->lastchangeUserId = 0; $this->lastchangeTimeStamp = 0; + } @@ -180,24 +182,22 @@ class Value */ function load() { - $db = db_connection(); - if ( $this->publisher->isPublic() ) - $sql = $db->sql( 'SELECT * FROM {{value}}'. + $stmt = db()->sql( 'SELECT * FROM {{value}}'. ' WHERE elementid ={elementid}'. ' AND pageid ={pageid}'. ' AND languageid={languageid}'. ' AND publish=1' ); else - $sql = $db->sql( 'SELECT * FROM {{value}}'. + $stmt = db()->sql( 'SELECT * FROM {{value}}'. ' WHERE elementid ={elementid}'. ' AND pageid ={pageid}'. ' AND languageid={languageid}'. ' AND active=1' ); - $sql->setInt( 'elementid' ,$this->element->elementid ); - $sql->setInt( 'pageid' ,$this->pageid ); - $sql->setInt( 'languageid',$this->languageid); - $row = $sql->getRow(); + $stmt->setInt( 'elementid' ,$this->element->elementid ); + $stmt->setInt( 'pageid' ,$this->pageid ); + $stmt->setInt( 'languageid',$this->languageid); + $row = $stmt->getRow(); if ( count($row) > 0 ) // Wenn Inhalt gefunden { @@ -533,13 +533,37 @@ SQL } + public function generate() { + + return $this->getCache()->get(); + } + + + /** + * + * @return LoaderCache + */ + public function getCache() { + + $cacheKey = array('db'=>db()->id, + 'value'=>$this->valueid, + 'page' =>is_object($this->page)?$this->page->objectid:0, + 'el'=>is_object($this->element)?$this->element->elementid:0, + 'language'=>$this->languageid, + 'model' =>is_object($this->page)?$this->page->modelid:0, + 'publish'=>\ClassUtils::getSimpleClassName($this->publisher) ); + return new LoaderCache( $cacheKey,function() { + return $this->generateValue(); + } ); + } + /** * Hier findet die eigentliche Bereitstellung des Inhaltes statt, zu * jedem Elementtyp wird ein Inhalt ermittelt. * * @return void (aber Eigenschaft 'value' wird gesetzt). */ - function generate() + private function generateValue() { global $conf; @@ -551,12 +575,6 @@ SQL global $conf; - if ( $conf['cache']['enable_cache'] && is_file( $this->tmpfile() )) - { - $this->value = implode('',file($this->tmpfile() )); // from cache. - return; - } - // Inhalt ist mit anderer Seite verkn�pft. if ( in_array($this->element->type,array('text','longtext','date','number')) && intval($this->linkToObjectId) != 0 && !$this->isLink ) { @@ -1537,11 +1555,7 @@ SQL $this->value = $inhalt; - - // Store in cache. - $f = fopen( $this->tmpfile(),'w' ); - fwrite( $f,$this->value ); - fclose( $f ); + return $this->value; } @@ -1653,12 +1667,7 @@ SQL function tmpfile() { $db = db_connection(); - $filename = \FileUtils::getTempFileName( array('db'=>$db->id, - 'va'=>$this->valueid, - 'el'=>$this->element->elementid, - 'la'=>$this->languageid, - 'm' =>$this->page->modelid, - 'pu'=>\ClassUtils::getSimpleClassName($this->publisher) ) ); + $filename = \FileUtils::getTempFileName( ); return $filename; } diff --git a/modules/util/ClassUtils.class.php b/modules/util/ClassUtils.class.php @@ -8,6 +8,9 @@ class ClassUtils { public static function getSimpleClassName($object) { + if ( ! is_object($object)) + return 'NotAnObject'; + $classname = get_class($object); if ($pos = strrpos($classname, '\\')) return substr($classname, $pos + 1); return $pos; diff --git a/modules/util/FileUtils.class.php b/modules/util/FileUtils.class.php @@ -61,7 +61,11 @@ class FileUtils } - + /** + * @param array $attr + * @return string + * @deprecated use \Cache + */ public static function getTempFileName( $attr = array() ) { $filename = FileUtils::getTempDir() . '/openrat'; diff --git a/modules/util/cache/LoaderCache.class.php b/modules/util/cache/LoaderCache.class.php @@ -0,0 +1,86 @@ +<?php + +namespace util; + +use FileUtils; + + +/** + * Simple Cache for caching of generated content. + * + * @package util + */ +class LoaderCache +{ + /** + * @var Callable + */ + private $loader; + + /** + * @var string + */ + private $filename; + + /** + * Creates a new Cache entry. + * + * @param $key array Cache-Key + * @param $loader Callable + */ + public function __construct( $key, $loader ) + { + $filename = FileUtils::getTempDir() . '/'. 'openrat-cache'; + + if ( is_array($key)) + foreach ($key as $a => $w) + $filename .= '.' . $a .'-'. $w; + else + $filename .= strval($key); + + $filename .= '.tmp'; + + $this->filename = $filename; + $this->loader = $loader; + } + + + /** + * Invalidates a cache entry. + */ + public function invalidate() { + + if ( is_file($this->filename)) + unlink( $this->filename); + } + + + /** + * Get the content. + */ + public function get() { + + if ( ! is_file($this->filename)) { + file_put_contents($this->filename,call_user_func($this->loader) ); + } + + return file_get_contents($this->filename); + } + + + /** + * Get the content. + */ + public function load() { + + if ( ! is_file($this->filename)) { + file_put_contents($this->filename,call_user_func($this->loader) ); + } + } + + + public function getFilename() { + return $this->filename; + } + +}+ \ No newline at end of file diff --git a/modules/util/require.php b/modules/util/require.php @@ -4,6 +4,8 @@ require_once( __DIR__.'/'.'exception/ValidationException.class.php' ); require_once( __DIR__.'/'.'exception/OpenRatException.class.php' ); require_once( __DIR__.'/'.'exception/SecurityException.class.php' ); +require_once( __DIR__.'/'.'cache/LoaderCache.class.php' ); + require_once( __DIR__.'/'.'ArrayUtils.class.php' ); require_once( __DIR__.'/'.'ClassUtils.class.php' ); require_once( __DIR__.'/'.'GlobalFunctions.class.php' ); diff --git a/modules/wikiparser/renderer/PdfRenderer.class.php b/modules/wikiparser/renderer/PdfRenderer.class.php @@ -105,7 +105,7 @@ class PdfRenderer // $image->width; // $image->height; - $this->pdf->Image($image->tmpfile(),$this->pdf->GetX(),$this->pdf->GetY(),0,0,$image->extension()); + $this->pdf->Image($image->getCache()->getFilename(),$this->pdf->GetX(),$this->pdf->GetY(),0,0,$image->extension()); $this->pdf->ln($image->height/2.5); $this->pdf->ln(5);