* @copyright 2008-2017 Alexander Schneider * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 * @version SVN: $id$ * @link http://wordpress.org/extend/plugins/user-access-manager/ */ namespace UserAccessManager\Cache; use UserAccessManager\Config\Config; use UserAccessManager\Config\ConfigFactory; use UserAccessManager\Config\ConfigParameterFactory; use UserAccessManager\Util\Util; use UserAccessManager\Wrapper\Php; use UserAccessManager\Wrapper\Wordpress; /** * Class FileSystemCacheProvider * * @package UserAccessManager\Cache */ class FileSystemCacheProvider implements CacheProviderInterface { const ID = 'FileSystemCacheProvider'; const CONFIG_KEY = 'uam_file_system_cache_provider'; const CONFIG_PATH = 'fs_cache_path'; const CONFIG_METHOD = 'fs_cache_method'; const METHOD_SERIALIZE = 'serialize'; const METHOD_IGBINARY = 'igbinary'; const METHOD_JSON = 'json'; const METHOD_VAR_EXPORT = 'var_export'; /** * @var Php */ private $php; /** * @var Wordpress */ private $wordpress; /** * @var Util */ private $util; /** * @var ConfigFactory */ private $configFactory; /** * @var ConfigParameterFactory */ private $configParameterFactory; /** * @var null|Config */ private $config = null; /** * @var string */ private $path = null; /** * FileSystemCacheProvider constructor. * * @param Php $php * @param Wordpress $wordpress * @param Util $util * @param ConfigFactory $configFactory * @param ConfigParameterFactory $configParameterFactory */ public function __construct( Php $php, Wordpress $wordpress, Util $util, ConfigFactory $configFactory, ConfigParameterFactory $configParameterFactory ) { $this->php = $php; $this->wordpress = $wordpress; $this->util = $util; $this->configFactory = $configFactory; $this->configParameterFactory = $configParameterFactory; } /** * Returns the id. * * @return string */ public function getId() { return self::ID; } /** * Returns the cache path. * * @return string */ private function getPath() { if ($this->path === null) { $this->path = $this->getConfig()->getParameterValue(self::CONFIG_PATH); if ($this->util->endsWith($this->path, DIRECTORY_SEPARATOR) === false) { $this->path .= DIRECTORY_SEPARATOR; } } return $this->path; } /** * Initialise the caching path. */ public function init() { $path = $this->getPath(); if (is_dir($path) === false) { $this->php->mkdir($path, 0775, true); } $htaccessFile = $path.'.htaccess'; if (file_exists($htaccessFile) === false) { file_put_contents($htaccessFile, 'Deny from all'); } } /** * Returns the cache config. * * @return Config */ public function getConfig() { if ($this->config === null) { $this->config = $this->configFactory->createConfig(self::CONFIG_KEY); $selections = [ self::METHOD_SERIALIZE, self::METHOD_JSON, self::METHOD_VAR_EXPORT ]; if ($this->php->functionExists('igbinary_serialize') === true) { $selections[] = self::METHOD_IGBINARY; } $configParameters = [ self::CONFIG_PATH => $this->configParameterFactory->createStringConfigParameter( self::CONFIG_PATH, $this->wordpress->getHomePath().'cache/uam' ), self::CONFIG_METHOD => $this->configParameterFactory->createSelectionConfigParameter( self::CONFIG_METHOD, self::METHOD_VAR_EXPORT, $selections ) ]; $this->config->setDefaultConfigParameters($configParameters); } return $this->config; } /** * Returns the caching method. * * @return string|null */ private function getCacheMethod() { $method = (string)$this->getConfig()->getParameterValue(self::CONFIG_METHOD); if ($method === self::METHOD_IGBINARY && ($this->php->functionExists('igbinary_serialize') === false || $this->php->functionExists('igbinary_unserialize') === false) ) { $method = null; } return $method; } /** * Returns the cache file name with path. * * @param string $method * @param string $key * * @return string */ private function getCacheFile($method, $key) { $cacheFile = $this->getPath().$key; $cacheFile .= ($method === self::METHOD_VAR_EXPORT) ? '.php' : '.cache'; return $cacheFile; } /** * Adds a value to the cache. * * @param string $key * @param mixed $value */ public function add($key, $value) { $method = $this->getCacheMethod(); $cacheFile = $this->getCacheFile($method, $key); if ($method === self::METHOD_SERIALIZE) { $this->php->filePutContents($cacheFile, base64_encode(serialize($value)), LOCK_EX); } elseif ($method === self::METHOD_IGBINARY) { /** @noinspection PhpUndefinedFunctionInspection */ $this->php->filePutContents($cacheFile, $this->php->igbinarySerialize($value), LOCK_EX); } elseif ($method === self::METHOD_JSON) { $this->php->filePutContents($cacheFile, json_encode($value), LOCK_EX); } elseif ($method === self::METHOD_VAR_EXPORT) { $this->php->filePutContents($cacheFile, "getCacheMethod(); $cacheFile = $this->getCacheFile($method, $key); if ((file_exists($cacheFile) === true)) { if ($method === self::METHOD_SERIALIZE) { return unserialize(base64_decode(file_get_contents($cacheFile))); } elseif ($method === self::METHOD_IGBINARY) { /** @noinspection PhpUndefinedFunctionInspection */ return $this->php->igbinaryUnserialize(file_get_contents($cacheFile)); } elseif ($method === self::METHOD_JSON) { return json_decode(file_get_contents($cacheFile), true); } elseif ($method === self::METHOD_VAR_EXPORT) { $cachedValue = null; /** @noinspection PhpIncludeInspection */ include($cacheFile); return $cachedValue; } } return null; } /** * Invalidates the cache. * * @param string $key */ public function invalidate($key) { $method = $this->getCacheMethod(); $cacheFile = $this->getCacheFile($method, $key); if ((file_exists($cacheFile) === true)) { unlink($cacheFile); } } }