PageRenderTime 103ms CodeModel.GetById 60ms app.highlight 7ms RepoModel.GetById 33ms app.codeStats 1ms

/Cache/Frontend/Class.php

https://bitbucket.org/goldie/zend-framework1
PHP | 265 lines | 102 code | 23 blank | 140 comment | 16 complexity | d39f67badf5a481d53eda24a5693be7e MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Cache
 17 * @subpackage Zend_Cache_Frontend
 18 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Class.php 24032 2011-05-10 21:08:20Z mabe $
 21 */
 22
 23/**
 24 * @see Zend_Cache_Core
 25 */
 26require_once 'Zend/Cache/Core.php';
 27
 28
 29/**
 30 * @package    Zend_Cache
 31 * @subpackage Zend_Cache_Frontend
 32 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 33 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 34 */
 35class Zend_Cache_Frontend_Class extends Zend_Cache_Core
 36{
 37    /**
 38     * Available options
 39     *
 40     * ====> (mixed) cached_entity :
 41     * - if set to a class name, we will cache an abstract class and will use only static calls
 42     * - if set to an object, we will cache this object methods
 43     *
 44     * ====> (boolean) cache_by_default :
 45     * - if true, method calls will be cached by default
 46     *
 47     * ====> (array) cached_methods :
 48     * - an array of method names which will be cached (even if cache_by_default = false)
 49     *
 50     * ====> (array) non_cached_methods :
 51     * - an array of method names which won't be cached (even if cache_by_default = true)
 52     *
 53     * @var array available options
 54     */
 55    protected $_specificOptions = array(
 56        'cached_entity' => null,
 57        'cache_by_default' => true,
 58        'cached_methods' => array(),
 59        'non_cached_methods' => array()
 60    );
 61
 62    /**
 63     * Tags array
 64     *
 65     * @var array
 66     */
 67    private $_tags = array();
 68
 69    /**
 70     * SpecificLifetime value
 71     *
 72     * false => no specific life time
 73     *
 74     * @var int
 75     */
 76    private $_specificLifetime = false;
 77
 78    /**
 79     * The cached object or the name of the cached abstract class
 80     *
 81     * @var mixed
 82     */
 83    private $_cachedEntity = null;
 84
 85     /**
 86      * The class name of the cached object or cached abstract class
 87      *
 88      * Used to differentiate between different classes with the same method calls.
 89      *
 90      * @var string
 91      */
 92    private $_cachedEntityLabel = '';
 93
 94    /**
 95     * Priority (used by some particular backends)
 96     *
 97     * @var int
 98     */
 99    private $_priority = 8;
100
101    /**
102     * Constructor
103     *
104     * @param  array $options Associative array of options
105     * @throws Zend_Cache_Exception
106     * @return void
107     */
108    public function __construct(array $options = array())
109    {
110        while (list($name, $value) = each($options)) {
111            $this->setOption($name, $value);
112        }
113        if ($this->_specificOptions['cached_entity'] === null) {
114            Zend_Cache::throwException('cached_entity must be set !');
115        }
116        $this->setCachedEntity($this->_specificOptions['cached_entity']);
117        $this->setOption('automatic_serialization', true);
118    }
119
120    /**
121     * Set a specific life time
122     *
123     * @param  int $specificLifetime
124     * @return void
125     */
126    public function setSpecificLifetime($specificLifetime = false)
127    {
128        $this->_specificLifetime = $specificLifetime;
129    }
130
131    /**
132     * Set the priority (used by some particular backends)
133     *
134     * @param int $priority integer between 0 (very low priority) and 10 (maximum priority)
135     */
136    public function setPriority($priority)
137    {
138        $this->_priority = $priority;
139    }
140
141    /**
142     * Public frontend to set an option
143     *
144     * Just a wrapper to get a specific behaviour for cached_entity
145     *
146     * @param  string $name  Name of the option
147     * @param  mixed  $value Value of the option
148     * @throws Zend_Cache_Exception
149     * @return void
150     */
151    public function setOption($name, $value)
152    {
153        if ($name == 'cached_entity') {
154            $this->setCachedEntity($value);
155        } else {
156            parent::setOption($name, $value);
157        }
158    }
159
160    /**
161     * Specific method to set the cachedEntity
162     *
163     * if set to a class name, we will cache an abstract class and will use only static calls
164     * if set to an object, we will cache this object methods
165     *
166     * @param mixed $cachedEntity
167     */
168    public function setCachedEntity($cachedEntity)
169    {
170        if (!is_string($cachedEntity) && !is_object($cachedEntity)) {
171            Zend_Cache::throwException('cached_entity must be an object or a class name');
172        }
173        $this->_cachedEntity = $cachedEntity;
174        $this->_specificOptions['cached_entity'] = $cachedEntity;
175        if (is_string($this->_cachedEntity)){
176            $this->_cachedEntityLabel = $this->_cachedEntity;
177        } else {
178            $ro = new ReflectionObject($this->_cachedEntity);
179            $this->_cachedEntityLabel = $ro->getName();
180        }
181    }
182
183    /**
184     * Set the cache array
185     *
186     * @param  array $tags
187     * @return void
188     */
189    public function setTagsArray($tags = array())
190    {
191        $this->_tags = $tags;
192    }
193
194    /**
195     * Main method : call the specified method or get the result from cache
196     *
197     * @param  string $name       Method name
198     * @param  array  $parameters Method parameters
199     * @return mixed Result
200     */
201    public function __call($name, $parameters)
202    {
203        $callback = array($this->_cachedEntity, $name);
204
205        if (!is_callable($callback, false)) {
206            Zend_Cache::throwException('Invalid callback');
207        }
208
209        $cacheBool1 = $this->_specificOptions['cache_by_default'];
210        $cacheBool2 = in_array($name, $this->_specificOptions['cached_methods']);
211        $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_methods']);
212        $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3));
213        if (!$cache) {
214            // We do not have not cache
215            return call_user_func_array($callback, $parameters);
216        }
217
218        $id = $this->_makeId($name, $parameters);
219        if ( ($rs = $this->load($id)) && isset($rs[0], $rs[1]) ) {
220            // A cache is available
221            $output = $rs[0];
222            $return = $rs[1];
223        } else {
224            // A cache is not available (or not valid for this frontend)
225            ob_start();
226            ob_implicit_flush(false);
227
228            try {
229                $return = call_user_func_array($callback, $parameters);
230                $output = ob_get_clean();
231                $data = array($output, $return);
232                $this->save($data, $id, $this->_tags, $this->_specificLifetime, $this->_priority);
233            } catch (Exception $e) {
234                ob_end_clean();
235                throw $e;
236            }
237        }
238
239        echo $output;
240        return $return;
241    }
242
243    /**
244     * ZF-9970
245     *
246     * @deprecated
247     */
248    private function _makeId($name, $args)
249    {
250        return $this->makeId($name, $args);
251    }
252
253    /**
254     * Make a cache id from the method name and parameters
255     *
256     * @param  string $name Method name
257     * @param  array  $args Method parameters
258     * @return string Cache id
259     */
260    public function makeId($name, array $args = array())
261    {
262        return md5($this->_cachedEntityLabel . '__' . $name . '__' . serialize($args));
263    }
264
265}