Completed
Push — master ( 415036...2a370b )
by Patrick
06:47
created

ResourceRegistrar::addResourceDestroy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 4
crap 1
1
<?php
2
3
namespace ShiftOneLabs\SingularResourceRoutes;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Routing\ResourceRegistrar as BaseResourceRegistrar;
7
8
class ResourceRegistrar extends BaseResourceRegistrar
9
{
10
    /**
11
     * The default actions for a singular resourceful controller.
12
     *
13
     * @var array
14
     */
15
    protected $singularResourceDefaults = ['create', 'store', 'show', 'edit', 'update', 'destroy'];
16
17
    /**
18
     * The resources to treat as singular.
19
     *
20
     * @var array
21
     */
22
    protected $singularResources = [];
23
24
    /**
25
     * Route a resource to a controller.
26
     *
27
     * @param  string  $name
28
     * @param  string  $controller
29
     * @param  array  $options
30
     *
31
     * @return void
32
     */
33 15
    public function register($name, $controller, array $options = [])
34
    {
35 15
        if (isset($options['parameters']) && !isset($this->parameters)) {
36 5
            $this->parameters = $options['parameters'];
37 2
        }
38
39
        // If the resource name contains a slash, we will assume the developer wishes to
40
        // register these resource routes with a prefix so we will set that up out of
41
        // the box so they don't have to mess with it. Otherwise, we will continue.
42 15
        if (Str::contains($name, '/')) {
43 5
            $this->prefixedResource($name, $controller, $options);
44
45 5
            return;
46
        }
47
48 15
        $resources = explode('.', $name);
49
50
        // If the singular option is set, we need to determine which resources are meant
51
        // to be singular resources. If set to true, then only the last resource will
52
        // be singular, otherwise intersect all resources with the given resources.
53 15
        if (!empty($options['singular'])) {
54 5
            $singular = $options['singular'];
55 5
            $this->singularResources = array_intersect(
56 5
                $resources,
57 5
                $singular === true ? [last($resources)] : (!is_array($singular) ? [$singular] : $singular)
58 2
            );
59 2
        }
60
61
        // We need to extract the base resource from the resource name. Nested resources
62
        // are supported in the framework, but we need to know what name to use for a
63
        // place-holder on the route parameters, which should be the base resources.
64 15
        $base = $this->getResourceWildcard(last($resources));
65
66 15
        $defaults = $this->getResourceDefaults(last($resources));
67
68 15
        foreach ($this->getResourceMethods($defaults, $options) as $m) {
69 15
            $this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
70 6
        }
71 15
    }
72
73
    /**
74
     * Get the default resource methods defaults for the given resource.
75
     *
76
     * @param  string  $resource
77
     *
78
     * @return array
79
     */
80 15
    protected function getResourceDefaults($resource)
81
    {
82 15
        if (in_array($resource, $this->singularResources)) {
83 5
            return $this->singularResourceDefaults;
84
        }
85
86 15
        return $this->resourceDefaults;
87
    }
88
89
    /**
90
     * Add the show method for a resourceful route.
91
     *
92
     * @param  string  $name
93
     * @param  string  $base
94
     * @param  string  $controller
95
     * @param  array  $options
96
     *
97
     * @return \Illuminate\Routing\Route
98
     */
99 15
    protected function addResourceShow($name, $base, $controller, $options)
100
    {
101 15
        $uri = $this->getResourceUri($name).$this->getResourceUriParameter($base);
102
103 15
        $action = $this->getResourceAction($name, $controller, 'show', $options);
104
105 15
        return $this->router->get($uri, $action);
106
    }
107
108
    /**
109
     * Add the edit method for a resourceful route.
110
     *
111
     * @param  string  $name
112
     * @param  string  $base
113
     * @param  string  $controller
114
     * @param  array  $options
115
     *
116
     * @return \Illuminate\Routing\Route
117
     */
118 15
    protected function addResourceEdit($name, $base, $controller, $options)
119
    {
120 15
        $uri = $this->getResourceUri($name).$this->getResourceUriParameter($base).'/'.$this->getVerb('edit');
121
122 15
        $action = $this->getResourceAction($name, $controller, 'edit', $options);
123
124 15
        return $this->router->get($uri, $action);
125
    }
126
127
    /**
128
     * Add the update method for a resourceful route.
129
     *
130
     * @param  string  $name
131
     * @param  string  $base
132
     * @param  string  $controller
133
     * @param  array  $options
134
     *
135
     * @return \Illuminate\Routing\Route
136
     */
137 15
    protected function addResourceUpdate($name, $base, $controller, $options)
138
    {
139 15
        $uri = $this->getResourceUri($name).$this->getResourceUriParameter($base);
140
141 15
        $action = $this->getResourceAction($name, $controller, 'update', $options);
142
143 15
        return $this->router->match(['PUT', 'PATCH'], $uri, $action);
144
    }
145
146
    /**
147
     * Add the destroy method for a resourceful route.
148
     *
149
     * @param  string  $name
150
     * @param  string  $base
151
     * @param  string  $controller
152
     * @param  array  $options
153
     *
154
     * @return \Illuminate\Routing\Route
155
     */
156 15
    protected function addResourceDestroy($name, $base, $controller, $options)
157
    {
158 15
        $uri = $this->getResourceUri($name).$this->getResourceUriParameter($base);
159
160 15
        $action = $this->getResourceAction($name, $controller, 'destroy', $options);
161
162 15
        return $this->router->delete($uri, $action);
163
    }
164
165
    /**
166
     * Get the URI for a nested resource segment array.
167
     *
168
     * @param  array  $segments
169
     *
170
     * @return string
171
     */
172
    protected function getNestedResourceUri(array $segments)
173
    {
174
        // We will spin through the segments and create a place-holder for each of the
175
        // resource segments, as well as the resource itself. Then we should get an
176
        // entire string for the resource URI that contains all nested resources.
177 15
        return implode('/', array_map(function ($s) {
178 15
            return $s.$this->getResourceUriParameter($this->getResourceWildcard($s));
179 15
        }, $segments));
180
    }
181
182
    /**
183
     * Format a resource parameter for usage.
184
     *
185
     * @param  string  $value
186
     *
187
     * @return string|null
188
     */
189 15
    public function getResourceWildcard($value)
190
    {
191 15
        if (in_array($value, $this->singularResources)) {
192 5
            return;
193
        }
194
195
        // parameters/parameterMap properties do not exist until 5.2.20
196 15
        if (property_exists($this, 'parameters')) {
197 15
            if (isset($this->parameters[$value])) {
198 5
                $value = $this->parameters[$value];
199 15
            } elseif (isset(static::$parameterMap[$value])) {
200 5
                $value = static::$parameterMap[$value];
201 15
            } elseif ($this->parameters === 'singular' || static::$singularParameters) {
202 15
                $value = Str::singular($value);
203 6
            }
204 6
        }
205
206 15
        return str_replace('-', '_', $value);
207
    }
208
209
    /**
210
     * Get the parameter name as a resource URI parameter segment.
211
     *
212
     * @param  string  $value
213
     *
214
     * @return string
215
     */
216 15
    protected function getResourceUriParameter($value)
217
    {
218 15
        if (empty($value)) {
219 5
            return '';
220
        }
221
222 15
        return '/{'.$value.'}';
223
    }
224
225
    /**
226
     * Get the url verb for the specified verb.
227
     *
228
     * @return string
229
     */
230 15
    protected function getVerb($verb)
231
    {
232
        // verbs property does not exist until 5.3.27
233 15
        if (property_exists(get_class(), 'verbs') && !empty(static::$verbs[$verb])) {
234 12
            return static::$verbs[$verb];
235
        }
236
237 3
        return $verb;
238
    }
239
}
240