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.
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 with
198:      * 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:      * Used to generate the id for caching.
258:      *
259:      * @param string $name
260:      *         Name of option
261:      * @param string $option
262:      *         Value of option (any variable)
263:      */
264:     public function addOption($name, $option) {
265:         $this->_aIDOptions[$name] = $option;
266:     }
267: 
268:     /**
269:      * Returns information cache hit/miss and execution time if caching is
270:      * enabled.
271:      *
272:      * @return string
273:      *         Information about cache if caching is enabled, otherwise nothing.
274:      */
275:     public function getInfo() {
276:         if (!$this->_bEnableCaching) {
277:             return;
278:         }
279: 
280:         return $this->_sDebugMsg;
281:     }
282: 
283:     /**
284:      * Starts the cache process.
285:      *
286:      * @return bool|string
287:      */
288:     protected function _start() {
289:         $id = $this->_sID;
290:         $group = $this->_sGroup;
291: 
292:         // this is already cached return it from the cache so that the user
293:         // can use the cache content and stop script execution
294:         if ($content = $this->_fileCache->get($id, $group)) {
295:             return $content;
296:         }
297: 
298:         // WARNING: we need the output buffer - possible clashes
299:         ob_start();
300:         ob_implicit_flush(false);
301: 
302:         return '';
303:     }
304: 
305:     /**
306:      * Handles PEAR caching.
307:      * The script will be terminated by calling die(), if any cached
308:      * content is found.
309:      *
310:      * @param int $iPageStartTime [optional]
311:      *         Optional start time, e. g. start time of main script
312:      */
313:     public function start($iPageStartTime = NULL) {
314:         if (!$this->_bEnableCaching) {
315:             return;
316:         }
317: 
318:         $this->_iStartTime = $this->_getMicroTime();
319: 
320:         // set cache object and unique id
321:         $this->_initFileCache();
322: 
323:         // check if it's cached and start the output buffering if necessary
324:         if ($content = $this->_start()) {
325:             // raise beforeoutput event
326:             $this->_raiseEvent('beforeoutput');
327: 
328:             $iEndTime = $this->_getMicroTime();
329:             if ($this->_bHtmlComment) {
330:                 $time = sprintf("%2.4f", $iEndTime - $this->_iStartTime);
331:                 $exp = ($this->_iLifetime == 0? 'infinite' : date('Y-m-d H:i:s', time() + $this->_iLifetime));
332:                 $content .= sprintf($this->_sHtmlCommentTpl, 'HIT', $time . ' sec.', $exp);
333:                 if ($iPageStartTime != NULL && is_numeric($iPageStartTime)) {
334:                     $content .= '<!-- [' . sprintf("%2.4f", $iEndTime - $iPageStartTime) . '] -->';
335:                 }
336:             }
337: 
338:             if ($this->_bDebug) {
339:                 $info = sprintf("HIT: %2.4f sec.", $iEndTime - $this->_iStartTime);
340:                 $info = sprintf($this->_sDebugTpl, $info);
341:                 $content = str_ireplace('</body>', $info . "\n</body>", $content);
342:             }
343: 
344:             echo $content;
345: 
346:             // raise afteroutput event
347:             $this->_raiseEvent('afteroutput');
348: 
349:             die();
350:         }
351:     }
352: 
353:     /**
354:      * Handles ending of PEAR caching.
355:      */
356:     public function end() {
357:         if (!$this->_bEnableCaching) {
358:             return;
359:         }
360: 
361:         $content = ob_get_contents();
362:         ob_end_clean();
363: 
364:         $this->_fileCache->save($content, $this->_sID, $this->_sGroup);
365: 
366:         echo $content;
367: 
368:         if ($this->_bDebug) {
369:             $this->_sDebugMsg .= "\n" . sprintf("MISS: %2.4f sec.\n", $this->_getMicroTime() - $this->_iStartTime);
370:             $this->_sDebugMsg = sprintf($this->_sDebugTpl, $this->_sDebugMsg);
371:         }
372:     }
373: 
374:     /**
375:      * Removes any cached content if exists.
376:      * This is nesessary to delete cached articles, if they are changed on
377:      * backend.
378:      */
379:     public function removeFromCache() {
380:         // set cache object and unique id
381:         $this->_initFileCache();
382:         $this->_fileCache->remove($this->_sID, $this->_sGroup);
383:     }
384: 
385:     /**
386:      * Creates one-time a instance of PEAR cache output object and also the
387:      * unique id,
388:      * if propery $this->_oPearCache is not set.
389:      */
390:     protected function _initFileCache() {
391:         if (is_object($this->_fileCache)) {
392:             return;
393:         }
394: 
395:         // create a output cache object mode - file storage
396:         $this->_fileCache = new cFileCache($this->_aCacheOptions);
397: 
398:         // generate an ID from whatever might influence the script behaviour
399:         $this->_sID = $this->_fileCache->generateID($this->_aIDOptions);
400:     }
401: 
402:     /**
403:      * Raises any defined event code by using eval().
404:      *
405:      * @param string $name
406:      *         Name of event to raise
407:      */
408:     protected function _raiseEvent($name) {
409:         // check if event exists, get out if not
410:         if (!isset($this->_aEventCode[$name]) && !is_array($this->_aEventCode[$name])) {
411:             return;
412:         }
413: 
414:         // loop array and execute each defined php-code
415:         foreach ($this->_aEventCode[$name] as $code) {
416:             eval($code);
417:         }
418:     }
419: 
420:     /**
421:      * Returns microtime (UNIX timestamp), used to calculate time of execution.
422:      *
423:      * @return float
424:      *         Timestamp
425:      */
426:     protected function _getMicroTime() {
427:         $mtime = explode(' ', microtime());
428:         $mtime = $mtime[1] + $mtime[0];
429: 
430:         return $mtime;
431:     }
432: }
433: 
434: /**
435:  * This class contains functions for the output cache handler in CONTENIDO.
436:  *
437:  * @package Core
438:  * @subpackage Cache
439:  */
440: class cOutputCacheHandler extends cOutputCache {
441: 
442:     /**
443:      * Constructor of cOutputCacheHandler.
444:      * Does some checks and sets the configuration of cache object.
445:      *
446:      * @param array $aConf
447:      *         Configuration of caching as follows:
448:      *         - $a['excludecontenido'] bool
449:      *             don't cache output, if we have a CONTENIDO variable,
450:      *             e. g. on calling frontend preview from backend
451:      *         - $a['enable'] bool
452:      *             activate caching of frontend output
453:      *         - $a['debug'] bool
454:      *             compose debuginfo (hit/miss and execution time of caching)
455:      *         - $a['infotemplate'] string
456:      *             debug information template
457:      *         - $a['htmlcomment'] bool
458:      *             add a html comment including several debug messages to output
459:      *         - $a['lifetime'] int
460:      *             lifetime in seconds to cache output
461:      *         - $a['cachedir'] string
462:      *             directory where cached content is to store.
463:      *         - $a['cachegroup'] string
464:      *             cache group, will be a subdirectory inside cachedir
465:      *         - $a['cacheprefix'] string
466:      *             add prefix to stored filenames
467:      *         - $a['idoptions'] array
468:      *             several variables to create a unique id,
469:      *             if the output depends on them. e. g.
470:      *             array(
471:      *                 'uri' => $_SERVER['REQUEST_URI'],
472:      *                 'post' => $_POST, 'get' => $_GET
473:      *             )
474:      * @param cDb $db
475:      *         CONTENIDO database object
476:      * @param int $iCreateCode [optional]
477:      *         Flag of createcode state from table con_cat_art
478:      */
479:     public function __construct($aConf, $db, $iCreateCode = NULL) {
480:         // check if caching is allowed on CONTENIDO variable
481:         if ($aConf['excludecontenido'] == true) {
482:             if (isset($GLOBALS['contenido'])) {
483:                 // CONTENIDO variable exists, set state and get out here
484:                 $this->_bEnableCaching = false;
485: 
486:                 return;
487:             }
488:         }
489: 
490:         // set enable state of caching
491:         if (is_bool($aConf['enable'])) {
492:             $this->_bEnableCaching = $aConf['enable'];
493:         }
494:         if ($this->_bEnableCaching == false) {
495:             return;
496:         }
497: 
498:         // check if current article shouldn't be cached (by stese)
499:         $sExcludeIdarts = getEffectiveSetting('cache', 'excludeidarts', false);
500:         if ($sExcludeIdarts && strlen($sExcludeIdarts) > 0) {
501:             $sExcludeIdarts = preg_replace("/[^0-9,]/", '', $sExcludeIdarts);
502:             $aExcludeIdart = explode(',', $sExcludeIdarts);
503:             if (in_array($GLOBALS['idart'], $aExcludeIdart)) {
504:                 $this->_bEnableCaching = false;
505: 
506:                 return;
507:             }
508:         }
509: 
510:         $this->_oDB = $db;
511: 
512:         // set caching configuration
513:         parent::__construct($aConf['cachedir'], $aConf['cachegroup']);
514:         $this->debug($aConf['debug']);
515:         $this->htmlComment($aConf['htmlcomment']);
516:         $this->lifetime($aConf['lifetime']);
517:         $this->infoTemplate($aConf['infotemplate']);
518:         foreach ($aConf['idoptions'] as $name => $var) {
519:             $this->addOption($name, $var);
520:         }
521: 
522:         if (is_array($aConf['raiseonevent'])) {
523:             $this->_aEventCode = $aConf['raiseonevent'];
524:         }
525: 
526:         // check, if code is to create
527:         $this->_bEnableCaching = !$this->_isCode2Create($iCreateCode);
528:         if ($this->_bEnableCaching == false) {
529:             $this->removeFromCache();
530:         }
531:     }
532: 
533:     /**
534:      * Checks, if the create code flag is set.
535:      * Output will be loaded from cache, if no code is to create.
536:      * It also checks the state of global variable $force.
537:      *
538:      * @param mixed $iCreateCode
539:      *         State of create code (0 or 1).
540:      *         The state will be loaded from database if value is NULL
541:      * @return bool
542:      *         True if code is to create, otherwise false.
543:      */
544:     protected function _isCode2Create($iCreateCode) {
545:         if ($this->_bEnableCaching == false) {
546:             return;
547:         }
548: 
549:         // check content of global variable $force, get out if is's set to '1'
550:         if (isset($GLOBALS['force']) && is_numeric($GLOBALS['force']) && $GLOBALS['force'] == 1) {
551:             return true;
552:         }
553: 
554:         if (is_null($iCreateCode)) {
555:             // check if code is expired
556: 
557:             $oApiCatArtColl = new cApiCategoryArticleCollection('idart="' . $GLOBALS['idart'] . '" AND idcat="' . $GLOBALS['idcat'] . '"');
558:             if ($oApiCatArt = $oApiCatArtColl->next()) {
559:                 $iCreateCode = $oApiCatArt->get('createcode');
560:                 unset($oApiCatArt);
561:             }
562:             unset($oApiCatArtColl);
563:         }
564: 
565:         return ($iCreateCode == 1) ? true : false;
566:     }
567: 
568: }
569: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0