CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.3 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.3
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • ApcEngine
  • FileEngine
  • MemcacheEngine
  • RedisEngine
  • WincacheEngine
  • XcacheEngine
  1: <?php
  2: /**
  3:  * File Storage engine for cache. Filestorage is the slowest cache storage
  4:  * to read and write. However, it is good for servers that don't have other storage
  5:  * engine available, or have content which is not performance sensitive.
  6:  *
  7:  * You can configure a FileEngine cache, using Cache::config()
  8:  *
  9:  * PHP 5
 10:  *
 11:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 12:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 13:  *
 14:  * Licensed under The MIT License
 15:  * For full copyright and license information, please see the LICENSE.txt
 16:  * Redistributions of files must retain the above copyright notice.
 17:  *
 18:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 19:  * @link          http://cakephp.org CakePHP(tm) Project
 20:  * @since         CakePHP(tm) v 1.2.0.4933
 21:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 22:  */
 23: 
 24: /**
 25:  * File Storage engine for cache. Filestorage is the slowest cache storage
 26:  * to read and write. However, it is good for servers that don't have other storage
 27:  * engine available, or have content which is not performance sensitive.
 28:  *
 29:  * You can configure a FileEngine cache, using Cache::config()
 30:  *
 31:  * @package       Cake.Cache.Engine
 32:  */
 33: class FileEngine extends CacheEngine {
 34: 
 35: /**
 36:  * Instance of SplFileObject class
 37:  *
 38:  * @var File
 39:  */
 40:     protected $_File = null;
 41: 
 42: /**
 43:  * Settings
 44:  *
 45:  * - path = absolute path to cache directory, default => CACHE
 46:  * - prefix = string prefix for filename, default => cake_
 47:  * - lock = enable file locking on write, default => false
 48:  * - serialize = serialize the data, default => true
 49:  *
 50:  * @var array
 51:  * @see CacheEngine::__defaults
 52:  */
 53:     public $settings = array();
 54: 
 55: /**
 56:  * True unless FileEngine::__active(); fails
 57:  *
 58:  * @var boolean
 59:  */
 60:     protected $_init = true;
 61: 
 62: /**
 63:  * Initialize the Cache Engine
 64:  *
 65:  * Called automatically by the cache frontend
 66:  * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
 67:  *
 68:  * @param array $settings array of setting for the engine
 69:  * @return boolean True if the engine has been successfully initialized, false if not
 70:  */
 71:     public function init($settings = array()) {
 72:         $settings += array(
 73:             'engine' => 'File',
 74:             'path' => CACHE,
 75:             'prefix' => 'cake_',
 76:             'lock' => true,
 77:             'serialize' => true,
 78:             'isWindows' => false,
 79:             'mask' => 0664
 80:         );
 81:         parent::init($settings);
 82: 
 83:         if (DS === '\\') {
 84:             $this->settings['isWindows'] = true;
 85:         }
 86:         if (substr($this->settings['path'], -1) !== DS) {
 87:             $this->settings['path'] .= DS;
 88:         }
 89:         if (!empty($this->_groupPrefix)) {
 90:             $this->_groupPrefix = str_replace('_', DS, $this->_groupPrefix);
 91:         }
 92:         return $this->_active();
 93:     }
 94: 
 95: /**
 96:  * Garbage collection. Permanently remove all expired and deleted data
 97:  *
 98:  * @param integer $expires [optional] An expires timestamp, invalidating all data before.
 99:  * @return boolean True if garbage collection was successful, false on failure
100:  */
101:     public function gc($expires = null) {
102:         return $this->clear(true);
103:     }
104: 
105: /**
106:  * Write data for key into cache
107:  *
108:  * @param string $key Identifier for the data
109:  * @param mixed $data Data to be cached
110:  * @param integer $duration How long to cache the data, in seconds
111:  * @return boolean True if the data was successfully cached, false on failure
112:  */
113:     public function write($key, $data, $duration) {
114:         if ($data === '' || !$this->_init) {
115:             return false;
116:         }
117: 
118:         if ($this->_setKey($key, true) === false) {
119:             return false;
120:         }
121: 
122:         $lineBreak = "\n";
123: 
124:         if ($this->settings['isWindows']) {
125:             $lineBreak = "\r\n";
126:         }
127: 
128:         if (!empty($this->settings['serialize'])) {
129:             if ($this->settings['isWindows']) {
130:                 $data = str_replace('\\', '\\\\\\\\', serialize($data));
131:             } else {
132:                 $data = serialize($data);
133:             }
134:         }
135: 
136:         $expires = time() + $duration;
137:         $contents = $expires . $lineBreak . $data . $lineBreak;
138: 
139:         if ($this->settings['lock']) {
140:             $this->_File->flock(LOCK_EX);
141:         }
142: 
143:         $this->_File->rewind();
144:         $success = $this->_File->ftruncate(0) && $this->_File->fwrite($contents) && $this->_File->fflush();
145: 
146:         if ($this->settings['lock']) {
147:             $this->_File->flock(LOCK_UN);
148:         }
149: 
150:         return $success;
151:     }
152: 
153: /**
154:  * Read a key from the cache
155:  *
156:  * @param string $key Identifier for the data
157:  * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
158:  */
159:     public function read($key) {
160:         if (!$this->_init || $this->_setKey($key) === false) {
161:             return false;
162:         }
163: 
164:         if ($this->settings['lock']) {
165:             $this->_File->flock(LOCK_SH);
166:         }
167: 
168:         $this->_File->rewind();
169:         $time = time();
170:         $cachetime = intval($this->_File->current());
171: 
172:         if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
173:             if ($this->settings['lock']) {
174:                 $this->_File->flock(LOCK_UN);
175:             }
176:             return false;
177:         }
178: 
179:         $data = '';
180:         $this->_File->next();
181:         while ($this->_File->valid()) {
182:             $data .= $this->_File->current();
183:             $this->_File->next();
184:         }
185: 
186:         if ($this->settings['lock']) {
187:             $this->_File->flock(LOCK_UN);
188:         }
189: 
190:         $data = trim($data);
191: 
192:         if ($data !== '' && !empty($this->settings['serialize'])) {
193:             if ($this->settings['isWindows']) {
194:                 $data = str_replace('\\\\\\\\', '\\', $data);
195:             }
196:             $data = unserialize((string)$data);
197:         }
198:         return $data;
199:     }
200: 
201: /**
202:  * Delete a key from the cache
203:  *
204:  * @param string $key Identifier for the data
205:  * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
206:  */
207:     public function delete($key) {
208:         if ($this->_setKey($key) === false || !$this->_init) {
209:             return false;
210:         }
211:         $path = $this->_File->getRealPath();
212:         $this->_File = null;
213:         return unlink($path);
214:     }
215: 
216: /**
217:  * Delete all values from the cache
218:  *
219:  * @param boolean $check Optional - only delete expired cache items
220:  * @return boolean True if the cache was successfully cleared, false otherwise
221:  */
222:     public function clear($check) {
223:         if (!$this->_init) {
224:             return false;
225:         }
226:         $this->_File = null;
227: 
228:         $threshold = $now = false;
229:         if ($check) {
230:             $now = time();
231:             $threshold = $now - $this->settings['duration'];
232:         }
233: 
234:         $this->_clearDirectory($this->settings['path'], $now, $threshold);
235: 
236:         $directory = new RecursiveDirectoryIterator($this->settings['path']);
237:         $contents = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
238:         $cleared = array();
239:         foreach ($contents as $path) {
240:             if ($path->isFile()) {
241:                 continue;
242:             }
243: 
244:             $path = $path->getRealPath() . DS;
245:             if (!in_array($path, $cleared)) {
246:                 $this->_clearDirectory($path, $now, $threshold);
247:                 $cleared[] = $path;
248:             }
249:         }
250:         return true;
251:     }
252: 
253: /**
254:  * Used to clear a directory of matching files.
255:  *
256:  * @param string $path The path to search.
257:  * @param integer $now The current timestamp
258:  * @param integer $threshold Any file not modified after this value will be deleted.
259:  * @return void
260:  */
261:     protected function _clearDirectory($path, $now, $threshold) {
262:         $prefixLength = strlen($this->settings['prefix']);
263: 
264:         if (!is_dir($path)) {
265:             return;
266:         }
267: 
268:         $dir = dir($path);
269:         while (($entry = $dir->read()) !== false) {
270:             if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) {
271:                 continue;
272:             }
273:             $filePath = $path . $entry;
274:             if (!file_exists($filePath) || is_dir($filePath)) {
275:                 continue;
276:             }
277:             $file = new SplFileObject($path . $entry, 'r');
278: 
279:             if ($threshold) {
280:                 $mtime = $file->getMTime();
281: 
282:                 if ($mtime > $threshold) {
283:                     continue;
284:                 }
285:                 $expires = (int)$file->current();
286: 
287:                 if ($expires > $now) {
288:                     continue;
289:                 }
290:             }
291:             if ($file->isFile()) {
292:                 $_path = $file->getRealPath();
293:                 $file = null;
294:                 unlink($_path);
295:             }
296:         }
297:     }
298: 
299: /**
300:  * Not implemented
301:  *
302:  * @param string $key
303:  * @param integer $offset
304:  * @return void
305:  * @throws CacheException
306:  */
307:     public function decrement($key, $offset = 1) {
308:         throw new CacheException(__d('cake_dev', 'Files cannot be atomically decremented.'));
309:     }
310: 
311: /**
312:  * Not implemented
313:  *
314:  * @param string $key
315:  * @param integer $offset
316:  * @return void
317:  * @throws CacheException
318:  */
319:     public function increment($key, $offset = 1) {
320:         throw new CacheException(__d('cake_dev', 'Files cannot be atomically incremented.'));
321:     }
322: 
323: /**
324:  * Sets the current cache key this class is managing, and creates a writable SplFileObject
325:  * for the cache file the key is referring to.
326:  *
327:  * @param string $key The key
328:  * @param boolean $createKey Whether the key should be created if it doesn't exists, or not
329:  * @return boolean true if the cache key could be set, false otherwise
330:  */
331:     protected function _setKey($key, $createKey = false) {
332:         $groups = null;
333:         if (!empty($this->_groupPrefix)) {
334:             $groups = vsprintf($this->_groupPrefix, $this->groups());
335:         }
336:         $dir = $this->settings['path'] . $groups;
337: 
338:         if (!is_dir($dir)) {
339:             mkdir($dir, 0777, true);
340:         }
341:         $path = new SplFileInfo($dir . $key);
342: 
343:         if (!$createKey && !$path->isFile()) {
344:             return false;
345:         }
346:         if (empty($this->_File) || $this->_File->getBaseName() !== $key) {
347:             $exists = file_exists($path->getPathname());
348:             try {
349:                 $this->_File = $path->openFile('c+');
350:             } catch (Exception $e) {
351:                 trigger_error($e->getMessage(), E_USER_WARNING);
352:                 return false;
353:             }
354:             unset($path);
355: 
356:             if (!$exists && !chmod($this->_File->getPathname(), (int)$this->settings['mask'])) {
357:                 trigger_error(__d(
358:                     'cake_dev', 'Could not apply permission mask "%s" on cache file "%s"',
359:                     array($this->_File->getPathname(), $this->settings['mask'])), E_USER_WARNING);
360:             }
361:         }
362:         return true;
363:     }
364: 
365: /**
366:  * Determine is cache directory is writable
367:  *
368:  * @return boolean
369:  */
370:     protected function _active() {
371:         $dir = new SplFileInfo($this->settings['path']);
372:         if ($this->_init && !($dir->isDir() && $dir->isWritable())) {
373:             $this->_init = false;
374:             trigger_error(__d('cake_dev', '%s is not writable', $this->settings['path']), E_USER_WARNING);
375:             return false;
376:         }
377:         return true;
378:     }
379: 
380: /**
381:  * Generates a safe key for use with cache engine storage engines.
382:  *
383:  * @param string $key the key passed over
384:  * @return mixed string $key or false
385:  */
386:     public function key($key) {
387:         if (empty($key)) {
388:             return false;
389:         }
390: 
391:         $key = Inflector::underscore(str_replace(array(DS, '/', '.', '<', '>', '?', ':', '|', '*', '"'), '_', strval($key)));
392:         return $key;
393:     }
394: 
395: /**
396:  * Recursively deletes all files under any directory named as $group
397:  *
398:  * @return boolean success
399:  */
400:     public function clearGroup($group) {
401:         $this->_File = null;
402:         $directoryIterator = new RecursiveDirectoryIterator($this->settings['path']);
403:         $contents = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
404:         foreach ($contents as $object) {
405:             $containsGroup = strpos($object->getPathName(), DS . $group . DS) !== false;
406:             $hasPrefix = strpos($object->getBaseName(), $this->settings['prefix']) === 0;
407:             if ($object->isFile() && $containsGroup && $hasPrefix) {
408:                 unlink($object->getPathName());
409:             }
410:         }
411:         return true;
412:     }
413: }
414: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs