Passed
Branch dev (8b2306)
by Alex
02:48
created

Resource::translate()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 0
cts 11
cp 0
rs 8.8571
cc 6
eloc 9
nc 4
nop 1
crap 42
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
            } else {
93
                if ($action === "edit" && isset($translations["edit"])) {
94
                    $route->setPatternWithoutReset(str_replace("edit", $translations["edit"], $route->getPattern()));
95
                }
96
            }
97
        }
98
99
        return $this;
100
    }
101
102
    /**
103
     * Add a route or a group of routes to the resource, it means that
104
     * every added route will now receive the parameters of the resource, like id.
105
     *
106
     * @param Route|Group $route
107
     * @return self
108
     */
109
110
    public function member($route)
111
    {
112
        $resource = new Resource;
113
        $resource->set($route);
114
        $this->nest($resource);
115
    }
116
117
    /**
118
     * Nested routes capture the relation between a resource and another resource.
119
     *
120
     * @param Resource $resource
121
     * @return self
122
     */
123
124 3
    public function nest(Resource $resource)
125
    {
126
        /** @var self $resource */
127 3
        foreach ($this->routes as $route) {
128 3
            if ($route->getAction()[1] === "show") {
129 3
                $this->set($resource->forget()->setPrefix($this->getNestedPrefix($route->getPattern()))); break;
130
            }
131 3
        }
132
133 3
        return $this;
134
    }
135
136
    /**
137
     * Nest resources but with only build routes with the minimal amount of information
138
     * to uniquely identify the resource.
139
     *
140
     * @param Resource $resource
141
     * @return self
142
     */
143
144 1
    public function shallow(Resource $resource)
145
    {
146
        /** @var self $resource */
147 1
        $newResource = new Resource;
148 1
        $resource->forget();
149 1
        $routes = $resource->all();
150
151 1
        foreach ($routes as $route) {
152 1
            if (strpos("index make create", $route->getAction()[1]) !== false) {
153 1
                $newResource->set($route);
154 1
            }
155 1
        }
156
157 1
        return $this->nest($newResource);
158
    }
159
160
    /**
161
     * Resolve the nesting pattern, setting the prefixes based on
162
     * parent resources patterns.
163
     *
164
     * @param string $pattern
165
     * @return string
166
     */
167
168 3
    protected function getNestedPrefix($pattern)
169
    {
170 3
        $segments = explode("/", $pattern);
171 3
        $pattern = "";
172
173 3
        foreach ($segments as $index => $segment) {
174 3
            if (strpos($segment, "{") === 0) {
175 3
                   $pattern .= "/{" . $segments[$index - 1] . "_" . ltrim($segment, "{");
176 3
            } else $pattern .= $segment;
177 3
        }
178
179 3
        return $pattern;
180
    }
181
182
}
183