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

  • CFilter
  • CFilterChain
  • CHttpCacheFilter
  • CInlineFilter
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * CHttpCacheFilter class file.
  4:  *
  5:  * @author Da:Sourcerer <webmaster@dasourcerer.net>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * CHttpCacheFilter implements http caching. It works a lot like {@link COutputCache}
 13:  * as a filter, except that content caching is being done on the client side.
 14:  *
 15:  * @author Da:Sourcerer <webmaster@dasourcerer.net>
 16:  * @package system.web.filters
 17:  * @since 1.1.11
 18:  */
 19: class CHttpCacheFilter extends CFilter
 20: {
 21:     /**
 22:      * @var string|integer Timestamp for the last modification date.
 23:      * Must be either a string parsable by {@link http://php.net/strtotime strtotime()}
 24:      * or an integer representing a unix timestamp.
 25:      */
 26:     public $lastModified;
 27:     /**
 28:      * @var string|callback PHP Expression for the last modification date.
 29:      * If set, this takes precedence over {@link lastModified}.
 30:      *
 31:      * The PHP expression will be evaluated using {@link evaluateExpression}.
 32:      *
 33:      * A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
 34:      * please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
 35:      */
 36:     public $lastModifiedExpression;
 37:     /**
 38:      * @var mixed Seed for the ETag.
 39:      * Can be anything that passes through {@link http://php.net/serialize serialize()}.
 40:      */
 41:     public $etagSeed;
 42:     /**
 43:      * @var string|callback Expression for the ETag seed.
 44:      * If set, this takes precedence over {@link etagSeed}.
 45:      *
 46:      * The PHP expression will be evaluated using {@link evaluateExpression}.
 47:      *
 48:      * A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
 49:      * please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
 50:      */
 51:     public $etagSeedExpression;
 52:     /**
 53:      * @var string Http cache control headers. Set this to an empty string in order to keep this
 54:      * header from being sent entirely.
 55:      */
 56:     public $cacheControl='max-age=3600, public';
 57: 
 58:     /**
 59:      * Performs the pre-action filtering.
 60:      * @param CFilterChain $filterChain the filter chain that the filter is on.
 61:      * @return boolean whether the filtering process should continue and the action should be executed.
 62:      */
 63:     public function preFilter($filterChain)
 64:     {
 65:         // Only cache GET and HEAD requests
 66:         if(!in_array(Yii::app()->getRequest()->getRequestType(), array('GET', 'HEAD')))
 67:             return true;
 68: 
 69:         $lastModified=$this->getLastModifiedValue();
 70:         $etag=$this->getEtagValue();
 71: 
 72:         if($etag===false&&$lastModified===false)
 73:             return true;
 74: 
 75:         if($etag)
 76:             header('ETag: '.$etag);
 77: 
 78:         if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])&&isset($_SERVER['HTTP_IF_NONE_MATCH']))
 79:         {
 80:             if($this->checkLastModified($lastModified)&&$this->checkEtag($etag))
 81:             {
 82:                 $this->send304Header();
 83:                 $this->sendCacheControlHeader();
 84:                 return false;
 85:             }
 86:         }
 87:         elseif(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
 88:         {
 89:             if($this->checkLastModified($lastModified))
 90:             {
 91:                 $this->send304Header();
 92:                 $this->sendCacheControlHeader();
 93:                 return false;
 94:             }
 95:         }
 96:         elseif(isset($_SERVER['HTTP_IF_NONE_MATCH']))
 97:         {
 98:             if($this->checkEtag($etag))
 99:             {
100:                 $this->send304Header();
101:                 $this->sendCacheControlHeader();
102:                 return false;
103:             }
104: 
105:         }
106: 
107:         if($lastModified)
108:             header('Last-Modified: '.gmdate('D, d M Y H:i:s', $lastModified).' GMT');
109: 
110:         $this->sendCacheControlHeader();
111:         return true;
112:     }
113: 
114:     /**
115:      * Gets the last modified value from either {@link lastModifiedExpression} or {@link lastModified}
116:      * and converts it into a unix timestamp if necessary
117:      * @throws CException
118:      * @return integer|boolean A unix timestamp or false if neither lastModified nor
119:      * lastModifiedExpression have been set
120:      */
121:     protected function getLastModifiedValue()
122:     {
123:         if($this->lastModifiedExpression)
124:         {
125:             $value=$this->evaluateExpression($this->lastModifiedExpression);
126:             if(is_numeric($value)&&$value==(int)$value)
127:                 return $value;
128:             elseif(($lastModified=strtotime($value))===false)
129:                 throw new CException(Yii::t('yii','Invalid expression for CHttpCacheFilter.lastModifiedExpression: The evaluation result "{value}" could not be understood by strtotime()',
130:                     array('{value}'=>$value)));
131:             return $lastModified;
132:         }
133: 
134:         if($this->lastModified)
135:         {
136:             if(is_numeric($this->lastModified)&&$this->lastModified==(int)$this->lastModified)
137:                 return $this->lastModified;
138:             elseif(($lastModified=strtotime($this->lastModified))===false)
139:                 throw new CException(Yii::t('yii','CHttpCacheFilter.lastModified contained a value that could not be understood by strtotime()'));
140:             return $lastModified;
141:         }
142:         return false;
143:     }
144: 
145:     /**
146:      *  Gets the ETag out of either {@link etagSeedExpression} or {@link etagSeed}
147:      *  @return string|boolean Either a quoted string serving as ETag or false if neither etagSeed nor etagSeedExpression have been set
148:      */
149:     protected function getEtagValue()
150:     {
151:         if($this->etagSeedExpression)
152:             return $this->generateEtag($this->evaluateExpression($this->etagSeedExpression));
153:         elseif($this->etagSeed)
154:             return $this->generateEtag($this->etagSeed);
155:         return false;
156:     }
157: 
158:     /**
159:      * Check if the etag supplied by the client matches our generated one
160:      * @param string $etag the supplied etag
161:      * @return boolean true if the supplied etag matches $etag
162:      */
163:     protected function checkEtag($etag)
164:     {
165:         return isset($_SERVER['HTTP_IF_NONE_MATCH'])&&$_SERVER['HTTP_IF_NONE_MATCH']==$etag;
166:     }
167: 
168:     /**
169:      * Checks if the last modified date supplied by the client is still up to date
170:      * @param integer $lastModified the last modified date
171:      * @return boolean true if the last modified date sent by the client is newer or equal to $lastModified
172:      */
173:     protected function checkLastModified($lastModified)
174:     {
175:         return isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])&&@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$lastModified;
176:     }
177: 
178:     /**
179:      * Sends the 304 HTTP status code to the client
180:      */
181:     protected function send304Header()
182:     {
183:         $httpVersion=Yii::app()->request->getHttpVersion();
184:         header("HTTP/$httpVersion 304 Not Modified");
185:     }
186: 
187:     /**
188:      * Sends the cache control header to the client
189:      * @see cacheControl
190:      * @since 1.1.12
191:      */
192:     protected function sendCacheControlHeader()
193:     {
194:         if(Yii::app()->session->isStarted)
195:         {
196:             session_cache_limiter('public');
197:             header('Pragma:',true);
198:         }
199:         header('Cache-Control: '.$this->cacheControl,true);
200:     }
201: 
202:     /**
203:      * Generates a quoted string out of the seed
204:      * @param mixed $seed Seed for the ETag
205:      */
206:     protected function generateEtag($seed)
207:     {
208:         return '"'.base64_encode(sha1(serialize($seed),true)).'"';
209:     }
210: }
211: 
API documentation generated by ApiGen 2.8.0