Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cFileCache
  • cOutputCache
  • cOutputCacheHandler
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * This file contains the output cache classes.
  5:  *
  6:  * @package Core
  7:  * @subpackage Cache
  8:  * @author Murat Purc <murat@purc.de>
  9:  * @copyright four for business AG <www.4fb.de>
 10:  * @license http://www.contenido.org/license/LIZENZ.txt
 11:  * @link http://www.4fb.de
 12:  * @link http://www.contenido.org
 13:  */
 14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17: /**
 18:  * This class contains functions for the CONTENIDO output cache.
 19:  *
 20:  * @package Core
 21:  * @subpackage Cache
 22:  */
 23: class cOutputCache {
 24: 
 25:     /**
 26:      * File cache object.
 27:      *
 28:      * @var cFileCache
 29:      */
 30:     protected $_fileCache;
 31: 
 32:     /**
 33:      * Flag to activate caching.
 34:      *
 35:      * @var bool
 36:      */
 37:     protected $_bEnableCaching = false;
 38: 
 39:     /**
 40:      * Flag for output of debug informations.
 41:      *
 42:      * @var bool
 43:      */
 44:     protected $_bDebug = false;
 45: 
 46:     /**
 47:      * Flag to print html comment including some debug informations.
 48:      *
 49:      * @var bool
 50:      */
 51:     protected $_bHtmlComment = false;
 52: 
 53:     /**
 54:      * Start time of caching.
 55:      *
 56:      * @var int
 57:      */
 58:     protected $_iStartTime;
 59: 
 60:     /**
 61:      * Option array for generating cache identifier
 62:      * (e.g. $_GET,$_POST, $_COOKIE, ...).
 63:      *
 64:      * @var array
 65:      */
 66:     protected $_aIDOptions;
 67: 
 68:     /**
 69:      * Option array for pear caching.
 70:      *
 71:      * @var array
 72:      */
 73:     protected $_aCacheOptions;
 74: 
 75:     /**
 76:      * Handler array to store code, beeing executed on some hooks.
 77:      * We have actually two hooks:
 78:      * - 'beforeoutput': code to execute before doing the output
 79:      * - 'afteroutput' code to execute after output
 80:      *
 81:      * @var array
 82:      */
 83:     protected $_aEventCode;
 84: 
 85:     /**
 86:      * Unique identifier for caching.
 87:      *
 88:      * @var string
 89:      */
 90:     protected $_sID;
 91: 
 92:     /**
 93:      * Directory to store cached output.
 94:      *
 95:      * @var string
 96:      */
 97:     protected $_sDir = 'cache/';
 98: 
 99:     /**
100:      * Subdirectory to store cached output.
101:      *
102:      * @var string
103:      */
104:     protected $_sGroup = 'default';
105: 
106:     /**
107:      * Substring to add as prefix to cache-filename.
108:      *
109:      * @var string
110:      */
111:     protected $_sPrefix = 'cache_output_';
112: 
113:     /**
114:      * Default lifetime of cached files.
115:      *
116:      * @var int
117:      */
118:     protected $_iLifetime = 3600;
119: 
120:     /**
121:      * Used to store debug message.
122:      *
123:      * @var string
124:      */
125:     protected $_sDebugMsg = '';
126: 
127:     /**
128:      * HTML code template used for debug message.
129:      *
130:      * @var string
131:      */
132:     protected $_sDebugTpl = '<div>%s</div>';
133: 
134:     /**
135:      * HTML comment template used for generating some debug infos.
136:      *
137:      * @var string
138:      */
139:     protected $_sHtmlCommentTpl = '
140: <!--
141: CACHESTATE:  %s
142: TIME:        %s
143: VALID UNTIL: %s
144: -->
145: ';
146: 
147:     /**
148:      * Constructor to create an instance of this class.
149:      *
150:      * @param string $cachedir [optional]
151:      *         Directory to cache files
152:      * @param string $cachegroup [optional]
153:      *         Subdirectory to cache files
154:      * @param string $cacheprefix [optional]
155:      *         Prefixname to add to cached files
156:      */
157:     public function __construct($cachedir = NULL, $cachegroup = NULL, $cacheprefix = NULL) {
158:         // wherever you want the cache files
159:         if (!is_null($cachedir)) {
160:             $this->_sDir = $cachedir;
161:         }
162: 
163:         // subdirectory where you want the cache files
164:         if (!is_null($cachegroup)) {
165:             $this->_sGroup = $cachegroup;
166:         }
167: 
168:         // optional a filename prefix
169:         if (!is_null($cacheprefix)) {
170:             $this->_sPrefix = $cacheprefix;
171:         }
172: 
173:         // config options are passed to the cache as an array
174:         $this->_aCacheOptions = array(
175:             'cacheDir' => $this->_sDir,
176:             'fileNamePrefix' => $this->_sPrefix
177:         );
178:     }
179: 
180:     /**
181:      * Get/Set the flag to enable caching.
182:      *
183:      * @param bool $enable [optional]
184:      *         True to enable caching or false
185:      * @return mixed
186:      *         Enable flag or void
187:      */
188:     public function enable($enable = NULL) {
189:         if (!is_null($enable) && is_bool($enable)) {
190:             $this->_bEnableCaching = $enable;
191:         } else {
192:             return $this->_bEnableCaching;
193:         }
194:     }
195: 
196:     /**
197:      * Get/Set the flag to debug cache object (prints out miss/hit state
198:      * with execution time).
199:      *
200:      * @param bool $debug
201:      *         True to activate debugging or false.
202:      * @return mixed
203:      *         Debug flag or void
204:      */
205:     public function debug($debug) {
206:         if (!is_null($debug) && is_bool($debug)) {
207:             $this->_bDebug = $debug;
208:         } else {
209:             return $this->_bDebug;
210:         }
211:     }
212: 
213:     /**
214:      * Get/Set flag to print out cache info as html comment.
215:      *
216:      * @param bool $htmlcomment
217:      *         True debugging or false.
218:      * @return void|string
219:      *         Htmlcomment flag or void
220:      */
221:     public function htmlComment($htmlcomment) {
222:         if (!is_null($htmlcomment) && is_bool($htmlcomment)) {
223:             $this->_bHtmlComment = $htmlcomment;
224:         } else {
225:             return $this->_bHtmlComment;
226:         }
227:     }
228: 
229:     /**
230:      * Get/Set caching lifetime in seconds.
231:      *
232:      * @param int $seconds [optional]
233:      *         New Lifetime in seconds
234:      * @return mixed
235:      *         Actual lifetime or void
236:      */
237:     public function lifetime($seconds = NULL) {
238:         if ($seconds != NULL && is_numeric($seconds) && $seconds > 0) {
239:             $this->_iLifetime = $seconds;
240:         } else {
241:             return $this->_iLifetime;
242:         }
243:     }
244: 
245:     /**
246:      * Get/Set template to use on printing the chache info.
247:      *
248:      * @param string $template
249:      *         Template string including the '%s' format definition.
250:      */
251:     public function infoTemplate($template) {
252:         $this->_sDebugTpl = $template;
253:     }
254: 
255:     /**
256:      * Add option for caching (e.g. $_GET,$_POST, $_COOKIE, ...).
257:      *
258:      * Used to generate the id for caching.
259:      *
260:      * @param string $name
261:      *         Name of option
262:      * @param string $option
263:      *         Value of option (any variable)
264:      */
265:     public function addOption($name, $option) {
266:         $this->_aIDOptions[$name] = $option;
267:     }
268: 
269:     /**
270:      * Returns information cache hit/miss and execution time if caching
271:      * is enabled.
272:      *
273:      * @return string
274:      *         Information about cache if caching is enabled, otherwise nothing.
275:      */
276:     public function getInfo() {
277:         if (!$this->_bEnableCaching) {
278:             return;
279:         }
280: 
281:         return $this->_sDebugMsg;
282:     }
283: 
284:     /**
285:      * Starts the cache process.
286:      *
287:      * @return bool|string
288:      */
289:     protected function _start() {
290:         $id = $this->_sID;
291:         $group = $this->_sGroup;
292: 
293:         // this is already cached return it from the cache so that the
294:         // user can use the cache content and stop script execution
295:         if ($content = $this->_fileCache->get($id, $group)) {
296:             return $content;
297:         }
298: 
299:         // WARNING: we need the output buffer - possible clashes
300:         ob_start();
301:         ob_implicit_flush(false);
302: 
303:         return '';
304:     }
305: 
306:     /**
307:      * Handles PEAR caching.
308:      *
309:      * The script will be terminated by calling die(), if any cached
310:      * content is found.
311:      *
312:      * @param int $iPageStartTime [optional]
313:      *         Optional start time, e.g. start time of main script
314:      */
315:     public function start($iPageStartTime = NULL) {
316:         if (!$this->_bEnableCaching) {
317:             return;
318:         }
319: 
320:         $this->_iStartTime = $this->_getMicroTime();
321: 
322:         // set cache object and unique id
323:         $this->_initFileCache();
324: 
325:         // check if it's cached and start the output buffering if necessary
326:         if ($content = $this->_start()) {
327:             // raise beforeoutput event
328:             $this->_raiseEvent('beforeoutput');
329: 
330:             $iEndTime = $this->_getMicroTime();
331:             if ($this->_bHtmlComment) {
332:                 $time = sprintf("%2.4f", $iEndTime - $this->_iStartTime);
333:                 $exp = ($this->_iLifetime == 0? 'infinite' : date('Y-m-d H:i:s', time() + $this->_iLifetime));
334:                 $content .= sprintf($this->_sHtmlCommentTpl, 'HIT', $time . ' sec.', $exp);
335:                 if ($iPageStartTime != NULL && is_numeric($iPageStartTime)) {
336:                     $content .= '<!-- [' . sprintf("%2.4f", $iEndTime - $iPageStartTime) . '] -->';
337:                 }
338:             }
339: 
340:             if ($this->_bDebug) {
341:                 $info = sprintf("HIT: %2.4f sec.", $iEndTime - $this->_iStartTime);
342:                 $info = sprintf($this->_sDebugTpl, $info);
343:                 $content = str_ireplace('</body>', $info . "\n</body>", $content);
344:             }
345: 
346:             echo $content;
347: 
348:             // raise afteroutput event
349:             $this->_raiseEvent('afteroutput');
350: 
351:             die();
352:         }
353:     }
354: 
355:     /**
356:      * Handles ending of PEAR caching.
357:      */
358:     public function end() {
359:         if (!$this->_bEnableCaching) {
360:             return;
361:         }
362: 
363:         $content = ob_get_contents();
364:         ob_end_clean();
365: 
366:         $this->_fileCache->save($content, $this->_sID, $this->_sGroup);
367: 
368:         echo $content;
369: 
370:         if ($this->_bDebug) {
371:             $this->_sDebugMsg .= "\n" . sprintf("MISS: %2.4f sec.\n", $this->_getMicroTime() - $this->_iStartTime);
372:             $this->_sDebugMsg = sprintf($this->_sDebugTpl, $this->_sDebugMsg);
373:         }
374:     }
375: 
376:     /**
377:      * Removes any cached content if exists.
378:      *
379:      * This is nesessary to delete cached articles, if they are changed on
380:      * backend.
381:      */
382:     public function removeFromCache() {
383:         // set cache object and unique id
384:         $this->_initFileCache();
385:         $this->_fileCache->remove($this->_sID, $this->_sGroup);
386:     }
387: 
388:     /**
389:      * Creates one-time a instance of PEAR cache output object and also
390:      * the unique id, if propery $this->_oPearCache is not set.
391:      */
392:     protected function _initFileCache() {
393:         if (is_object($this->_fileCache)) {
394:             return;
395:         }
396: 
397:         // create an output cache object mode - file storage
398:         $this->_fileCache = new cFileCache($this->_aCacheOptions);
399: 
400:         // generate an ID from whatever might influence the script behaviour
401:         $this->_sID = $this->_fileCache->generateID($this->_aIDOptions);
402:     }
403: 
404:     /**
405:      * Raises any defined event code by using eval().
406:      *
407:      * @param string $name
408:      *         Name of event to raise
409:      */
410:     protected function _raiseEvent($name) {
411:         // skip if event does not exist
412:         if (!isset($this->_aEventCode[$name]) && !is_array($this->_aEventCode[$name])) {
413:             return;
414:         }
415: 
416:         // loop array and execute each defined php-code
417:         foreach ($this->_aEventCode[$name] as $code) {
418:             eval($code);
419:         }
420:     }
421: 
422:     /**
423:      * Returns microtime (UNIX timestamp), used to calculate time of execution.
424:      *
425:      * @return float
426:      *         Timestamp
427:      */
428:     protected function _getMicroTime() {
429:         $mtime = explode(' ', microtime());
430:         $mtime = $mtime[1] + $mtime[0];
431: 
432:         return $mtime;
433:     }
434: }
435: 
436: /**
437:  * This class contains functions for the output cache handler in CONTENIDO.
438:  *
439:  * @package Core
440:  * @subpackage Cache
441:  */
442: class cOutputCacheHandler extends cOutputCache {
443: 
444:     /**
445:      * Constructor to create an instance of this class.
446:      *
447:      * Does some checks and sets the configuration of cache object.
448:      *
449:      * @param array $aConf
450:      *         Configuration of caching as follows:
451:      *         - $a['excludecontenido'] bool
452:      *             don't cache output, if we have a CONTENIDO variable,
453:      *             e.g. on calling frontend preview from backend
454:      *         - $a['enable'] bool
455:      *             activate caching of frontend output
456:      *         - $a['debug'] bool
457:      *             compose debuginfo (hit/miss and execution time of caching)
458:      *         - $a['infotemplate'] string
459:      *             debug information template
460:      *         - $a['htmlcomment'] bool
461:      *             add a html comment including several debug messages to output
462:      *         - $a['lifetime'] int
463:      *             lifetime in seconds to cache output
464:      *         - $a['cachedir'] string
465:      *             directory where cached content is to store.
466:      *         - $a['cachegroup'] string
467:      *             cache group, will be a subdirectory inside cachedir
468:      *         - $a['cacheprefix'] string
469:      *             add prefix to stored filenames
470:      *         - $a['idoptions'] array
471:      *             several variables to create a unique id,
472:      *             if the output depends on them. e.g.
473:      *             array(
474:      *                 'uri' => $_SERVER['REQUEST_URI'],
475:      *                 'post' => $_POST, 'get' => $_GET
476:      *             )
477:      * @param cDb $db
478:      *         CONTENIDO database object
479:      * @param int $iCreateCode [optional]
480:      *         Flag of createcode state from table con_cat_art
481:      */
482:     public function __construct($aConf, $db, $iCreateCode = NULL) {
483:         // check if caching is allowed on CONTENIDO variable
484:         if ($aConf['excludecontenido'] == true) {
485:             if (isset($GLOBALS['contenido'])) {
486:                 // CONTENIDO variable exists, set state and get out here
487:                 $this->_bEnableCaching = false;
488: 
489:                 return;
490:             }
491:         }
492: 
493:         // set enable state of caching
494:         if (is_bool($aConf['enable'])) {
495:             $this->_bEnableCaching = $aConf['enable'];
496:         }
497:         if ($this->_bEnableCaching == false) {
498:             return;
499:         }
500: 
501:         // check if current article shouldn't be cached (by stese)
502:         $sExcludeIdarts = getEffectiveSetting('cache', 'excludeidarts', false);
503:         if ($sExcludeIdarts && strlen($sExcludeIdarts) > 0) {
504:             $sExcludeIdarts = preg_replace("/[^0-9,]/", '', $sExcludeIdarts);
505:             $aExcludeIdart = explode(',', $sExcludeIdarts);
506:             if (in_array($GLOBALS['idart'], $aExcludeIdart)) {
507:                 $this->_bEnableCaching = false;
508: 
509:                 return;
510:             }
511:         }
512: 
513:         $this->_oDB = $db;
514: 
515:         // set caching configuration
516:         parent::__construct($aConf['cachedir'], $aConf['cachegroup']);
517:         $this->debug($aConf['debug']);
518:         $this->htmlComment($aConf['htmlcomment']);
519:         $this->lifetime($aConf['lifetime']);
520:         $this->infoTemplate($aConf['infotemplate']);
521:         foreach ($aConf['idoptions'] as $name => $var) {
522:             $this->addOption($name, $var);
523:         }
524: 
525:         if (is_array($aConf['raiseonevent'])) {
526:             $this->_aEventCode = $aConf['raiseonevent'];
527:         }
528: 
529:         // check, if code is to create
530:         $this->_bEnableCaching = !$this->_isCode2Create($iCreateCode);
531:         if ($this->_bEnableCaching == false) {
532:             $this->removeFromCache();
533:         }
534:     }
535: 
536:     /**
537:      * Checks, if the create code flag is set.
538:      * Output will be loaded from cache, if no code is to create.
539:      * It also checks the state of global variable $force.
540:      *
541:      * @param mixed $iCreateCode
542:      *         State of create code (0 or 1).
543:      *         The state will be loaded from database if value is NULL
544:      * @return bool
545:      *         True if code is to create, otherwise false.
546:      */
547:     protected function _isCode2Create($iCreateCode) {
548:         if ($this->_bEnableCaching == false) {
549:             return;
550:         }
551: 
552:         // check content of global variable $force, get out if is's set to '1'
553:         if (isset($GLOBALS['force']) && is_numeric($GLOBALS['force']) && $GLOBALS['force'] == 1) {
554:             return true;
555:         }
556: 
557:         if (is_null($iCreateCode)) {
558:             // check if code is expired
559: 
560:             $oApiCatArtColl = new cApiCategoryArticleCollection('idart="' . $GLOBALS['idart'] . '" AND idcat="' . $GLOBALS['idcat'] . '"');
561:             if ($oApiCatArt = $oApiCatArtColl->next()) {
562:                 $iCreateCode = $oApiCatArt->get('createcode');
563:                 unset($oApiCatArt);
564:             }
565:             unset($oApiCatArtColl);
566:         }
567: 
568:         return ($iCreateCode == 1) ? true : false;
569:     }
570: 
571: }
572: 
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0