Passed
Branch dev (473855)
by Alex
02:25
created

Resource   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 69.64%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 22
c 1
b 0
f 0
lcom 1
cbo 2
dl 0
loc 161
ccs 39
cts 56
cp 0.6964
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setMethod() 0 4 1
A only() 0 5 1
A except() 0 5 1
A filterByMethod() 0 10 3
B translate() 0 15 6
A member() 0 6 1
A nest() 0 11 3
A shallow() 0 15 3
A getNestedPrefix() 0 13 3
1
<?php
2
3
/**
4
 * Codeburner Framework.
5
 *
6
 * @author Alex Rohleder <[email protected]>
7
 * @copyright 2016 Alex Rohleder
8
 * @license http://opensource.org/licenses/MIT
9
 */
10
11
namespace Codeburner\Router;
12
13
/**
14
 * Representation of a group of several routes with same
15
 * controller and respecting the resourceful actions.
16
 *
17
 * @author Alex Rohleder <[email protected]>
18
 */
19
20
class Resource extends Group
21
{
22
23
    /**
24
     * @inheritdoc
25
     * @throws \BadMethodCallException
26
     */
27
28
    public function setMethod($method)
29
    {
30
        throw new \BadMethodCallException("Resources can't chance they http method.");
31
    }
32
33
    /**
34
     * Remove the routes without the passed methods.
35
     *
36
     * @param string|array $methods
37
     * @return self
38
     */
39
40 1
    public function only($methods)
41
    {
42 1
        $this->filterByMethod((array) $methods, false);
43 1
        return $this;
44
    }
45
46
    /**
47
     * Remove the routes with the passed methods.
48
     *
49
     * @param string|array $methods
50
     * @return self
51
     */
52
53 1
    public function except($methods)
54
    {
55 1
        $this->filterByMethod((array) $methods, true);
56 1
        return $this;
57
    }
58
59
    /**
60
     * Forget the grouped routes filtering by http methods.
61
     *
62
     * @param array $methods
63
     * @param bool $alt Should remove?
64
     */
65
66 2
    private function filterByMethod(array $methods, $alt)
67
    {
68 2
        $methods = array_flip(array_map('strtolower', $methods));
69
70 2
        foreach ($this->routes as $route) {
71 2
            if (isset($methods[$route->getAction()[1]]) === $alt) {
72 2
                $route->forget();
73 2
            }
74 2
        }
75 2
    }
76
77
    /**
78
     * Translate the "make" or "edit" from resources path.
79
     *
80
     * @param string[] $translations
81
     * @return self
82
     */
83
84
    public function translate(array $translations)
85
    {
86
        /** @var Route $route */
87
        foreach ($this->routes as $route) {
88
            $action = $route->getAction()[1];
89
90
            if ($action === "make" && isset($translations["make"])) {
91
                $route->setPatternWithoutReset(str_replace("make", $translations["make"], $route->getPattern()));
92
            } elseif ($action === "edit" && isset($translations["edit"])) {
93
                $route->setPatternWithoutReset(str_replace("edit", $translations["edit"], $route->getPattern()));
94
            }
95
        }
96
97
        return $this;
98
    }
99
100
    /**
101
     * Add a route or a group of routes to the resource, it means that
102
     * every added route will now receive the parameters of the resource, like id.
103
     *
104
     * @param Route|Group $route
105
     * @return self
106
     */
107
108
    public function member($route)
109
    {
110
        $resource = new Resource;
111
        $resource->set($route);
112
        $this->nest($resource);
113
    }
114
115
    /**
116
     * Nested routes capture the relation between a resource and another resource.
117
     *
118
     * @param Resource $resource
119
     * @return self
120
     */
121
122 3
    public function nest(Resource $resource)
123
    {
124
        /** @var self $resource */
125 3
        foreach ($this->routes as $route) {
126 3
            if ($route->getAction()[1] === "show") {
127 3
                $this->set($resource->forget()->setPrefix($this->getNestedPrefix($route->getPattern()))); break;
128
            }
129 3
        }
130
131 3
        return $this;
132
    }
133
134
    /**
135
     * Nest resources but with only build routes with the minimal amount of information
136
     * to uniquely identify the resource.
137
     *
138
     * @param Resource $resource
139
     * @return self
140
     */
141
142 1
    public function shallow(Resource $resource)
143
    {
144
        /** @var self $resource */
145 1
        $newResource = new Resource;
146 1
        $resource->forget();
147 1
        $routes = $resource->all();
148
149 1
        foreach ($routes as $route) {
150 1
            if (strpos("index make create", $route->getAction()[1]) !== false) {
151 1
                $newResource->set($route);
152 1
            }
153 1
        }
154
155 1
        return $this->nest($newResource);
156
    }
157
158
    /**
159
     * Resolve the nesting pattern, setting the prefixes based on
160
     * parent resources patterns.
161
     *
162
     * @param string $pattern
163
     * @return string
164
     */
165
166 3
    protected function getNestedPrefix($pattern)
167
    {
168 3
        $segments = explode("/", $pattern);
169 3
        $pattern = "";
170
171 3
        foreach ($segments as $index => $segment) {
172 3
            if (strpos($segment, "{") === 0) {
173 3
                   $pattern .= "/{" . $segments[$index - 1] . "_" . ltrim($segment, "{");
174 3
            } else $pattern .= $segment;
175 3
        }
176
177 3
        return $pattern;
178
    }
179
180
}
181