PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/zf2/vendor/Zend/Module/Listener/ConfigListener.php

http://github.com/eryx/php-framework-benchmark
PHP | 269 lines | 180 code | 27 blank | 62 comment | 19 complexity | 3a69589c1021d7b07e27982372969211 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  1. <?php
  2. namespace Zend\Module\Listener;
  3. use Traversable,
  4. Zend\Config\Config,
  5. Zend\Config\Xml as XmlConfig,
  6. Zend\Config\Ini as IniConfig,
  7. Zend\Config\Yaml as YamlConfig,
  8. Zend\Config\Json as JsonConfig,
  9. Zend\Module\ModuleEvent,
  10. Zend\Stdlib\IteratorToArray;
  11. class ConfigListener extends AbstractListener implements ConfigMerger
  12. {
  13. /**
  14. * @var array
  15. */
  16. protected $mergedConfig = array();
  17. /**
  18. * @var Config
  19. */
  20. protected $mergedConfigObject;
  21. /**
  22. * @var bool
  23. */
  24. protected $skipConfig = false;
  25. /**
  26. * @var array
  27. */
  28. protected $globPaths = array();
  29. /**
  30. * __construct
  31. *
  32. * @param ListenerOptions $options
  33. * @return void
  34. */
  35. public function __construct(ListenerOptions $options = null)
  36. {
  37. parent::__construct($options);
  38. if ($this->hasCachedConfig()) {
  39. $this->skipConfig = true;
  40. $this->setMergedConfig($this->getCachedConfig());
  41. }
  42. }
  43. public function __invoke(ModuleEvent $e)
  44. {
  45. if (true === $this->skipConfig) {
  46. return;
  47. }
  48. $module = $e->getModule();
  49. if (is_callable(array($module, 'getConfig'))) {
  50. $this->mergeModuleConfig($module);
  51. }
  52. }
  53. /**
  54. * getMergedConfig
  55. *
  56. * @param bool $returnConfigAsObject
  57. * @return mixed
  58. */
  59. public function getMergedConfig($returnConfigAsObject = true)
  60. {
  61. if ($returnConfigAsObject === true) {
  62. if ($this->mergedConfigObject === null) {
  63. $this->mergedConfigObject = new Config($this->mergedConfig);
  64. }
  65. return $this->mergedConfigObject;
  66. } else {
  67. return $this->mergedConfig;
  68. }
  69. }
  70. /**
  71. * setMergedConfig
  72. *
  73. * @param array $config
  74. * @return ConfigListener
  75. */
  76. public function setMergedConfig(array $config)
  77. {
  78. $this->mergedConfig = $config;
  79. $this->mergedConfigObject = null;
  80. return $this;
  81. }
  82. /**
  83. * Add a glob path of config files to merge after loading modules
  84. *
  85. * @param string $globPath
  86. * @return ConfigListener
  87. */
  88. public function addConfigGlobPath($globPath)
  89. {
  90. if (!is_string($globPath)) {
  91. throw new Exception\InvalidArgumentException(
  92. sprintf('Parameter to %s::%s() must be a string; %s given.',
  93. __CLASS__, __METHOD__, gettype($globPath))
  94. );
  95. }
  96. $this->globPaths[] = $globPath;
  97. return $this;
  98. }
  99. /**
  100. * Add an array of glob paths of config files to merge after loading modules
  101. *
  102. * @param mixed $globPaths
  103. * @return ConfigListener
  104. */
  105. public function addConfigGlobPaths($globPaths)
  106. {
  107. if ($globPaths instanceof Traversable) {
  108. $globPaths = IteratorToArray::convert($globPaths);
  109. }
  110. if (!is_array($globPaths)) {
  111. throw new Exception\InvalidArgumentException(
  112. sprintf('Argument passed to %::%s() must be an array, '
  113. . 'implement the \Traversable interface, or be an '
  114. . 'instance of Zend\Config\Config. %s given.',
  115. __CLASS__, __METHOD__, gettype($globPaths))
  116. );
  117. }
  118. foreach ($globPaths as $globPath) {
  119. $this->addConfigGlobPath($globPath);
  120. }
  121. return $this;
  122. }
  123. /**
  124. * Merge all config files matched by the given glob()s
  125. *
  126. * This should really only be called by the module manager.
  127. *
  128. * @return ConfigListener
  129. */
  130. public function mergeConfigGlobPaths()
  131. {
  132. foreach ($this->globPaths as $globPath) {
  133. $this->mergeGlobPath($globPath);
  134. }
  135. return $this;
  136. }
  137. /**
  138. * Merge all config files matching a glob
  139. *
  140. * @param mixed $globPath
  141. * @return ConfigListener
  142. */
  143. protected function mergeGlobPath($globPath)
  144. {
  145. foreach (glob($globPath, GLOB_BRACE) as $path) {
  146. $pathInfo = pathinfo($path);
  147. switch (strtolower($pathInfo['extension'])) {
  148. case 'php':
  149. case 'inc':
  150. $config = include $path;
  151. break;
  152. case 'xml':
  153. $config = new XmlConfig($path);
  154. break;
  155. case 'json':
  156. $config = new JsonConfig($path);
  157. break;
  158. case 'ini':
  159. $config = new IniConfig($path);
  160. break;
  161. case 'yaml':
  162. case 'yml':
  163. $config = new YamlConfig($path);
  164. break;
  165. default:
  166. throw new Exception\RuntimeException(sprintf(
  167. 'Unable to detect config file type by extension: %s',
  168. $path
  169. ));
  170. break;
  171. }
  172. $this->mergeTraversableConfig($config);
  173. }
  174. return $this;
  175. }
  176. /**
  177. * mergeModuleConfig
  178. *
  179. * @param mixed $module
  180. * @return ConfigListener
  181. */
  182. protected function mergeModuleConfig($module)
  183. {
  184. if ((false === $this->skipConfig)
  185. && (is_callable(array($module, 'getConfig')))
  186. ) {
  187. $config = $module->getConfig($this->getOptions()->getApplicationEnvironment());
  188. try {
  189. $this->mergeTraversableConfig($config);
  190. } catch (Exception\InvalidArgumentException $e) {
  191. // Throw a more descriptive exception
  192. throw new Exception\InvalidArgumentException(
  193. sprintf('getConfig() method of %s must be an array, '
  194. . 'implement the \Traversable interface, or be an '
  195. . 'instance of Zend\Config\Config. %s given.',
  196. get_class($module), gettype($config))
  197. );
  198. }
  199. if ($this->getOptions()->getConfigCacheEnabled()) {
  200. $this->updateCache();
  201. }
  202. }
  203. return $this;
  204. }
  205. protected function mergeTraversableConfig($config)
  206. {
  207. if ($config instanceof Traversable) {
  208. $config = IteratorToArray::convert($config);
  209. }
  210. if (!is_array($config)) {
  211. throw new Exception\InvalidArgumentException(
  212. sprintf('Config being merged must be an array, '
  213. . 'implement the \Traversable interface, or be an '
  214. . 'instance of Zend\Config\Config. %s given.', gettype($config))
  215. );
  216. }
  217. $this->setMergedConfig(array_replace_recursive($this->mergedConfig, $config));
  218. }
  219. protected function hasCachedConfig()
  220. {
  221. if (($this->getOptions()->getConfigCacheEnabled())
  222. && (file_exists($this->getOptions()->getConfigCacheFile()))
  223. ) {
  224. return true;
  225. }
  226. return false;
  227. }
  228. protected function getCachedConfig()
  229. {
  230. return include $this->getOptions()->getConfigCacheFile();
  231. }
  232. protected function updateCache()
  233. {
  234. if (($this->getOptions()->getConfigCacheEnabled())
  235. && (false === $this->skipConfig)
  236. ) {
  237. $configFile = $this->getOptions()->getConfigCacheFile();
  238. $this->writeArrayToFile($configFile, $this->getMergedConfig(false));
  239. }
  240. return $this;
  241. }
  242. }