Completed
Push — master ( 210649...ef3b6a )
by Neomerx
05:34
created

FluteRoutesTrait::removeInRelationship()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 12
loc 12
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 9.8666
cc 1
nc 1
nop 5
crap 1
1
<?php namespace Limoncello\Flute\Http\Traits;
2
3
/**
4
 * Copyright 2015-2018 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Limoncello\Contracts\Routing\GroupInterface;
20
use Limoncello\Contracts\Routing\RouteInterface;
21
use Limoncello\Flute\Contracts\Http\Controller\ControllerCreateInterface;
22
use Limoncello\Flute\Contracts\Http\Controller\ControllerDeleteInterface;
23
use Limoncello\Flute\Contracts\Http\Controller\ControllerIndexInterface;
24
use Limoncello\Flute\Contracts\Http\Controller\ControllerInstanceInterface;
25
use Limoncello\Flute\Contracts\Http\Controller\ControllerReadInterface;
26
use Limoncello\Flute\Contracts\Http\Controller\ControllerUpdateInterface;
27
use Limoncello\Flute\Contracts\Http\JsonApiControllerInterface as JCI;
28
use Limoncello\Flute\Contracts\Http\WebControllerInterface as FCI;
29
use Neomerx\JsonApi\Contracts\Document\DocumentInterface;
30
31
/**
32
 * @package Limoncello\Flute
33
 */
