Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • Net
  • None
  • PHP
  • system
    • base
    • caching
      • dependencies
    • collections
    • console
    • db
      • ar
      • schema
        • cubrid
        • mssql
        • mysql
        • oci
        • pgsql
        • sqlite
    • i18n
      • gettext
    • logging
    • test
    • utils
    • validators
    • web
      • actions
      • auth
      • filters
      • form
      • helpers
      • renderers
      • services
      • widgets
        • captcha
        • pagers
  • Text
    • Highlighter
  • zii
    • behaviors
    • widgets
      • grid
      • jui

Classes

  • ActionActiveForm
  • ActionActiveFormBase
  • CActiveForm
  • CalendarEventActiveForm
  • CallActiveForm
  • CClipWidget
  • CContentDecorator
  • CFilterWidget
  • CFlexWidget
  • CHtmlPurifier
  • CInputWidget
  • CMarkdown
  • CMaskedTextField
  • CMultiFileUpload
  • COutputCache
  • COutputProcessor
  • CStarRating
  • CTabView
  • CTextHighlighter
  • CTreeView
  • CWidget
  • EventActiveForm
  • MobileActiveForm
  • NoteActiveForm
  • TimeActiveForm
  • X2ActiveForm
  • X2StarRating
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * COutputCache class file.
  4:  *
  5:  * @author Qiang Xue <qiang.xue@gmail.com>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * COutputCache enables caching the output generated by an action or a view fragment.
 13:  *
 14:  * If the output to be displayed is found valid in cache, the cached
 15:  * version will be displayed instead, which saves the time for generating
 16:  * the original output.
 17:  *
 18:  * Since COutputCache extends from {@link CFilterWidget}, it can be used
 19:  * as either a filter (for action caching) or a widget (for fragment caching).
 20:  * For the latter, the shortcuts {@link CBaseController::beginCache()} and {@link CBaseController::endCache()}
 21:  * are often used instead, like the following in a view file:
 22:  * <pre>
 23:  * if($this->beginCache('cacheName',array('property1'=>'value1',...))
 24:  * {
 25:  *     // ... display the content to be cached here
 26:  *    $this->endCache();
 27:  * }
 28:  * </pre>
 29:  *
 30:  * COutputCache must work with a cache application component specified via {@link cacheID}.
 31:  * If the cache application component is not available, COutputCache will be disabled.
 32:  *
 33:  * The validity of the cached content is determined based on two factors:
 34:  * the {@link duration} and the cache {@link dependency}.
 35:  * The former specifies the number of seconds that the data can remain
 36:  * valid in cache (defaults to 60s), while the latter specifies conditions
 37:  * that the cached data depends on. If a dependency changes,
 38:  * (e.g. relevant data in DB are updated), the cached data will be invalidated.
 39:  * For more details about cache dependency, see {@link CCacheDependency}.
 40:  *
 41:  * Sometimes, it is necessary to turn off output caching only for certain request types.
 42:  * For example, we only want to cache a form when it is initially requested;
 43:  * any subsequent display of the form should not be cached because it contains user input.
 44:  * We can set {@link requestTypes} to be <code>array('GET')</code> to accomplish this task.
 45:  *
 46:  * The content fetched from cache may be variated with respect to
 47:  * some parameters. COutputCache supports four kinds of variations:
 48:  * <ul>
 49:  * <li>{@link varyByRoute}: this specifies whether the cached content
 50:  *   should be varied with the requested route (controller and action)</li>
 51:  * <li>{@link varyByParam}: this specifies a list of GET parameter names
 52:  *   and uses the corresponding values to determine the version of the cached content.</li>
 53:  * <li>{@link varyBySession}: this specifies whether the cached content
 54:  *   should be varied with the user session.</li>
 55:  * <li>{@link varyByExpression}: this specifies whether the cached content
 56:  *   should be varied with the result of the specified PHP expression.</li>
 57:  * <li>{@link varyByLanguage}: this specifies whether the cached content
 58:  *   should by varied with the user's language. Available since 1.1.14.</li>
 59:  * </ul>
 60:  * For more advanced variation, override {@link getBaseCacheKey()} method.
 61:  *
 62:  * @property boolean $isContentCached Whether the content can be found from cache.
 63:  *
 64:  * @author Qiang Xue <qiang.xue@gmail.com>
 65:  * @package system.web.widgets
 66:  * @since 1.0
 67:  */
 68: class COutputCache extends CFilterWidget
 69: {
 70:     /**
 71:      * Prefix to the keys for storing cached data
 72:      */
 73:     const CACHE_KEY_PREFIX='Yii.COutputCache.';
 74: 
 75:     /**
 76:      * @var integer number of seconds that the data can remain in cache. Defaults to 60 seconds.
 77:      * If it is 0, existing cached content would be removed from the cache.
 78:      * If it is a negative value, the cache will be disabled (any existing cached content will
 79:      * remain in the cache.)
 80:      *
 81:      * Note, if cache dependency changes or cache space is limited,
 82:      * the data may be purged out of cache earlier.
 83:      */
 84:     public $duration=60;
 85:     /**
 86:      * @var boolean whether the content being cached should be differentiated according to route.
 87:      * A route consists of the requested controller ID and action ID.
 88:      * Defaults to true.
 89:      */
 90:     public $varyByRoute=true;
 91:     /**
 92:      * @var boolean whether the content being cached should be differentiated according to user sessions. Defaults to false.
 93:      */
 94:     public $varyBySession=false;
 95:     /**
 96:      * @var array list of GET parameters that should participate in cache key calculation.
 97:      * By setting this property, the output cache will use different cached data
 98:      * for each different set of GET parameter values.
 99:      */
100:     public $varyByParam;
101:     /**
102:      * @var string a PHP expression whose result is used in the cache key calculation.
103:      * By setting this property, the output cache will use different cached data
104:      * for each different expression result.
105:      * The expression can also be a valid PHP callback,
106:      * including class method name (array(ClassName/Object, MethodName)),
107:      * or anonymous function (PHP 5.3.0+). The function/method signature should be as follows:
108:      * <pre>
109:      * function foo($cache) { ... }
110:      * </pre>
111:      * where $cache refers to the output cache component.
112:      *
113:      * The PHP expression will be evaluated using {@link evaluateExpression}.
114:      *
115:      * A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
116:      * please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
117:      */
118:     public $varyByExpression;
119:     /**
120:      * @var boolean whether the content being cached should be differentiated according to user's language.
121:      * A language is retrieved via Yii::app()->language.
122:      * Defaults to false.
123:      * @since 1.1.14
124:      */
125:     public $varyByLanguage=false;
126:     /**
127:      * @var array list of request types (e.g. GET, POST) for which the cache should be enabled only.
128:      * Defaults to null, meaning all request types.
129:      */
130:     public $requestTypes;
131:     /**
132:      * @var string the ID of the cache application component. Defaults to 'cache' (the primary cache application component.)
133:      */
134:     public $cacheID='cache';
135:     /**
136:      * @var mixed the dependency that the cached content depends on.
137:      * This can be either an object implementing {@link ICacheDependency} interface or an array
138:      * specifying the configuration of the dependency object. For example,
139:      * <pre>
140:      * array(
141:      *     'class'=>'CDbCacheDependency',
142:      *     'sql'=>'SELECT MAX(lastModified) FROM Post',
143:      * )
144:      * </pre>
145:      * would make the output cache depends on the last modified time of all posts.
146:      * If any post has its modification time changed, the cached content would be invalidated.
147:      */
148:     public $dependency;
149: 
150:     private $_key;
151:     private $_cache;
152:     private $_contentCached;
153:     private $_content;
154:     private $_actions;
155: 
156:     /**
157:      * Performs filtering before the action is executed.
158:      * This method is meant to be overridden by child classes if begin-filtering is needed.
159:      * @param CFilterChain $filterChain list of filters being applied to an action
160:      * @return boolean whether the filtering process should stop after this filter. Defaults to false.
161:      */
162:     public function filter($filterChain)
163:     {
164:         if(!$this->getIsContentCached())
165:             $filterChain->run();
166:         $this->run();
167:     }
168: 
169:     /**
170:      * Marks the start of content to be cached.
171:      * Content displayed after this method call and before {@link endCache()}
172:      * will be captured and saved in cache.
173:      * This method does nothing if valid content is already found in cache.
174:      */
175:     public function init()
176:     {
177:         if($this->getIsContentCached())
178:             $this->replayActions();
179:         elseif($this->_cache!==null)
180:         {
181:             $this->getController()->getCachingStack()->push($this);
182:             ob_start();
183:             ob_implicit_flush(false);
184:         }
185:     }
186: 
187:     /**
188:      * Marks the end of content to be cached.
189:      * Content displayed before this method call and after {@link init()}
190:      * will be captured and saved in cache.
191:      * This method does nothing if valid content is already found in cache.
192:      */
193:     public function run()
194:     {
195:         if($this->getIsContentCached())
196:         {
197:             if($this->getController()->isCachingStackEmpty())
198:                 echo $this->getController()->processDynamicOutput($this->_content);
199:             else
200:                 echo $this->_content;
201:         }
202:         elseif($this->_cache!==null)
203:         {
204:             $this->_content=ob_get_clean();
205:             $this->getController()->getCachingStack()->pop();
206:             $data=array($this->_content,$this->_actions);
207:             if(is_array($this->dependency))
208:                 $this->dependency=Yii::createComponent($this->dependency);
209:             $this->_cache->set($this->getCacheKey(),$data,$this->duration,$this->dependency);
210: 
211:             if($this->getController()->isCachingStackEmpty())
212:                 echo $this->getController()->processDynamicOutput($this->_content);
213:             else
214:                 echo $this->_content;
215:         }
216:     }
217: 
218:     /**
219:      * @return boolean whether the content can be found from cache
220:      */
221:     public function getIsContentCached()
222:     {
223:         if($this->_contentCached!==null)
224:             return $this->_contentCached;
225:         else
226:             return $this->_contentCached=$this->checkContentCache();
227:     }
228: 
229:     /**
230:      * Looks for content in cache.
231:      * @return boolean whether the content is found in cache.
232:      */
233:     protected function checkContentCache()
234:     {
235:         if((empty($this->requestTypes) || in_array(Yii::app()->getRequest()->getRequestType(),$this->requestTypes))
236:             && ($this->_cache=$this->getCache())!==null)
237:         {
238:             if($this->duration>0 && ($data=$this->_cache->get($this->getCacheKey()))!==false)
239:             {
240:                 $this->_content=$data[0];
241:                 $this->_actions=$data[1];
242:                 return true;
243:             }
244:             if($this->duration==0)
245:                 $this->_cache->delete($this->getCacheKey());
246:             if($this->duration<=0)
247:                 $this->_cache=null;
248:         }
249:         return false;
250:     }
251: 
252:     /**
253:      * @return ICache the cache used for caching the content.
254:      */
255:     protected function getCache()
256:     {
257:         return Yii::app()->getComponent($this->cacheID);
258:     }
259: 
260:     /**
261:      * Caclulates the base cache key.
262:      * The calculated key will be further variated in {@link getCacheKey}.
263:      * Derived classes may override this method if more variations are needed.
264:      * @return string basic cache key without variations
265:      */
266:     protected function getBaseCacheKey()
267:     {
268:         return self::CACHE_KEY_PREFIX.$this->getId().'.';
269:     }
270: 
271:     /**
272:      * Calculates the cache key.
273:      * The key is calculated based on {@link getBaseCacheKey} and other factors, including
274:      * {@link varyByRoute}, {@link varyByParam}, {@link varyBySession} and {@link varyByLanguage}.
275:      * @return string cache key
276:      */
277:     protected function getCacheKey()
278:     {
279:         if($this->_key!==null)
280:             return $this->_key;
281:         else
282:         {
283:             $key=$this->getBaseCacheKey().'.';
284:             if($this->varyByRoute)
285:             {
286:                 $controller=$this->getController();
287:                 $key.=$controller->getUniqueId().'/';
288:                 if(($action=$controller->getAction())!==null)
289:                     $key.=$action->getId();
290:             }
291:             $key.='.';
292: 
293:             if($this->varyBySession)
294:                 $key.=Yii::app()->getSession()->getSessionID();
295:             $key.='.';
296: 
297:             if(is_array($this->varyByParam) && isset($this->varyByParam[0]))
298:             {
299:                 $params=array();
300:                 foreach($this->varyByParam as $name)
301:                 {
302:                     if(isset($_GET[$name]))
303:                         $params[$name]=$_GET[$name];
304:                     else
305:                         $params[$name]='';
306:                 }
307:                 $key.=serialize($params);
308:             }
309:             $key.='.';
310: 
311:             if($this->varyByExpression!==null)
312:                 $key.=$this->evaluateExpression($this->varyByExpression);
313:             $key.='.';
314: 
315:             if($this->varyByLanguage)
316:                 $key.=Yii::app()->language;
317:             $key.='.';
318: 
319:             return $this->_key=$key;
320:         }
321:     }
322: 
323:     /**
324:      * Records a method call when this output cache is in effect.
325:      * When the content is served from the output cache, the recorded
326:      * method will be re-invoked.
327:      * @param string $context a property name of the controller. The property should refer to an object
328:      * whose method is being recorded. If empty it means the controller itself.
329:      * @param string $method the method name
330:      * @param array $params parameters passed to the method
331:      */
332:     public function recordAction($context,$method,$params)
333:     {
334:         $this->_actions[]=array($context,$method,$params);
335:     }
336: 
337:     /**
338:      * Replays the recorded method calls.
339:      */
340:     protected function replayActions()
341:     {
342:         if(empty($this->_actions))
343:             return;
344:         $controller=$this->getController();
345:         $cs=Yii::app()->getClientScript();
346:         foreach($this->_actions as $action)
347:         {
348:             if($action[0]==='clientScript')
349:                 $object=$cs;
350:             elseif($action[0]==='')
351:                 $object=$controller;
352:             else
353:                 $object=$controller->{$action[0]};
354:             if(method_exists($object,$action[1]))
355:                 call_user_func_array(array($object,$action[1]),$action[2]);
356:             elseif($action[0]==='' && function_exists($action[1]))
357:                 call_user_func_array($action[1],$action[2]);
358:             else
359:                 throw new CException(Yii::t('yii','Unable to replay the action "{object}.{method}". The method does not exist.',
360:                     array('object'=>$action[0],
361:                         'method'=>$action[1])));
362:         }
363:     }
364: }
365: 
API documentation generated by ApiGen 2.8.0