RouteCollection::mergeSubCollection()   B
last analyzed

Complexity

Conditions 6
Paths 17

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
c 0
b 0
f 0
rs 8.5125
cc 6
eloc 17
nc 17
nop 2
1
<?php
2
/**
3
 * slince routing library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\Routing;
7
8
class RouteCollection implements \Countable, \IteratorAggregate
9
{
10
    use RouteBuilderTrait;
11
12
    /**
13
     * Array of routes
14
     * @var Route[]
15
     */
16
    protected $routes = [];
17
18
    /**
19
     * Array of route names
20
     * @var Route[]
21
     */
22
    protected $names = [];
23
24
    /**
25
     * Array of route actions
26
     * @var Route[]
27
     */
28
    protected $actions = [];
29
30
    protected static $defaultOptions = [
31
        'prefix' => null,
32
        'host' => null,
33
        'methods' => [],
34
        'schemes' => [],
35
        'requirements' => [],
36
        'defaults' => []
37
    ];
38
39
    public function __construct(array $routes = [])
40
    {
41
        foreach ($routes as $route) {
42
            $this->add($route);
43
        }
44
    }
45
46
    /**
47
     * Add a route to the collection
48
     * @param Route $route
49
     */
50
    public function add(Route $route)
51
    {
52
        if ($route->getName()) {
53
            $this->names[$route->getName()] = $route;
54
        }
55
        $action = $route->getAction();
56
        if (is_scalar($action)) {
57
            $this->actions[$action] = $route;
58
        }
59
        $this->routes[] = $route;
60
    }
61
62
    /**
63
     * Finds the route by the given name
64
     * @param string $name
65
     * @return Route|null
66
     */
67
    public function getByName($name)
68
    {
69
        return isset($this->names[$name]) ? $this->names[$name] : null;
70
    }
71
72
    /**
73
     * Finds the route by the given action
74
     * @param string $action
75
     * @return Route|null
76
     */
77
    public function getByAction($action)
78
    {
79
        return isset($this->actions[$action]) ? $this->actions[$action] : null;
80
    }
81
82
    /**
83
     * Gets all named routes
84
     * @return Route[]
85
     */
86
    public function getNamedRoutes()
87
    {
88
        return $this->names;
89
    }
90
91
    /**
92
     * Creates a sub collection routes
93
     * @param string|array $options
94
     * @param \Closure $callback
95
     */
96
    public function group($options, \Closure $callback)
97
    {
98
        if (is_string($options)) {
99
            $options = ['prefix' => $options];
100
        }
101
        $collection = new RouteCollection([]);
102
        call_user_func($callback, $collection);
103
        $this->mergeSubCollection($collection, $options);
104
    }
105
106
    /**
107
     * Merges routes from an route collection
108
     * @param RouteCollection $collection
109
     * @param array $options
110
     */
111
    protected function mergeSubCollection(RouteCollection $collection, $options = [])
112
    {
113
        $extraParameters = array_diff_key($options, static::$defaultOptions);
114
        $options = array_replace(static::$defaultOptions, $options);
115
        foreach ($collection->all() as $route) {
116
            if ($options['prefix']) {
117
                $path =  trim($options['prefix'], '/') . '/' . trim($route->getPath(), '/');
118
                $route->setPath($path);
119
            }
120
            if (!$route->getHost()) {
121
                $route->setHost($options['host']);
122
            }
123
            if (!$route->getMethods()) {
124
                $route->setMethods((array)$options['methods']);
125
            }
126
            if (!$route->getSchemes()) {
127
                $route->setSchemes((array)$options['schemes']);
128
            }
129
            $route->addRequirements($options['requirements']);
130
            $route->addDefaults($options['defaults']);
131
            $route->addParameters($extraParameters);
132
            $this->add($route);
133
        }
134
    }
135
136
    /**
137
     * Gets all routes
138
     * @return Route[]
139
     */
140
    public function all()
141
    {
142
        return $this->routes;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function count()
149
    {
150
        return count($this->routes);
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function getIterator()
157
    {
158
        return new \ArrayIterator($this->routes);
159
    }
160
}