Passed
Push — develop ( fa8907...8a4c3e )
by Edwin
05:11
created

AbstractResource   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 2
dl 0
loc 249
ccs 82
cts 82
cp 1
rs 8.2769
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
D __call() 0 39 12
A __construct() 0 4 1
A getAction() 0 8 2
A getRequest() 0 4 1
A hasAction() 0 8 2
A getChildResources() 0 4 1
A request() 0 15 1
D getEndpoint() 0 26 10
A getMethod() 0 10 2
A getResourceKey() 0 10 2
A getResponseKey() 0 10 2
B getRequestOptions() 0 24 5

How to fix   Complexity   

Complex Class

Complex classes like AbstractResource often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractResource, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace ShopifyClient\Resource;
4
5
use ShopifyClient\Exception\ClientException;
6
use ShopifyClient\Request;
7
8
abstract class AbstractResource
9
{
10
    /**
11
     * @var Request
12
     */
13
    protected $request;
14
15
    /**
16
     * @var array
17
     */
18
    protected $actions = [];
19
20
    /**
21
     * @var array
22
     */
23
    protected $childResources = [];
24
25
    /**
26
     * AbstractResource constructor.
27
     * @param Request $request
28
     */
29 5
    public function __construct(Request $request)
30
    {
31 5
        $this->request = $request;
32 5
    }
33
34
    /**
35
     * @param string $action
36
     * @return array
37
     * @throws ClientException
38
     */
39 133
    public function getAction(string $action): array
40
    {
41 133
        if (!$this->hasAction($action)) {
42 1
            throw new ClientException(sprintf('Action: %s not found on resource. ', $action, get_called_class()));
43
        }
44
45 132
        return $this->actions[$action];
46
    }
47
48
    /**
49
     * @return Request
50
     */
51 1
    public function getRequest()
52
    {
53 1
        return $this->request;
54
    }
55
56
    /**
57
     * @param string $action
58
     * @return bool
59
     */
60 133
    public function hasAction(string $action): bool
61
    {
62 133
        if (!isset($this->actions[$action])) {
63 3
            return false;
64
        }
65
66 132
        return true;
67
    }
68
69
    /**
70
     * @return array
71
     */
72 5
    public function getChildResources(): array
73
    {
74 5
        return $this->childResources;
75
    }
76
77
    /**
78
     * @param string $action
79
     * @param float|null $parentId
80
     * @param float|null $childId
81
     * @param float|null $childChildId
82
     * @param array|null $parameters
83
     * @return array|bool
84
     */
85 133
    protected function request(
86
        string $action,
87
        float $parentId = null,
88
        float $childId = null,
89
        float $childChildId = null,
90
        array $parameters = []
91
    ) {
92 133
        $this->request->setResponseKey($this->getResponseKey($action));
93
94 132
        return $this->request->request(
95 132
            $this->getMethod($action),
96 131
            $this->getEndpoint($action, $parentId, $childId, $childChildId),
97 130
            $this->getRequestOptions($action, $parameters)
98
        );
99
    }
100
101
    /**
102
     * @param string $action
103
     * @param float|null $parentId
104
     * @param float|null $childId
105
     * @param float|null $childChildId
106
     * @return string
107
     * @throws ClientException
108
     */
109 131
    protected function getEndpoint(
110
        string $action,
111
        float $parentId = null,
112
        float $childId = null,
113
        float $childChildId = null
114
    ): string {
115 131
        $actionData = $this->getAction($action);
116
117 131
        if (!isset($actionData['endpoint'])) {
118 1
            throw new ClientException(sprintf('Endpoint key not set for action: %s.', $action));
119
        }
120
121 130
        if (!empty($parentId) && empty($childId)) {
122 61
            return sprintf($actionData['endpoint'], $parentId);
123
        }
124
125 71
        if (!empty($parentId) && !empty($childId) && empty($childChildId)) {
126 38
            return sprintf($actionData['endpoint'], $parentId, $childId);
127
        }
128
129 33
        if (!empty($parentId) && !empty($childId) && !empty($childChildId)) {
130 8
            return sprintf($actionData['endpoint'], $parentId, $childId, $childChildId);
131
        }
132
133 25
        return $actionData['endpoint'];
134
    }
135
136
    /**
137
     * @param string $action
138
     * @return string
139
     * @throws ClientException
140
     */
141 132
    protected function getMethod(string $action): string
142
    {
143 132
        $actionData = $this->getAction($action);
144
145 132
        if (!isset($actionData['method'])) {
146 1
            throw new ClientException(sprintf('Method key not set for action: %s.', $action));
147
        }
148
149 131
        return $actionData['method'];
150
    }
151
152
    /**
153
     * @param string $action
154
     * @return string
155
     */
156 52
    protected function getResourceKey(string $action): string
157
    {
158 52
        $actionData = $this->getAction($action);
159
160 52
        if (!isset($actionData['resourceKey'])) {
161 3
            return '';
162
        }
163
164 49
        return $actionData['resourceKey'];
165
    }
166
167
    /**
168
     * @param string $action
169
     * @return string
170
     */
171 133
    protected function getResponseKey(string $action): string
172
    {
173 133
        $actionData = $this->getAction($action);
174
175 132
        if (!isset($actionData['responseKey'])) {
176 25
            return '';
177
        }
178
179 108
        return $actionData['responseKey'];
180
    }
181
182
    /**
183
     * @param string $action
184
     * @param array $parameters
185
     * @return array
186
     */
187 130
    private function getRequestOptions(string $action, array $parameters): array
188
    {
189 130
        switch ($this->getMethod($action)) {
190 130
            case 'GET':
191
                return [
192 59
                    'query' => $parameters
193
                ];
194 74
            case 'POST':
195 46
            case 'PUT':
196 52
                if (strlen($this->getResourceKey($action)) < 1) {
197 3
                    return [];
198
                }
199
200
                return [
201 49
                    'body' => json_encode([
202 49
                        $this->getResourceKey($action) => $parameters
203
                    ])
204
                ];
205
            default:
206
                return [
207 23
                    'query' => $parameters
208
                ];
209
        }
210
    }
211
212
    /**
213
     * @param string $method
214
     * @param array|null $arguments
215
     * @return array|bool
216
     */
217 133
    public function __call(string $method, array $arguments = [])
218
    {
219 133
        $parentId     = null;
220 133
        $childId      = null;
221 133
        $childChildId = null;
222 133
        $parameters   = [];
223
224 133
        if (!empty($arguments[0])) {
225 126
            if (is_numeric($arguments[0])) {
226 109
                $parentId = $arguments[0];
227 19
            } elseif (is_array($arguments[0])) {
228 19
                $parameters = $arguments[0];
229
            }
230
        }
231
232 133
        if (!empty($arguments[1])) {
233 75
            if (is_numeric($arguments[1])) {
234 46
                $childId = $arguments[1];
235 29
            } elseif (is_array($arguments[1])) {
236 29
                $parameters = $arguments[1];
237
            }
238
        }
239
240 133
        if (!empty($arguments[2])) {
241 24
            if (is_numeric($arguments[2])) {
242 8
                $childChildId = $arguments[2];
243 16
            } elseif (is_array($arguments[2])) {
244 16
                $parameters = $arguments[2];
245
            }
246
        }
247
248 133
        if (!empty($arguments[3])) {
249 2
            if (is_array($arguments[3])) {
250 2
                $parameters = $arguments[3];
251
            }
252
        }
253
254 133
        return $this->request($method, $parentId, $childId, $childChildId, $parameters);
255
    }
256
}
257