LazyRouteCollection::__construct()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
rs 8.5125
cc 5
eloc 14
nc 4
nop 2
1
<?php
2
/**
3
 * Dash
4
 *
5
 * @link      http://github.com/DASPRiD/Dash For the canonical source repository
6
 * @copyright 2013-2015 Ben Scholzen 'DASPRiD'
7
 * @license   http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
 */
9
10
namespace Dash\RouteCollection;
11
12
use Dash\Exception;
13
use Dash\Route\RouteInterface;
14
use Dash\Route\RouteManager;
15
use IteratorAggregate;
16
17
/**
18
 * Lazy route collection which only instantiates routes when required.
19
 */
20
class LazyRouteCollection implements IteratorAggregate, RouteCollectionInterface
21
{
22
    /**
23
     * @var RouteManager
24
     */
25
    protected $routeManager;
26
27
    /**
28
     * @var array
29
     */
30
    protected $routes = [];
31
32
    /**
33
     * @param RouteManager $routeManager
34
     * @param array[]      $routes
35
     */
36
    public function __construct(RouteManager $routeManager, array $routes)
37
    {
38
        $this->routeManager = $routeManager;
39
        $serial = 0;
40
41
        foreach ($routes as $name => $route) {
42
            if (!is_array($route)) {
43
                throw new Exception\UnexpectedValueException(sprintf(
44
                    'Route definition must be an array, %s given',
45
                    is_object($route) ? get_class($route) : gettype($route)
46
                ));
47
            }
48
49
            $this->routes[$name] = [
50
                'priority' => isset($route['priority']) ? $route['priority'] : 1,
51
                'serial'   => ++$serial,
52
                'options'  => $route,
53
                'instance' => null,
54
            ];
55
        }
56
57
        // Note: the order of the elements in the array is important for the sorting to work, do not change it!
58
        arsort($this->routes);
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function get($name)
65
    {
66
        if (!isset($this->routes[$name])) {
67
            throw new Exception\OutOfBoundsException(sprintf('Route with name "%s" was not found', $name));
68
        }
69
70
        return $this->getInstance($name);
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function getIterator()
77
    {
78
        foreach ($this->routes as $name => $route) {
79
            yield $name => $this->getInstance($name);
80
        }
81
    }
82
83
    /**
84
     * Returns an instance of a given route.
85
     *
86
     * We do not validate the existence of the route here again, as it is supposed to be checked by the calling method.
87
     *
88
     * @param  string $name
89
     * @return RouteInterface
90
     */
91
    protected function getInstance($name)
92
    {
93
        $route = &$this->routes[$name];
94
95
        if (null === $route['instance']) {
96
            $route['instance'] = $this->routeManager->build(
97
                !isset($route['options']['type']) ? 'Generic' : $route['options']['type'],
98
                $route['options']
99
            );
100
        }
101
102
        return $route['instance'];
103
    }
104
}
105