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-2015 Zend Technologies USA Inc. (http://www.zend.com) 19 * @license http://framework.zend.com/license/new-bsd New BSD License 20 * @version $Id$ 21 */ 22 23 24/** 25 * @see Zend_Cache_Core 26 */ 27 28 29/** 30 * @package Zend_Cache 31 * @subpackage Zend_Cache_Frontend 32 * @copyright Copyright (c) 2005-2015 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_File extends Zend_Cache_Core 36{ 37 38 /** 39 * Consts for master_files_mode 40 */ 41 const MODE_AND = 'AND'; 42 const MODE_OR = 'OR'; 43 44 /** 45 * Available options 46 * 47 * ====> (string) master_file : 48 * - a complete path of the master file 49 * - deprecated (see master_files) 50 * 51 * ====> (array) master_files : 52 * - an array of complete path of master files 53 * - this option has to be set ! 54 * 55 * ====> (string) master_files_mode : 56 * - Zend_Cache_Frontend_File::MODE_AND or Zend_Cache_Frontend_File::MODE_OR 57 * - if MODE_AND, then all master files have to be touched to get a cache invalidation 58 * - if MODE_OR (default), then a single touched master file is enough to get a cache invalidation 59 * 60 * ====> (boolean) ignore_missing_master_files 61 * - if set to true, missing master files are ignored silently 62 * - if set to false (default), an exception is thrown if there is a missing master file 63 * @var array available options 64 */ 65 protected $_specificOptions = array( 66 'master_file' => null, 67 'master_files' => null, 68 'master_files_mode' => 'OR', 69 'ignore_missing_master_files' => false 70 ); 71 72 /** 73 * Master file mtimes 74 * 75 * Array of int 76 * 77 * @var array 78 */ 79 private $_masterFile_mtimes = null; 80 81 /** 82 * Constructor 83 * 84 * @param array $options Associative array of options 85 * @throws Zend_Cache_Exception 86 * @return void 87 */ 88 public function __construct(array $options = array()) 89 { 90 foreach ($options as $name => $value) { 91 $this->setOption($name, $value); 92 } 93 if (!isset($this->_specificOptions['master_files'])) { 94 Zend_Cache::throwException('master_files option must be set'); 95 } 96 } 97 98 /** 99 * Change the master_files option 100 * 101 * @param array $masterFiles the complete paths and name of the master files 102 */ 103 public function setMasterFiles(array $masterFiles) 104 { 105 $this->_specificOptions['master_file'] = null; // to keep a compatibility 106 $this->_specificOptions['master_files'] = null; 107 $this->_masterFile_mtimes = array(); 108 109 clearstatcache(); 110 $i = 0; 111 foreach ($masterFiles as $masterFile) { 112 if (file_exists($masterFile)) { 113 $mtime = filemtime($masterFile); 114 } else { 115 $mtime = false; 116 } 117 118 if (!$this->_specificOptions['ignore_missing_master_files'] && !$mtime) { 119 Zend_Cache::throwException('Unable to read master_file : ' . $masterFile); 120 } 121 122 $this->_masterFile_mtimes[$i] = $mtime; 123 $this->_specificOptions['master_files'][$i] = $masterFile; 124 if ($i === 0) { // to keep a compatibility 125 $this->_specificOptions['master_file'] = $masterFile; 126 } 127 128 $i++; 129 } 130 } 131 132 /** 133 * Change the master_file option 134 * 135 * To keep the compatibility 136 * 137 * @deprecated 138 * @param string $masterFile the complete path and name of the master file 139 */ 140 public function setMasterFile($masterFile) 141 { 142 $this->setMasterFiles(array($masterFile)); 143 } 144 145 /** 146 * Public frontend to set an option 147 * 148 * Just a wrapper to get a specific behaviour for master_file 149 * 150 * @param string $name Name of the option 151 * @param mixed $value Value of the option 152 * @throws Zend_Cache_Exception 153 * @return void 154 */ 155 public function setOption($name, $value) 156 { 157 if ($name == 'master_file') { 158 $this->setMasterFile($value); 159 } else if ($name == 'master_files') { 160 $this->setMasterFiles($value); 161 } else { 162 parent::setOption($name, $value); 163 } 164 } 165 166 /** 167 * Test if a cache is available for the given id and (if yes) return it (false else) 168 * 169 * @param string $id Cache id 170 * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested 171 * @param boolean $doNotUnserialize Do not serialize (even if automatic_serialization is true) => for internal use 172 * @return mixed|false Cached datas 173 */ 174 public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false) 175 { 176 if (!$doNotTestCacheValidity) { 177 if ($this->test($id)) { 178 return parent::load($id, true, $doNotUnserialize); 179 } 180 return false; 181 } 182 return parent::load($id, true, $doNotUnserialize); 183 } 184 185 /** 186 * Test if a cache is available for the given id 187 * 188 * @param string $id Cache id 189 * @return int|false Last modified time of cache entry if it is available, false otherwise 190 */ 191 public function test($id) 192 { 193 $lastModified = parent::test($id); 194 if ($lastModified) { 195 if ($this->_specificOptions['master_files_mode'] == self::MODE_AND) { 196 // MODE_AND 197 foreach($this->_masterFile_mtimes as $masterFileMTime) { 198 if ($masterFileMTime) { 199 if ($lastModified > $masterFileMTime) { 200 return $lastModified; 201 } 202 } 203 } 204 } else { 205 // MODE_OR 206 $res = true; 207 foreach($this->_masterFile_mtimes as $masterFileMTime) { 208 if ($masterFileMTime) { 209 if ($lastModified <= $masterFileMTime) { 210 return false; 211 } 212 } 213 } 214 return $lastModified; 215 } 216 } 217 return false; 218 } 219 220} 221 222