XOOPS RMCommon Utilities  2.1.8.91RC
 All Classes Namespaces Files Functions Variables
DependencyContainer.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of SwiftMailer.
5  * (c) 2004-2009 Chris Corbyn
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10 
11 //@require 'Swift/DependencyException.php';
12 
19 {
20 
22  const TYPE_VALUE = 0x0001;
23 
25  const TYPE_INSTANCE = 0x0010;
26 
28  const TYPE_SHARED = 0x0100;
29 
31  const TYPE_ALIAS = 0x1000;
32 
34  private static $_instance = null;
35 
37  private $_store = array();
38 
40  private $_endPoint;
41 
46  public function __construct() { }
47 
52  public static function getInstance()
53  {
54  if (!isset(self::$_instance))
55  {
56  self::$_instance = new self();
57  }
58  return self::$_instance;
59  }
60 
65  public function listItems()
66  {
67  return array_keys($this->_store);
68  }
69 
76  public function has($itemName)
77  {
78  return array_key_exists($itemName, $this->_store)
79  && isset($this->_store[$itemName]['lookupType']);
80  }
81 
89  public function lookup($itemName)
90  {
91  if (!$this->has($itemName))
92  {
93  throw new Swift_DependencyException(
94  'Cannot lookup dependency "' . $itemName . '" since it is not registered.'
95  );
96  }
97 
98  switch ($this->_store[$itemName]['lookupType'])
99  {
100  case self::TYPE_ALIAS:
101  return $this->_createAlias($itemName);
102  case self::TYPE_VALUE:
103  return $this->_getValue($itemName);
104  case self::TYPE_INSTANCE:
105  return $this->_createNewInstance($itemName);
106  case self::TYPE_SHARED:
107  return $this->_createSharedInstance($itemName);
108  }
109  }
110 
116  public function createDependenciesFor($itemName)
117  {
118  $args = array();
119  if (isset($this->_store[$itemName]['args']))
120  {
121  $args = $this->_resolveArgs($this->_store[$itemName]['args']);
122  }
123  return $args;
124  }
125 
136  public function register($itemName)
137  {
138  $this->_store[$itemName] = array();
139  $this->_endPoint =& $this->_store[$itemName];
140  return $this;
141  }
142 
150  public function asValue($value)
151  {
152  $endPoint =& $this->_getEndPoint();
153  $endPoint['lookupType'] = self::TYPE_VALUE;
154  $endPoint['value'] = $value;
155  return $this;
156  }
157 
163  public function asAliasOf($lookup)
164  {
165  $endPoint =& $this->_getEndPoint();
166  $endPoint['lookupType'] = self::TYPE_ALIAS;
167  $endPoint['ref'] = $lookup;
168  return $this;
169  }
170 
181  public function asNewInstanceOf($className)
182  {
183  $endPoint =& $this->_getEndPoint();
184  $endPoint['lookupType'] = self::TYPE_INSTANCE;
185  $endPoint['className'] = $className;
186  return $this;
187  }
188 
195  public function asSharedInstanceOf($className)
196  {
197  $endPoint =& $this->_getEndPoint();
198  $endPoint['lookupType'] = self::TYPE_SHARED;
199  $endPoint['className'] = $className;
200  return $this;
201  }
202 
211  public function withDependencies(array $lookups)
212  {
213  $endPoint =& $this->_getEndPoint();
214  $endPoint['args'] = array();
215  foreach ($lookups as $lookup)
216  {
217  $this->addConstructorLookup($lookup);
218  }
219  return $this;
220  }
221 
230  public function addConstructorValue($value)
231  {
232  $endPoint =& $this->_getEndPoint();
233  if (!isset($endPoint['args']))
234  {
235  $endPoint['args'] = array();
236  }
237  $endPoint['args'][] = array('type' => 'value', 'item' => $value);
238  return $this;
239  }
240 
249  public function addConstructorLookup($lookup)
250  {
251  $endPoint =& $this->_getEndPoint();
252  if (!isset($this->_endPoint['args']))
253  {
254  $endPoint['args'] = array();
255  }
256  $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup);
257  return $this;
258  }
259 
260  // -- Private methods
261 
263  private function _getValue($itemName)
264  {
265  return $this->_store[$itemName]['value'];
266  }
267 
269  private function _createAlias($itemName)
270  {
271  return $this->lookup($this->_store[$itemName]['ref']);
272  }
273 
275  private function _createNewInstance($itemName)
276  {
277  $reflector = new ReflectionClass($this->_store[$itemName]['className']);
278  if ($reflector->getConstructor())
279  {
280  return $reflector->newInstanceArgs(
281  $this->createDependenciesFor($itemName)
282  );
283  }
284  else
285  {
286  return $reflector->newInstance();
287  }
288  }
289 
291  private function _createSharedInstance($itemName)
292  {
293  if (!isset($this->_store[$itemName]['instance']))
294  {
295  $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName);
296  }
297  return $this->_store[$itemName]['instance'];
298  }
299 
301  private function &_getEndPoint()
302  {
303  if (!isset($this->_endPoint))
304  {
305  throw new BadMethodCallException(
306  'Component must first be registered by calling register()'
307  );
308  }
309  return $this->_endPoint;
310  }
311 
313  private function _resolveArgs(array $args)
314  {
315  $resolved = array();
316  foreach ($args as $argDefinition)
317  {
318  switch ($argDefinition['type'])
319  {
320  case 'lookup':
321  $resolved[] = $this->_lookupRecursive($argDefinition['item']);
322  break;
323  case 'value':
324  $resolved[] = $argDefinition['item'];
325  break;
326  }
327  }
328  return $resolved;
329  }
330 
332  private function _lookupRecursive($item)
333  {
334  if (is_array($item))
335  {
336  $collection = array();
337  foreach ($item as $k => $v)
338  {
339  $collection[$k] = $this->_lookupRecursive($v);
340  }
341  return $collection;
342  }
343  else
344  {
345  return $this->lookup($item);
346  }
347  }
348 
349 }