1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\Cache; 11 12use Traversable; 13use Zend\EventManager\EventsCapableInterface; 14use Zend\Stdlib\ArrayUtils; 15 16abstract class StorageFactory 17{ 18 /** 19 * Plugin manager for loading adapters 20 * 21 * @var null|Storage\AdapterPluginManager 22 */ 23 protected static $adapters = null; 24 25 /** 26 * Plugin manager for loading plugins 27 * 28 * @var null|Storage\PluginManager 29 */ 30 protected static $plugins = null; 31 32 /** 33 * The storage factory 34 * This can instantiate storage adapters and plugins. 35 * 36 * @param array|Traversable $cfg 37 * @return Storage\StorageInterface 38 * @throws Exception\InvalidArgumentException 39 */ 40 public static function factory($cfg) 41 { 42 if ($cfg instanceof Traversable) { 43 $cfg = ArrayUtils::iteratorToArray($cfg); 44 } 45 46 if (!is_array($cfg)) { 47 throw new Exception\InvalidArgumentException( 48 'The factory needs an associative array ' 49 . 'or a Traversable object as an argument' 50 ); 51 } 52 53 // instantiate the adapter 54 if (!isset($cfg['adapter'])) { 55 throw new Exception\InvalidArgumentException('Missing "adapter"'); 56 } 57 $adapterName = $cfg['adapter']; 58 $adapterOptions = array(); 59 if (is_array($cfg['adapter'])) { 60 if (!isset($cfg['adapter']['name'])) { 61 throw new Exception\InvalidArgumentException('Missing "adapter.name"'); 62 } 63 64 $adapterName = $cfg['adapter']['name']; 65 $adapterOptions = isset($cfg['adapter']['options']) ? $cfg['adapter']['options'] : array(); 66 } 67 if (isset($cfg['options'])) { 68 $adapterOptions = array_merge($adapterOptions, $cfg['options']); 69 } 70 71 $adapter = static::adapterFactory((string) $adapterName, $adapterOptions); 72 73 // add plugins 74 if (isset($cfg['plugins'])) { 75 if (!$adapter instanceof EventsCapableInterface) { 76 throw new Exception\RuntimeException(sprintf( 77 "The adapter '%s' doesn't implement '%s' and therefore can't handle plugins", 78 get_class($adapter), 79 'Zend\EventManager\EventsCapableInterface' 80 )); 81 } 82 83 if (!is_array($cfg['plugins'])) { 84 throw new Exception\InvalidArgumentException( 85 'Plugins needs to be an array' 86 ); 87 } 88 89 foreach ($cfg['plugins'] as $k => $v) { 90 $pluginPrio = 1; // default priority 91 92 if (is_string($k)) { 93 if (!is_array($v)) { 94 throw new Exception\InvalidArgumentException( 95 "'plugins.{$k}' needs to be an array" 96 ); 97 } 98 $pluginName = $k; 99 $pluginOptions = $v; 100 } elseif (is_array($v)) { 101 if (!isset($v['name'])) { 102 throw new Exception\InvalidArgumentException("Invalid plugins[{$k}] or missing plugins[{$k}].name"); 103 } 104 $pluginName = (string) $v['name']; 105 106 if (isset($v['options'])) { 107 $pluginOptions = $v['options']; 108 } else { 109 $pluginOptions = array(); 110 } 111 112 if (isset($v['priority'])) { 113 $pluginPrio = $v['priority']; 114 } 115 } else { 116 $pluginName = $v; 117 $pluginOptions = array(); 118 } 119 120 $plugin = static::pluginFactory($pluginName, $pluginOptions); 121 $adapter->addPlugin($plugin, $pluginPrio); 122 } 123 } 124 125 return $adapter; 126 } 127 128 /** 129 * Instantiate a storage adapter 130 * 131 * @param string|Storage\StorageInterface $adapterName 132 * @param array|Traversable|Storage\Adapter\AdapterOptions $options 133 * @return Storage\StorageInterface 134 * @throws Exception\RuntimeException 135 */ 136 public static function adapterFactory($adapterName, $options = array()) 137 { 138 if ($adapterName instanceof Storage\StorageInterface) { 139 // $adapterName is already an adapter object 140 $adapter = $adapterName; 141 } else { 142 $adapter = static::getAdapterPluginManager()->get($adapterName); 143 } 144 145 if ($options) { 146 $adapter->setOptions($options); 147 } 148 149 return $adapter; 150 } 151 152 /** 153 * Get the adapter plugin manager 154 * 155 * @return Storage\AdapterPluginManager 156 */ 157 public static function getAdapterPluginManager() 158 { 159 if (static::$adapters === null) { 160 static::$adapters = new Storage\AdapterPluginManager(); 161 } 162 return static::$adapters; 163 } 164 165 /** 166 * Change the adapter plugin manager 167 * 168 * @param Storage\AdapterPluginManager $adapters 169 * @return void 170 */ 171 public static function setAdapterPluginManager(Storage\AdapterPluginManager $adapters) 172 { 173 static::$adapters = $adapters; 174 } 175 176 /** 177 * Resets the internal adapter plugin manager 178 * 179 * @return void 180 */ 181 public static function resetAdapterPluginManager() 182 { 183 static::$adapters = null; 184 } 185 186 /** 187 * Instantiate a storage plugin 188 * 189 * @param string|Storage\Plugin\PluginInterface $pluginName 190 * @param array|Traversable|Storage\Plugin\PluginOptions $options 191 * @return Storage\Plugin\PluginInterface 192 * @throws Exception\RuntimeException 193 */ 194 public static function pluginFactory($pluginName, $options = array()) 195 { 196 if ($pluginName instanceof Storage\Plugin\PluginInterface) { 197 // $pluginName is already a plugin object 198 $plugin = $pluginName; 199 } else { 200 $plugin = static::getPluginManager()->get($pluginName); 201 } 202 203 if (!$options instanceof Storage\Plugin\PluginOptions) { 204 $options = new Storage\Plugin\PluginOptions($options); 205 } 206 207 if ($options) { 208 $plugin->setOptions($options); 209 } 210 211 return $plugin; 212 } 213 214 /** 215 * Get the plugin manager 216 * 217 * @return Storage\PluginManager 218 */ 219 public static function getPluginManager() 220 { 221 if (static::$plugins === null) { 222 static::$plugins = new Storage\PluginManager(); 223 } 224 return static::$plugins; 225 } 226 227 /** 228 * Change the plugin manager 229 * 230 * @param Storage\PluginManager $plugins 231 * @return void 232 */ 233 public static function setPluginManager(Storage\PluginManager $plugins) 234 { 235 static::$plugins = $plugins; 236 } 237 238 /** 239 * Resets the internal plugin manager 240 * 241 * @return void 242 */ 243 public static function resetPluginManager() 244 { 245 static::$plugins = null; 246 } 247} 248