34
trait FluteRoutesTrait
35
{
36
    /**
37
     * @param GroupInterface $group
38
     * @param string         $resourceName
39
     * @param string         $controllerClass
40
     *
41
     * @return GroupInterface
42
     */
43 1
    protected static function apiController(
44
        GroupInterface $group,
45
        string $resourceName,
46
        string $controllerClass
47
    ): GroupInterface {
48 1
        assert(class_exists($controllerClass) === true);
49
50 1
        $groupPrefix = $group->getUriPrefix();
51 1
        $indexSlug   = '/{' . JCI::ROUTE_KEY_INDEX . '}';
52
        $params      = function (string $method) use ($groupPrefix, $resourceName): array {
53 1
            return [RouteInterface::PARAM_NAME => static::routeName($groupPrefix, $resourceName, $method)];
54 1
        };
55
        $handler     = function (string $method) use ($controllerClass): array {
56 1
            return [$controllerClass, $method];
57 1
        };
58
59
        // if the class implements any of CRUD methods a corresponding route will be added
60 1
        $classInterfaces = class_implements($controllerClass);
61 1
        if (in_array(ControllerIndexInterface::class, $classInterfaces) === true) {
62 1
            $group->get($resourceName, $handler(JCI::METHOD_INDEX), $params(JCI::METHOD_INDEX));
63
        }
64 1
        if (in_array(ControllerCreateInterface::class, $classInterfaces) === true) {
65 1
            $group->post($resourceName, $handler(JCI::METHOD_CREATE), $params(JCI::METHOD_CREATE));
66
        }
67 1
        if (in_array(ControllerReadInterface::class, $classInterfaces) === true) {
68 1
            $group->get($resourceName . $indexSlug, $handler(JCI::METHOD_READ), $params(JCI::METHOD_READ));
69
        }
70 1
        if (in_array(ControllerUpdateInterface::class, $classInterfaces) === true) {
71 1
            $group->patch($resourceName . $indexSlug, $handler(JCI::METHOD_UPDATE), $params(JCI::METHOD_UPDATE));
72
        }
73 1 View Code Duplication
        if (in_array(ControllerDeleteInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74 1
            $group->delete($resourceName . $indexSlug, $handler(JCI::METHOD_DELETE), $params(JCI::METHOD_DELETE));
75
        }
76
77 1
        return $group;
78
    }
79
80
    /**
81
     * @param GroupInterface $group
82
     * @param string         $subUri
83
     * @param string         $controllerClass
84
     * @param string         $createSubUrl
85
     *
86
     * @return GroupInterface
87
     */
88 1
    protected static function webController(
89
        GroupInterface $group,
90
        string $subUri,
91
        string $controllerClass,
92
        string $createSubUrl = '/create'
93
    ): GroupInterface {
94
        // normalize url to have predictable URLs and their names
95 1
        if ($subUri[-1] === '/') {
96 1
            $subUri = substr($subUri, 0, -1);
97
        }
98
99 1
        $groupPrefix = $group->getUriPrefix();
100 1
        $slugged     = $subUri . '/{' . FCI::ROUTE_KEY_INDEX . '}';
101
        $params      = function (string $method) use ($groupPrefix, $subUri) : array {
102 1
            return [RouteInterface::PARAM_NAME => static::routeName($groupPrefix, $subUri, $method)];
103 1
        };
104
        $handler     = function (string $method) use ($controllerClass): array {
105 1
            return [$controllerClass, $method];
106 1
        };
107
108
        // if the class implements any of CRUD methods a corresponding route will be added
109
        // as HTML forms do not support methods other than GET/POST we use POST and special URI for update and delete.
110 1
        $classInterfaces = class_implements($controllerClass);
111 1
        if (in_array(ControllerIndexInterface::class, $classInterfaces) === true) {
112 1
            $group->get($subUri, $handler(FCI::METHOD_INDEX), $params(FCI::METHOD_INDEX));
113
        }
114 1 View Code Duplication
        if (in_array(ControllerInstanceInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115 1
            $group->get($subUri . $createSubUrl, $handler(FCI::METHOD_INSTANCE), $params(FCI::METHOD_INSTANCE));
116
        }
117 1 View Code Duplication
        if (in_array(ControllerCreateInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118 1
            $group->post($subUri . $createSubUrl, $handler(FCI::METHOD_CREATE), $params(FCI::METHOD_CREATE));
119
        }
120 1 View Code Duplication
        if (in_array(ControllerReadInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121 1
            $group->get($slugged, $handler(FCI::METHOD_READ), $params(FCI::METHOD_READ));
122
        }
123 1 View Code Duplication
        if (in_array(ControllerUpdateInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124 1
            $group->post($slugged, $handler(FCI::METHOD_UPDATE), $params(FCI::METHOD_UPDATE));
125
        }
126 1 View Code Duplication
        if (in_array(ControllerDeleteInterface::class, $classInterfaces) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127 1
            $deleteUri = $slugged . '/' . FCI::METHOD_DELETE;
128 1
            $group->post($deleteUri, $handler(FCI::METHOD_DELETE), $params(FCI::METHOD_DELETE));
129
        }
130
131 1
        return $group;
132
    }
133
134
    /**
135
     * @param GroupInterface $group
136
     * @param string         $resourceName
137
     * @param string         $relationshipName
138
     * @param string         $controllerClass
139
     * @param string         $selfGetMethod
140
     *
141
     * @return GroupInterface
142
     */
143 1
    protected static function relationship(
144
        GroupInterface $group,
145
        string $resourceName,
146
        string $relationshipName,
147
        string $controllerClass,
148
        string $selfGetMethod
149
    ): GroupInterface {
150 1
        $resourceIdUri = $resourceName . '/{' . JCI::ROUTE_KEY_INDEX . '}/';
151 1
        $selfUri       = $resourceIdUri . DocumentInterface::KEYWORD_RELATIONSHIPS . '/' . $relationshipName;
152
153
        return $group
154
            // `self`
155 1
            ->get($selfUri, [$controllerClass, $selfGetMethod])
156
            // `related`
157 1
            ->get($resourceIdUri . $relationshipName, [$controllerClass, $selfGetMethod]);
158
    }
159
160
    /**
161
     * @param GroupInterface $group
162
     * @param string         $resourceName
163
     * @param string         $relationshipName
164
     * @param string         $controllerClass
165
     * @param string         $addMethod
166
     *
167
     * @return GroupInterface
168
     */
169 1 View Code Duplication
    protected static function addInRelationship(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
        GroupInterface $group,
171
        string $resourceName,
172
        string $relationshipName,
173
        string $controllerClass,
174
        string $addMethod
175
    ): GroupInterface {
176 1
        $url = $resourceName . '/{' . JCI::ROUTE_KEY_INDEX . '}/' .
177 1
            DocumentInterface::KEYWORD_RELATIONSHIPS . '/' . $relationshipName;
178
179 1
        return $group->post($url, [$controllerClass, $addMethod]);
180
    }
181
182
    /**
183
     * @param GroupInterface $group
184
     * @param string         $resourceName
185
     * @param string         $relationshipName
186
     * @param string         $controllerClass
187
     * @param string         $deleteMethod
188
     *
189
     * @return GroupInterface
190
     */
191 1 View Code Duplication
    protected static function removeInRelationship(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
        GroupInterface $group,
193
        string $resourceName,
194
        string $relationshipName,
195
        string $controllerClass,
196
        string $deleteMethod
197
    ): GroupInterface {
198 1
        $url = $resourceName . '/{' . JCI::ROUTE_KEY_INDEX . '}/' .
199 1
            DocumentInterface::KEYWORD_RELATIONSHIPS . '/' . $relationshipName;
200
201 1
        return $group->delete($url, [$controllerClass, $deleteMethod]);
202
    }
203
204
    /**
205
     * @param string $prefix
206
     * @param string $subUri
207
     * @param string $method
208
     *
209
     * @return string
210
     */
211 3
    protected static function routeName(string $prefix, string $subUri, string $method): string
212
    {
213 3
        assert(empty($method) === false);
214
215
        // normalize prefix and url to have predictable name
216
217 3
        if (empty($prefix) === true || $prefix[-1] !== '/') {
218 3
            $prefix .= '/';
219
        }
220
221 3
        if (empty($subUri) === false && $subUri[-1] === '/') {
222 1
            $subUri = substr($subUri, 0, -1);
223
        }
224
225 3
        return $prefix . $subUri . '::' . $method;
226
    }
227
}
228