File indexing completed on 2024-05-12 06:02:19

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Cache
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 
0023 /**
0024  * @package    Zend_Cache
0025  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0026  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0027  */
0028 class Zend_Cache_Core
0029 {
0030     /**
0031      * Messages
0032      */
0033     const BACKEND_NOT_SUPPORTS_TAG = 'tags are not supported by the current backend';
0034     const BACKEND_NOT_IMPLEMENTS_EXTENDED_IF = 'Current backend doesn\'t implement the Zend_Cache_Backend_ExtendedInterface, so this method is not available';
0035 
0036     /**
0037      * Backend Object
0038      *
0039      * @var Zend_Cache_Backend_Interface $_backend
0040      */
0041     protected $_backend = null;
0042 
0043     /**
0044      * Available options
0045      *
0046      * ====> (boolean) write_control :
0047      * - Enable / disable write control (the cache is read just after writing to detect corrupt entries)
0048      * - Enable write control will lightly slow the cache writing but not the cache reading
0049      * Write control can detect some corrupt cache files but maybe it's not a perfect control
0050      *
0051      * ====> (boolean) caching :
0052      * - Enable / disable caching
0053      * (can be very useful for the debug of cached scripts)
0054      *
0055      * =====> (string) cache_id_prefix :
0056      * - prefix for cache ids (namespace)
0057      *
0058      * ====> (boolean) automatic_serialization :
0059      * - Enable / disable automatic serialization
0060      * - It can be used to save directly datas which aren't strings (but it's slower)
0061      *
0062      * ====> (int) automatic_cleaning_factor :
0063      * - Disable / Tune the automatic cleaning process
0064      * - The automatic cleaning process destroy too old (for the given life time)
0065      *   cache files when a new cache file is written :
0066      *     0               => no automatic cache cleaning
0067      *     1               => systematic cache cleaning
0068      *     x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
0069      *
0070      * ====> (int) lifetime :
0071      * - Cache lifetime (in seconds)
0072      * - If null, the cache is valid forever.
0073      *
0074      * ====> (boolean) logging :
0075      * - If set to true, logging is activated (but the system is slower)
0076      *
0077      * ====> (boolean) ignore_user_abort
0078      * - If set to true, the core will set the ignore_user_abort PHP flag inside the
0079      *   save() method to avoid cache corruptions in some cases (default false)
0080      *
0081      * @var array $_options available options
0082      */
0083     protected $_options = array(
0084         'write_control'             => true,
0085         'caching'                   => true,
0086         'cache_id_prefix'           => null,
0087         'automatic_serialization'   => false,
0088         'automatic_cleaning_factor' => 10,
0089         'lifetime'                  => 3600,
0090         'logging'                   => false,
0091         'logger'                    => null,
0092         'ignore_user_abort'         => false
0093     );
0094 
0095     /**
0096      * Array of options which have to be transfered to backend
0097      *
0098      * @var array $_directivesList
0099      */
0100     protected static $_directivesList = array('lifetime', 'logging', 'logger');
0101 
0102     /**
0103      * Not used for the core, just a sort a hint to get a common setOption() method (for the core and for frontends)
0104      *
0105      * @var array $_specificOptions
0106      */
0107     protected $_specificOptions = array();
0108 
0109     /**
0110      * Last used cache id
0111      *
0112      * @var string $_lastId
0113      */
0114     private $_lastId = null;
0115 
0116     /**
0117      * True if the backend implements Zend_Cache_Backend_ExtendedInterface
0118      *
0119      * @var boolean $_extendedBackend
0120      */
0121     protected $_extendedBackend = false;
0122 
0123     /**
0124      * Array of capabilities of the backend (only if it implements Zend_Cache_Backend_ExtendedInterface)
0125      *
0126      * @var array
0127      */
0128     protected $_backendCapabilities = array();
0129 
0130     /**
0131      * Constructor
0132      *
0133      * @param  array|Zend_Config $options Associative array of options or Zend_Config instance
0134      * @throws Zend_Cache_Exception
0135      * @return void
0136      */
0137     public function __construct($options = array())
0138     {
0139         if ($options instanceof Zend_Config) {
0140             $options = $options->toArray();
0141         }
0142         if (!is_array($options)) {
0143             Zend_Cache::throwException("Options passed were not an array"
0144             . " or Zend_Config instance.");
0145         }
0146         foreach ($options as $name => $value) {
0147             $this->setOption($name, $value);
0148         }
0149         $this->_loggerSanity();
0150     }
0151 
0152     /**
0153      * Set options using an instance of type Zend_Config
0154      *
0155      * @param Zend_Config $config
0156      * @return Zend_Cache_Core
0157      */
0158     public function setConfig(Zend_Config $config)
0159     {
0160         $options = $config->toArray();
0161         foreach ($options as $name => $value) {
0162             $this->setOption($name, $value);
0163         }
0164         return $this;
0165     }
0166 
0167     /**
0168      * Set the backend
0169      *
0170      * @param  Zend_Cache_Backend $backendObject
0171      * @throws Zend_Cache_Exception
0172      * @return void
0173      */
0174     public function setBackend(Zend_Cache_Backend $backendObject)
0175     {
0176         $this->_backend= $backendObject;
0177         // some options (listed in $_directivesList) have to be given
0178         // to the backend too (even if they are not "backend specific")
0179         $directives = array();
0180         foreach (Zend_Cache_Core::$_directivesList as $directive) {
0181             $directives[$directive] = $this->_options[$directive];
0182         }
0183         $this->_backend->setDirectives($directives);
0184         if (in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_backend))) {
0185             $this->_extendedBackend = true;
0186             $this->_backendCapabilities = $this->_backend->getCapabilities();
0187         }
0188 
0189     }
0190 
0191     /**
0192      * Returns the backend
0193      *
0194      * @return Zend_Cache_Backend backend object
0195      */
0196     public function getBackend()
0197     {
0198         return $this->_backend;
0199     }
0200 
0201     /**
0202      * Public frontend to set an option
0203      *
0204      * There is an additional validation (relatively to the protected _setOption method)
0205      *
0206      * @param  string $name  Name of the option
0207      * @param  mixed  $value Value of the option
0208      * @throws Zend_Cache_Exception
0209      * @return void
0210      */
0211     public function setOption($name, $value)
0212     {
0213         if (!is_string($name)) {
0214             Zend_Cache::throwException("Incorrect option name!");
0215         }
0216         $name = strtolower($name);
0217         if (array_key_exists($name, $this->_options)) {
0218             // This is a Core option
0219             $this->_setOption($name, $value);
0220             return;
0221         }
0222         if (array_key_exists($name, $this->_specificOptions)) {
0223             // This a specic option of this frontend
0224             $this->_specificOptions[$name] = $value;
0225             return;
0226         }
0227     }
0228 
0229     /**
0230      * Public frontend to get an option value
0231      *
0232      * @param  string $name  Name of the option
0233      * @throws Zend_Cache_Exception
0234      * @return mixed option value
0235      */
0236     public function getOption($name)
0237     {
0238         $name = strtolower($name);
0239 
0240         if (array_key_exists($name, $this->_options)) {
0241             // This is a Core option
0242             return $this->_options[$name];
0243         }
0244 
0245         if (array_key_exists($name, $this->_specificOptions)) {
0246             // This a specic option of this frontend
0247             return $this->_specificOptions[$name];
0248         }
0249 
0250         Zend_Cache::throwException("Incorrect option name : $name");
0251     }
0252 
0253     /**
0254      * Set an option
0255      *
0256      * @param  string $name  Name of the option
0257      * @param  mixed  $value Value of the option
0258      * @throws Zend_Cache_Exception
0259      * @return void
0260      */
0261     private function _setOption($name, $value)
0262     {
0263         if (!is_string($name) || !array_key_exists($name, $this->_options)) {
0264             Zend_Cache::throwException("Incorrect option name : $name");
0265         }
0266         if ($name == 'lifetime' && empty($value)) {
0267             $value = null;
0268         }
0269         $this->_options[$name] = $value;
0270     }
0271 
0272     /**
0273      * Force a new lifetime
0274      *
0275      * The new value is set for the core/frontend but for the backend too (directive)
0276      *
0277      * @param  int $newLifetime New lifetime (in seconds)
0278      * @return void
0279      */
0280     public function setLifetime($newLifetime)
0281     {
0282         $this->_options['lifetime'] = $newLifetime;
0283         $this->_backend->setDirectives(array(
0284             'lifetime' => $newLifetime
0285         ));
0286     }
0287 
0288     /**
0289      * Test if a cache is available for the given id and (if yes) return it (false else)
0290      *
0291      * @param  string  $id                     Cache id
0292      * @param  boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
0293      * @param  boolean $doNotUnserialize       Do not serialize (even if automatic_serialization is true) => for internal use
0294      * @return mixed|false Cached datas
0295      */
0296     public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false)
0297     {
0298         if (!$this->_options['caching']) {
0299             return false;
0300         }
0301         $id = $this->_id($id); // cache id may need prefix
0302         $this->_lastId = $id;
0303         $this->_validateIdOrTag($id);
0304 
0305         $this->_log("Zend_Cache_Core: load item '{$id}'", 7);
0306         $data = $this->_backend->load($id, $doNotTestCacheValidity);
0307         if ($data===false) {
0308             // no cache available
0309             return false;
0310         }
0311         if ((!$doNotUnserialize) && $this->_options['automatic_serialization']) {
0312             // we need to unserialize before sending the result
0313             return unserialize($data);
0314         }
0315         return $data;
0316     }
0317 
0318     /**
0319      * Test if a cache is available for the given id
0320      *
0321      * @param  string $id Cache id
0322      * @return int|false Last modified time of cache entry if it is available, false otherwise
0323      */
0324     public function test($id)
0325     {
0326         if (!$this->_options['caching']) {
0327             return false;
0328         }
0329         $id = $this->_id($id); // cache id may need prefix
0330         $this->_validateIdOrTag($id);
0331         $this->_lastId = $id;
0332 
0333         $this->_log("Zend_Cache_Core: test item '{$id}'", 7);
0334         return $this->_backend->test($id);
0335     }
0336 
0337     /**
0338      * Save some data in a cache
0339      *
0340      * @param  mixed $data           Data to put in cache (can be another type than string if automatic_serialization is on)
0341      * @param  string $id             Cache id (if not set, the last cache id will be used)
0342      * @param  array $tags           Cache tags
0343      * @param  int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
0344      * @param  int   $priority         integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends
0345      * @throws Zend_Cache_Exception
0346      * @return boolean True if no problem
0347      */
0348     public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8)
0349     {
0350         if (!$this->_options['caching']) {
0351             return true;
0352         }
0353         if ($id === null) {
0354             $id = $this->_lastId;
0355         } else {
0356             $id = $this->_id($id);
0357         }
0358         $this->_validateIdOrTag($id);
0359         $this->_validateTagsArray($tags);
0360         if ($this->_options['automatic_serialization']) {
0361             // we need to serialize datas before storing them
0362             $data = serialize($data);
0363         } else {
0364             if (!is_string($data)) {
0365                 Zend_Cache::throwException("Datas must be string or set automatic_serialization = true");
0366             }
0367         }
0368 
0369         // automatic cleaning
0370         if ($this->_options['automatic_cleaning_factor'] > 0) {
0371             $rand = rand(1, $this->_options['automatic_cleaning_factor']);
0372             if ($rand==1) {
0373                 //  new way                 || deprecated way
0374                 if ($this->_extendedBackend || method_exists($this->_backend, 'isAutomaticCleaningAvailable')) {
0375                     $this->_log("Zend_Cache_Core::save(): automatic cleaning running", 7);
0376                     $this->clean(Zend_Cache::CLEANING_MODE_OLD);
0377                 } else {
0378                     $this->_log("Zend_Cache_Core::save(): automatic cleaning is not available/necessary with current backend", 4);
0379                 }
0380             }
0381         }
0382 
0383         $this->_log("Zend_Cache_Core: save item '{$id}'", 7);
0384         if ($this->_options['ignore_user_abort']) {
0385             $abort = ignore_user_abort(true);
0386         }
0387         if (($this->_extendedBackend) && ($this->_backendCapabilities['priority'])) {
0388             $result = $this->_backend->save($data, $id, $tags, $specificLifetime, $priority);
0389         } else {
0390             $result = $this->_backend->save($data, $id, $tags, $specificLifetime);
0391         }
0392         if ($this->_options['ignore_user_abort']) {
0393             ignore_user_abort($abort);
0394         }
0395 
0396         if (!$result) {
0397             // maybe the cache is corrupted, so we remove it !
0398             $this->_log("Zend_Cache_Core::save(): failed to save item '{$id}' -> removing it", 4);
0399             $this->_backend->remove($id);
0400             return false;
0401         }
0402 
0403         if ($this->_options['write_control']) {
0404             $data2 = $this->_backend->load($id, true);
0405             if ($data!=$data2) {
0406                 $this->_log("Zend_Cache_Core::save(): write control of item '{$id}' failed -> removing it", 4);
0407                 $this->_backend->remove($id);
0408                 return false;
0409             }
0410         }
0411 
0412         return true;
0413     }
0414 
0415     /**
0416      * Remove a cache
0417      *
0418      * @param  string $id Cache id to remove
0419      * @return boolean True if ok
0420      */
0421     public function remove($id)
0422     {
0423         if (!$this->_options['caching']) {
0424             return true;
0425         }
0426         $id = $this->_id($id); // cache id may need prefix
0427         $this->_validateIdOrTag($id);
0428 
0429         $this->_log("Zend_Cache_Core: remove item '{$id}'", 7);
0430         return $this->_backend->remove($id);
0431     }
0432 
0433     /**
0434      * Clean cache entries
0435      *
0436      * Available modes are :
0437      * 'all' (default)  => remove all cache entries ($tags is not used)
0438      * 'old'            => remove too old cache entries ($tags is not used)
0439      * 'matchingTag'    => remove cache entries matching all given tags
0440      *                     ($tags can be an array of strings or a single string)
0441      * 'notMatchingTag' => remove cache entries not matching one of the given tags
0442      *                     ($tags can be an array of strings or a single string)
0443      * 'matchingAnyTag' => remove cache entries matching any given tags
0444      *                     ($tags can be an array of strings or a single string)
0445      *
0446      * @param  string       $mode
0447      * @param  array|string $tags
0448      * @throws Zend_Cache_Exception
0449      * @return boolean True if ok
0450      */
0451     public function clean($mode = 'all', $tags = array())
0452     {
0453         if (!$this->_options['caching']) {
0454             return true;
0455         }
0456         if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL,
0457                                    Zend_Cache::CLEANING_MODE_OLD,
0458                                    Zend_Cache::CLEANING_MODE_MATCHING_TAG,
0459                                    Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG,
0460                                    Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG))) {
0461             Zend_Cache::throwException('Invalid cleaning mode');
0462         }
0463         $this->_validateTagsArray($tags);
0464 
0465         return $this->_backend->clean($mode, $tags);
0466     }
0467 
0468     /**
0469      * Return an array of stored cache ids which match given tags
0470      *
0471      * In case of multiple tags, a logical AND is made between tags
0472      *
0473      * @param array $tags array of tags
0474      * @return array array of matching cache ids (string)
0475      */
0476     public function getIdsMatchingTags($tags = array())
0477     {
0478         if (!$this->_extendedBackend) {
0479             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0480         }
0481         if (!($this->_backendCapabilities['tags'])) {
0482             Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG);
0483         }
0484 
0485         $ids = $this->_backend->getIdsMatchingTags($tags);
0486 
0487         // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600)
0488         if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') {
0489             $prefix    = & $this->_options['cache_id_prefix'];
0490             $prefixLen = strlen($prefix);
0491             foreach ($ids as &$id) {
0492                 if (strpos($id, $prefix) === 0) {
0493                     $id = substr($id, $prefixLen);
0494                 }
0495             }
0496         }
0497 
0498         return $ids;
0499     }
0500 
0501     /**
0502      * Return an array of stored cache ids which don't match given tags
0503      *
0504      * In case of multiple tags, a logical OR is made between tags
0505      *
0506      * @param array $tags array of tags
0507      * @return array array of not matching cache ids (string)
0508      */
0509     public function getIdsNotMatchingTags($tags = array())
0510     {
0511         if (!$this->_extendedBackend) {
0512             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0513         }
0514         if (!($this->_backendCapabilities['tags'])) {
0515             Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG);
0516         }
0517 
0518         $ids = $this->_backend->getIdsNotMatchingTags($tags);
0519 
0520         // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600)
0521         if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') {
0522             $prefix    = & $this->_options['cache_id_prefix'];
0523             $prefixLen = strlen($prefix);
0524             foreach ($ids as &$id) {
0525                 if (strpos($id, $prefix) === 0) {
0526                     $id = substr($id, $prefixLen);
0527                 }
0528             }
0529         }
0530 
0531         return $ids;
0532     }
0533 
0534     /**
0535      * Return an array of stored cache ids which match any given tags
0536      *
0537      * In case of multiple tags, a logical OR is made between tags
0538      *
0539      * @param array $tags array of tags
0540      * @return array array of matching any cache ids (string)
0541      */
0542     public function getIdsMatchingAnyTags($tags = array())
0543     {
0544         if (!$this->_extendedBackend) {
0545             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0546         }
0547         if (!($this->_backendCapabilities['tags'])) {
0548             Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG);
0549         }
0550 
0551         $ids = $this->_backend->getIdsMatchingAnyTags($tags);
0552 
0553         // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600)
0554         if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') {
0555             $prefix    = & $this->_options['cache_id_prefix'];
0556             $prefixLen = strlen($prefix);
0557             foreach ($ids as &$id) {
0558                 if (strpos($id, $prefix) === 0) {
0559                     $id = substr($id, $prefixLen);
0560                 }
0561             }
0562         }
0563 
0564         return $ids;
0565     }
0566 
0567     /**
0568      * Return an array of stored cache ids
0569      *
0570      * @return array array of stored cache ids (string)
0571      */
0572     public function getIds()
0573     {
0574         if (!$this->_extendedBackend) {
0575             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0576         }
0577 
0578         $ids = $this->_backend->getIds();
0579 
0580         // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600)
0581         if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') {
0582             $prefix    = & $this->_options['cache_id_prefix'];
0583             $prefixLen = strlen($prefix);
0584             foreach ($ids as &$id) {
0585                 if (strpos($id, $prefix) === 0) {
0586                     $id = substr($id, $prefixLen);
0587                 }
0588             }
0589         }
0590 
0591         return $ids;
0592     }
0593 
0594     /**
0595      * Return an array of stored tags
0596      *
0597      * @return array array of stored tags (string)
0598      */
0599     public function getTags()
0600     {
0601         if (!$this->_extendedBackend) {
0602             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0603         }
0604         if (!($this->_backendCapabilities['tags'])) {
0605             Zend_Cache::throwException(self::BACKEND_NOT_SUPPORTS_TAG);
0606         }
0607         return $this->_backend->getTags();
0608     }
0609 
0610     /**
0611      * Return the filling percentage of the backend storage
0612      *
0613      * @return int integer between 0 and 100
0614      */
0615     public function getFillingPercentage()
0616     {
0617         if (!$this->_extendedBackend) {
0618             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0619         }
0620         return $this->_backend->getFillingPercentage();
0621     }
0622 
0623     /**
0624      * Return an array of metadatas for the given cache id
0625      *
0626      * The array will include these keys :
0627      * - expire : the expire timestamp
0628      * - tags : a string array of tags
0629      * - mtime : timestamp of last modification time
0630      *
0631      * @param string $id cache id
0632      * @return array array of metadatas (false if the cache id is not found)
0633      */
0634     public function getMetadatas($id)
0635     {
0636         if (!$this->_extendedBackend) {
0637             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0638         }
0639         $id = $this->_id($id); // cache id may need prefix
0640         return $this->_backend->getMetadatas($id);
0641     }
0642 
0643     /**
0644      * Give (if possible) an extra lifetime to the given cache id
0645      *
0646      * @param string $id cache id
0647      * @param int $extraLifetime
0648      * @return boolean true if ok
0649      */
0650     public function touch($id, $extraLifetime)
0651     {
0652         if (!$this->_extendedBackend) {
0653             Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF);
0654         }
0655         $id = $this->_id($id); // cache id may need prefix
0656 
0657         $this->_log("Zend_Cache_Core: touch item '{$id}'", 7);
0658         return $this->_backend->touch($id, $extraLifetime);
0659     }
0660 
0661     /**
0662      * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...)
0663      *
0664      * Throw an exception if a problem is found
0665      *
0666      * @param  string $string Cache id or tag
0667      * @throws Zend_Cache_Exception
0668      * @return void
0669      */
0670     protected function _validateIdOrTag($string)
0671     {
0672         if (!is_string($string)) {
0673             Zend_Cache::throwException('Invalid id or tag : must be a string');
0674         }
0675         if (substr($string, 0, 9) == 'internal-') {
0676             Zend_Cache::throwException('"internal-*" ids or tags are reserved');
0677         }
0678         if (!preg_match('~^[a-zA-Z0-9_]+$~D', $string)) {
0679             Zend_Cache::throwException("Invalid id or tag '$string' : must use only [a-zA-Z0-9_]");
0680         }
0681     }
0682 
0683     /**
0684      * Validate a tags array (security, reliable filenames, reserved prefixes...)
0685      *
0686      * Throw an exception if a problem is found
0687      *
0688      * @param  array $tags Array of tags
0689      * @throws Zend_Cache_Exception
0690      * @return void
0691      */
0692     protected function _validateTagsArray($tags)
0693     {
0694         if (!is_array($tags)) {
0695             Zend_Cache::throwException('Invalid tags array : must be an array');
0696         }
0697         foreach($tags as $tag) {
0698             $this->_validateIdOrTag($tag);
0699         }
0700         reset($tags);
0701     }
0702 
0703     /**
0704      * Make sure if we enable logging that the Zend_Log class
0705      * is available.
0706      * Create a default log object if none is set.
0707      *
0708      * @throws Zend_Cache_Exception
0709      * @return void
0710      */
0711     protected function _loggerSanity()
0712     {
0713         if (!isset($this->_options['logging']) || !$this->_options['logging']) {
0714             return;
0715         }
0716 
0717         if (isset($this->_options['logger']) && $this->_options['logger'] instanceof Zend_Log) {
0718             return;
0719         }
0720 
0721         // Create a default logger to the standard output stream
0722         // require_once 'Zend/Log.php';
0723         // require_once 'Zend/Log/Writer/Stream.php';
0724         // require_once 'Zend/Log/Filter/Priority.php';
0725         $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output'));
0726         $logger->addFilter(new Zend_Log_Filter_Priority(Zend_Log::WARN, '<='));
0727         $this->_options['logger'] = $logger;
0728     }
0729 
0730     /**
0731      * Log a message at the WARN (4) priority.
0732      *
0733      * @param string $message
0734      * @throws Zend_Cache_Exception
0735      * @return void
0736      */
0737     protected function _log($message, $priority = 4)
0738     {
0739         if (!$this->_options['logging']) {
0740             return;
0741         }
0742         if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) {
0743             Zend_Cache::throwException('Logging is enabled but logger is not set');
0744         }
0745         $logger = $this->_options['logger'];
0746         $logger->log($message, $priority);
0747     }
0748 
0749     /**
0750      * Make and return a cache id
0751      *
0752      * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null
0753      *
0754      * @param  string $id Cache id
0755      * @return string Cache id (with or without prefix)
0756      */
0757     protected function _id($id)
0758     {
0759         if (($id !== null) && isset($this->_options['cache_id_prefix'])) {
0760             return $this->_options['cache_id_prefix'] . $id; // return with prefix
0761         }
0762         return $id; // no prefix, just return the $id passed
0763     }
0764 
0765 }