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