Blame | Last modification | View Log | Download
<?php namespace ProcessWire;/*** ProcessWire Markup Cache module** A simple way to cache segments of markup in your templates.* A simpler front end to ProcessWire's CacheFile class.** Example usage:** $mycache = $modules->get("MarkupCache");* if(!$data = $mycache->get("cityOptions")) {* foreach($pages->find("template=city, sort=name") as $city) {* $data .= "<option value='{$city->id}'>{$city->title}</option>";* }* $mycache->save($data);* }* echo $data;*** ProcessWire 3.x, Copyright 2016 by Ryan Cramer* https://processwire.com*** @todo add serialize/unserialize to support non-string data in MarkupCache**/class MarkupCache extends Wire implements Module, ConfigurableModule {/*** getModuleInfo is a module required by all modules to tell ProcessWire about them** @return array**/public static function getModuleInfo() {return array('title' => 'Markup Cache','version' => 101,'summary' => 'A simple way to cache segments of markup in your templates. ','href' => 'https://processwire.com/api/modules/markupcache/','singular' => true,'autoload' => true,);}/*** Instance of CacheFile** @var CacheFile**/protected $cache = null;/*** Boolean indicating whether we've already cleared the cache.**/protected $cleared = false;/*** Path to cache files, as set by the init() method.**/protected $path = '';/*** Non zero when caches shouldn't expire on page save**/protected $noExpire = 0;/*** Generate the module's path, static so it can be used by the static getModuleConfigInputfields function**/public function path() {return $this->wire('config')->paths->cache . 'MarkupCache' . '/';}/*** Initialize the module and add a hook after Pages::save**/public function init() {$this->path = $this->path();if(!$this->noExpire) $this->pages->addHookAfter('save', $this, 'expire');}/*** Get cached data identified by 'uniqueName' or false if cache not available** @param string $uniqueName A unique string or number to identify this cache, i.e. 'citiesList'* @param int $seconds The number of seconds the cache should live.* @return string|bool Returns the cache data, or FALSE if it has expired and needs to be re-created.* @throws WireException**/public function get($uniqueName, $seconds = 3600) {$cache = $this->wire(new CacheFile($this->path, $uniqueName, $seconds));if(!$cache) throw new WireException("Unable to create cache '{$this->path}/$uniqueName'");$this->cache = $cache;return $this->cache->get();}/*** Save the data to the cache** Must be preceded by a call to get() so that you have set the cache unique name** @param string $data Data to cache* @return int Number of bytes written to cache, or FALSE on failure.* @throws WireException**/public function save($data) {if(!$this->cache) throw new WireException("You must attempt to retrieve a cache first, before you can save it.");$result = $this->cache->save($data);$this->cache = null;return $result;}/*** Expire the cache, automatically hooked to every $pages->save() call**/public function expire($event = null) {/** If already cleared during this session, don't do it again* that way if we're saving 100+ pages, we aren't clearing the cache 100+ times**/if($this->cleared) return;if($this->cache) $cache = $this->cache;else $cache = $this->wire(new CacheFile($this->path, '', 0));$cache->expireAll();$this->cleared = true;}/*** Clears all MarkupCache files** @return number of files/dirs deleted**/public function removeAll() {$path = $this->path();try {$num = CacheFile::removeAll($path, true);} catch(\Exception $e) {$num = 0;}return $num;}/*** For ConfigurableModule interface, even though we aren't currently using it**/public function __set($key, $value) {if($key == 'noExpire') $this->noExpire = (int) $value;// intentionally left blank}/*** Provide cache clearing capability in the module's configuration** @param array $data* @return InputfieldWrapper**/public function getModuleConfigInputfields(array $data) {$inputfields = $this->wire(new InputfieldWrapper());$clearNow = $this->wire('input')->post->_clearCache ? true : false;$message = '';if($clearNow) {$numFiles = $this->removeAll();$message = "Cleared $numFiles MarkupCache files and dirs";$inputfields->message($message);}$name = "_clearCache"; // prefix with '_' tells ProcessModule not to save it in module's config data$f = $this->wire('modules')->get('InputfieldCheckbox');$f->attr('name', $name);$f->attr('value', 1);$f->attr('checked', '');$f->label = "Clear the MarkupCache?";$f->notes = $message;$f->description = "This will remove all files and directories used by the MarkupCache";$inputfields->append($f);$f = $this->wire('modules')->get('InputfieldRadios');$f->attr('name', 'noExpire');$f->attr('value', empty($data['noExpire']) ? 0 : 1);$f->label = "Expire markup caches when pages are saved?";$f->description = "If you want to ensure stale data is never shown, you should choose: Yes. If you want to maximize performance, you should choose: No.";$f->addOption(0, "Yes - Expire markup caches");$f->addOption(1, "No - Don't expire markup caches");$inputfields->append($f);return $inputfields;}/*** Uninstall this module and remove it's files**/public function ___uninstall() {$numFiles = $this->removeAll();$this->message("Removed $numFiles MarkupCache files");}}