Scope::scopify()   B
last analyzed

Complexity

Conditions 7
Paths 36

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 7

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 11
c 3
b 0
f 0
dl 0
loc 22
ccs 7
cts 7
cp 1
rs 8.8333
cc 7
nc 36
nop 1
crap 7
1
<?php
2
declare(strict_types=1);
3
4
namespace Lead\Router;
5
6
/**
7
 * Scope
8
 */
9
class Scope implements ScopeInterface
10
{
11
    /**
12
     * The router instance.
13
     *
14
     * @var object
15
     */
16
    protected $_router = null;
17
18
    /**
19
     * The parent instance.
20
     *
21
     * @var object
22
     */
23
    protected $_parent = null;
24
25
    /**
26
     * The middleware array.
27
     *
28
     * @var array
29
     */
30
    protected $_middleware = [];
31
32
    /**
33
     * The scope data.
34
     *
35
     * @var array
36
     */
37
    protected $_scope = [];
38
39
    /**
40
     * The constructor.
41
     *
42
     * @param array $config The config array.
43
     */
44
    public function __construct($config = [])
45
    {
46
        $defaults = [
47
            'router' => null,
48
            'parent' => null,
49
            'middleware' => [],
50
            'scope'  => []
51 56
        ];
52 56
        $config += $defaults;
53
54 56
        $this->_router = $config['router'];
55 56
        $this->_parent = $config['parent'];
56 56
        $this->_middleware = $config['middleware'];
57
        $this->_scope = $config['scope'] + [
58
            'name'           => '',
59
            'scheme'         => '*',
60
            'host'           => '*',
61
            'methods'        => '*',
62
            'prefix'         => '',
63
            'namespace'      => '',
64
            'persist'        => []
65 56
        ];
66
    }
67
68
    /**
69
     * Creates a new sub scope based on the instance scope.
70
     *
71
     * @param  array $options The route options to scopify.
72
     * @return $this          The new sub scope.
73
     */
74
    public function seed(array $options): ScopeInterface
75
    {
76
        return new static(
77
            [
78
            'router' => $this->_router,
79
            'parent' => $this,
80
            'scope'  => $this->scopify($options)
81
            ]
82 16
        );
83
    }
84
85
    /**
86
     * Scopes an options array according to the instance scope data.
87
     *
88
     * @param  array $options The options to scope.
89
     * @return array          The scoped options.
90
     */
91
    public function scopify(array $options): array
92
    {
93 45
        $scope = $this->_scope;
94
95
        if (!empty($options['name'])) {
96 10
            $options['name'] = $scope['name'] ? $scope['name'] . '.' . $options['name'] : $options['name'];
97
        }
98
99
        if (!empty($options['prefix'])) {
100 15
            $options['prefix'] = $scope['prefix'] . trim($options['prefix'], '/');
101 15
            $options['prefix'] = $options['prefix'] ? $options['prefix'] . '/' : '';
102
        }
103
104
        if (isset($options['persist'])) {
105 2
            $options['persist'] = ((array) $options['persist']) + $scope['persist'];
106
        }
107
108
        if (isset($options['namespace'])) {
109 1
            $options['namespace'] = $scope['namespace'] . trim($options['namespace'], '\\') . '\\';
110
        }
111
112 45
        return $options + $scope;
113
    }
114
115
    /**
116
     * Middleware generator.
117
     *
118
     * @return callable
119
     */
120
    public function middleware()
121
    {
122
        foreach ($this->_middleware as $middleware) {
123 3
            yield $middleware;
0 ignored issues
show
Bug Best Practice introduced by
The expression yield $middleware returns the type Generator which is incompatible with the documented return type callable.
Loading history...
124
        }
125
        if ($this->_parent) {
126
            foreach ($this->_parent->middleware() as $middleware) {
127 1
                yield $middleware;
128
            }
129
        }
130
    }
131
132
    /**
133
     * Adds a middleware to the list of middleware
134
     *
135
     * @param object|\Closure A callable middleware
0 ignored issues
show
Bug introduced by
The type Lead\Router\A was not found. Did you mean A? If so, make sure to prefix the type with \.
Loading history...
136
     * @return \Lead\Router\ScopeInterface
137
     */
138
    public function apply($middleware): ScopeInterface
139
    {
140
        foreach (func_get_args() as $mw) {
141 3
            array_unshift($this->_middleware, $mw);
142
        }
143
144 3
        return $this;
145
    }
146
147
    /**
148
     * Delegates calls to the router instance
149
     *
150
     * @param string $name The method name
151
     * @param array $params The parameters
152
     * @return mixed
153
     */
154
    public function __call(string $name, array $params)
155
    {
156 1
        $this->_router->pushScope($this);
157 1
        $result = call_user_func_array([$this->_router, $name], $params);
158 1
        $this->_router->popScope();
159
160 1
        return $result;
161
    }
162
}
163