PageRenderTime 60ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Pyrus/ChannelRegistry.php

https://github.com/saltybeagle/Pyrus
PHP | 252 lines | 189 code | 20 blank | 43 comment | 8 complexity | fc9a32f1c2186df24bcdb13a28f8b828 MD5 | raw file
  1. <?php
  2. /**
  3. * \Pyrus\ChannelRegistry
  4. *
  5. * PHP version 5
  6. *
  7. * @category Pyrus
  8. * @package Pyrus
  9. * @author Greg Beaver <cellog@php.net>
  10. * @copyright 2010 The PEAR Group
  11. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  12. * @link https://github.com/pyrus/Pyrus
  13. */
  14. /**
  15. * Base class for Pyrus.
  16. *
  17. * @category Pyrus
  18. * @package Pyrus
  19. * @author Greg Beaver <cellog@php.net>
  20. * @copyright 2010 The PEAR Group
  21. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  22. * @link https://github.com/pyrus/Pyrus
  23. */
  24. namespace Pyrus;
  25. class ChannelRegistry implements \ArrayAccess, \IteratorAggregate, \Pyrus\ChannelRegistryInterface
  26. {
  27. /**
  28. * Class to instantiate for singleton.
  29. *
  30. * This is useful for unit-testing and for extending the registry
  31. * @var string
  32. */
  33. static public $className = 'Pyrus\ChannelRegistry';
  34. /**
  35. * The parent registry
  36. *
  37. * This is used to implement cascading registries
  38. * @var \Pyrus\ChannelRegistry
  39. */
  40. protected $parent;
  41. protected $path;
  42. protected $readonly;
  43. private $_registries = array();
  44. public function __construct($path, $registries = array('Sqlite3', 'Xml'), $readonly = false)
  45. {
  46. $this->path = $path;
  47. $this->readonly = $readonly;
  48. $exceptions = new \PEAR2\MultiErrors;
  49. foreach ($registries as $registry) {
  50. try {
  51. $registry = ucfirst($registry);
  52. $registry = 'Pyrus\ChannelRegistry\\' . $registry;
  53. if (!class_exists($registry, true)) {
  54. $exceptions->E_ERROR[] = new ChannelRegistry\Exception(
  55. 'Unknown channel registry type: ' . $registry);
  56. continue;
  57. }
  58. $this->_registries[] = new $registry($path, $readonly);
  59. } catch (ChannelRegistry\Exception $e) {
  60. $exceptions->E_ERROR[] = $e;
  61. } catch (Registry\Exception $e) {
  62. $exceptions->E_ERROR[] = $e;
  63. }
  64. }
  65. if (!count($this->_registries)) {
  66. throw new ChannelRegistry\Exception(
  67. 'Unable to initialize registry for path "' . $path . '"',
  68. $exceptions);
  69. }
  70. }
  71. public function setParent(ChannelRegistry $parent = null)
  72. {
  73. $this->parent = $parent;
  74. }
  75. /**
  76. * Add a channel to the registry.
  77. *
  78. * @param \Pyrus\ChannelInterface $channel Channel to add.
  79. */
  80. public function add(ChannelInterface $channel, $update = false, $lastmodified = false)
  81. {
  82. if ($this->readonly) {
  83. throw new ChannelRegistry\Exception('Cannot add channel, registry is read-only');
  84. }
  85. foreach ($this->_registries as $reg) {
  86. $reg->add($channel, $update, $lastmodified);
  87. }
  88. }
  89. public function update(ChannelInterface $channel)
  90. {
  91. if ($this->readonly) {
  92. throw new ChannelRegistry\Exception('Cannot update channel, registry is read-only');
  93. }
  94. foreach ($this->_registries as $reg) {
  95. $reg->update($channel);
  96. }
  97. }
  98. public function delete(ChannelInterface $channel)
  99. {
  100. if ($this->readonly) {
  101. throw new ChannelRegistry\Exception('Cannot delete channel, registry is read-only');
  102. }
  103. if (in_array($channel->name, $this->_registries[0]->getDefaultChannels())) {
  104. throw new ChannelRegistry\Exception('Cannot delete default channel ' .
  105. $channel->name);
  106. }
  107. foreach ($this->_registries as $reg) {
  108. $reg->delete($channel);
  109. }
  110. }
  111. public function get($channel, $strict = true)
  112. {
  113. try {
  114. return $this->_registries[0]->get($channel, $strict);
  115. } catch (\Exception $e) {
  116. // don't fail on the default channels, these should always exist
  117. switch ($channel) {
  118. case 'pyrus.net' :
  119. return $this->_registries[0]->getPyrusChannel();
  120. case 'pear.php.net' :
  121. return $this->_registries[0]->getPearChannel();
  122. case 'pear2.php.net' :
  123. return $this->_registries[0]->getPear2Channel();
  124. case 'pecl.php.net' :
  125. return $this->_registries[0]->getPeclChannel();
  126. case 'doc.php.net' :
  127. return $this->_registries[0]->getDocChannel();
  128. case '__uri' :
  129. return $this->_registries[0]->getUriChannel();
  130. }
  131. throw $e;
  132. }
  133. }
  134. /**
  135. * Check if channel has been discovered and in the registry.
  136. *
  137. * @param string $channel Channel name or alias: pear.php.net, pear
  138. * @param bool $strict Do not check aliases.
  139. *
  140. * @return bool
  141. */
  142. public function exists($channel, $strict = true)
  143. {
  144. $status = $this->_registries[0]->exists($channel, $strict);
  145. if (is_bool($status)) {
  146. return $status;
  147. }
  148. if (1 === $status) {
  149. return true;
  150. }
  151. return false;
  152. }
  153. public function parseName($name, $defaultChannel = 'pear2.php.net')
  154. {
  155. foreach ($this->_registries as $reg) {
  156. try {
  157. return $reg->parseName($name, $defaultChannel);
  158. } catch (\Exception $e) {
  159. continue;
  160. }
  161. }
  162. if ($this->parent) {
  163. return $this->parent->parseName($name, $defaultChannel);
  164. }
  165. // recycle last exception
  166. throw new ChannelRegistry\Exception('Unable to process package name', $e);
  167. }
  168. public function parsedNameToString($name, $brief = false)
  169. {
  170. return $this->_registries[0]->parsedNameToString($name, $brief);
  171. }
  172. public function listChannels()
  173. {
  174. return $this->_registries[0]->listChannels();
  175. }
  176. public function offsetGet($offset)
  177. {
  178. return $this->get($offset, false);
  179. }
  180. public function offsetSet($offset, $value)
  181. {
  182. if ($this->readonly) {
  183. throw new ChannelRegistry\Exception('Cannot add channel, registry is read-only');
  184. }
  185. if ($value instanceof ChannelFileInterface) {
  186. $value = new Channel($value);
  187. }
  188. foreach ($this->_registries as $reg) {
  189. $reg->add($value);
  190. }
  191. }
  192. public function offsetExists($offset)
  193. {
  194. return $this->exists($offset);
  195. }
  196. public function offsetUnset($offset)
  197. {
  198. if ($this->readonly) {
  199. throw new ChannelRegistry\Exception('Cannot delete channel, registry is read-only');
  200. }
  201. $chan = $this->get($offset, false);
  202. foreach ($this->_registries as $reg) {
  203. $reg->delete($chan);
  204. }
  205. }
  206. public function __call($method, $args)
  207. {
  208. return call_user_func_array(array($this->_registries[0], $method), $args);
  209. }
  210. public function getIterator()
  211. {
  212. return $this->_registries[0];
  213. }
  214. public function getParent()
  215. {
  216. return $this->parent;
  217. }
  218. public function getPath()
  219. {
  220. return $this->path;
  221. }
  222. }