Can handle single- and multi-key reads.
Read-through caching can be used by passing expiry and the to-be-cached value
in the write option. Following three ways to achieve this.
Cache::read('default', 'foo', array(
'write' => array('+5 days' => 'bar')
)); // returns 'bar'
Cache::read('default', 'foo', array(
'write' => array('+5 days' => function() { return 'bar'; })
));
Cache::read('default', 'foo', array(
'write' => function() { return array('+5 days' => 'bar'); }
));
public static read ( string $name, mixed $key, array $options = [] ) : mixed | ||
$name | string | Configuration to be used for reading. |
$key | mixed | Key to uniquely identify the cache entry or an array of keys for multikey-reads. |
$options | array | Options for the method and strategies. - `'write'`: Allows for read-through caching see description for usage. - `'strategies'` _boolean_: Indicates if strategies should be used, defaults to `true`. - `'conditions'` _mixed_: A function or item that must return or evaluate to `true` in order to continue write operation. |
Résultat | mixed | For single-key reads will return the result if the cache key has been found otherwise returns `null`. When reading multiple keys a results array is returned mapping keys to retrieved values. Keys where the value couldn't successfully been read will not be contained in the results array. |
public function testExpiresQuick() { Cache::write($this->cachedName, 'foo', 'bar', '+5 second'); $this->assertEqual('bar', Cache::read($this->cachedName, 'foo')); sleep(10); $this->assertNull(Cache::read($this->cachedName, 'foo')); }
/** * This renders a a block. * * * @param string $position The block position identifier * @param array $options * @return string HTML code for the menu */ public function render($position = null, $data = array(), $options = array()) { $defaults = array('cache' => false, 'wrapperId' => false); $options += $defaults; if (empty($position) || !is_string($position)) { return ''; } // set the cache key for the menu $cache_key = 'li3b_blocks.' . $position; $blocks = false; // if told to use the block content from cache if (!empty($options['cache'])) { $blocks = Cache::read('default', $cache_key); } // if the content hasn't been set in cache or it was empty for some reason, get a fresh copy of its data if (empty($blocks)) { $blocks = Block::staticBlock($position); } // if using cache, write the menu data to the cache key if (!empty($options['cache'])) { Cache::write('default', $cache_key, $blocks, $options['cache']); } $string = "\n"; if ($options['wrapperId']) { $string .= '<div id="' . $options['wrapperId'] . '">'; } foreach ($blocks as $block) { if (isset($block['options']['wrapperId'])) { $string .= "\n\t" . '<div id="' . $block['options']['wrapperId'] . '">'; } // Blocks can be very simple and contain all the content in the array. if (is_string($block['content'])) { $string .= "\n\t\t" . $block['content']; } // Or, they can point to an element view template. These are essentially like elements, only they can have layout templates as well. if (is_array($block['content'])) { if (isset($block['content']['template'])) { $elementOptions = isset($block['content']['options']) ? $block['content']['options'] : array(); if (isset($block['content']['library'])) { $elementOptions['library'] = $block['content']['library']; } $elementOptions['layout'] = isset($block['content']['layout']) ? $block['content']['layout'] : 'blank'; $elementOptions['template'] = $block['content']['template']; $appConfig = Libraries::get(true); $paths = array('layout' => array('{:library}/views/layouts/{:layout}.{:type}.php', $appConfig['path'] . '/views/layouts/{:layout}.{:type}.php'), 'template' => array($appConfig['path'] . '/views/_libraries/' . $elementOptions['library'] . '/blocks/{:template}.{:type}.php', '{:library}/views/blocks/{:template}.{:type}.php', $appConfig['path'] . '/views/blocks/{:template}.{:type}.php')); $View = new View(array('paths' => $paths)); $string .= $View->render('all', $data, $elementOptions); } } if (isset($block['options']['wrapperId'])) { $string .= "\n\t" . '</div>'; } } if ($options['wrapperId']) { $string .= '</div>'; } $string .= "\n"; return $string; }
public static function cache_get($key, $cache_name = 'default') { if (CACHE) { $key = self::_get_cache_name($key); return Cache::read($cache_name, $key); } return null; }
/** * Tests the correct writing to the cache adapter. In this test we use the * "Memory" cache adapter so that we can easily verify the written message. */ public function testWrite() { $message = "CacheLog test message..."; $result = Logger::write('info', $message, array('name' => 'cachelog')); $this->assertNotEmpty($result); $result = CacheStorage::read('cachelog', 'cachelog_testkey'); $this->assertEqual($message, $result); }
/** * * Retrieve Stackoverflow tags I am active on, equivalent to the users tags `me` endpoint. * * @param int $min Stackoverflow `min` * @return object Returns an array user tags objects. */ public static function me_tags($min = 5) { if ($cache = Cache::read('memcache', 'stackoverflow_me_tags')) { return $cache; } $service = new Service(array('scheme' => 'https', 'host' => 'api.stackexchange.com', 'timeout' => 2)); // using `userid` instead of `me` so we don't need to auth $data = $service->get('/' . self::API_VERSION . '/users/' . self::USERID . '/tags?key=' . self::KEY . '&order=desc&min=' . $min . '&sort=popular&site=stackoverflow'); $me_tags = self::response_to_object($data)->items; Cache::write('memcache', 'stackoverflow_me_tags', $me_tags, '+2 hours'); return $me_tags; }
/** * Gets and caches gallery file list. * * @return void */ protected function _getGalleryFiles() { $galleryFiles = Cache::read('default', 'gallery_files'); if ($galleryFiles === false) { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_galleryPath)); $filesIter = new \RegexIterator($iterator, '/^.+\\.jpg$/i', \RecursiveRegexIterator::GET_MATCH); foreach ($filesIter as $file) { $this->_galleryFiles[] = str_replace(Libraries::get('app', 'path') . '/webroot', '', $file[0]); } Cache::write('default', 'gallery_files', serialize($this->_galleryFiles)); } else { $this->_galleryFiles = unserialize($galleryFiles); } }
/** * Read cache files for assets * Returns CSS/Js from Cache if exists * @param object $request * @return string contents of cache file */ function readCache($request, array $options) { $http_response_code = null; if (!($content = Cache::read('default', $request->url))) { // TODO: config switch if (!$options['cacheOnly']) { return false; } $http_response_code = 404; $content = '404: ' . $options['name'] . ' does not exist'; } // TODO: use lithium constructs header('Content-Type: ' . $options['type'], true, $http_response_code); echo $content; return true; }
/** * parses input string with lessc and returns generated css * * @param string $input complete less code, may include @import statements * @param array $options Additional options to control flow of method * - cache - controls, whether to cache the result * - cachePath - Where to cache files, defaults to * resources/tmp/cache * @return string|boolean generated css, false in case of error */ public static function parse($input, array $options = array()) { $defaults = array('header' => true, 'cache' => true, 'cacheConfig' => 'default', 'cacheKey' => md5($input)); $options += $defaults; if ($output = Cache::read($options['cacheConfig'], $options['cacheKey'])) { return $output; } try { $less = static::_getLess(); $output = $less->parse($input); } catch (Exception $e) { header('Content-Type: text/css', true, 500); $output = "/* less compiler exception: {$e->getMessage()} */"; } if ($options['header']) { $output = static::_prependHeader($output); } if ($options['cache']) { Cache::read($options['cacheConfig'], $options['cacheKey'], $output); } return $output; }
public static function latest() { $cacheKey = 'posts_latest'; if ($cached = Cache::read('default', $cacheKey)) { return $cached; } $config = static::$_serviceConfig; try { $client = new Tumblr($config['consumerKey'], $config['consumerSecret'], $config['token'], $config['tokenSecret']); $results = $client->getBlogPosts($config['name'], ['limit' => 2]); $results = $results->posts; } catch (CurlException $e) { return []; } catch (Exception $e) { return []; } $results = (new Collection(['data' => $results]))->find(function ($item) { return $item->timestamp >= strtotime('-2 months'); })->each(function ($item) { return static::create((array) $item); }); Cache::write('default', $cacheKey, $results, '+1 hour'); return $results; }
public function show($placeId = null) { $placeId = isset($this->request->params['placeId']) ? $this->request->params['placeId'] : $placeId; if (empty($placeId)) { $this->redirect('/'); } $place = unserialize(Cache::read('default', $placeId)); if (empty($place)) { $place = $this->api->getPlace(array('placeid' => $placeId)); if (!empty($place)) { Cache::write("default", $placeId, serialize($place), "+1 day"); } } if ($place instanceof Place) { $thePlaceId = $placeId; $location = new Location(); $location->load(); $placeId = $thePlaceId; $visitors = $this->api->getVisitors(array('placeid' => $placeId)); $place->setNumVisitors($visitors->getNumFound()); $photos = $this->api->getPhotos(array('placeId' => $placeId)); $place->setNumPhotos(count($photos->getItems())); $showCheckin = true; $og = new OpenGraph(); $og->populate($place); $abm = new ABMeta(); $abm->populate($place); $meta = implode('', array($og->getMeta(), $abm->getMeta(), "\t<link rel=\"canonical\" href=\"" . $place->getPlaceUrl() . "\" />\n")); $abmType = $abm->get('type'); $title = $place->getName(); return compact('meta', 'title', 'location', 'abmType', 'numVisitors', 'showCheckin', 'place'); } else { $this->redirect('/'); } }
* removed post-install, and the cache should be configured with the adapter you plan to use. */ $cachePath = Libraries::get(true, 'resources') . '/tmp/cache'; if (!($apcEnabled = Apc::enabled()) && !is_writable($cachePath)) { return; } /** * This configures the default cache, based on whether ot not APC user caching is enabled. If it is * not, file caching will be used. Most of this code is for getting you up and running only, and * should be replaced with a hard-coded configuration, based on the cache(s) you plan to use. */ $default = array('adapter' => 'File', 'strategies' => array('Serializer')); if ($apcEnabled) { $default = array('adapter' => 'Apc'); } Cache::config(compact('default')); /** * Caches paths for auto-loaded and service-located classes. */ Dispatcher::applyFilter('run', function ($self, $params, $chain) { $key = md5(LITHIUM_APP_PATH) . '.core.libraries'; if ($cache = Cache::read('default', $key)) { $cache = (array) $cache + Libraries::cache(); Libraries::cache($cache); } $result = $chain->next($self, $params, $chain); if ($cache != Libraries::cache()) { Cache::write('default', $key, Libraries::cache(), '+1 day'); } return $result; });
return; } Dispatcher::applyFilter('run', function ($self, $params, $chain) { $cacheKey = 'core.libraries'; if ($cached = Cache::read('default', $cacheKey)) { $cached = (array) $cached + Libraries::cache(); Libraries::cache($cached); } $result = $chain->next($self, $params, $chain); if ($cached != ($data = Libraries::cache())) { Cache::write('default', $cacheKey, $data, '+1 day'); } return $result; }); Dispatcher::applyFilter('run', function ($self, $params, $chain) { foreach (Connections::get() as $name) { if (!($connection = Connections::get($name)) instanceof Database) { continue; } $connection->applyFilter('describe', function ($self, $params, $chain) use($name) { if ($params['fields']) { return $chain->next($self, $params, $chain); } $cacheKey = "data.connections.{$name}.sources.{$params['entity']}.schema"; return Cache::read('default', $cacheKey, array('write' => function () use($self, $params, $chain) { return array('+1 day' => $chain->next($self, $params, $chain)); })); }); } return $chain->next($self, $params, $chain); });
public function show($userId = null) { if (empty($userId)) { OauthController::verifyLogged('apontador'); $userId = Session::read('apontadorId'); } $user = unserialize(Cache::read('default', $userId)); if (empty($user)) { $user = $this->userRepository->get($userId); if (!empty($user)) { Cache::write("default", $userId, serialize($user), "+1 day"); } } $location = new Location(); $location->load(); $myUserId = Session::read('apontadorId'); $iFollow = $this->api->isUserFollowedByMe($myUserId, $userId); $title = 'Perfil de ' . $user->getName(); return compact('title', 'location', 'user', 'iFollow'); }
Libraries::cache($cached); } $result = $chain->next($self, $params, $chain); if ($cached != ($data = Libraries::cache())) { Cache::write('default', $cacheKey, $data, '+1 day'); } return $result; }); if (!Environment::is('development')) { Dispatcher::applyFilter('run', function ($self, $params, $chain) { $request = $params['request']; if (!$request->is('get')) { return $chain->next($self, $params, $chain); } $cacheKey = 'fpc_' . md5($request->url); if ($cached = Cache::read('default', $cacheKey)) { return $cached; } $response = $chain->next($self, $params, $chain); switch ($request->url) { case strpos($request->url, '/bot') === 0: $ttl = '+2 minutes'; case '/': $ttl = '+1 hour'; default: $ttl = Cache::PERSIST; } Cache::write('default', $cacheKey, $response, $ttl); return $response; }); Dispatcher::applyFilter('run', function ($self, $params, $chain) {
public function index($username = false) { try { $flickr = \lithium\data\Connections::get('flickr'); } catch (\lithium\core\ConfigException $flickrDebugVars) { return $this->set(compact('flickrDebugVars')); } $username = !$username ? 'JacopKane' : $username; $flickrDebugVars = $flickr ? array( 'flickr.test.echo' => $flickr->test_echo() ? $flickr->connection->last->response : 'fail', 'this->userId' => $this->userId = isset($flickr->people_findByUsername(array( 'username' => $username ))->user->nsid) ? $flickr->connection->last->response->user->nsid : false, 'flickr.test.login' => $flickr->test_login() ? $flickr->connection->last->response : 'fail', 'permission.default' => $flickr->checkPermission('default') ? 'pass' : 'fail', 'permission.read' => $flickr->checkPermission('read') ? 'pass' : $this->redirect($flickr->getAuthUrl('read')), 'permission.write' => $flickr->checkPermission('write') ? 'pass' : 'fail', 'permission.delete' => $flickr->checkPermission('delete') ? 'pass' : 'fail', 'flickr.people.getPhotos me' => ( isset($flickr->people_getPhotos(array( 'user_id' => 'me' ))->photos->photo) ? $flickr->connection->last->response->photos->photo : 'fail' ), 'photoDomain' => $this->photoTest = empty($flickr->connection->last->response->photos->photo) ? false : ( $flickr->getDomain(array( 'id' => 5723127353, 'secret' => 9634646433, 'server' => 5172, 'farm' => 6, 'size' => 'b', 'extension' => 'jpg' ), 'photo') ), 'photoTest' => $this->photoTest === false ? 'no photos found' : ( "<img src=\"{$this->photoTest}\" />" ), 'flickr.people.getInfo' => $flickr->people_getInfo(array( 'user_id' => $this->userId )) ? $flickr->connection->last->response : 'fail', 'flickr.favorites.getList' => $flickr->favorites_getList() ? $flickr->connection->last->response : 'fail', 'api' => array_map(function($method) { return $method->_content; }, isset($flickr->reflection_getMethods()->methods->method) ? $flickr->reflection_getMethods()->methods->method : array()), 'cached_methods' => \lithium\storage\Cache::read('default', 'li3_flickr_methods') ): 'no connection'; $this->set(compact('flickrDebugVars')); }
public function testFileAdapterMultipleStrategies() { $resources = Libraries::get(true, 'resources'); $path = "{$resources}/tmp/cache"; $this->skipIf(!$this->_checkPath(), "{$path} does not have the proper permissions."); $config = array('default' => compact('path') + array('adapter' => 'File', 'filters' => array(), 'strategies' => array('Serializer', 'Base64'))); Cache::config($config); $data = array('some' => 'data'); $time = time(); $result = Cache::write('default', 'key', $data, "@{$time} +1 minute"); $this->assertNotEmpty($result); $time = $time + 60; $result = file_get_contents("{$path}/key"); $expected = "{:expiry:{$time}}\nYToxOntzOjQ6InNvbWUiO3M6NDoiZGF0YSI7fQ=="; $this->assertEqual($result, $expected); $result = Cache::read('default', 'key'); $this->assertEqual($data, $result); $result = unlink("{$path}/key"); $this->assertTrue($result); $this->assertFileNotExists("{$path}/key"); }
/** * This renders a menu for use with Twitter Bootstrap * CSS and JS for Twitter Bootstrap style drop down menus. * * Note: No need to pass class names, etc. unless they are different * than what Twitter Bootstrap requires. * * @param string $name The menu name * @param array $options * @return string HTML code for the menu */ public function render($name = null, $options = array()) { $defaults = array('cache' => false, 'menuId' => '', 'menuClass' => '', 'activeClass' => 'active'); $options += $defaults; if (empty($name) || !is_string($name)) { return ''; } // Get the current URL (false excludes the domain) $here = $this->_context->html->here(false); // set the cache key for the menu $cache_key = empty($name) ? 'li3b_menus.all' : 'li3b_menus.' . $name; $menu = false; // if told to use the menu from cache (note: filters will not be applied for this call because Menu::staticMenu() should not be called provided there's a copy in cache) if (!empty($options['cache'])) { $menu = Cache::read('default', $cache_key); } // if the menu hasn't been set in cache or it was empty for some reason, get a fresh copy of its data if (empty($menu)) { $menu = Menu::staticMenu($name); } // if using cache, write the menu data to the cache key if (!empty($options['cache'])) { Cache::write('default', $cache_key, $menu, $options['cache']); } // Format the HTML for the menu // option for additional custom menu class $menuClass = ' ' . $options['menuClass']; $activeClassName = ' ' . $options['activeClass']; $string = "\n"; $string .= '<ul class="nav nav-pills ' . $name . '_menu' . $menuClass . '" id="' . $options['menuId'] . '">'; $string .= "\n"; if (is_array($menu)) { $i = 1; $total = count($menu); foreach ($menu as $parent) { $title = isset($parent['title']) && !empty($parent['title']) ? $parent['title'] : false; $url = isset($parent['url']) && !empty($parent['url']) ? $parent['url'] : false; $activeIf = isset($parent['activeIf']) && !empty($parent['activeIf']) ? $parent['activeIf'] : array(); $options = isset($parent['options']) && is_array($parent['options']) ? $parent['options'] : array(); $sub_items = isset($parent['subItems']) && is_array($parent['subItems']) ? $parent['subItems'] : array(); if ($parent == 'separator' || $parent == 'spacer' || $parent == 'divider') { $string .= '<li class="divider-vertical"></li>'; } else { if ($title && $url) { $string .= "\t"; $matched_route = false; try { $matched_route = Router::match($url); } catch (\Exception $e) { } // /admin is of course admin_ prefix actions $activeClass = $matched_route == $here || strstr($here, '/admin' . $matched_route) ? $activeClassName : ''; // This plus the Router::match() above really needs some love. // Less if statements...Should be some shorter/nicer way to write it. if (!empty($activeIf)) { if (isset($activeIf['library']) && isset($this->_context->request()->params['library'])) { if ($activeIf['library'] == $this->_context->request()->params['library']) { $activeClass = $activeClassName; } } elseif (isset($this->_context->request()->params['controller']) && (isset($activeIf['controller']) && $activeIf['controller'] == $this->_context->request()->params['controller'])) { $activeClass = $activeClassName; } elseif (isset($activeIf['url']) && $activeIf['url'] == $this->_context->request()->url) { $activeClass = $activeClassName; } } $string .= '<li class="dropdown ' . $activeClass . '">' . $this->_context->html->link($title, $url, $options += array('class' => 'dropdown-toggle', 'data-toggle' => 'dropdown')); // sub menu items if (count($sub_items) > 0) { $string .= "\n\t"; $string .= '<ul class="dropdown-menu">'; $string .= "\n"; foreach ($sub_items as $child) { // let any of these do it if ($child == 'separator' || $child == 'spacer' || $child == 'divider') { $string .= '<li class="divider"></li>'; } else { $title = isset($child['title']) && !empty($child['title']) ? $child['title'] : false; $url = isset($child['url']) && !empty($child['url']) ? $child['url'] : false; $options = isset($child['options']) && is_array($child['options']) ? $child['options'] : array(); if ($title && $url) { $string .= "\t\t"; $string .= '<li>' . $this->_context->html->link($title, $url, $options) . '</li>'; $string .= "\n"; } } } $string .= "\t"; $string .= '</ul>'; $string .= "\n"; } $string .= '</li>'; $string .= "\n"; } } $i++; } } $string .= '</ul>'; $string .= "\n"; return $string; }
return false; }; $lithium = class_exists('\\lithium\\storage\\Cache'); $version = is_callable('Configure::version') ? Configure::version() : null; $cakephp20 = $version && version_compare($version, '2.0', '>='); $cakephp13 = $version && version_compare($version, '1.3', '>=') && !$cakephp20; if ($cakephp13 || $cakephp20) { $cacheRead = function ($key) { return Cache::read($key); }; $cacheWrite = function ($key, $value) { return Cache::write($key, $value); }; } elseif ($lithium) { $cacheRead = function ($key) { return \lithium\storage\Cache::read('default', $key); }; $cacheWrite = function ($key, $value) { return \lithium\storage\Cache::write('default', $key, $value); }; } /* * Test for features on this system. */ $hasFileinfo = extension_loaded('fileinfo'); $hasImagick = extension_loaded('imagick'); /* * Configure the MIME type detection. The detection class is two headed which means it * uses both a glob (for matching against file extensions) and a magic adapter (for * detecting the type from the content of files). Available `glob` adapters are `Apache`, * `Freedesktop`, `Memory` and `Php`. These adapters are also available as a `magic`
public static function hasYear($channel, $date) { $cacheKey = 'li3_bot_log_messages_has_year_' . md5($channel . $date); if (($cached = Cache::read('default', $cacheKey)) !== null) { return $cached; } $result = (bool) static::find('count', ['conditions' => ['channel' => $channel, "YEAR(created)" => $date]]); if ($date <= date('Y')) { // Do not cache future missed years. Cache::write('default', $cacheKey, $result, Cache::PERSIST); } return $result; }
public function testDecrement() { $config = array('default' => array('adapter' => 'Memory', 'filters' => array())); Cache::config($config); $result = Cache::config(); $expected = $config; $this->assertEqual($expected, $result); $result = Cache::write('default', 'decrement', 5, '+1 minute'); $this->assertTrue($result); $result = Cache::decrement('default', 'decrement'); $this->assertTrue($result); $result = Cache::read('default', 'decrement'); $this->assertEqual(4, $result); }
public function testIntegrationFileAdapterMultipleStrategies() { $directory = new SplFileInfo(Libraries::get(true, 'resources') . "/tmp/cache/"); $accessible = $directory->isDir() && $directory->isReadable() && $directory->isWritable(); $message = "{$directory} does not have the proper permissions."; $this->skipIf(!$accessible, $message); $config = array('default' => array('adapter' => 'File', 'path' => Libraries::get(true, 'resources') . '/tmp/cache', 'filters' => array(), 'strategies' => array('Serializer', 'Base64'))); Cache::config($config); $data = array('some' => 'data'); $result = Cache::write('default', 'key', $data, '+1 minute'); $this->assertTrue($result); $time = time() + 60; $result = file_get_contents(Libraries::get(true, 'resources') . '/tmp/cache/key'); $expected = "{:expiry:{$time}}\nYToxOntzOjQ6InNvbWUiO3M6NDoiZGF0YSI7fQ=="; $this->assertEqual($result, $expected); $result = Cache::read('default', 'key'); $this->assertEqual($data, $result); $result = unlink(Libraries::get(true, 'resources') . '/tmp/cache/key'); $this->assertTrue($result); $this->assertFalse(file_exists(Libraries::get(true, 'resources') . '/tmp/cache/key')); }
* Lithium: the most rad php framework * * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org) * @license http://opensource.org/licenses/bsd-license.php The BSD License */ /** * This file creates a default cache configuration using the most optimized adapter available, and * uses it to provide default caching for high-overhead operations. */ use lithium\storage\Cache; use lithium\core\Libraries; use lithium\action\Dispatcher; use lithium\storage\cache\adapter\Apc; /** * If APC is not available and the cache directory is not writeable, bail out. */ if (!($apcEnabled = Apc::enabled() && !is_writable(LITHIUM_APP_PATH . '/resources/tmp/cache'))) { return; } Cache::config(array('default' => array('adapter' => '\\lithium\\storage\\cache\\adapter\\' . ($apcEnabled ? 'Apc' : 'File')))); Dispatcher::applyFilter('run', function ($self, $params, $chain) { if ($cache = Cache::read('default', 'core.libraries')) { $cache = (array) unserialize($cache) + Libraries::cache(); Libraries::cache($cache); } $result = $chain->next($self, $params, $chain); if ($cache != Libraries::cache()) { Cache::write('default', 'core.libraries', serialize(Libraries::cache()), '+1 day'); } return $result; });
/** * Check cache and spits out the style/script link * @param string $filename name of the cache file * @param object $content Assetic style object * @param array $options file stats and helper type * @return string lithium link helper */ private function buildHelper($filename, $content, array $options = array()) { // print_r($options); $filename = "{$filename}_{$options['stats']['size']}_{$options['stats']['modified']}.{$options['type']}"; // If Cache doesn't exist then we recache // Recache removes old caches and adds the new // --- // If you change a file in the styles added then a recache is made due // to the fact that the file stats changed if (!($cached = Cache::read('default', "{$options['type']}/{$filename}"))) { $this->setCache($filename, $content->dump(), array('location' => $options['type'])); } // pass single stylesheet link switch ($options['type']) { case 'css': return $this->_context->helper('html')->style("{$filename}") . "\n\t"; case 'js': return $this->_context->helper('html')->script("{$filename}") . "\n\t"; } }