├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── autoload └── patternPluginManagerPolyfill.php ├── composer.json └── src ├── ConfigProvider.php ├── Exception ├── BadMethodCallException.php ├── ExceptionInterface.php ├── ExtensionNotLoadedException.php ├── InvalidArgumentException.php ├── LogicException.php ├── MissingDependencyException.php ├── MissingKeyException.php ├── OutOfSpaceException.php ├── RuntimeException.php ├── UnexpectedValueException.php └── UnsupportedMethodCallException.php ├── Module.php ├── Pattern ├── AbstractPattern.php ├── CallbackCache.php ├── CaptureCache.php ├── ClassCache.php ├── ObjectCache.php ├── OutputCache.php ├── PatternInterface.php └── PatternOptions.php ├── PatternFactory.php ├── PatternPluginManager ├── PatternPluginManagerTrait.php ├── PatternPluginManagerV2Polyfill.php └── PatternPluginManagerV3Polyfill.php ├── Psr ├── CacheItemPool │ ├── CacheException.php │ ├── CacheItem.php │ ├── CacheItemPoolDecorator.php │ └── InvalidArgumentException.php ├── SerializationTrait.php └── SimpleCache │ ├── SimpleCacheDecorator.php │ ├── SimpleCacheException.php │ └── SimpleCacheInvalidArgumentException.php ├── Service ├── PatternPluginManagerFactory.php ├── PluginManagerLookupTrait.php ├── StorageAdapterPluginManagerFactory.php ├── StorageCacheAbstractServiceFactory.php ├── StorageCacheFactory.php └── StoragePluginManagerFactory.php ├── Storage ├── Adapter │ ├── AbstractAdapter.php │ ├── AbstractZendServer.php │ ├── AdapterOptions.php │ ├── Apc.php │ ├── ApcIterator.php │ ├── ApcOptions.php │ ├── Apcu.php │ ├── ApcuIterator.php │ ├── ApcuOptions.php │ ├── BlackHole.php │ ├── Dba.php │ ├── DbaIterator.php │ ├── DbaOptions.php │ ├── ExtMongoDb.php │ ├── ExtMongoDbOptions.php │ ├── ExtMongoDbResourceManager.php │ ├── Filesystem.php │ ├── FilesystemIterator.php │ ├── FilesystemOptions.php │ ├── KeyListIterator.php │ ├── Memcache.php │ ├── MemcacheOptions.php │ ├── MemcacheResourceManager.php │ ├── Memcached.php │ ├── MemcachedOptions.php │ ├── MemcachedResourceManager.php │ ├── Memory.php │ ├── MemoryOptions.php │ ├── MongoDb.php │ ├── MongoDbOptions.php │ ├── MongoDbResourceManager.php │ ├── Redis.php │ ├── RedisOptions.php │ ├── RedisResourceManager.php │ ├── Session.php │ ├── SessionOptions.php │ ├── WinCache.php │ ├── WinCacheOptions.php │ ├── XCache.php │ ├── XCacheOptions.php │ ├── ZendServerDisk.php │ └── ZendServerShm.php ├── AdapterPluginManager.php ├── AvailableSpaceCapableInterface.php ├── Capabilities.php ├── ClearByNamespaceInterface.php ├── ClearByPrefixInterface.php ├── ClearExpiredInterface.php ├── Event.php ├── ExceptionEvent.php ├── FlushableInterface.php ├── IterableInterface.php ├── IteratorInterface.php ├── OptimizableInterface.php ├── Plugin │ ├── AbstractPlugin.php │ ├── ClearExpiredByFactor.php │ ├── ExceptionHandler.php │ ├── IgnoreUserAbort.php │ ├── OptimizeByFactor.php │ ├── PluginInterface.php │ ├── PluginOptions.php │ └── Serializer.php ├── PluginManager.php ├── PostEvent.php ├── StorageInterface.php ├── TaggableInterface.php └── TotalSpaceCapableInterface.php └── StorageFactory.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2018, Zend Technologies USA, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | - Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | - Neither the name of Zend Technologies USA, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zend-cache 2 | 3 | > ## Repository abandoned 2019-12-31 4 | > 5 | > This repository has moved to [laminas/laminas-cache](https://github.com/laminas/laminas-cache). 6 | 7 | [![Build Status](https://secure.travis-ci.org/zendframework/zend-cache.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-cache) 8 | [![Coverage Status](https://coveralls.io/repos/github/zendframework/zend-cache/badge.svg?branch=master)](https://coveralls.io/github/zendframework/zend-cache?branch=master) 9 | 10 | `Zend\Cache` provides a general cache system for PHP. The `Zend\Cache` component 11 | is able to cache different patterns (class, object, output, etc) using different 12 | storage adapters (DB, File, Memcache, etc). 13 | 14 | 15 | - File issues at https://github.com/zendframework/zend-cache/issues 16 | - Documentation is at https://docs.zendframework.com/zend-cache/ 17 | 18 | ## Benchmarks 19 | 20 | We provide scripts for benchmarking zend-cache using the 21 | [PHPBench](https://github.com/phpbench/phpbench) framework; these can be 22 | found in the `benchmark/` directory. 23 | 24 | To execute the benchmarks you can run the following command: 25 | 26 | ```bash 27 | $ vendor/bin/phpbench run --report=aggregate 28 | ``` 29 | -------------------------------------------------------------------------------- /autoload/patternPluginManagerPolyfill.php: -------------------------------------------------------------------------------- 1 | = 5.1.0, to use the APCu storage adapter", 41 | "ext-dba": "DBA, to use the DBA storage adapter", 42 | "ext-memcache": "Memcache >= 2.0.0 to use the Memcache storage adapter", 43 | "ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter", 44 | "ext-mongo": "Mongo, to use MongoDb storage adapter", 45 | "ext-mongodb": "MongoDB, to use the ExtMongoDb storage adapter", 46 | "ext-redis": "Redis, to use Redis storage adapter", 47 | "ext-wincache": "WinCache, to use the WinCache storage adapter", 48 | "ext-xcache": "XCache, to use the XCache storage adapter", 49 | "mongodb/mongodb": "Required for use with the ext-mongodb adapter", 50 | "mongofill/mongofill": "Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement" 51 | }, 52 | "autoload": { 53 | "files": [ 54 | "autoload/patternPluginManagerPolyfill.php" 55 | ], 56 | "psr-4": { 57 | "Zend\\Cache\\": "src/" 58 | } 59 | }, 60 | "autoload-dev": { 61 | "psr-4": { 62 | "ZendTest\\Cache\\": "test/", 63 | "ZendBench\\Cache\\": "benchmark/" 64 | }, 65 | "files": [ 66 | "test/autoload.php" 67 | ] 68 | }, 69 | "config": { 70 | "process-timeout": 600, 71 | "sort-packages": true 72 | }, 73 | "provide": { 74 | "psr/cache-implementation": "1.0", 75 | "psr/simple-cache-implementation": "1.0" 76 | }, 77 | "extra": { 78 | "branch-alias": { 79 | "dev-master": "2.9.x-dev", 80 | "dev-develop": "2.10.x-dev" 81 | }, 82 | "zf": { 83 | "component": "Zend\\Cache", 84 | "config-provider": "Zend\\Cache\\ConfigProvider" 85 | } 86 | }, 87 | "scripts": { 88 | "check": [ 89 | "@cs-check", 90 | "@test" 91 | ], 92 | "cs-check": "phpcs", 93 | "cs-fix": "phpcbf", 94 | "test": "phpunit --colors=always", 95 | "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/ConfigProvider.php: -------------------------------------------------------------------------------- 1 | $this->getDependencyConfig(), 21 | ]; 22 | } 23 | 24 | /** 25 | * Return default service mappings for zend-cache. 26 | * 27 | * @return array 28 | */ 29 | public function getDependencyConfig() 30 | { 31 | return [ 32 | 'abstract_factories' => [ 33 | Service\StorageCacheAbstractServiceFactory::class, 34 | ], 35 | 'factories' => [ 36 | PatternPluginManager::class => Service\PatternPluginManagerFactory::class, 37 | Storage\AdapterPluginManager::class => Service\StorageAdapterPluginManagerFactory::class, 38 | Storage\PluginManager::class => Service\StoragePluginManagerFactory::class, 39 | ], 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Exception/BadMethodCallException.php: -------------------------------------------------------------------------------- 1 | $provider->getDependencyConfig(), 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Pattern/AbstractPattern.php: -------------------------------------------------------------------------------- 1 | options = $options; 35 | return $this; 36 | } 37 | 38 | /** 39 | * Get all pattern options 40 | * 41 | * @return PatternOptions 42 | */ 43 | public function getOptions() 44 | { 45 | if (null === $this->options) { 46 | $this->setOptions(new PatternOptions()); 47 | } 48 | return $this->options; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Pattern/CallbackCache.php: -------------------------------------------------------------------------------- 1 | getStorage()) { 29 | throw new Exception\InvalidArgumentException("Missing option 'storage'"); 30 | } 31 | return $this; 32 | } 33 | 34 | /** 35 | * Call the specified callback or get the result from cache 36 | * 37 | * @param callable $callback A valid callback 38 | * @param array $args Callback arguments 39 | * @return mixed Result 40 | * @throws Exception\RuntimeException if invalid cached data 41 | * @throws \Exception 42 | */ 43 | public function call($callback, array $args = []) 44 | { 45 | $options = $this->getOptions(); 46 | $storage = $options->getStorage(); 47 | $success = null; 48 | $key = $this->generateCallbackKey($callback, $args); 49 | $result = $storage->getItem($key, $success); 50 | if ($success) { 51 | if (! array_key_exists(0, $result)) { 52 | throw new Exception\RuntimeException("Invalid cached data for key '{$key}'"); 53 | } 54 | 55 | echo isset($result[1]) ? $result[1] : ''; 56 | return $result[0]; 57 | } 58 | 59 | $cacheOutput = $options->getCacheOutput(); 60 | if ($cacheOutput) { 61 | ob_start(); 62 | ob_implicit_flush(0); 63 | } 64 | 65 | // TODO: do not cache on errors using [set|restore]_error_handler 66 | 67 | try { 68 | if ($args) { 69 | $ret = call_user_func_array($callback, $args); 70 | } else { 71 | $ret = call_user_func($callback); 72 | } 73 | } catch (\Exception $e) { 74 | if ($cacheOutput) { 75 | ob_end_flush(); 76 | } 77 | throw $e; 78 | } 79 | 80 | if ($cacheOutput) { 81 | $data = [$ret, ob_get_flush()]; 82 | } else { 83 | $data = [$ret]; 84 | } 85 | 86 | $storage->setItem($key, $data); 87 | 88 | return $ret; 89 | } 90 | 91 | /** 92 | * function call handler 93 | * 94 | * @param string $function Function name to call 95 | * @param array $args Function arguments 96 | * @return mixed 97 | * @throws Exception\RuntimeException 98 | * @throws \Exception 99 | */ 100 | public function __call($function, array $args) 101 | { 102 | return $this->call($function, $args); 103 | } 104 | 105 | /** 106 | * Generate a unique key in base of a key representing the callback part 107 | * and a key representing the arguments part. 108 | * 109 | * @param callable $callback A valid callback 110 | * @param array $args Callback arguments 111 | * @return string 112 | * @throws Exception\RuntimeException 113 | * @throws Exception\InvalidArgumentException 114 | */ 115 | public function generateKey($callback, array $args = []) 116 | { 117 | return $this->generateCallbackKey($callback, $args); 118 | } 119 | 120 | /** 121 | * Generate a unique key in base of a key representing the callback part 122 | * and a key representing the arguments part. 123 | * 124 | * @param callable $callback A valid callback 125 | * @param array $args Callback arguments 126 | * @throws Exception\RuntimeException if callback not serializable 127 | * @throws Exception\InvalidArgumentException if invalid callback 128 | * @return string 129 | */ 130 | protected function generateCallbackKey($callback, array $args) 131 | { 132 | if (! is_callable($callback, false, $callbackKey)) { 133 | throw new Exception\InvalidArgumentException('Invalid callback'); 134 | } 135 | 136 | // functions, methods and classnames are case-insensitive 137 | $callbackKey = strtolower($callbackKey); 138 | 139 | // generate a unique key of object callbacks 140 | if (is_object($callback)) { 141 | // Closures & __invoke 142 | $object = $callback; 143 | } elseif (isset($callback[0])) { 144 | // array($object, 'method') 145 | $object = $callback[0]; 146 | } 147 | if (isset($object)) { 148 | ErrorHandler::start(); 149 | try { 150 | $serializedObject = serialize($object); 151 | } catch (\Exception $e) { 152 | ErrorHandler::stop(); 153 | throw new Exception\RuntimeException("Can't serialize callback: see previous exception", 0, $e); 154 | } 155 | $error = ErrorHandler::stop(); 156 | 157 | if (! $serializedObject) { 158 | throw new Exception\RuntimeException( 159 | sprintf('Cannot serialize callback%s', ($error ? ': ' . $error->getMessage() : '')), 160 | 0, 161 | $error 162 | ); 163 | } 164 | $callbackKey .= $serializedObject; 165 | } 166 | 167 | return md5($callbackKey) . $this->generateArgumentsKey($args); 168 | } 169 | 170 | /** 171 | * Generate a unique key of the argument part. 172 | * 173 | * @param array $args 174 | * @throws Exception\RuntimeException 175 | * @return string 176 | */ 177 | protected function generateArgumentsKey(array $args) 178 | { 179 | if (! $args) { 180 | return ''; 181 | } 182 | 183 | ErrorHandler::start(); 184 | try { 185 | $serializedArgs = serialize(array_values($args)); 186 | } catch (\Exception $e) { 187 | ErrorHandler::stop(); 188 | throw new Exception\RuntimeException("Can't serialize arguments: see previous exception", 0, $e); 189 | } 190 | $error = ErrorHandler::stop(); 191 | 192 | if (! $serializedArgs) { 193 | throw new Exception\RuntimeException( 194 | sprintf('Cannot serialize arguments%s', ($error ? ': ' . $error->getMessage() : '')), 195 | 0, 196 | $error 197 | ); 198 | } 199 | 200 | return md5($serializedArgs); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/Pattern/ClassCache.php: -------------------------------------------------------------------------------- 1 | getClass()) { 29 | throw new Exception\InvalidArgumentException("Missing option 'class'"); 30 | } elseif (! $options->getStorage()) { 31 | throw new Exception\InvalidArgumentException("Missing option 'storage'"); 32 | } 33 | return $this; 34 | } 35 | 36 | /** 37 | * Call and cache a class method 38 | * 39 | * @param string $method Method name to call 40 | * @param array $args Method arguments 41 | * @return mixed 42 | * @throws Exception\RuntimeException 43 | * @throws \Exception 44 | */ 45 | public function call($method, array $args = []) 46 | { 47 | $options = $this->getOptions(); 48 | $classname = $options->getClass(); 49 | $method = strtolower($method); 50 | $callback = $classname . '::' . $method; 51 | 52 | $cache = $options->getCacheByDefault(); 53 | if ($cache) { 54 | $cache = ! in_array($method, $options->getClassNonCacheMethods()); 55 | } else { 56 | $cache = in_array($method, $options->getClassCacheMethods()); 57 | } 58 | 59 | if (! $cache) { 60 | if ($args) { 61 | return call_user_func_array($callback, $args); 62 | } else { 63 | return $classname::$method(); 64 | } 65 | } 66 | 67 | return parent::call($callback, $args); 68 | } 69 | 70 | /** 71 | * Generate a unique key in base of a key representing the callback part 72 | * and a key representing the arguments part. 73 | * 74 | * @param string $method The method 75 | * @param array $args Callback arguments 76 | * @return string 77 | * @throws Exception\RuntimeException 78 | */ 79 | public function generateKey($method, array $args = []) 80 | { 81 | return $this->generateCallbackKey( 82 | $this->getOptions()->getClass() . '::' . $method, 83 | $args 84 | ); 85 | } 86 | 87 | /** 88 | * Generate a unique key in base of a key representing the callback part 89 | * and a key representing the arguments part. 90 | * 91 | * @param callable $callback A valid callback 92 | * @param array $args Callback arguments 93 | * @return string 94 | * @throws Exception\RuntimeException 95 | */ 96 | protected function generateCallbackKey($callback, array $args) 97 | { 98 | $callbackKey = md5(strtolower($callback)); 99 | $argumentKey = $this->generateArgumentsKey($args); 100 | return $callbackKey . $argumentKey; 101 | } 102 | 103 | /** 104 | * Calling a method of the entity. 105 | * 106 | * @param string $method Method name to call 107 | * @param array $args Method arguments 108 | * @return mixed 109 | * @throws Exception\RuntimeException 110 | * @throws \Exception 111 | */ 112 | public function __call($method, array $args) 113 | { 114 | return $this->call($method, $args); 115 | } 116 | 117 | /** 118 | * Set a static property 119 | * 120 | * @param string $name 121 | * @param mixed $value 122 | * @return void 123 | * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members 124 | */ 125 | public function __set($name, $value) 126 | { 127 | $class = $this->getOptions()->getClass(); 128 | $class::$name = $value; 129 | } 130 | 131 | /** 132 | * Get a static property 133 | * 134 | * @param string $name 135 | * @return mixed 136 | * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members 137 | */ 138 | public function __get($name) 139 | { 140 | $class = $this->getOptions()->getClass(); 141 | return $class::$name; 142 | } 143 | 144 | /** 145 | * Is a static property exists. 146 | * 147 | * @param string $name 148 | * @return bool 149 | */ 150 | public function __isset($name) 151 | { 152 | $class = $this->getOptions()->getClass(); 153 | return isset($class::$name); 154 | } 155 | 156 | /** 157 | * Unset a static property 158 | * 159 | * @param string $name 160 | * @return void 161 | */ 162 | public function __unset($name) 163 | { 164 | $class = $this->getOptions()->getClass(); 165 | unset($class::$name); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/Pattern/OutputCache.php: -------------------------------------------------------------------------------- 1 | getStorage()) { 35 | throw new Exception\InvalidArgumentException("Missing option 'storage'"); 36 | } 37 | 38 | return $this; 39 | } 40 | 41 | /** 42 | * if there is a cached item with the given key display it's data and return true 43 | * else start buffering output until end() is called or the script ends. 44 | * 45 | * @param string $key Key 46 | * @throws Exception\MissingKeyException if key is missing 47 | * @return bool 48 | */ 49 | public function start($key) 50 | { 51 | if (($key = (string) $key) === '') { 52 | throw new Exception\MissingKeyException('Missing key to read/write output from cache'); 53 | } 54 | 55 | $success = null; 56 | $data = $this->getOptions()->getStorage()->getItem($key, $success); 57 | if ($success) { 58 | echo $data; 59 | return true; 60 | } 61 | 62 | ob_start(); 63 | ob_implicit_flush(0); 64 | $this->keyStack[] = $key; 65 | return false; 66 | } 67 | 68 | /** 69 | * Stops buffering output, write buffered data to cache using the given key on start() 70 | * and displays the buffer. 71 | * 72 | * @throws Exception\RuntimeException if output cache not started or buffering not active 73 | * @return bool TRUE on success, FALSE on failure writing to cache 74 | */ 75 | public function end() 76 | { 77 | $key = array_pop($this->keyStack); 78 | if ($key === null) { 79 | throw new Exception\RuntimeException('Output cache not started'); 80 | } 81 | 82 | $output = ob_get_flush(); 83 | if ($output === false) { 84 | throw new Exception\RuntimeException('Output buffering not active'); 85 | } 86 | 87 | return $this->getOptions()->getStorage()->setItem($key, $output); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Pattern/PatternInterface.php: -------------------------------------------------------------------------------- 1 | toArray(); 37 | } 38 | 39 | if ($options instanceof Traversable) { 40 | $options = ArrayUtils::iteratorToArray($options); 41 | } 42 | 43 | if (! is_array($options)) { 44 | throw new Exception\InvalidArgumentException(sprintf( 45 | '%s expects an array, Traversable object, or %s\Pattern\PatternOptions object; received "%s"', 46 | __METHOD__, 47 | __NAMESPACE__, 48 | (is_object($options) ? get_class($options) : gettype($options)) 49 | )); 50 | } 51 | 52 | if ($patternName instanceof Pattern\PatternInterface) { 53 | $patternName->setOptions(new Pattern\PatternOptions($options)); 54 | return $patternName; 55 | } 56 | 57 | return static::getPluginManager()->get($patternName, $options); 58 | } 59 | 60 | /** 61 | * Get the pattern plugin manager 62 | * 63 | * @return PatternPluginManager 64 | */ 65 | public static function getPluginManager() 66 | { 67 | if (static::$plugins === null) { 68 | static::$plugins = new PatternPluginManager(new ServiceManager); 69 | } 70 | 71 | return static::$plugins; 72 | } 73 | 74 | /** 75 | * Set the pattern plugin manager 76 | * 77 | * @param PatternPluginManager $plugins 78 | * @return void 79 | */ 80 | public static function setPluginManager(PatternPluginManager $plugins) 81 | { 82 | static::$plugins = $plugins; 83 | } 84 | 85 | /** 86 | * Reset pattern plugin manager to default 87 | * 88 | * @return void 89 | */ 90 | public static function resetPluginManager() 91 | { 92 | static::$plugins = null; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/PatternPluginManager/PatternPluginManagerTrait.php: -------------------------------------------------------------------------------- 1 | setOptions(new Pattern\PatternOptions($options)); 36 | return $plugin; 37 | } 38 | 39 | /** 40 | * Validate the plugin is of the expected type (v3). 41 | * 42 | * Validates against `$instanceOf`. 43 | * 44 | * @param mixed $instance 45 | * @throws InvalidServiceException 46 | */ 47 | public function validate($instance) 48 | { 49 | if (! $instance instanceof $this->instanceOf) { 50 | throw new InvalidServiceException(sprintf( 51 | '%s can only create instances of %s; %s is invalid', 52 | get_class($this), 53 | $this->instanceOf, 54 | (is_object($instance) ? get_class($instance) : gettype($instance)) 55 | )); 56 | } 57 | } 58 | 59 | /** 60 | * Validate the plugin is of the expected type (v2). 61 | * 62 | * Proxies to `validate()`. 63 | * 64 | * @param mixed $plugin 65 | * @throws Exception\RuntimeException if invalid 66 | */ 67 | public function validatePlugin($plugin) 68 | { 69 | try { 70 | $this->validate($plugin); 71 | } catch (InvalidServiceException $e) { 72 | throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/PatternPluginManager/PatternPluginManagerV2Polyfill.php: -------------------------------------------------------------------------------- 1 | Pattern\CallbackCache::class, 27 | 'Callback' => Pattern\CallbackCache::class, 28 | 'capture' => Pattern\CaptureCache::class, 29 | 'Capture' => Pattern\CaptureCache::class, 30 | 'class' => Pattern\ClassCache::class, 31 | 'Class' => Pattern\ClassCache::class, 32 | 'object' => Pattern\ObjectCache::class, 33 | 'Object' => Pattern\ObjectCache::class, 34 | 'output' => Pattern\OutputCache::class, 35 | 'Output' => Pattern\OutputCache::class, 36 | ]; 37 | 38 | protected $factories = [ 39 | Pattern\CallbackCache::class => InvokableFactory::class, 40 | Pattern\CaptureCache::class => InvokableFactory::class, 41 | Pattern\ClassCache::class => InvokableFactory::class, 42 | Pattern\ObjectCache::class => InvokableFactory::class, 43 | Pattern\OutputCache::class => InvokableFactory::class, 44 | 45 | // v2 normalized FQCNs 46 | 'zendcachepatterncallbackcache' => InvokableFactory::class, 47 | 'zendcachepatterncapturecache' => InvokableFactory::class, 48 | 'zendcachepatternclasscache' => InvokableFactory::class, 49 | 'zendcachepatternobjectcache' => InvokableFactory::class, 50 | 'zendcachepatternoutputcache' => InvokableFactory::class, 51 | ]; 52 | 53 | /** 54 | * Don't share by default 55 | * 56 | * @var bool 57 | */ 58 | protected $shareByDefault = false; 59 | 60 | /** 61 | * Don't share by default 62 | * 63 | * @var bool 64 | */ 65 | protected $sharedByDefault = false; 66 | 67 | /** 68 | * @var string 69 | */ 70 | protected $instanceOf = Pattern\PatternInterface::class; 71 | 72 | /** 73 | * Override get to inject options as PatternOptions instance. 74 | * 75 | * {@inheritDoc} 76 | */ 77 | public function get($plugin, $options = [], $usePeeringServiceManagers = true) 78 | { 79 | if (empty($options)) { 80 | return parent::get($plugin, [], $usePeeringServiceManagers); 81 | } 82 | 83 | $plugin = parent::get($plugin, [], $usePeeringServiceManagers); 84 | $plugin->setOptions(new Pattern\PatternOptions($options)); 85 | return $plugin; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/PatternPluginManager/PatternPluginManagerV3Polyfill.php: -------------------------------------------------------------------------------- 1 | Pattern\CallbackCache::class, 27 | 'Callback' => Pattern\CallbackCache::class, 28 | 'capture' => Pattern\CaptureCache::class, 29 | 'Capture' => Pattern\CaptureCache::class, 30 | 'class' => Pattern\ClassCache::class, 31 | 'Class' => Pattern\ClassCache::class, 32 | 'object' => Pattern\ObjectCache::class, 33 | 'Object' => Pattern\ObjectCache::class, 34 | 'output' => Pattern\OutputCache::class, 35 | 'Output' => Pattern\OutputCache::class, 36 | ]; 37 | 38 | protected $factories = [ 39 | Pattern\CallbackCache::class => InvokableFactory::class, 40 | Pattern\CaptureCache::class => InvokableFactory::class, 41 | Pattern\ClassCache::class => InvokableFactory::class, 42 | Pattern\ObjectCache::class => InvokableFactory::class, 43 | Pattern\OutputCache::class => InvokableFactory::class, 44 | 45 | // v2 normalized FQCNs 46 | 'zendcachepatterncallbackcache' => InvokableFactory::class, 47 | 'zendcachepatterncapturecache' => InvokableFactory::class, 48 | 'zendcachepatternclasscache' => InvokableFactory::class, 49 | 'zendcachepatternobjectcache' => InvokableFactory::class, 50 | 'zendcachepatternoutputcache' => InvokableFactory::class, 51 | ]; 52 | 53 | /** 54 | * Don't share by default 55 | * 56 | * @var bool 57 | */ 58 | protected $shareByDefault = false; 59 | 60 | /** 61 | * Don't share by default 62 | * 63 | * @var bool 64 | */ 65 | protected $sharedByDefault = false; 66 | 67 | /** 68 | * @var string 69 | */ 70 | protected $instanceOf = Pattern\PatternInterface::class; 71 | 72 | /** 73 | * Override get to inject options as PatternOptions instance. 74 | * 75 | * {@inheritDoc} 76 | */ 77 | public function get($plugin, array $options = null, $usePeeringServiceManagers = true) 78 | { 79 | if (empty($options)) { 80 | return parent::get($plugin, null, $usePeeringServiceManagers); 81 | } 82 | 83 | $plugin = parent::get($plugin, null, $usePeeringServiceManagers); 84 | $plugin->setOptions(new Pattern\PatternOptions($options)); 85 | return $plugin; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Psr/CacheItemPool/CacheException.php: -------------------------------------------------------------------------------- 1 | key = $key; 63 | $this->value = $isHit ? $value : null; 64 | $this->isHit = $isHit; 65 | $this->utc = new DateTimeZone('UTC'); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | public function getKey() 72 | { 73 | return $this->key; 74 | } 75 | 76 | /** 77 | * {@inheritdoc} 78 | */ 79 | public function get() 80 | { 81 | return $this->value; 82 | } 83 | 84 | /** 85 | * {@inheritdoc} 86 | */ 87 | public function isHit() 88 | { 89 | if (! $this->isHit) { 90 | return false; 91 | } 92 | $ttl = $this->getTtl(); 93 | return $ttl === null || $ttl > 0; 94 | } 95 | 96 | /** 97 | * Sets isHit value 98 | * 99 | * This function is called by CacheItemPoolDecorator::saveDeferred() and is not intended for use by other calling 100 | * code. 101 | * 102 | * @param boolean $isHit 103 | * @return $this 104 | */ 105 | public function setIsHit($isHit) 106 | { 107 | $this->isHit = $isHit; 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * {@inheritdoc} 114 | */ 115 | public function set($value) 116 | { 117 | $this->value = $value; 118 | 119 | return $this; 120 | } 121 | 122 | /** 123 | * {@inheritdoc} 124 | */ 125 | public function expiresAt($expiration) 126 | { 127 | if (! ($expiration === null || $expiration instanceof DateTimeInterface)) { 128 | throw new InvalidArgumentException('$expiration must be null or an instance of DateTimeInterface'); 129 | } 130 | 131 | $this->expiration = $expiration instanceof DateTimeInterface ? $expiration->getTimestamp() : null; 132 | $this->ttl = null; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * {@inheritdoc} 139 | */ 140 | public function expiresAfter($time) 141 | { 142 | if ($time instanceof DateInterval) { 143 | $now = new DateTimeImmutable('now', $this->utc); 144 | $end = $now->add($time); 145 | $this->ttl = $end->getTimestamp() - $now->getTimestamp(); 146 | } elseif (is_int($time) || $time === null) { 147 | $this->ttl = $time; 148 | } else { 149 | throw new InvalidArgumentException(sprintf('Invalid $time "%s"', gettype($time))); 150 | } 151 | 152 | $this->expiration = null; 153 | 154 | return $this; 155 | } 156 | 157 | /** 158 | * Returns number of seconds until item expires 159 | * 160 | * If NULL, the pool should use the default TTL for the storage adapter. If <= 0, the item has expired. 161 | * 162 | * @return int|null 163 | */ 164 | public function getTtl() 165 | { 166 | $ttl = $this->ttl; 167 | if ($this->expiration !== null) { 168 | $ttl = $this->expiration - time(); 169 | } 170 | return $ttl; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/Psr/CacheItemPool/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | getCapabilities(); 27 | $requiredTypes = ['string', 'integer', 'double', 'boolean', 'NULL', 'array', 'object']; 28 | $types = $capabilities->getSupportedDatatypes(); 29 | 30 | foreach ($requiredTypes as $type) { 31 | // 'object' => 'object' is OK 32 | // 'integer' => 'string' is not (redis) 33 | // 'integer' => 'integer' is not (memcache) 34 | if (! (isset($types[$type]) && in_array($types[$type], [true, 'array', 'object'], true))) { 35 | return true; 36 | } 37 | } 38 | 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Psr/SimpleCache/SimpleCacheException.php: -------------------------------------------------------------------------------- 1 | creationOptions); 42 | } 43 | 44 | /** 45 | * zend-servicemanager v2 support for invocation options. 46 | * 47 | * @param array $options 48 | * @return void 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->creationOptions = $options; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Service/PluginManagerLookupTrait.php: -------------------------------------------------------------------------------- 1 | lookupStorageAdapterPluginManager($container)); 26 | StorageFactory::setPluginManager($this->lookupStoragePluginManager($container)); 27 | } 28 | 29 | /** 30 | * Lookup the storage adapter plugin manager. 31 | * 32 | * Returns the Zend\Cache\Storage\AdapterPluginManager service if present, 33 | * or creates a new instance otherwise. 34 | * 35 | * @param ContainerInterface $container 36 | * @return AdapterPluginManager 37 | */ 38 | private function lookupStorageAdapterPluginManager(ContainerInterface $container) 39 | { 40 | if ($container->has(AdapterPluginManager::class)) { 41 | return $container->get(AdapterPluginManager::class); 42 | } 43 | return new AdapterPluginManager($container); 44 | } 45 | 46 | /** 47 | * Lookup the storage plugins plugin manager. 48 | * 49 | * Returns the Zend\Cache\Storage\PluginManager service if present, or 50 | * creates a new instance otherwise. 51 | * 52 | * @param ContainerInterface $container 53 | * @return PluginManager 54 | */ 55 | private function lookupStoragePluginManager(ContainerInterface $container) 56 | { 57 | if ($container->has(PluginManager::class)) { 58 | return $container->get(PluginManager::class); 59 | } 60 | return new PluginManager($container); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Service/StorageAdapterPluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | creationOptions); 42 | } 43 | 44 | /** 45 | * zend-servicemanager v2 support for invocation options. 46 | * 47 | * @param array $options 48 | * @return void 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->creationOptions = $options; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Service/StorageCacheAbstractServiceFactory.php: -------------------------------------------------------------------------------- 1 | getConfig($container); 44 | if (empty($config)) { 45 | return false; 46 | } 47 | return (isset($config[$requestedName]) && is_array($config[$requestedName])); 48 | } 49 | 50 | /** 51 | * @param ServiceLocatorInterface $serviceLocator 52 | * @param string $name 53 | * @param string $requestedName 54 | * @return boolean 55 | */ 56 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 57 | { 58 | return $this->canCreate($serviceLocator, $requestedName); 59 | } 60 | 61 | /** 62 | * Create an object 63 | * 64 | * @param ContainerInterface $container 65 | * @param string $requestedName 66 | * @param null|array $options 67 | * @return object 68 | */ 69 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 70 | { 71 | $this->prepareStorageFactory($container); 72 | 73 | $config = $this->getConfig($container); 74 | return StorageFactory::factory($config[$requestedName]); 75 | } 76 | 77 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 78 | { 79 | return $this($serviceLocator, $requestedName); 80 | } 81 | 82 | /** 83 | * Retrieve cache configuration, if any 84 | * 85 | * @param ContainerInterface $container 86 | * @return array 87 | */ 88 | protected function getConfig(ContainerInterface $container) 89 | { 90 | if ($this->config !== null) { 91 | return $this->config; 92 | } 93 | 94 | if (! $container->has('config')) { 95 | $this->config = []; 96 | return $this->config; 97 | } 98 | 99 | $config = $container->get('config'); 100 | if (! isset($config[$this->configKey])) { 101 | $this->config = []; 102 | return $this->config; 103 | } 104 | 105 | $this->config = $config[$this->configKey]; 106 | return $this->config; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Service/StorageCacheFactory.php: -------------------------------------------------------------------------------- 1 | prepareStorageFactory($container); 28 | 29 | $config = $container->get('config'); 30 | $cacheConfig = isset($config['cache']) ? $config['cache'] : []; 31 | return StorageFactory::factory($cacheConfig); 32 | } 33 | 34 | public function createService(ServiceLocatorInterface $serviceLocator) 35 | { 36 | return $this($serviceLocator, StorageInterface::class); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Service/StoragePluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | creationOptions); 42 | } 43 | 44 | /** 45 | * zend-servicemanager v2 support for invocation options. 46 | * 47 | * @param array $options 48 | * @return void 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->creationOptions = $options; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ApcIterator.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 55 | $this->baseIterator = $baseIterator; 56 | $this->prefixLength = strlen($prefix); 57 | } 58 | 59 | /** 60 | * Get storage instance 61 | * 62 | * @return Apc 63 | */ 64 | public function getStorage() 65 | { 66 | return $this->storage; 67 | } 68 | 69 | /** 70 | * Get iterator mode 71 | * 72 | * @return int Value of IteratorInterface::CURRENT_AS_* 73 | */ 74 | public function getMode() 75 | { 76 | return $this->mode; 77 | } 78 | 79 | /** 80 | * Set iterator mode 81 | * 82 | * @param int $mode 83 | * @return ApcIterator Provides a fluent interface 84 | */ 85 | public function setMode($mode) 86 | { 87 | $this->mode = (int) $mode; 88 | return $this; 89 | } 90 | 91 | /* Iterator */ 92 | 93 | /** 94 | * Get current key, value or metadata. 95 | * 96 | * @return mixed 97 | */ 98 | public function current() 99 | { 100 | if ($this->mode == IteratorInterface::CURRENT_AS_SELF) { 101 | return $this; 102 | } 103 | 104 | $key = $this->key(); 105 | 106 | if ($this->mode == IteratorInterface::CURRENT_AS_VALUE) { 107 | return $this->storage->getItem($key); 108 | } elseif ($this->mode == IteratorInterface::CURRENT_AS_METADATA) { 109 | return $this->storage->getMetadata($key); 110 | } 111 | 112 | return $key; 113 | } 114 | 115 | /** 116 | * Get current key 117 | * 118 | * @return string 119 | */ 120 | public function key() 121 | { 122 | $key = $this->baseIterator->key(); 123 | 124 | // remove namespace prefix 125 | return substr($key, $this->prefixLength); 126 | } 127 | 128 | /** 129 | * Move forward to next element 130 | * 131 | * @return void 132 | */ 133 | public function next() 134 | { 135 | $this->baseIterator->next(); 136 | } 137 | 138 | /** 139 | * Checks if current position is valid 140 | * 141 | * @return bool 142 | */ 143 | public function valid() 144 | { 145 | return $this->baseIterator->valid(); 146 | } 147 | 148 | /** 149 | * Rewind the Iterator to the first element. 150 | * 151 | * @return void 152 | */ 153 | public function rewind() 154 | { 155 | return $this->baseIterator->rewind(); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ApcOptions.php: -------------------------------------------------------------------------------- 1 | triggerOptionEvent('namespace_separator', $namespaceSeparator); 34 | $this->namespaceSeparator = $namespaceSeparator; 35 | return $this; 36 | } 37 | 38 | /** 39 | * Get namespace separator 40 | * 41 | * @return string 42 | */ 43 | public function getNamespaceSeparator() 44 | { 45 | return $this->namespaceSeparator; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ApcuIterator.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 55 | $this->baseIterator = $baseIterator; 56 | $this->prefixLength = strlen($prefix); 57 | } 58 | 59 | /** 60 | * Get storage instance 61 | * 62 | * @return Apcu 63 | */ 64 | public function getStorage() 65 | { 66 | return $this->storage; 67 | } 68 | 69 | /** 70 | * Get iterator mode 71 | * 72 | * @return int Value of IteratorInterface::CURRENT_AS_* 73 | */ 74 | public function getMode() 75 | { 76 | return $this->mode; 77 | } 78 | 79 | /** 80 | * Set iterator mode 81 | * 82 | * @param int $mode 83 | * @return ApcuIterator Provides a fluent interface 84 | */ 85 | public function setMode($mode) 86 | { 87 | $this->mode = (int) $mode; 88 | return $this; 89 | } 90 | 91 | /* Iterator */ 92 | 93 | /** 94 | * Get current key, value or metadata. 95 | * 96 | * @return mixed 97 | */ 98 | public function current() 99 | { 100 | if ($this->mode == IteratorInterface::CURRENT_AS_SELF) { 101 | return $this; 102 | } 103 | 104 | $key = $this->key(); 105 | 106 | if ($this->mode == IteratorInterface::CURRENT_AS_VALUE) { 107 | return $this->storage->getItem($key); 108 | } elseif ($this->mode == IteratorInterface::CURRENT_AS_METADATA) { 109 | return $this->storage->getMetadata($key); 110 | } 111 | 112 | return $key; 113 | } 114 | 115 | /** 116 | * Get current key 117 | * 118 | * @return string 119 | */ 120 | public function key() 121 | { 122 | $key = $this->baseIterator->key(); 123 | 124 | // remove namespace prefix 125 | return substr($key, $this->prefixLength); 126 | } 127 | 128 | /** 129 | * Move forward to next element 130 | * 131 | * @return void 132 | */ 133 | public function next() 134 | { 135 | $this->baseIterator->next(); 136 | } 137 | 138 | /** 139 | * Checks if current position is valid 140 | * 141 | * @return bool 142 | */ 143 | public function valid() 144 | { 145 | return $this->baseIterator->valid(); 146 | } 147 | 148 | /** 149 | * Rewind the Iterator to the first element. 150 | * 151 | * @return void 152 | */ 153 | public function rewind() 154 | { 155 | return $this->baseIterator->rewind(); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ApcuOptions.php: -------------------------------------------------------------------------------- 1 | triggerOptionEvent('namespace_separator', $namespaceSeparator); 34 | $this->namespaceSeparator = $namespaceSeparator; 35 | return $this; 36 | } 37 | 38 | /** 39 | * Get namespace separator 40 | * 41 | * @return string 42 | */ 43 | public function getNamespaceSeparator() 44 | { 45 | return $this->namespaceSeparator; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Storage/Adapter/DbaIterator.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 62 | $this->handle = $handle; 63 | $this->prefixLength = strlen($prefix); 64 | 65 | $this->rewind(); 66 | } 67 | 68 | /** 69 | * Get storage instance 70 | * 71 | * @return Dba 72 | */ 73 | public function getStorage() 74 | { 75 | return $this->storage; 76 | } 77 | 78 | /** 79 | * Get iterator mode 80 | * 81 | * @return int Value of IteratorInterface::CURRENT_AS_* 82 | */ 83 | public function getMode() 84 | { 85 | return $this->mode; 86 | } 87 | 88 | /** 89 | * Set iterator mode 90 | * 91 | * @param int $mode 92 | * @return DbaIterator Provides a fluent interface 93 | */ 94 | public function setMode($mode) 95 | { 96 | $this->mode = (int) $mode; 97 | return $this; 98 | } 99 | 100 | /* Iterator */ 101 | 102 | /** 103 | * Get current key, value or metadata. 104 | * 105 | * @return mixed 106 | * @throws Exception\RuntimeException 107 | */ 108 | public function current() 109 | { 110 | if ($this->mode == IteratorInterface::CURRENT_AS_SELF) { 111 | return $this; 112 | } 113 | 114 | $key = $this->key(); 115 | 116 | if ($this->mode == IteratorInterface::CURRENT_AS_VALUE) { 117 | return $this->storage->getItem($key); 118 | } elseif ($this->mode == IteratorInterface::CURRENT_AS_METADATA) { 119 | return $this->storage->getMetadata($key); 120 | } 121 | 122 | return $key; 123 | } 124 | 125 | /** 126 | * Get current key 127 | * 128 | * @return string 129 | * @throws Exception\RuntimeException 130 | */ 131 | public function key() 132 | { 133 | if ($this->currentInternalKey === false) { 134 | throw new Exception\RuntimeException("Iterator is on an invalid state"); 135 | } 136 | 137 | // remove namespace prefix 138 | return substr($this->currentInternalKey, $this->prefixLength); 139 | } 140 | 141 | /** 142 | * Move forward to next element 143 | * 144 | * @return void 145 | * @throws Exception\RuntimeException 146 | */ 147 | public function next() 148 | { 149 | if ($this->currentInternalKey === false) { 150 | throw new Exception\RuntimeException("Iterator is on an invalid state"); 151 | } 152 | 153 | $this->currentInternalKey = dba_nextkey($this->handle); 154 | 155 | // Workaround for PHP-Bug #62492 156 | if ($this->currentInternalKey === null) { 157 | $this->currentInternalKey = false; 158 | } 159 | } 160 | 161 | /** 162 | * Checks if current position is valid 163 | * 164 | * @return bool 165 | */ 166 | public function valid() 167 | { 168 | return ($this->currentInternalKey !== false); 169 | } 170 | 171 | /** 172 | * Rewind the Iterator to the first element. 173 | * 174 | * @return void 175 | * @throws Exception\RuntimeException 176 | */ 177 | public function rewind() 178 | { 179 | if ($this->currentInternalKey === false) { 180 | throw new Exception\RuntimeException("Iterator is on an invalid state"); 181 | } 182 | 183 | $this->currentInternalKey = dba_firstkey($this->handle); 184 | 185 | // Workaround for PHP-Bug #62492 186 | if ($this->currentInternalKey === null) { 187 | $this->currentInternalKey = false; 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/Storage/Adapter/DbaOptions.php: -------------------------------------------------------------------------------- 1 | triggerOptionEvent('namespace_separator', $namespaceSeparator); 57 | $this->namespaceSeparator = $namespaceSeparator; 58 | return $this; 59 | } 60 | 61 | /** 62 | * Get namespace separator 63 | * 64 | * @return string 65 | */ 66 | public function getNamespaceSeparator() 67 | { 68 | return $this->namespaceSeparator; 69 | } 70 | 71 | /** 72 | * Set pathname to database file 73 | * 74 | * @param string $pathname 75 | * @return DbaOptions Provides a fluent interface 76 | */ 77 | public function setPathname($pathname) 78 | { 79 | $this->pathname = (string) $pathname; 80 | $this->triggerOptionEvent('pathname', $pathname); 81 | return $this; 82 | } 83 | 84 | /** 85 | * Get pathname to database file 86 | * 87 | * @return string 88 | */ 89 | public function getPathname() 90 | { 91 | return $this->pathname; 92 | } 93 | 94 | /** 95 | * 96 | * 97 | * @param string $mode 98 | * @return DbaOptions Provides a fluent interface 99 | */ 100 | public function setMode($mode) 101 | { 102 | $this->mode = (string) $mode; 103 | $this->triggerOptionEvent('mode', $mode); 104 | return $this; 105 | } 106 | 107 | public function getMode() 108 | { 109 | return $this->mode; 110 | } 111 | 112 | /** 113 | * 114 | * 115 | * @param string $handler 116 | * @return DbaOptions Provides a fluent interface 117 | */ 118 | public function setHandler($handler) 119 | { 120 | $handler = (string) $handler; 121 | 122 | if (! function_exists('dba_handlers') || ! in_array($handler, dba_handlers())) { 123 | throw new Exception\ExtensionNotLoadedException("DBA-Handler '{$handler}' not supported"); 124 | } 125 | 126 | if ($handler === 'inifile') { 127 | throw new Exception\ExtensionNotLoadedException( 128 | "DBA-Handler 'inifile' does not reliably support write operations" 129 | ); 130 | } 131 | 132 | $this->triggerOptionEvent('handler', $handler); 133 | $this->handler = $handler; 134 | return $this; 135 | } 136 | 137 | public function getHandler() 138 | { 139 | return $this->handler; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ExtMongoDbOptions.php: -------------------------------------------------------------------------------- 1 | namespaceSeparator !== $namespaceSeparator) { 62 | $this->triggerOptionEvent('namespace_separator', $namespaceSeparator); 63 | 64 | $this->namespaceSeparator = $namespaceSeparator; 65 | } 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * Get namespace separator 72 | * 73 | * @return string 74 | */ 75 | public function getNamespaceSeparator() 76 | { 77 | return $this->namespaceSeparator; 78 | } 79 | 80 | /** 81 | * Set the ext-mongodb resource manager to use 82 | * 83 | * @param null|ExtMongoDbResourceManager $resourceManager 84 | * @return self Provides a fluent interface 85 | */ 86 | public function setResourceManager(ExtMongoDbResourceManager $resourceManager = null) 87 | { 88 | if ($this->resourceManager !== $resourceManager) { 89 | $this->triggerOptionEvent('resource_manager', $resourceManager); 90 | 91 | $this->resourceManager = $resourceManager; 92 | } 93 | 94 | return $this; 95 | } 96 | 97 | /** 98 | * Get the ext-mongodb resource manager 99 | * 100 | * @return ExtMongoDbResourceManager 101 | */ 102 | public function getResourceManager() 103 | { 104 | return $this->resourceManager ?: $this->resourceManager = new ExtMongoDbResourceManager(); 105 | } 106 | 107 | /** 108 | * Get the ext-mongodb resource id 109 | * 110 | * @return string 111 | */ 112 | public function getResourceId() 113 | { 114 | return $this->resourceId; 115 | } 116 | 117 | /** 118 | * Set the ext-mongodb resource id 119 | * 120 | * @param string $resourceId 121 | * @return self Provides a fluent interface 122 | */ 123 | public function setResourceId($resourceId) 124 | { 125 | $resourceId = (string) $resourceId; 126 | 127 | if ($this->resourceId !== $resourceId) { 128 | $this->triggerOptionEvent('resource_id', $resourceId); 129 | 130 | $this->resourceId = $resourceId; 131 | } 132 | 133 | return $this; 134 | } 135 | 136 | /** 137 | * Set the ext-mongodb server 138 | * 139 | * @param string $server 140 | * @return self Provides a fluent interface 141 | */ 142 | public function setServer($server) 143 | { 144 | $this->getResourceManager()->setServer($this->getResourceId(), $server); 145 | return $this; 146 | } 147 | 148 | /** 149 | * @param array $connectionOptions 150 | * @return self Provides a fluent interface 151 | */ 152 | public function setConnectionOptions(array $connectionOptions) 153 | { 154 | $this->getResourceManager()->setConnectionOptions($this->getResourceId(), $connectionOptions); 155 | return $this; 156 | } 157 | 158 | /** 159 | * @param array $driverOptions ext-mongodb driver options 160 | * @return self Provides a fluent interface 161 | */ 162 | public function setDriverOptions(array $driverOptions) 163 | { 164 | $this->getResourceManager()->setDriverOptions($this->getResourceId(), $driverOptions); 165 | return $this; 166 | } 167 | 168 | /** 169 | * @param string $database 170 | * @return string Provides a fluent interface 171 | */ 172 | public function setDatabase($database) 173 | { 174 | $this->getResourceManager()->setDatabase($this->getResourceId(), $database); 175 | return $this; 176 | } 177 | 178 | /** 179 | * @param string $collection 180 | * @return self Provides a fluent interface 181 | */ 182 | public function setCollection($collection) 183 | { 184 | $this->getResourceManager()->setCollection($this->getResourceId(), $collection); 185 | return $this; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ExtMongoDbResourceManager.php: -------------------------------------------------------------------------------- 1 | resources[$id]); 39 | } 40 | 41 | /** 42 | * Set a resource 43 | * 44 | * @param string $id 45 | * @param array|Collection $resource 46 | * @return self Provides a fluent interface 47 | * @throws Exception\RuntimeException 48 | */ 49 | public function setResource($id, $resource) 50 | { 51 | if ($resource instanceof Collection) { 52 | $this->resources[$id] = [ 53 | 'db' => (string) $resource->db, 54 | 'db_instance' => $resource->db, 55 | 'collection' => (string) $resource, 56 | 'collection_instance' => $resource, 57 | ]; 58 | return $this; 59 | } 60 | 61 | if (! is_array($resource)) { 62 | throw new Exception\InvalidArgumentException(sprintf( 63 | '%s expects an array or %s; received %s', 64 | __METHOD__, 65 | Collection::class, 66 | is_object($resource) ? get_class($resource) : gettype($resource) 67 | )); 68 | } 69 | 70 | $this->resources[$id] = $resource; 71 | return $this; 72 | } 73 | 74 | /** 75 | * Instantiate and return the Collection resource 76 | * 77 | * @param string $id 78 | * @return Collection 79 | * @throws Exception\RuntimeException 80 | */ 81 | public function getResource($id) 82 | { 83 | if (! $this->hasResource($id)) { 84 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 85 | } 86 | 87 | $resource = $this->resources[$id]; 88 | if (! isset($resource['collection_instance'])) { 89 | try { 90 | if (! isset($resource['db_instance'])) { 91 | if (! isset($resource['client_instance'])) { 92 | $resource['client_instance'] = new Client( 93 | isset($resource['server']) ? $resource['server'] : null, 94 | isset($resource['connection_options']) ? $resource['connection_options'] : [], 95 | isset($resource['driver_options']) ? $resource['driver_options'] : [] 96 | ); 97 | } 98 | } 99 | 100 | $collection = $resource['client_instance']->selectCollection( 101 | isset($resource['db']) ? $resource['db'] : 'zend', 102 | isset($resource['collection']) ? $resource['collection'] : 'cache' 103 | ); 104 | $collection->createIndex(['key' => 1]); 105 | 106 | $this->resources[$id]['collection_instance'] = $collection; 107 | } catch (MongoDriverException $e) { 108 | throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); 109 | } 110 | } 111 | 112 | return $this->resources[$id]['collection_instance']; 113 | } 114 | 115 | /** 116 | * @param string $id 117 | * @param string $server 118 | * @return void 119 | */ 120 | public function setServer($id, $server) 121 | { 122 | $this->resources[$id]['server'] = (string) $server; 123 | 124 | unset($this->resources[$id]['client_instance']); 125 | unset($this->resources[$id]['db_instance']); 126 | unset($this->resources[$id]['collection_instance']); 127 | } 128 | 129 | /** 130 | * @param string $id 131 | * @return null|string 132 | * @throws Exception\RuntimeException if no matching resource discovered 133 | */ 134 | public function getServer($id) 135 | { 136 | if (! $this->hasResource($id)) { 137 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 138 | } 139 | 140 | return isset($this->resources[$id]['server']) ? $this->resources[$id]['server'] : null; 141 | } 142 | 143 | /** 144 | * @param string $id 145 | * @param array $connectionOptions 146 | * @return void 147 | */ 148 | public function setConnectionOptions($id, array $connectionOptions) 149 | { 150 | $this->resources[$id]['connection_options'] = $connectionOptions; 151 | 152 | unset($this->resources[$id]['client_instance']); 153 | unset($this->resources[$id]['db_instance']); 154 | unset($this->resources[$id]['collection_instance']); 155 | } 156 | 157 | /** 158 | * @param string $id 159 | * @return array 160 | * @throws Exception\RuntimeException if no matching resource discovered 161 | */ 162 | public function getConnectionOptions($id) 163 | { 164 | if (! $this->hasResource($id)) { 165 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 166 | } 167 | 168 | return isset($this->resources[$id]['connection_options']) 169 | ? $this->resources[$id]['connection_options'] 170 | : []; 171 | } 172 | 173 | /** 174 | * @param string $id 175 | * @param array $driverOptions 176 | * @return void 177 | */ 178 | public function setDriverOptions($id, array $driverOptions) 179 | { 180 | $this->resources[$id]['driver_options'] = $driverOptions; 181 | 182 | unset($this->resources[$id]['client_instance']); 183 | unset($this->resources[$id]['db_instance']); 184 | unset($this->resources[$id]['collection_instance']); 185 | } 186 | 187 | /** 188 | * @param string $id 189 | * @return array 190 | * @throws Exception\RuntimeException if no matching resource discovered 191 | */ 192 | public function getDriverOptions($id) 193 | { 194 | if (! $this->hasResource($id)) { 195 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 196 | } 197 | 198 | return isset($this->resources[$id]['driver_options']) ? $this->resources[$id]['driver_options'] : []; 199 | } 200 | 201 | /** 202 | * @param string $id 203 | * @param string $database 204 | * @return void 205 | */ 206 | public function setDatabase($id, $database) 207 | { 208 | $this->resources[$id]['db'] = (string) $database; 209 | 210 | unset($this->resources[$id]['db_instance']); 211 | unset($this->resources[$id]['collection_instance']); 212 | } 213 | 214 | /** 215 | * @param string $id 216 | * @return string 217 | * @throws Exception\RuntimeException if no matching resource discovered 218 | */ 219 | public function getDatabase($id) 220 | { 221 | if (! $this->hasResource($id)) { 222 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 223 | } 224 | 225 | return isset($this->resources[$id]['db']) ? $this->resources[$id]['db'] : ''; 226 | } 227 | 228 | /** 229 | * @param string $id 230 | * @param string $collection 231 | * @return void 232 | */ 233 | public function setCollection($id, $collection) 234 | { 235 | $this->resources[$id]['collection'] = (string) $collection; 236 | 237 | unset($this->resources[$id]['collection_instance']); 238 | } 239 | 240 | /** 241 | * @param string $id 242 | * @return string 243 | * @throws Exception\RuntimeException if no matching resource discovered 244 | */ 245 | public function getCollection($id) 246 | { 247 | if (! $this->hasResource($id)) { 248 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 249 | } 250 | 251 | return isset($this->resources[$id]['collection']) ? $this->resources[$id]['collection'] : ''; 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/Storage/Adapter/FilesystemIterator.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 62 | $this->globIterator = new GlobIterator($path, GlobIterator::KEY_AS_FILENAME); 63 | $this->prefix = $prefix; 64 | $this->prefixLength = strlen($prefix); 65 | } 66 | 67 | /** 68 | * Get storage instance 69 | * 70 | * @return Filesystem 71 | */ 72 | public function getStorage() 73 | { 74 | return $this->storage; 75 | } 76 | 77 | /** 78 | * Get iterator mode 79 | * 80 | * @return int Value of IteratorInterface::CURRENT_AS_* 81 | */ 82 | public function getMode() 83 | { 84 | return $this->mode; 85 | } 86 | 87 | /** 88 | * Set iterator mode 89 | * 90 | * @param int $mode 91 | * @return FilesystemIterator Provides a fluent interface 92 | */ 93 | public function setMode($mode) 94 | { 95 | $this->mode = (int) $mode; 96 | return $this; 97 | } 98 | 99 | /* Iterator */ 100 | 101 | /** 102 | * Get current key, value or metadata. 103 | * 104 | * @return mixed 105 | */ 106 | public function current() 107 | { 108 | if ($this->mode == IteratorInterface::CURRENT_AS_SELF) { 109 | return $this; 110 | } 111 | 112 | $key = $this->key(); 113 | 114 | if ($this->mode == IteratorInterface::CURRENT_AS_VALUE) { 115 | return $this->storage->getItem($key); 116 | } elseif ($this->mode == IteratorInterface::CURRENT_AS_METADATA) { 117 | return $this->storage->getMetadata($key); 118 | } 119 | 120 | return $key; 121 | } 122 | 123 | /** 124 | * Get current key 125 | * 126 | * @return string 127 | */ 128 | public function key() 129 | { 130 | $filename = $this->globIterator->key(); 131 | 132 | // return without namespace prefix and file suffix 133 | return substr($filename, $this->prefixLength, -4); 134 | } 135 | 136 | /** 137 | * Move forward to next element 138 | * 139 | * @return void 140 | */ 141 | public function next() 142 | { 143 | $this->globIterator->next(); 144 | } 145 | 146 | /** 147 | * Checks if current position is valid 148 | * 149 | * @return bool 150 | */ 151 | public function valid() 152 | { 153 | try { 154 | return $this->globIterator->valid(); 155 | } catch (\LogicException $e) { 156 | // @link https://bugs.php.net/bug.php?id=55701 157 | // GlobIterator throws LogicException with message 158 | // 'The parent constructor was not called: the object is in an invalid state' 159 | return false; 160 | } 161 | } 162 | 163 | /** 164 | * Rewind the Iterator to the first element. 165 | * 166 | * @return bool false if the operation failed. 167 | */ 168 | public function rewind() 169 | { 170 | try { 171 | return $this->globIterator->rewind(); 172 | } catch (\LogicException $e) { 173 | // @link https://bugs.php.net/bug.php?id=55701 174 | // GlobIterator throws LogicException with message 175 | // 'The parent constructor was not called: the object is in an invalid state' 176 | return false; 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/Storage/Adapter/KeyListIterator.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 62 | $this->keys = $keys; 63 | $this->count = count($keys); 64 | } 65 | 66 | /** 67 | * Get storage instance 68 | * 69 | * @return StorageInterface 70 | */ 71 | public function getStorage() 72 | { 73 | return $this->storage; 74 | } 75 | 76 | /** 77 | * Get iterator mode 78 | * 79 | * @return int Value of IteratorInterface::CURRENT_AS_* 80 | */ 81 | public function getMode() 82 | { 83 | return $this->mode; 84 | } 85 | 86 | /** 87 | * Set iterator mode 88 | * 89 | * @param int $mode 90 | * @return KeyListIterator Provides a fluent interface 91 | */ 92 | public function setMode($mode) 93 | { 94 | $this->mode = (int) $mode; 95 | return $this; 96 | } 97 | 98 | /** 99 | * Get current key, value or metadata. 100 | * 101 | * @return mixed 102 | */ 103 | public function current() 104 | { 105 | if ($this->mode == IteratorInterface::CURRENT_AS_SELF) { 106 | return $this; 107 | } 108 | 109 | $key = $this->key(); 110 | 111 | if ($this->mode == IteratorInterface::CURRENT_AS_METADATA) { 112 | return $this->storage->getMetadata($key); 113 | } elseif ($this->mode == IteratorInterface::CURRENT_AS_VALUE) { 114 | return $this->storage->getItem($key); 115 | } 116 | 117 | return $key; 118 | } 119 | 120 | /** 121 | * Get current key 122 | * 123 | * @return string 124 | */ 125 | public function key() 126 | { 127 | return $this->keys[$this->position]; 128 | } 129 | 130 | /** 131 | * Checks if current position is valid 132 | * 133 | * @return bool 134 | */ 135 | public function valid() 136 | { 137 | return $this->position < $this->count; 138 | } 139 | 140 | /** 141 | * Move forward to next element 142 | * 143 | * @return void 144 | */ 145 | public function next() 146 | { 147 | $this->position++; 148 | } 149 | 150 | /** 151 | * Rewind the Iterator to the first element. 152 | * 153 | * @return void 154 | */ 155 | public function rewind() 156 | { 157 | $this->position = 0; 158 | } 159 | 160 | /** 161 | * Count number of items 162 | * 163 | * @return int 164 | */ 165 | public function count() 166 | { 167 | return $this->count; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/Storage/Adapter/MemcacheOptions.php: -------------------------------------------------------------------------------- 1 | namespaceSeparator !== $namespaceSeparator) { 88 | $this->triggerOptionEvent('namespace_separator', $namespaceSeparator); 89 | $this->namespaceSeparator = $namespaceSeparator; 90 | } 91 | return $this; 92 | } 93 | 94 | /** 95 | * Get namespace separator 96 | * 97 | * @return string 98 | */ 99 | public function getNamespaceSeparator() 100 | { 101 | return $this->namespaceSeparator; 102 | } 103 | 104 | /** 105 | * Set the memcache resource manager to use 106 | * 107 | * @param null|MemcacheResourceManager $resourceManager 108 | * @return MemcacheOptions 109 | */ 110 | public function setResourceManager(MemcacheResourceManager $resourceManager = null) 111 | { 112 | if ($this->resourceManager !== $resourceManager) { 113 | $this->triggerOptionEvent('resource_manager', $resourceManager); 114 | $this->resourceManager = $resourceManager; 115 | } 116 | return $this; 117 | } 118 | 119 | /** 120 | * Get the memcache resource manager 121 | * 122 | * @return MemcacheResourceManager 123 | */ 124 | public function getResourceManager() 125 | { 126 | if (! $this->resourceManager) { 127 | $this->resourceManager = new MemcacheResourceManager(); 128 | } 129 | return $this->resourceManager; 130 | } 131 | 132 | /** 133 | * Get the memcache resource id 134 | * 135 | * @return string 136 | */ 137 | public function getResourceId() 138 | { 139 | return $this->resourceId; 140 | } 141 | 142 | /** 143 | * Set the memcache resource id 144 | * 145 | * @param string $resourceId 146 | * @return MemcacheOptions 147 | */ 148 | public function setResourceId($resourceId) 149 | { 150 | $resourceId = (string) $resourceId; 151 | if ($this->resourceId !== $resourceId) { 152 | $this->triggerOptionEvent('resource_id', $resourceId); 153 | $this->resourceId = $resourceId; 154 | } 155 | return $this; 156 | } 157 | 158 | /** 159 | * Is compressed writes turned on? 160 | * 161 | * @return boolean 162 | */ 163 | public function getCompression() 164 | { 165 | return $this->compression; 166 | } 167 | 168 | /** 169 | * Set whether compressed writes are turned on or not 170 | * 171 | * @param boolean $compression 172 | * @return $this 173 | */ 174 | public function setCompression($compression) 175 | { 176 | $compression = (bool) $compression; 177 | if ($this->compression !== $compression) { 178 | $this->triggerOptionEvent('compression', $compression); 179 | $this->compression = $compression; 180 | } 181 | return $this; 182 | } 183 | 184 | /** 185 | * Sets a list of memcache servers to add on initialize 186 | * 187 | * @param string|array $servers list of servers 188 | * @return MemcacheOptions 189 | * @throws Exception\InvalidArgumentException 190 | */ 191 | public function setServers($servers) 192 | { 193 | $this->getResourceManager()->addServers($this->getResourceId(), $servers); 194 | return $this; 195 | } 196 | 197 | /** 198 | * Get Servers 199 | * 200 | * @return array 201 | */ 202 | public function getServers() 203 | { 204 | return $this->getResourceManager()->getServers($this->getResourceId()); 205 | } 206 | 207 | /** 208 | * Set compress threshold 209 | * 210 | * @param int|string|array|\ArrayAccess|null $threshold 211 | * @return MemcacheOptions 212 | */ 213 | public function setAutoCompressThreshold($threshold) 214 | { 215 | $this->getResourceManager()->setAutoCompressThreshold($this->getResourceId(), $threshold); 216 | return $this; 217 | } 218 | 219 | /** 220 | * Get compress threshold 221 | * 222 | * @return int|null 223 | */ 224 | public function getAutoCompressThreshold() 225 | { 226 | return $this->getResourceManager()->getAutoCompressThreshold($this->getResourceId()); 227 | } 228 | 229 | /** 230 | * Set compress min savings option 231 | * 232 | * @param float|string|null $minSavings 233 | * @return MemcacheOptions 234 | */ 235 | public function setAutoCompressMinSavings($minSavings) 236 | { 237 | $this->getResourceManager()->setAutoCompressMinSavings($this->getResourceId(), $minSavings); 238 | return $this; 239 | } 240 | 241 | /** 242 | * Get compress min savings 243 | * 244 | * @throws Exception\RuntimeException 245 | */ 246 | public function getAutoCompressMinSavings() 247 | { 248 | return $this->getResourceManager()->getAutoCompressMinSavings($this->getResourceId()); 249 | } 250 | 251 | /** 252 | * Set default server values 253 | * 254 | * @param array $serverDefaults 255 | * @return MemcacheOptions 256 | */ 257 | public function setServerDefaults(array $serverDefaults) 258 | { 259 | $this->getResourceManager()->setServerDefaults($this->getResourceId(), $serverDefaults); 260 | return $this; 261 | } 262 | 263 | /** 264 | * Get default server values 265 | * 266 | * @return array 267 | */ 268 | public function getServerDefaults() 269 | { 270 | return $this->getResourceManager()->getServerDefaults($this->getResourceId()); 271 | } 272 | 273 | /** 274 | * Set callback for server connection failures 275 | * 276 | * @param callable $callback 277 | * @return $this 278 | */ 279 | public function setFailureCallback($callback) 280 | { 281 | $this->getResourceManager()->setFailureCallback($this->getResourceId(), $callback); 282 | return $this; 283 | } 284 | 285 | /** 286 | * Get callback for server connection failures 287 | * 288 | * @return callable 289 | */ 290 | public function getFailureCallback() 291 | { 292 | return $this->getResourceManager()->getFailureCallback($this->getResourceId()); 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /src/Storage/Adapter/MemoryOptions.php: -------------------------------------------------------------------------------- 1 | normalizeMemoryLimit($memoryLimit); 41 | 42 | if ($this->memoryLimit != $memoryLimit) { 43 | $this->triggerOptionEvent('memory_limit', $memoryLimit); 44 | $this->memoryLimit = $memoryLimit; 45 | } 46 | 47 | return $this; 48 | } 49 | 50 | /** 51 | * Get memory limit 52 | * 53 | * If the used memory of PHP exceeds this limit an OutOfSpaceException 54 | * will be thrown. 55 | * 56 | * @return int 57 | */ 58 | public function getMemoryLimit() 59 | { 60 | if ($this->memoryLimit === null) { 61 | // By default use half of PHP's memory limit if possible 62 | $memoryLimit = $this->normalizeMemoryLimit(ini_get('memory_limit')); 63 | if ($memoryLimit >= 0) { 64 | $this->memoryLimit = (int) ($memoryLimit / 2); 65 | } else { 66 | // disable memory limit 67 | $this->memoryLimit = 0; 68 | } 69 | } 70 | 71 | return $this->memoryLimit; 72 | } 73 | 74 | /** 75 | * Normalized a given value of memory limit into the number of bytes 76 | * 77 | * @param string|int $value 78 | * @throws Exception\InvalidArgumentException 79 | * @return int 80 | */ 81 | protected function normalizeMemoryLimit($value) 82 | { 83 | if (is_numeric($value)) { 84 | return (int) $value; 85 | } 86 | 87 | if (! preg_match('/(\-?\d+)\s*(\w*)/', ini_get('memory_limit'), $matches)) { 88 | throw new Exception\InvalidArgumentException("Invalid memory limit '{$value}'"); 89 | } 90 | 91 | $value = (int) $matches[1]; 92 | if ($value <= 0) { 93 | return 0; 94 | } 95 | 96 | switch (strtoupper($matches[2])) { 97 | case 'G': 98 | $value *= 1024; 99 | // no break 100 | 101 | case 'M': 102 | $value *= 1024; 103 | // no break 104 | 105 | case 'K': 106 | $value *= 1024; 107 | // no break 108 | } 109 | 110 | return $value; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Storage/Adapter/MongoDbOptions.php: -------------------------------------------------------------------------------- 1 | namespaceSeparator !== $namespaceSeparator) { 57 | $this->triggerOptionEvent('namespace_separator', $namespaceSeparator); 58 | 59 | $this->namespaceSeparator = $namespaceSeparator; 60 | } 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * Get namespace separator 67 | * 68 | * @return string 69 | */ 70 | public function getNamespaceSeparator() 71 | { 72 | return $this->namespaceSeparator; 73 | } 74 | 75 | /** 76 | * Set the mongodb resource manager to use 77 | * 78 | * @param null|MongoDbResourceManager $resourceManager 79 | * 80 | * @return MongoDbOptions Provides a fluent interface 81 | */ 82 | public function setResourceManager(MongoDbResourceManager $resourceManager = null) 83 | { 84 | if ($this->resourceManager !== $resourceManager) { 85 | $this->triggerOptionEvent('resource_manager', $resourceManager); 86 | 87 | $this->resourceManager = $resourceManager; 88 | } 89 | 90 | return $this; 91 | } 92 | 93 | /** 94 | * Get the mongodb resource manager 95 | * 96 | * @return MongoDbResourceManager 97 | */ 98 | public function getResourceManager() 99 | { 100 | return $this->resourceManager ?: $this->resourceManager = new MongoDbResourceManager(); 101 | } 102 | 103 | /** 104 | * Get the mongodb resource id 105 | * 106 | * @return string 107 | */ 108 | public function getResourceId() 109 | { 110 | return $this->resourceId; 111 | } 112 | 113 | /** 114 | * Set the mongodb resource id 115 | * 116 | * @param string $resourceId 117 | * 118 | * @return MongoDbOptions Provides a fluent interface 119 | */ 120 | public function setResourceId($resourceId) 121 | { 122 | $resourceId = (string) $resourceId; 123 | 124 | if ($this->resourceId !== $resourceId) { 125 | $this->triggerOptionEvent('resource_id', $resourceId); 126 | 127 | $this->resourceId = $resourceId; 128 | } 129 | 130 | return $this; 131 | } 132 | 133 | /** 134 | * Set the mongo DB server 135 | * 136 | * @param string $server 137 | * 138 | * @return MongoDbOptions Provides a fluent interface 139 | */ 140 | public function setServer($server) 141 | { 142 | $this->getResourceManager()->setServer($this->getResourceId(), $server); 143 | return $this; 144 | } 145 | 146 | /** 147 | * 148 | * 149 | * @param array $connectionOptions 150 | * 151 | * @return MongoDbOptions Provides a fluent interface 152 | */ 153 | public function setConnectionOptions(array $connectionOptions) 154 | { 155 | $this->getResourceManager()->setConnectionOptions($this->getResourceId(), $connectionOptions); 156 | return $this; 157 | } 158 | 159 | /** 160 | * 161 | * 162 | * @param array $driverOptions 163 | MongoDbOptions 164 | * @return MongoDbOptions Provides a fluent interface 165 | */ 166 | public function setDriverOptions(array $driverOptions) 167 | { 168 | $this->getResourceManager()->setDriverOptions($this->getResourceId(), $driverOptions); 169 | return $this; 170 | } 171 | 172 | /** 173 | * 174 | * 175 | * @param string $database 176 | * 177 | * @return MongoDbOptions Provides a fluent interface 178 | */ 179 | public function setDatabase($database) 180 | { 181 | $this->getResourceManager()->setDatabase($this->getResourceId(), $database); 182 | return $this; 183 | } 184 | 185 | /** 186 | * 187 | * 188 | * @param string $collection 189 | * 190 | * @return MongoDbOptions Provides a fluent interface 191 | */ 192 | public function setCollection($collection) 193 | { 194 | $this->getResourceManager()->setCollection($this->getResourceId(), $collection); 195 | return $this; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/Storage/Adapter/MongoDbResourceManager.php: -------------------------------------------------------------------------------- 1 | resources[$id]); 35 | } 36 | 37 | /** 38 | * Set a resource 39 | * 40 | * @param string $id 41 | * @param array|MongoCollection $resource 42 | * 43 | * @return MongoDbResourceManager Provides a fluent interface 44 | * 45 | * @throws Exception\RuntimeException 46 | */ 47 | public function setResource($id, $resource) 48 | { 49 | if ($resource instanceof MongoCollection) { 50 | $this->resources[$id] = [ 51 | 'db' => (string) $resource->db, 52 | 'db_instance' => $resource->db, 53 | 'collection' => (string) $resource, 54 | 'collection_instance' => $resource, 55 | ]; 56 | return $this; 57 | } 58 | 59 | if (! is_array($resource)) { 60 | throw new Exception\InvalidArgumentException(sprintf( 61 | '%s expects an array or MongoCollection; received %s', 62 | __METHOD__, 63 | (is_object($resource) ? get_class($resource) : gettype($resource)) 64 | )); 65 | } 66 | 67 | $this->resources[$id] = $resource; 68 | return $this; 69 | } 70 | 71 | /** 72 | * Instantiate and return the MongoCollection resource 73 | * 74 | * @param string $id 75 | * @return MongoCollection 76 | * @throws Exception\RuntimeException 77 | */ 78 | public function getResource($id) 79 | { 80 | if (! $this->hasResource($id)) { 81 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 82 | } 83 | 84 | $resource = $this->resources[$id]; 85 | if (! isset($resource['collection_instance'])) { 86 | try { 87 | if (! isset($resource['db_instance'])) { 88 | if (! isset($resource['client_instance'])) { 89 | $clientClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient'; 90 | $resource['client_instance'] = new $clientClass( 91 | isset($resource['server']) ? $resource['server'] : null, 92 | isset($resource['connection_options']) ? $resource['connection_options'] : [], 93 | isset($resource['driver_options']) ? $resource['driver_options'] : [] 94 | ); 95 | } 96 | 97 | $resource['db_instance'] = $resource['client_instance']->selectDB( 98 | isset($resource['db']) ? $resource['db'] : '' 99 | ); 100 | } 101 | 102 | $collection = $resource['db_instance']->selectCollection( 103 | isset($resource['collection']) ? $resource['collection'] : '' 104 | ); 105 | $collection->ensureIndex(['key' => 1]); 106 | 107 | $this->resources[$id]['collection_instance'] = $collection; 108 | } catch (MongoException $e) { 109 | throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); 110 | } 111 | } 112 | 113 | return $this->resources[$id]['collection_instance']; 114 | } 115 | 116 | public function setServer($id, $server) 117 | { 118 | $this->resources[$id]['server'] = (string)$server; 119 | 120 | unset($this->resources[$id]['client_instance']); 121 | unset($this->resources[$id]['db_instance']); 122 | unset($this->resources[$id]['collection_instance']); 123 | } 124 | 125 | public function getServer($id) 126 | { 127 | if (! $this->hasResource($id)) { 128 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 129 | } 130 | 131 | return isset($this->resources[$id]['server']) ? $this->resources[$id]['server'] : null; 132 | } 133 | 134 | public function setConnectionOptions($id, array $connectionOptions) 135 | { 136 | $this->resources[$id]['connection_options'] = $connectionOptions; 137 | 138 | unset($this->resources[$id]['client_instance']); 139 | unset($this->resources[$id]['db_instance']); 140 | unset($this->resources[$id]['collection_instance']); 141 | } 142 | 143 | public function getConnectionOptions($id) 144 | { 145 | if (! $this->hasResource($id)) { 146 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 147 | } 148 | 149 | return isset($this->resources[$id]['connection_options']) 150 | ? $this->resources[$id]['connection_options'] 151 | : []; 152 | } 153 | 154 | public function setDriverOptions($id, array $driverOptions) 155 | { 156 | $this->resources[$id]['driver_options'] = $driverOptions; 157 | 158 | unset($this->resources[$id]['client_instance']); 159 | unset($this->resources[$id]['db_instance']); 160 | unset($this->resources[$id]['collection_instance']); 161 | } 162 | 163 | public function getDriverOptions($id) 164 | { 165 | if (! $this->hasResource($id)) { 166 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 167 | } 168 | 169 | return isset($this->resources[$id]['driver_options']) ? $this->resources[$id]['driver_options'] : []; 170 | } 171 | 172 | public function setDatabase($id, $database) 173 | { 174 | $this->resources[$id]['db'] = (string)$database; 175 | 176 | unset($this->resources[$id]['db_instance']); 177 | unset($this->resources[$id]['collection_instance']); 178 | } 179 | 180 | public function getDatabase($id) 181 | { 182 | if (! $this->hasResource($id)) { 183 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 184 | } 185 | 186 | return isset($this->resources[$id]['db']) ? $this->resources[$id]['db'] : ''; 187 | } 188 | 189 | public function setCollection($id, $collection) 190 | { 191 | $this->resources[$id]['collection'] = (string)$collection; 192 | 193 | unset($this->resources[$id]['collection_instance']); 194 | } 195 | 196 | public function getCollection($id) 197 | { 198 | if (! $this->hasResource($id)) { 199 | throw new Exception\RuntimeException("No resource with id '{$id}'"); 200 | } 201 | 202 | return isset($this->resources[$id]['collection']) ? $this->resources[$id]['collection'] : ''; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/Storage/Adapter/RedisOptions.php: -------------------------------------------------------------------------------- 1 | namespaceSeparator !== $namespaceSeparator) { 82 | $this->triggerOptionEvent('namespace_separator', $namespaceSeparator); 83 | $this->namespaceSeparator = $namespaceSeparator; 84 | } 85 | return $this; 86 | } 87 | 88 | /** 89 | * Get namespace separator 90 | * 91 | * @return string 92 | */ 93 | public function getNamespaceSeparator() 94 | { 95 | return $this->namespaceSeparator; 96 | } 97 | 98 | /** 99 | * Set the redis resource manager to use 100 | * 101 | * @param null|RedisResourceManager $resourceManager 102 | * @return RedisOptions Provides a fluent interface 103 | */ 104 | public function setResourceManager(RedisResourceManager $resourceManager = null) 105 | { 106 | if ($this->resourceManager !== $resourceManager) { 107 | $this->triggerOptionEvent('resource_manager', $resourceManager); 108 | $this->resourceManager = $resourceManager; 109 | } 110 | return $this; 111 | } 112 | 113 | /** 114 | * Get the redis resource manager 115 | * 116 | * @return RedisResourceManager 117 | */ 118 | public function getResourceManager() 119 | { 120 | if (! $this->resourceManager) { 121 | $this->resourceManager = new RedisResourceManager(); 122 | } 123 | return $this->resourceManager; 124 | } 125 | 126 | /** 127 | * Get the redis resource id 128 | * 129 | * @return string 130 | */ 131 | public function getResourceId() 132 | { 133 | return $this->resourceId; 134 | } 135 | 136 | /** 137 | * Set the redis resource id 138 | * 139 | * @param string $resourceId 140 | * @return RedisOptions Provides a fluent interface 141 | */ 142 | public function setResourceId($resourceId) 143 | { 144 | $resourceId = (string) $resourceId; 145 | if ($this->resourceId !== $resourceId) { 146 | $this->triggerOptionEvent('resource_id', $resourceId); 147 | $this->resourceId = $resourceId; 148 | } 149 | return $this; 150 | } 151 | 152 | /** 153 | * Get the persistent id 154 | * 155 | * @return string 156 | */ 157 | public function getPersistentId() 158 | { 159 | return $this->getResourceManager()->getPersistentId($this->getResourceId()); 160 | } 161 | 162 | /** 163 | * Set the persistent id 164 | * 165 | * @param string $persistentId 166 | * @return RedisOptions Provides a fluent interface 167 | */ 168 | public function setPersistentId($persistentId) 169 | { 170 | $this->triggerOptionEvent('persistent_id', $persistentId); 171 | $this->getResourceManager()->setPersistentId($this->getResourceId(), $persistentId); 172 | return $this; 173 | } 174 | 175 | /** 176 | * Set redis options 177 | * 178 | * @param array $libOptions 179 | * @return RedisOptions Provides a fluent interface 180 | * @link http://github.com/nicolasff/phpredis#setoption 181 | */ 182 | public function setLibOptions(array $libOptions) 183 | { 184 | $this->triggerOptionEvent('lib_option', $libOptions); 185 | $this->getResourceManager()->setLibOptions($this->getResourceId(), $libOptions); 186 | return $this; 187 | } 188 | 189 | /** 190 | * Get redis options 191 | * 192 | * @return array 193 | * @link http://github.com/nicolasff/phpredis#setoption 194 | */ 195 | public function getLibOptions() 196 | { 197 | return $this->getResourceManager()->getLibOptions($this->getResourceId()); 198 | } 199 | 200 | /** 201 | * Set server 202 | * 203 | * Server can be described as follows: 204 | * - URI: /path/to/sock.sock 205 | * - Assoc: array('host' => [, 'port' => [, 'timeout' => ]]) 206 | * - List: array([, , [, ]]) 207 | * 208 | * @param string|array $server 209 | * 210 | * @return RedisOptions Provides a fluent interface 211 | */ 212 | public function setServer($server) 213 | { 214 | $this->getResourceManager()->setServer($this->getResourceId(), $server); 215 | return $this; 216 | } 217 | 218 | /** 219 | * Get server 220 | * 221 | * @return array array('host' => [, 'port' => [, 'timeout' => ]]) 222 | */ 223 | public function getServer() 224 | { 225 | return $this->getResourceManager()->getServer($this->getResourceId()); 226 | } 227 | 228 | /** 229 | * Set resource database number 230 | * 231 | * @param int $database Database number 232 | * 233 | * @return RedisOptions Provides a fluent interface 234 | */ 235 | public function setDatabase($database) 236 | { 237 | $this->getResourceManager()->setDatabase($this->getResourceId(), $database); 238 | return $this; 239 | } 240 | 241 | /** 242 | * Get resource database number 243 | * 244 | * @return int Database number 245 | */ 246 | public function getDatabase() 247 | { 248 | return $this->getResourceManager()->getDatabase($this->getResourceId()); 249 | } 250 | 251 | /** 252 | * Set resource password 253 | * 254 | * @param string $password Password 255 | * 256 | * @return RedisOptions Provides a fluent interface 257 | */ 258 | public function setPassword($password) 259 | { 260 | $this->getResourceManager()->setPassword($this->getResourceId(), $password); 261 | return $this; 262 | } 263 | 264 | /** 265 | * Get resource password 266 | * 267 | * @return string 268 | */ 269 | public function getPassword() 270 | { 271 | return $this->getResourceManager()->getPassword($this->getResourceId()); 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /src/Storage/Adapter/SessionOptions.php: -------------------------------------------------------------------------------- 1 | sessionContainer != $sessionContainer) { 35 | $this->triggerOptionEvent('session_container', $sessionContainer); 36 | $this->sessionContainer = $sessionContainer; 37 | } 38 | 39 | return $this; 40 | } 41 | 42 | /** 43 | * Get the session container 44 | * 45 | * @return null|SessionContainer 46 | */ 47 | public function getSessionContainer() 48 | { 49 | return $this->sessionContainer; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Storage/Adapter/WinCacheOptions.php: -------------------------------------------------------------------------------- 1 | triggerOptionEvent('namespace_separator', $namespaceSeparator); 34 | $this->namespaceSeparator = $namespaceSeparator; 35 | return $this; 36 | } 37 | 38 | /** 39 | * Get namespace separator 40 | * 41 | * @return string 42 | */ 43 | public function getNamespaceSeparator() 44 | { 45 | return $this->namespaceSeparator; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Storage/Adapter/XCacheOptions.php: -------------------------------------------------------------------------------- 1 | triggerOptionEvent('namespace_separator', $namespaceSeparator); 55 | $this->namespaceSeparator = $namespaceSeparator; 56 | return $this; 57 | } 58 | 59 | /** 60 | * Get namespace separator 61 | * 62 | * @return string 63 | */ 64 | public function getNamespaceSeparator() 65 | { 66 | return $this->namespaceSeparator; 67 | } 68 | 69 | /** 70 | * Set username to call admin functions 71 | * 72 | * @param null|string $adminUser 73 | * @return XCacheOptions Provides a fluent interface 74 | */ 75 | public function setAdminUser($adminUser) 76 | { 77 | $adminUser = ($adminUser === null) ? null : (string) $adminUser; 78 | if ($this->adminUser !== $adminUser) { 79 | $this->triggerOptionEvent('admin_user', $adminUser); 80 | $this->adminUser = $adminUser; 81 | } 82 | return $this; 83 | } 84 | 85 | /** 86 | * Get username to call admin functions 87 | * 88 | * @return string 89 | */ 90 | public function getAdminUser() 91 | { 92 | return $this->adminUser; 93 | } 94 | 95 | /** 96 | * Enable/Disable admin authentication handling 97 | * 98 | * @param bool $adminAuth 99 | * @return XCacheOptions Provides a fluent interface 100 | */ 101 | public function setAdminAuth($adminAuth) 102 | { 103 | $adminAuth = (bool) $adminAuth; 104 | if ($this->adminAuth !== $adminAuth) { 105 | $this->triggerOptionEvent('admin_auth', $adminAuth); 106 | $this->adminAuth = $adminAuth; 107 | } 108 | return $this; 109 | } 110 | 111 | /** 112 | * Get admin authentication enabled 113 | * 114 | * @return bool 115 | */ 116 | public function getAdminAuth() 117 | { 118 | return $this->adminAuth; 119 | } 120 | 121 | /** 122 | * Set password to call admin functions 123 | * 124 | * @param null|string $adminPass 125 | * @return XCacheOptions Provides a fluent interface 126 | */ 127 | public function setAdminPass($adminPass) 128 | { 129 | $adminPass = ($adminPass === null) ? null : (string) $adminPass; 130 | if ($this->adminPass !== $adminPass) { 131 | $this->triggerOptionEvent('admin_pass', $adminPass); 132 | $this->adminPass = $adminPass; 133 | } 134 | return $this; 135 | } 136 | 137 | /** 138 | * Get password to call admin functions 139 | * 140 | * @return string 141 | */ 142 | public function getAdminPass() 143 | { 144 | return $this->adminPass; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ZendServerDisk.php: -------------------------------------------------------------------------------- 1 | totalSpace === null) { 90 | $path = ini_get('zend_datacache.disk.save_path'); 91 | 92 | ErrorHandler::start(); 93 | $total = disk_total_space($path); 94 | $error = ErrorHandler::stop(); 95 | if ($total === false) { 96 | throw new Exception\RuntimeException("Can't detect total space of '{$path}'", 0, $error); 97 | } 98 | 99 | $this->totalSpace = $total; 100 | } 101 | return $this->totalSpace; 102 | } 103 | 104 | /* AvailableSpaceCapableInterface */ 105 | 106 | /** 107 | * Get available space in bytes 108 | * 109 | * @throws Exception\RuntimeException 110 | * @return int|float 111 | */ 112 | public function getAvailableSpace() 113 | { 114 | $path = ini_get('zend_datacache.disk.save_path'); 115 | 116 | ErrorHandler::start(); 117 | $avail = disk_free_space($path); 118 | $error = ErrorHandler::stop(); 119 | if ($avail === false) { 120 | throw new Exception\RuntimeException("Can't detect free space of '{$path}'", 0, $error); 121 | } 122 | 123 | return $avail; 124 | } 125 | 126 | /* internal */ 127 | 128 | /** 129 | * Store data into Zend Data Disk Cache 130 | * 131 | * @param string $internalKey 132 | * @param mixed $value 133 | * @param int $ttl 134 | * @return void 135 | * @throws Exception\RuntimeException 136 | */ 137 | protected function zdcStore($internalKey, $value, $ttl) 138 | { 139 | if (! zend_disk_cache_store($internalKey, $value, $ttl)) { 140 | $valueType = gettype($value); 141 | throw new Exception\RuntimeException( 142 | "zend_disk_cache_store($internalKey, <{$valueType}>, {$ttl}) failed" 143 | ); 144 | } 145 | } 146 | 147 | /** 148 | * Fetch a single item from Zend Data Disk Cache 149 | * 150 | * @param string $internalKey 151 | * @return mixed The stored value or FALSE if item wasn't found 152 | * @throws Exception\RuntimeException 153 | */ 154 | protected function zdcFetch($internalKey) 155 | { 156 | return zend_disk_cache_fetch((string) $internalKey); 157 | } 158 | 159 | /** 160 | * Fetch multiple items from Zend Data Disk Cache 161 | * 162 | * @param array $internalKeys 163 | * @return array All found items 164 | * @throws Exception\RuntimeException 165 | */ 166 | protected function zdcFetchMulti(array $internalKeys) 167 | { 168 | $items = zend_disk_cache_fetch($internalKeys); 169 | if ($items === false) { 170 | throw new Exception\RuntimeException("zend_disk_cache_fetch() failed"); 171 | } 172 | return $items; 173 | } 174 | 175 | /** 176 | * Delete data from Zend Data Disk Cache 177 | * 178 | * @param string $internalKey 179 | * @return bool 180 | * @throws Exception\RuntimeException 181 | */ 182 | protected function zdcDelete($internalKey) 183 | { 184 | return zend_disk_cache_delete($internalKey); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/Storage/Adapter/ZendServerShm.php: -------------------------------------------------------------------------------- 1 | , {$ttl}) failed" 98 | ); 99 | } 100 | } 101 | 102 | /** 103 | * Fetch a single item from Zend Data SHM Cache 104 | * 105 | * @param string $internalKey 106 | * @return mixed The stored value or FALSE if item wasn't found 107 | * @throws Exception\RuntimeException 108 | */ 109 | protected function zdcFetch($internalKey) 110 | { 111 | return zend_shm_cache_fetch((string) $internalKey); 112 | } 113 | 114 | /** 115 | * Fetch multiple items from Zend Data SHM Cache 116 | * 117 | * @param array $internalKeys 118 | * @return array All found items 119 | * @throws Exception\RuntimeException 120 | */ 121 | protected function zdcFetchMulti(array $internalKeys) 122 | { 123 | $items = zend_shm_cache_fetch($internalKeys); 124 | if ($items === false) { 125 | throw new Exception\RuntimeException("zend_shm_cache_fetch() failed"); 126 | } 127 | return $items; 128 | } 129 | 130 | /** 131 | * Delete data from Zend Data SHM Cache 132 | * 133 | * @param string $internalKey 134 | * @return bool 135 | * @throws Exception\RuntimeException 136 | */ 137 | protected function zdcDelete($internalKey) 138 | { 139 | return zend_shm_cache_delete($internalKey); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Storage/AdapterPluginManager.php: -------------------------------------------------------------------------------- 1 | Adapter\Apc::class, 28 | 'Apc' => Adapter\Apc::class, 29 | 'APC' => Adapter\Apc::class, 30 | 'apcu' => Adapter\Apcu::class, 31 | 'ApcU' => Adapter\Apcu::class, 32 | 'Apcu' => Adapter\Apcu::class, 33 | 'APCu' => Adapter\Apcu::class, 34 | 'black_hole' => Adapter\BlackHole::class, 35 | 'blackhole' => Adapter\BlackHole::class, 36 | 'blackHole' => Adapter\BlackHole::class, 37 | 'BlackHole' => Adapter\BlackHole::class, 38 | 'dba' => Adapter\Dba::class, 39 | 'Dba' => Adapter\Dba::class, 40 | 'DBA' => Adapter\Dba::class, 41 | 'ext_mongo_db' => Adapter\ExtMongoDb::class, 42 | 'extmongodb' => Adapter\ExtMongoDb::class, 43 | 'ExtMongoDb' => Adapter\ExtMongoDb::class, 44 | 'ExtMongoDB' => Adapter\ExtMongoDb::class, 45 | 'extMongoDb' => Adapter\ExtMongoDb::class, 46 | 'extMongoDB' => Adapter\ExtMongoDb::class, 47 | 'filesystem' => Adapter\Filesystem::class, 48 | 'Filesystem' => Adapter\Filesystem::class, 49 | 'memcache' => Adapter\Memcache::class, 50 | 'Memcache' => Adapter\Memcache::class, 51 | 'memcached' => Adapter\Memcached::class, 52 | 'Memcached' => Adapter\Memcached::class, 53 | 'memory' => Adapter\Memory::class, 54 | 'Memory' => Adapter\Memory::class, 55 | 'mongo_db' => Adapter\MongoDb::class, 56 | 'mongodb' => Adapter\MongoDb::class, 57 | 'MongoDb' => Adapter\MongoDb::class, 58 | 'MongoDB' => Adapter\MongoDb::class, 59 | 'mongoDb' => Adapter\MongoDb::class, 60 | 'mongoDB' => Adapter\MongoDb::class, 61 | 'redis' => Adapter\Redis::class, 62 | 'Redis' => Adapter\Redis::class, 63 | 'session' => Adapter\Session::class, 64 | 'Session' => Adapter\Session::class, 65 | 'xcache' => Adapter\XCache::class, 66 | 'xCache' => Adapter\XCache::class, 67 | 'Xcache' => Adapter\XCache::class, 68 | 'XCache' => Adapter\XCache::class, 69 | 'win_cache' => Adapter\WinCache::class, 70 | 'wincache' => Adapter\WinCache::class, 71 | 'winCache' => Adapter\WinCache::class, 72 | 'WinCache' => Adapter\WinCache::class, 73 | 'zend_server_disk' => Adapter\ZendServerDisk::class, 74 | 'zendserverdisk' => Adapter\ZendServerDisk::class, 75 | 'zendServerDisk' => Adapter\ZendServerDisk::class, 76 | 'ZendServerDisk' => Adapter\ZendServerDisk::class, 77 | 'zend_server_shm' => Adapter\ZendServerShm::class, 78 | 'zendservershm' => Adapter\ZendServerShm::class, 79 | 'zendServerShm' => Adapter\ZendServerShm::class, 80 | 'zendServerSHM' => Adapter\ZendServerShm::class, 81 | 'ZendServerShm' => Adapter\ZendServerShm::class, 82 | 'ZendServerSHM' => Adapter\ZendServerShm::class, 83 | ]; 84 | 85 | protected $factories = [ 86 | Adapter\Apc::class => InvokableFactory::class, 87 | Adapter\Apcu::class => InvokableFactory::class, 88 | Adapter\BlackHole::class => InvokableFactory::class, 89 | Adapter\Dba::class => InvokableFactory::class, 90 | Adapter\ExtMongoDb::class => InvokableFactory::class, 91 | Adapter\Filesystem::class => InvokableFactory::class, 92 | Adapter\Memcache::class => InvokableFactory::class, 93 | Adapter\Memcached::class => InvokableFactory::class, 94 | Adapter\Memory::class => InvokableFactory::class, 95 | Adapter\MongoDb::class => InvokableFactory::class, 96 | Adapter\Redis::class => InvokableFactory::class, 97 | Adapter\Session::class => InvokableFactory::class, 98 | Adapter\WinCache::class => InvokableFactory::class, 99 | Adapter\XCache::class => InvokableFactory::class, 100 | Adapter\ZendServerDisk::class => InvokableFactory::class, 101 | Adapter\ZendServerShm::class => InvokableFactory::class, 102 | 103 | // v2 normalized FQCNs 104 | 'zendcachestorageadapterapc' => InvokableFactory::class, 105 | 'zendcachestorageadapterapcu' => InvokableFactory::class, 106 | 'zendcachestorageadapterblackhole' => InvokableFactory::class, 107 | 'zendcachestorageadapterdba' => InvokableFactory::class, 108 | 'zendcachestorageadapterextmongodb' => InvokableFactory::class, 109 | 'zendcachestorageadapterfilesystem' => InvokableFactory::class, 110 | 'zendcachestorageadaptermemcache' => InvokableFactory::class, 111 | 'zendcachestorageadaptermemcached' => InvokableFactory::class, 112 | 'zendcachestorageadaptermemory' => InvokableFactory::class, 113 | 'zendcachestorageadaptermongodb' => InvokableFactory::class, 114 | 'zendcachestorageadapterredis' => InvokableFactory::class, 115 | 'zendcachestorageadaptersession' => InvokableFactory::class, 116 | 'zendcachestorageadapterwincache' => InvokableFactory::class, 117 | 'zendcachestorageadapterxcache' => InvokableFactory::class, 118 | 'zendcachestorageadapterzendserverdisk' => InvokableFactory::class, 119 | 'zendcachestorageadapterzendservershm' => InvokableFactory::class, 120 | ]; 121 | 122 | /** 123 | * Do not share by default (v3) 124 | * 125 | * @var array 126 | */ 127 | protected $sharedByDefault = false; 128 | 129 | /** 130 | * Don't share by default (v2) 131 | * 132 | * @var boolean 133 | */ 134 | protected $shareByDefault = false; 135 | 136 | /** 137 | * @var string 138 | */ 139 | protected $instanceOf = StorageInterface::class; 140 | 141 | /** 142 | * Validate the plugin is of the expected type (v3). 143 | * 144 | * Validates against `$instanceOf`. 145 | * 146 | * @param mixed $instance 147 | * @throws InvalidServiceException 148 | */ 149 | public function validate($instance) 150 | { 151 | if (! $instance instanceof $this->instanceOf) { 152 | throw new InvalidServiceException(sprintf( 153 | '%s can only create instances of %s; %s is invalid', 154 | get_class($this), 155 | $this->instanceOf, 156 | (is_object($instance) ? get_class($instance) : gettype($instance)) 157 | )); 158 | } 159 | } 160 | 161 | /** 162 | * Validate the plugin is of the expected type (v2). 163 | * 164 | * Proxies to `validate()`. 165 | * 166 | * @param mixed $instance 167 | * @throws InvalidServiceException 168 | */ 169 | public function validatePlugin($instance) 170 | { 171 | try { 172 | $this->validate($instance); 173 | } catch (InvalidServiceException $e) { 174 | throw new RuntimeException($e->getMessage(), $e->getCode(), $e); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/Storage/AvailableSpaceCapableInterface.php: -------------------------------------------------------------------------------- 1 | setStorage($target); 41 | } 42 | 43 | /** 44 | * Alias of setTarget 45 | * 46 | * @param StorageInterface $storage 47 | * @return Event 48 | * @see Zend\EventManager\Event::setTarget() 49 | */ 50 | public function setStorage(StorageInterface $storage) 51 | { 52 | $this->target = $storage; 53 | return $this; 54 | } 55 | 56 | /** 57 | * Alias of getTarget 58 | * 59 | * @return StorageInterface 60 | */ 61 | public function getStorage() 62 | { 63 | return $this->getTarget(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Storage/ExceptionEvent.php: -------------------------------------------------------------------------------- 1 | setException($exception); 46 | } 47 | 48 | /** 49 | * Set the exception to be thrown 50 | * 51 | * @param Exception $exception 52 | * @return ExceptionEvent 53 | */ 54 | public function setException(Exception $exception) 55 | { 56 | $this->exception = $exception; 57 | return $this; 58 | } 59 | 60 | /** 61 | * Get the exception to be thrown 62 | * 63 | * @return Exception 64 | */ 65 | public function getException() 66 | { 67 | return $this->exception; 68 | } 69 | 70 | /** 71 | * Throw the exception or use the result 72 | * 73 | * @param bool $flag 74 | * @return ExceptionEvent 75 | */ 76 | public function setThrowException($flag) 77 | { 78 | $this->throwException = (bool) $flag; 79 | return $this; 80 | } 81 | 82 | /** 83 | * Throw the exception or use the result 84 | * 85 | * @return bool 86 | */ 87 | public function getThrowException() 88 | { 89 | return $this->throwException; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Storage/FlushableInterface.php: -------------------------------------------------------------------------------- 1 | options = $options; 30 | return $this; 31 | } 32 | 33 | /** 34 | * Get all pattern options 35 | * 36 | * @return PluginOptions 37 | */ 38 | public function getOptions() 39 | { 40 | if (null === $this->options) { 41 | $this->setOptions(new PluginOptions()); 42 | } 43 | return $this->options; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Storage/Plugin/ClearExpiredByFactor.php: -------------------------------------------------------------------------------- 1 | listeners[] = $events->attach('setItem.post', $callback, $priority); 26 | $this->listeners[] = $events->attach('setItems.post', $callback, $priority); 27 | $this->listeners[] = $events->attach('addItem.post', $callback, $priority); 28 | $this->listeners[] = $events->attach('addItems.post', $callback, $priority); 29 | } 30 | 31 | /** 32 | * Clear expired items by factor after writing new item(s) 33 | * 34 | * @param PostEvent $event 35 | * @return void 36 | */ 37 | public function clearExpiredByFactor(PostEvent $event) 38 | { 39 | $storage = $event->getStorage(); 40 | if (! ($storage instanceof ClearExpiredInterface)) { 41 | return; 42 | } 43 | 44 | $factor = $this->getOptions()->getClearingFactor(); 45 | if ($factor && mt_rand(1, $factor) == 1) { 46 | $storage->clearExpired(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Storage/Plugin/ExceptionHandler.php: -------------------------------------------------------------------------------- 1 | listeners[] = $events->attach('getItem.exception', $callback, $priority); 26 | $this->listeners[] = $events->attach('getItems.exception', $callback, $priority); 27 | 28 | $this->listeners[] = $events->attach('hasItem.exception', $callback, $priority); 29 | $this->listeners[] = $events->attach('hasItems.exception', $callback, $priority); 30 | 31 | $this->listeners[] = $events->attach('getMetadata.exception', $callback, $priority); 32 | $this->listeners[] = $events->attach('getMetadatas.exception', $callback, $priority); 33 | 34 | // write 35 | $this->listeners[] = $events->attach('setItem.exception', $callback, $priority); 36 | $this->listeners[] = $events->attach('setItems.exception', $callback, $priority); 37 | 38 | $this->listeners[] = $events->attach('addItem.exception', $callback, $priority); 39 | $this->listeners[] = $events->attach('addItems.exception', $callback, $priority); 40 | 41 | $this->listeners[] = $events->attach('replaceItem.exception', $callback, $priority); 42 | $this->listeners[] = $events->attach('replaceItems.exception', $callback, $priority); 43 | 44 | $this->listeners[] = $events->attach('touchItem.exception', $callback, $priority); 45 | $this->listeners[] = $events->attach('touchItems.exception', $callback, $priority); 46 | 47 | $this->listeners[] = $events->attach('removeItem.exception', $callback, $priority); 48 | $this->listeners[] = $events->attach('removeItems.exception', $callback, $priority); 49 | 50 | $this->listeners[] = $events->attach('checkAndSetItem.exception', $callback, $priority); 51 | 52 | // increment / decrement item(s) 53 | $this->listeners[] = $events->attach('incrementItem.exception', $callback, $priority); 54 | $this->listeners[] = $events->attach('incrementItems.exception', $callback, $priority); 55 | 56 | $this->listeners[] = $events->attach('decrementItem.exception', $callback, $priority); 57 | $this->listeners[] = $events->attach('decrementItems.exception', $callback, $priority); 58 | 59 | // utility 60 | $this->listeners[] = $events->attach('clearExpired.exception', $callback, $priority); 61 | } 62 | 63 | /** 64 | * On exception 65 | * 66 | * @param ExceptionEvent $event 67 | * @return void 68 | */ 69 | public function onException(ExceptionEvent $event) 70 | { 71 | $options = $this->getOptions(); 72 | $callback = $options->getExceptionCallback(); 73 | if ($callback) { 74 | call_user_func($callback, $event->getException()); 75 | } 76 | 77 | $event->setThrowException($options->getThrowExceptions()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Storage/Plugin/IgnoreUserAbort.php: -------------------------------------------------------------------------------- 1 | listeners[] = $events->attach('setItem.pre', $cbOnBefore, $priority); 33 | $this->listeners[] = $events->attach('setItem.post', $cbOnAfter, $priority); 34 | $this->listeners[] = $events->attach('setItem.exception', $cbOnAfter, $priority); 35 | 36 | $this->listeners[] = $events->attach('setItems.pre', $cbOnBefore, $priority); 37 | $this->listeners[] = $events->attach('setItems.post', $cbOnAfter, $priority); 38 | $this->listeners[] = $events->attach('setItems.exception', $cbOnAfter, $priority); 39 | 40 | $this->listeners[] = $events->attach('addItem.pre', $cbOnBefore, $priority); 41 | $this->listeners[] = $events->attach('addItem.post', $cbOnAfter, $priority); 42 | $this->listeners[] = $events->attach('addItem.exception', $cbOnAfter, $priority); 43 | 44 | $this->listeners[] = $events->attach('addItems.pre', $cbOnBefore, $priority); 45 | $this->listeners[] = $events->attach('addItems.post', $cbOnAfter, $priority); 46 | $this->listeners[] = $events->attach('addItems.exception', $cbOnAfter, $priority); 47 | 48 | $this->listeners[] = $events->attach('replaceItem.pre', $cbOnBefore, $priority); 49 | $this->listeners[] = $events->attach('replaceItem.post', $cbOnAfter, $priority); 50 | $this->listeners[] = $events->attach('replaceItem.exception', $cbOnAfter, $priority); 51 | 52 | $this->listeners[] = $events->attach('replaceItems.pre', $cbOnBefore, $priority); 53 | $this->listeners[] = $events->attach('replaceItems.post', $cbOnAfter, $priority); 54 | $this->listeners[] = $events->attach('replaceItems.exception', $cbOnAfter, $priority); 55 | 56 | $this->listeners[] = $events->attach('checkAndSetItem.pre', $cbOnBefore, $priority); 57 | $this->listeners[] = $events->attach('checkAndSetItem.post', $cbOnAfter, $priority); 58 | $this->listeners[] = $events->attach('checkAndSetItem.exception', $cbOnAfter, $priority); 59 | 60 | // increment / decrement item(s) 61 | $this->listeners[] = $events->attach('incrementItem.pre', $cbOnBefore, $priority); 62 | $this->listeners[] = $events->attach('incrementItem.post', $cbOnAfter, $priority); 63 | $this->listeners[] = $events->attach('incrementItem.exception', $cbOnAfter, $priority); 64 | 65 | $this->listeners[] = $events->attach('incrementItems.pre', $cbOnBefore, $priority); 66 | $this->listeners[] = $events->attach('incrementItems.post', $cbOnAfter, $priority); 67 | $this->listeners[] = $events->attach('incrementItems.exception', $cbOnAfter, $priority); 68 | 69 | $this->listeners[] = $events->attach('decrementItem.pre', $cbOnBefore, $priority); 70 | $this->listeners[] = $events->attach('decrementItem.post', $cbOnAfter, $priority); 71 | $this->listeners[] = $events->attach('decrementItem.exception', $cbOnAfter, $priority); 72 | 73 | $this->listeners[] = $events->attach('decrementItems.pre', $cbOnBefore, $priority); 74 | $this->listeners[] = $events->attach('decrementItems.post', $cbOnAfter, $priority); 75 | $this->listeners[] = $events->attach('decrementItems.exception', $cbOnAfter, $priority); 76 | } 77 | 78 | /** 79 | * Activate ignore_user_abort if not already done 80 | * and save the target who activated it. 81 | * 82 | * @param Event $event 83 | * @return void 84 | */ 85 | public function onBefore(Event $event) 86 | { 87 | if ($this->activatedTarget === null && ! ignore_user_abort(true)) { 88 | $this->activatedTarget = $event->getStorage(); 89 | } 90 | } 91 | 92 | /** 93 | * Reset ignore_user_abort if it's activated and if it's the same target 94 | * who activated it. 95 | * 96 | * If exit_on_abort is enabled and the connection has been aborted 97 | * exit the script. 98 | * 99 | * @param Event $event 100 | * @return void 101 | */ 102 | public function onAfter(Event $event) 103 | { 104 | if ($this->activatedTarget === $event->getStorage()) { 105 | // exit if connection aborted 106 | if ($this->getOptions()->getExitOnAbort() && connection_aborted()) { 107 | exit; 108 | } 109 | 110 | // reset ignore_user_abort 111 | ignore_user_abort(false); 112 | 113 | // remove activated target 114 | $this->activatedTarget = null; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Storage/Plugin/OptimizeByFactor.php: -------------------------------------------------------------------------------- 1 | listeners[] = $events->attach('removeItem.post', $callback, $priority); 25 | $this->listeners[] = $events->attach('removeItems.post', $callback, $priority); 26 | } 27 | 28 | /** 29 | * Optimize by factor on a success _RESULT_ 30 | * 31 | * @param PostEvent $event 32 | * @return void 33 | */ 34 | public function optimizeByFactor(PostEvent $event) 35 | { 36 | $storage = $event->getStorage(); 37 | if (! ($storage instanceof OptimizableInterface)) { 38 | return; 39 | } 40 | 41 | $factor = $this->getOptions()->getOptimizingFactor(); 42 | if ($factor && mt_rand(1, $factor) == 1) { 43 | $storage->optimize(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Storage/Plugin/PluginInterface.php: -------------------------------------------------------------------------------- 1 | clearingFactor = $this->normalizeFactor($clearingFactor); 80 | return $this; 81 | } 82 | 83 | /** 84 | * Get automatic clearing factor 85 | * 86 | * Used by: 87 | * - ClearExpiredByFactor 88 | * 89 | * @return int 90 | */ 91 | public function getClearingFactor() 92 | { 93 | return $this->clearingFactor; 94 | } 95 | 96 | /** 97 | * Set callback to call on intercepted exception 98 | * 99 | * Used by: 100 | * - ExceptionHandler 101 | * 102 | * @param null|callable $exceptionCallback 103 | * @throws Exception\InvalidArgumentException 104 | * @return PluginOptions Provides a fluent interface 105 | */ 106 | public function setExceptionCallback($exceptionCallback) 107 | { 108 | if ($exceptionCallback !== null && ! is_callable($exceptionCallback, true)) { 109 | throw new Exception\InvalidArgumentException('Not a valid callback'); 110 | } 111 | $this->exceptionCallback = $exceptionCallback; 112 | return $this; 113 | } 114 | 115 | /** 116 | * Get callback to call on intercepted exception 117 | * 118 | * Used by: 119 | * - ExceptionHandler 120 | * 121 | * @return null|callable 122 | */ 123 | public function getExceptionCallback() 124 | { 125 | return $this->exceptionCallback; 126 | } 127 | 128 | /** 129 | * Exit if connection aborted and ignore_user_abort is disabled. 130 | * 131 | * @param bool $exitOnAbort 132 | * @return PluginOptions Provides a fluent interface 133 | */ 134 | public function setExitOnAbort($exitOnAbort) 135 | { 136 | $this->exitOnAbort = (bool) $exitOnAbort; 137 | return $this; 138 | } 139 | 140 | /** 141 | * Exit if connection aborted and ignore_user_abort is disabled. 142 | * 143 | * @return bool 144 | */ 145 | public function getExitOnAbort() 146 | { 147 | return $this->exitOnAbort; 148 | } 149 | 150 | /** 151 | * Set automatic optimizing factor 152 | * 153 | * Used by: 154 | * - OptimizeByFactor 155 | * 156 | * @param int $optimizingFactor 157 | * @return PluginOptions Provides a fluent interface 158 | */ 159 | public function setOptimizingFactor($optimizingFactor) 160 | { 161 | $this->optimizingFactor = $this->normalizeFactor($optimizingFactor); 162 | return $this; 163 | } 164 | 165 | /** 166 | * Set automatic optimizing factor 167 | * 168 | * Used by: 169 | * - OptimizeByFactor 170 | * 171 | * @return int 172 | */ 173 | public function getOptimizingFactor() 174 | { 175 | return $this->optimizingFactor; 176 | } 177 | 178 | /** 179 | * Set serializer 180 | * 181 | * Used by: 182 | * - Serializer 183 | * 184 | * @param string|SerializerAdapter $serializer 185 | * @throws Exception\InvalidArgumentException 186 | * @return PluginOptions Provides a fluent interface 187 | */ 188 | public function setSerializer($serializer) 189 | { 190 | if (! is_string($serializer) && ! $serializer instanceof SerializerAdapter) { 191 | throw new Exception\InvalidArgumentException(sprintf( 192 | '%s expects either a string serializer name or Zend\Serializer\Adapter\AdapterInterface instance; ' 193 | . 'received "%s"', 194 | __METHOD__, 195 | (is_object($serializer) ? get_class($serializer) : gettype($serializer)) 196 | )); 197 | } 198 | $this->serializer = $serializer; 199 | return $this; 200 | } 201 | 202 | /** 203 | * Get serializer 204 | * 205 | * Used by: 206 | * - Serializer 207 | * 208 | * @return SerializerAdapter 209 | */ 210 | public function getSerializer() 211 | { 212 | if (! $this->serializer instanceof SerializerAdapter) { 213 | // use default serializer 214 | if (! $this->serializer) { 215 | $this->setSerializer(SerializerFactory::getDefaultAdapter()); 216 | // instantiate by class name + serializer_options 217 | } else { 218 | $options = $this->getSerializerOptions(); 219 | $this->setSerializer(SerializerFactory::factory($this->serializer, $options)); 220 | } 221 | } 222 | return $this->serializer; 223 | } 224 | 225 | /** 226 | * Set configuration options for instantiating a serializer adapter 227 | * 228 | * Used by: 229 | * - Serializer 230 | * 231 | * @param mixed $serializerOptions 232 | * @return PluginOptions Provides a fluent interface 233 | */ 234 | public function setSerializerOptions($serializerOptions) 235 | { 236 | $this->serializerOptions = $serializerOptions; 237 | return $this; 238 | } 239 | 240 | /** 241 | * Get configuration options for instantiating a serializer adapter 242 | * 243 | * Used by: 244 | * - Serializer 245 | * 246 | * @return array 247 | */ 248 | public function getSerializerOptions() 249 | { 250 | return $this->serializerOptions; 251 | } 252 | 253 | /** 254 | * Set flag indicating we should re-throw exceptions 255 | * 256 | * Used by: 257 | * - ExceptionHandler 258 | * 259 | * @param bool $throwExceptions 260 | * @return PluginOptions Provides a fluent interface 261 | */ 262 | public function setThrowExceptions($throwExceptions) 263 | { 264 | $this->throwExceptions = (bool) $throwExceptions; 265 | return $this; 266 | } 267 | 268 | /** 269 | * Should we re-throw exceptions? 270 | * 271 | * Used by: 272 | * - ExceptionHandler 273 | * 274 | * @return bool 275 | */ 276 | public function getThrowExceptions() 277 | { 278 | return $this->throwExceptions; 279 | } 280 | 281 | /** 282 | * Normalize a factor 283 | * 284 | * Cast to int and ensure we have a value greater than zero. 285 | * 286 | * @param int $factor 287 | * @return int 288 | * @throws Exception\InvalidArgumentException 289 | */ 290 | protected function normalizeFactor($factor) 291 | { 292 | $factor = (int) $factor; 293 | if ($factor < 0) { 294 | throw new Exception\InvalidArgumentException( 295 | "Invalid factor '{$factor}': must be greater or equal 0" 296 | ); 297 | } 298 | return $factor; 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /src/Storage/PluginManager.php: -------------------------------------------------------------------------------- 1 | Plugin\ClearExpiredByFactor::class, 28 | 'clearexpiredbyfactor' => Plugin\ClearExpiredByFactor::class, 29 | 'clearExpiredByFactor' => Plugin\ClearExpiredByFactor::class, 30 | 'ClearExpiredByFactor' => Plugin\ClearExpiredByFactor::class, 31 | 'exception_handler' => Plugin\ExceptionHandler::class, 32 | 'exceptionhandler' => Plugin\ExceptionHandler::class, 33 | 'exceptionHandler' => Plugin\ExceptionHandler::class, 34 | 'ExceptionHandler' => Plugin\ExceptionHandler::class, 35 | 'ignore_user_abort' => Plugin\IgnoreUserAbort::class, 36 | 'ignoreuserabort' => Plugin\IgnoreUserAbort::class, 37 | 'ignoreUserAbort' => Plugin\IgnoreUserAbort::class, 38 | 'IgnoreUserAbort' => Plugin\IgnoreUserAbort::class, 39 | 'optimize_by_factor' => Plugin\OptimizeByFactor::class, 40 | 'optimizebyfactor' => Plugin\OptimizeByFactor::class, 41 | 'optimizeByFactor' => Plugin\OptimizeByFactor::class, 42 | 'OptimizeByFactor' => Plugin\OptimizeByFactor::class, 43 | 'serializer' => Plugin\Serializer::class, 44 | 'Serializer' => Plugin\Serializer::class 45 | ]; 46 | 47 | protected $factories = [ 48 | Plugin\ClearExpiredByFactor::class => InvokableFactory::class, 49 | Plugin\ExceptionHandler::class => InvokableFactory::class, 50 | Plugin\IgnoreUserAbort::class => InvokableFactory::class, 51 | Plugin\OptimizeByFactor::class => InvokableFactory::class, 52 | Plugin\Serializer::class => InvokableFactory::class, 53 | 54 | // v2 normalized FQCNs 55 | 'zendcachestoragepluginclearexpiredbyfactor' => InvokableFactory::class, 56 | 'zendcachestoragepluginexceptionhandler' => InvokableFactory::class, 57 | 'zendcachestoragepluginignoreuserabort' => InvokableFactory::class, 58 | 'zendcachestoragepluginoptimizebyfactor' => InvokableFactory::class, 59 | 'zendcachestoragepluginserializer' => InvokableFactory::class, 60 | ]; 61 | 62 | /** 63 | * Do not share by default (v3) 64 | * 65 | * @var array 66 | */ 67 | protected $sharedByDefault = false; 68 | 69 | /** 70 | * Do not share by default (v2) 71 | * 72 | * @var array 73 | */ 74 | protected $shareByDefault = false; 75 | 76 | /** 77 | * @var string 78 | */ 79 | protected $instanceOf = Plugin\PluginInterface::class; 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | public function validate($instance) 85 | { 86 | if ($instance instanceof $this->instanceOf) { 87 | // we're okay 88 | return; 89 | } 90 | 91 | throw new InvalidServiceException(sprintf( 92 | 'Plugin of type %s is invalid; must implement %s\Plugin\PluginInterface', 93 | (is_object($instance) ? get_class($instance) : gettype($instance)), 94 | __NAMESPACE__ 95 | )); 96 | } 97 | 98 | /** 99 | * Validate the plugin 100 | * 101 | * Checks that the plugin loaded is an instance of Plugin\PluginInterface. 102 | * 103 | * @param mixed $plugin 104 | * @return void 105 | * @throws Exception\RuntimeException if invalid 106 | */ 107 | public function validatePlugin($plugin) 108 | { 109 | try { 110 | $this->validate($plugin); 111 | } catch (InvalidServiceException $e) { 112 | throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Storage/PostEvent.php: -------------------------------------------------------------------------------- 1 | setResult($result); 37 | } 38 | 39 | /** 40 | * Set the result/return value 41 | * 42 | * @param mixed $value 43 | * @return PostEvent 44 | */ 45 | public function setResult(& $value) 46 | { 47 | $this->result = & $value; 48 | return $this; 49 | } 50 | 51 | /** 52 | * Get the result/return value 53 | * 54 | * @return mixed 55 | */ 56 | public function & getResult() 57 | { 58 | return $this->result; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Storage/StorageInterface.php: -------------------------------------------------------------------------------- 1 | $v) { 91 | $pluginPrio = 1; // default priority 92 | 93 | if (is_string($k)) { 94 | if (! is_array($v)) { 95 | throw new Exception\InvalidArgumentException( 96 | "'plugins.{$k}' needs to be an array" 97 | ); 98 | } 99 | $pluginName = $k; 100 | $pluginOptions = $v; 101 | } elseif (is_array($v)) { 102 | if (! isset($v['name'])) { 103 | throw new Exception\InvalidArgumentException( 104 | "Invalid plugins[{$k}] or missing plugins[{$k}].name" 105 | ); 106 | } 107 | $pluginName = (string) $v['name']; 108 | 109 | if (isset($v['options'])) { 110 | $pluginOptions = $v['options']; 111 | } else { 112 | $pluginOptions = []; 113 | } 114 | 115 | if (isset($v['priority'])) { 116 | $pluginPrio = $v['priority']; 117 | } 118 | } else { 119 | $pluginName = $v; 120 | $pluginOptions = []; 121 | } 122 | 123 | $plugin = static::pluginFactory($pluginName, $pluginOptions); 124 | if (! $adapter->hasPlugin($plugin)) { 125 | $adapter->addPlugin($plugin, $pluginPrio); 126 | } 127 | } 128 | } 129 | 130 | return $adapter; 131 | } 132 | 133 | /** 134 | * Instantiate a storage adapter 135 | * 136 | * @param string|Storage\StorageInterface $adapterName 137 | * @param array|Traversable|Storage\Adapter\AdapterOptions $options 138 | * @return Storage\StorageInterface 139 | * @throws Exception\RuntimeException 140 | */ 141 | public static function adapterFactory($adapterName, $options = []) 142 | { 143 | if ($adapterName instanceof Storage\StorageInterface) { 144 | // $adapterName is already an adapter object 145 | $adapter = $adapterName; 146 | } else { 147 | $adapter = static::getAdapterPluginManager()->get($adapterName); 148 | } 149 | 150 | if ($options) { 151 | $adapter->setOptions($options); 152 | } 153 | 154 | return $adapter; 155 | } 156 | 157 | /** 158 | * Get the adapter plugin manager 159 | * 160 | * @return Storage\AdapterPluginManager 161 | */ 162 | public static function getAdapterPluginManager() 163 | { 164 | if (static::$adapters === null) { 165 | static::$adapters = new Storage\AdapterPluginManager(new ServiceManager); 166 | } 167 | return static::$adapters; 168 | } 169 | 170 | /** 171 | * Change the adapter plugin manager 172 | * 173 | * @param Storage\AdapterPluginManager $adapters 174 | * @return void 175 | */ 176 | public static function setAdapterPluginManager(Storage\AdapterPluginManager $adapters) 177 | { 178 | static::$adapters = $adapters; 179 | } 180 | 181 | /** 182 | * Resets the internal adapter plugin manager 183 | * 184 | * @return void 185 | */ 186 | public static function resetAdapterPluginManager() 187 | { 188 | static::$adapters = null; 189 | } 190 | 191 | /** 192 | * Instantiate a storage plugin 193 | * 194 | * @param string|Storage\Plugin\PluginInterface $pluginName 195 | * @param array|Traversable|Storage\Plugin\PluginOptions $options 196 | * @return Storage\Plugin\PluginInterface 197 | * @throws Exception\RuntimeException 198 | */ 199 | public static function pluginFactory($pluginName, $options = []) 200 | { 201 | if ($pluginName instanceof Storage\Plugin\PluginInterface) { 202 | // $pluginName is already a plugin object 203 | $plugin = $pluginName; 204 | } else { 205 | $plugin = static::getPluginManager()->get($pluginName); 206 | } 207 | 208 | if ($options) { 209 | if (! $options instanceof Storage\Plugin\PluginOptions) { 210 | $options = new Storage\Plugin\PluginOptions($options); 211 | } 212 | $plugin->setOptions($options); 213 | } 214 | 215 | return $plugin; 216 | } 217 | 218 | /** 219 | * Get the plugin manager 220 | * 221 | * @return Storage\PluginManager 222 | */ 223 | public static function getPluginManager() 224 | { 225 | if (static::$plugins === null) { 226 | static::$plugins = new Storage\PluginManager(new ServiceManager); 227 | } 228 | return static::$plugins; 229 | } 230 | 231 | /** 232 | * Change the plugin manager 233 | * 234 | * @param Storage\PluginManager $plugins 235 | * @return void 236 | */ 237 | public static function setPluginManager(Storage\PluginManager $plugins) 238 | { 239 | static::$plugins = $plugins; 240 | } 241 | 242 | /** 243 | * Resets the internal plugin manager 244 | * 245 | * @return void 246 | */ 247 | public static function resetPluginManager() 248 | { 249 | static::$plugins = null; 250 | } 251 | } 252 | --------------------------------------------------------------------------------