TYPO3  7.6
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 
17 {
19  const TYPE_VALUE = 0x0001;
20 
22  const TYPE_INSTANCE = 0x0010;
23 
25  const TYPE_SHARED = 0x0100;
26 
28  const TYPE_ALIAS = 0x1000;
29 
31  private static $_instance = null;
32 
34  private $_store = array();
35 
37  private $_endPoint;
38 
44  public function __construct()
45  {
46  }
47 
53  public static function getInstance()
54  {
55  if (!isset(self::$_instance)) {
56  self::$_instance = new self();
57  }
58 
59  return self::$_instance;
60  }
61 
67  public function listItems()
68  {
69  return array_keys($this->_store);
70  }
71 
81  public function has($itemName)
82  {
83  return array_key_exists($itemName, $this->_store)
84  && isset($this->_store[$itemName]['lookupType']);
85  }
86 
98  public function lookup($itemName)
99  {
100  if (!$this->has($itemName)) {
101  throw new Swift_DependencyException(
102  'Cannot lookup dependency "'.$itemName.'" since it is not registered.'
103  );
104  }
105 
106  switch ($this->_store[$itemName]['lookupType']) {
107  case self::TYPE_ALIAS:
108  return $this->_createAlias($itemName);
109  case self::TYPE_VALUE:
110  return $this->_getValue($itemName);
111  case self::TYPE_INSTANCE:
112  return $this->_createNewInstance($itemName);
113  case self::TYPE_SHARED:
114  return $this->_createSharedInstance($itemName);
115  }
116  }
117 
125  public function createDependenciesFor($itemName)
126  {
127  $args = array();
128  if (isset($this->_store[$itemName]['args'])) {
129  $args = $this->_resolveArgs($this->_store[$itemName]['args']);
130  }
131 
132  return $args;
133  }
134 
148  public function register($itemName)
149  {
150  $this->_store[$itemName] = array();
151  $this->_endPoint = &$this->_store[$itemName];
152 
153  return $this;
154  }
155 
165  public function asValue($value)
166  {
167  $endPoint = &$this->_getEndPoint();
168  $endPoint['lookupType'] = self::TYPE_VALUE;
169  $endPoint['value'] = $value;
170 
171  return $this;
172  }
173 
181  public function asAliasOf($lookup)
182  {
183  $endPoint = &$this->_getEndPoint();
184  $endPoint['lookupType'] = self::TYPE_ALIAS;
185  $endPoint['ref'] = $lookup;
186 
187  return $this;
188  }
189 
203  public function asNewInstanceOf($className)
204  {
205  $endPoint = &$this->_getEndPoint();
206  $endPoint['lookupType'] = self::TYPE_INSTANCE;
207  $endPoint['className'] = $className;
208 
209  return $this;
210  }
211 
221  public function asSharedInstanceOf($className)
222  {
223  $endPoint = &$this->_getEndPoint();
224  $endPoint['lookupType'] = self::TYPE_SHARED;
225  $endPoint['className'] = $className;
226 
227  return $this;
228  }
229 
241  public function withDependencies(array $lookups)
242  {
243  $endPoint = &$this->_getEndPoint();
244  $endPoint['args'] = array();
245  foreach ($lookups as $lookup) {
246  $this->addConstructorLookup($lookup);
247  }
248 
249  return $this;
250  }
251 
262  public function addConstructorValue($value)
263  {
264  $endPoint = &$this->_getEndPoint();
265  if (!isset($endPoint['args'])) {
266  $endPoint['args'] = array();
267  }
268  $endPoint['args'][] = array('type' => 'value', 'item' => $value);
269 
270  return $this;
271  }
272 
283  public function addConstructorLookup($lookup)
284  {
285  $endPoint = &$this->_getEndPoint();
286  if (!isset($this->_endPoint['args'])) {
287  $endPoint['args'] = array();
288  }
289  $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup);
290 
291  return $this;
292  }
293 
295  private function _getValue($itemName)
296  {
297  return $this->_store[$itemName]['value'];
298  }
299 
301  private function _createAlias($itemName)
302  {
303  return $this->lookup($this->_store[$itemName]['ref']);
304  }
305 
307  private function _createNewInstance($itemName)
308  {
309  $reflector = new ReflectionClass($this->_store[$itemName]['className']);
310  if ($reflector->getConstructor()) {
311  return $reflector->newInstanceArgs(
312  $this->createDependenciesFor($itemName)
313  );
314  } else {
315  return $reflector->newInstance();
316  }
317  }
318 
320  private function _createSharedInstance($itemName)
321  {
322  if (!isset($this->_store[$itemName]['instance'])) {
323  $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName);
324  }
325 
326  return $this->_store[$itemName]['instance'];
327  }
328 
330  private function &_getEndPoint()
331  {
332  if (!isset($this->_endPoint)) {
333  throw new BadMethodCallException(
334  'Component must first be registered by calling register()'
335  );
336  }
337 
338  return $this->_endPoint;
339  }
340 
342  private function _resolveArgs(array $args)
343  {
344  $resolved = array();
345  foreach ($args as $argDefinition) {
346  switch ($argDefinition['type']) {
347  case 'lookup':
348  $resolved[] = $this->_lookupRecursive($argDefinition['item']);
349  break;
350  case 'value':
351  $resolved[] = $argDefinition['item'];
352  break;
353  }
354  }
355 
356  return $resolved;
357  }
358 
360  private function _lookupRecursive($item)
361  {
362  if (is_array($item)) {
363  $collection = array();
364  foreach ($item as $k => $v) {
365  $collection[$k] = $this->_lookupRecursive($v);
366  }
367 
368  return $collection;
369  } else {
370  return $this->lookup($item);
371  }
372  }
373 }