This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace As3\Modlr\Api; |
||
4 | |||
5 | use As3\Modlr\Exception\HttpExceptionInterface; |
||
6 | use As3\Modlr\Metadata\EntityMetadata; |
||
7 | use As3\Modlr\Models\Collections\Collection; |
||
8 | use As3\Modlr\Models\Model; |
||
9 | use As3\Modlr\Rest; |
||
10 | use As3\Modlr\Store\Store; |
||
11 | |||
12 | /** |
||
13 | * Abstract Adapter implementation for handling API operations. |
||
14 | * |
||
15 | * @author Jacob Bare <[email protected]> |
||
16 | */ |
||
17 | abstract class AbstractAdapter implements AdapterInterface |
||
18 | { |
||
19 | /** |
||
20 | * The Serializer |
||
21 | * |
||
22 | * @var SerializerInterface |
||
23 | */ |
||
24 | protected $serializer; |
||
25 | |||
26 | /** |
||
27 | * The Normalizer |
||
28 | * |
||
29 | * @var NormalizerInterface |
||
30 | */ |
||
31 | protected $normalizer; |
||
32 | |||
33 | /** |
||
34 | * The Store to use for persistence operations. |
||
35 | * |
||
36 | * @var Store |
||
37 | */ |
||
38 | protected $store; |
||
39 | |||
40 | /** |
||
41 | * The current REST request. |
||
42 | * |
||
43 | * @var Rest\RestRequest |
||
44 | */ |
||
45 | protected $request; |
||
46 | |||
47 | /** |
||
48 | * The REST configuration. |
||
49 | * |
||
50 | * @var Rest\RestConfiguration |
||
51 | */ |
||
52 | protected $config; |
||
53 | |||
54 | /** |
||
55 | * Constructor. |
||
56 | * |
||
57 | * @param SerializerInterface $serializer |
||
58 | * @param NormalizerInterface $normalizer |
||
59 | * @param Store $store |
||
60 | * @param Rest\RestConfiguration $config |
||
61 | */ |
||
62 | public function __construct(SerializerInterface $serializer, NormalizerInterface $normalizer, Store $store, Rest\RestConfiguration $config) |
||
63 | { |
||
64 | $this->serializer = $serializer; |
||
65 | $this->normalizer = $normalizer; |
||
66 | $this->store = $store; |
||
67 | $this->config = $config; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * {@inheritDoc} |
||
72 | */ |
||
73 | abstract public function processRequest(Rest\RestRequest $request); |
||
74 | |||
75 | /** |
||
76 | * {@inheritDoc} |
||
77 | */ |
||
78 | public function findRecord($typeKey, $identifier, array $fields = [], array $inclusions = []) |
||
79 | { |
||
80 | $model = $this->getStore()->find($typeKey, $identifier); |
||
81 | $payload = $this->serialize($model); |
||
82 | return $this->createRestResponse(200, $payload); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * {@inheritDoc} |
||
87 | */ |
||
88 | public function findAll($typeKey, array $identifiers = [], array $fields = [], array $sort = [], array $pagination = [], array $inclusions = []) |
||
89 | { |
||
90 | $collection = $this->getStore()->findAll($typeKey, $identifiers, $fields, $sort, $pagination['offset'], $pagination['limit']); |
||
91 | $payload = $this->serializeCollection($collection); |
||
92 | return $this->createRestResponse(200, $payload); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * {@inheritDoc} |
||
97 | */ |
||
98 | public function findQuery($typeKey, array $criteria, array $fields = [], array $sort = [], array $pagination = [], array $inclusions = []) |
||
99 | { |
||
100 | $collection = $this->getStore()->findQuery($typeKey, $criteria, $fields, $sort, $pagination['offset'], $pagination['limit']); |
||
101 | $payload = $this->serializeCollection($collection); |
||
102 | return $this->createRestResponse(200, $payload); |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * {@inheritDoc} |
||
107 | */ |
||
108 | public function findRelationship($typeKey, $identifier, $fieldKey) |
||
109 | { |
||
110 | $model = $this->getStore()->find($typeKey, $identifier); |
||
111 | if (false === $model->isRelationship($fieldKey)) { |
||
112 | throw AdapterException::badRequest(sprintf('The relationship field "%s" does not exist on model "%s"', $fieldKey, $typeKey)); |
||
113 | } |
||
114 | $rel = $model->get($fieldKey); |
||
115 | $payload = (true === $model->isHasOne($fieldKey)) ? $this->serialize($rel) : $this->serializeArray($rel); |
||
116 | return $this->createRestResponse(200, $payload); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * {@inheritDoc} |
||
121 | */ |
||
122 | View Code Duplication | public function createRecord($typeKey, Rest\RestPayload $payload) //, array $fields = [], array $inclusions = []) |
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
53% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
123 | { |
||
124 | $normalized = $this->normalize($payload); |
||
125 | $this->validateCreatePayload($typeKey, $normalized); |
||
126 | |||
127 | $model = $this->getStore()->create($normalized['type']); |
||
128 | $model->apply($normalized['properties']); |
||
129 | $model->save(); |
||
130 | $payload = $this->serialize($model); |
||
131 | return $this->createRestResponse(201, $payload); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * {@inheritDoc} |
||
136 | */ |
||
137 | View Code Duplication | public function updateRecord($typeKey, $identifier, Rest\RestPayload $payload) // , array $fields = [], array $inclusions = []) |
|
0 ignored issues
–
show
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. ![]() Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
138 | { |
||
139 | $normalized = $this->normalize($payload); |
||
140 | $this->validateUpdatePayload($typeKey, $identifier, $normalized); |
||
141 | |||
142 | $model = $this->getStore()->find($typeKey, $normalized['id']); |
||
143 | $model->apply($normalized['properties']); |
||
144 | $model->save(); |
||
145 | $payload = $this->serialize($model); |
||
146 | return $this->createRestResponse(200, $payload); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * {@inheritDoc} |
||
151 | */ |
||
152 | public function deleteRecord($typeKey, $identifier) |
||
153 | { |
||
154 | $this->getStore()->delete($typeKey, $identifier); |
||
155 | return $this->createRestResponse(204); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * {@inheritDoc} |
||
160 | */ |
||
161 | public function autocomplete($typeKey, $attributeKey, $searchValue, array $pagination = []) |
||
162 | { |
||
163 | $collection = $this->getStore()->searchAutocomplete($typeKey, $attributeKey, $searchValue); |
||
164 | $payload = $this->serializeCollection($collection); |
||
165 | return $this->createRestResponse(200, $payload); |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * {@inheritDoc} |
||
170 | */ |
||
171 | public function getRequest() |
||
172 | { |
||
173 | return $this->request; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * {@inheritDoc} |
||
178 | */ |
||
179 | abstract public function buildUrl(EntityMetadata $metadata, $identifier, $relFieldKey = null, $isRelatedLink = false); |
||
180 | |||
181 | /** |
||
182 | * Validates a normalized create record payload. |
||
183 | * |
||
184 | * @param string $typeKey |
||
185 | * @param array $normalized |
||
186 | * @throws AdapterException On invalid create record payload. |
||
187 | */ |
||
188 | abstract protected function validateCreatePayload($typeKey, array $normalized); |
||
189 | |||
190 | /** |
||
191 | * Validates a normalized update record payload. |
||
192 | * |
||
193 | * @param string $typeKey |
||
194 | * @param string $identifier |
||
195 | * @param array $normalized |
||
196 | * @throws AdapterException On invalid update record payload. |
||
197 | */ |
||
198 | abstract protected function validateUpdatePayload($typeKey, $identifier, array $normalized); |
||
199 | |||
200 | /** |
||
201 | * Creates a RestResponse object based on common response parameters shared by this adapter. |
||
202 | * |
||
203 | * @param int $status |
||
204 | * @param Rest\RestPayload $payload |
||
205 | * @return Rest\RestResponse |
||
206 | */ |
||
207 | abstract protected function createRestResponse($status, Rest\RestPayload $payload = null); |
||
208 | |||
209 | /** |
||
210 | * {@inheritDoc} |
||
211 | */ |
||
212 | public function handleException(\Exception $e) |
||
213 | { |
||
214 | if (extension_loaded('newrelic')) { |
||
215 | newrelic_notice_error($e->getMessage(), $e); |
||
216 | } |
||
217 | $refl = new \ReflectionClass($e); |
||
218 | if ($e instanceof HttpExceptionInterface) { |
||
219 | $title = sprintf('%s::%s', $refl->getShortName(), $e->getErrorType()); |
||
220 | $detail = $e->getMessage(); |
||
221 | $status = $e->getHttpCode(); |
||
222 | } else { |
||
223 | $title = $refl->getShortName(); |
||
224 | $detail = 'Oh no! Something bad happened on the server! Please try again.'; |
||
225 | $status = 500; |
||
226 | } |
||
227 | |||
228 | $serialized = $this->getSerializer()->serializeError($title, $detail, $status); |
||
229 | $payload = new Rest\RestPayload($serialized); |
||
230 | return $this->createRestResponse($status, $payload); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * {@inheritDoc} |
||
235 | */ |
||
236 | public function getStore() |
||
237 | { |
||
238 | return $this->store; |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * {@inheritDoc} |
||
243 | */ |
||
244 | public function getSerializer() |
||
245 | { |
||
246 | return $this->serializer; |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * {@inheritDoc} |
||
251 | */ |
||
252 | public function getNormalizer() |
||
253 | { |
||
254 | return $this->normalizer; |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * {@inheritDoc} |
||
259 | */ |
||
260 | public function normalize(Rest\RestPayload $payload) |
||
261 | { |
||
262 | return $this->getNormalizer()->normalize($payload, $this); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * {@inheritDoc} |
||
267 | */ |
||
268 | public function serialize(Model $model = null) |
||
269 | { |
||
270 | $serialized = (String) $this->getSerializer()->serialize($model, $this); |
||
271 | $this->validateSerialization($serialized); |
||
272 | return new Rest\RestPayload($serialized); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * {@inheritDoc} |
||
277 | */ |
||
278 | public function serializeArray(array $models) |
||
279 | { |
||
280 | $serialized = (String) $this->getSerializer()->serializeArray($models, $this); |
||
281 | $this->validateSerialization($serialized); |
||
282 | return new Rest\RestPayload($serialized); |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * {@inheritDoc} |
||
287 | */ |
||
288 | public function serializeCollection(Collection $collection) |
||
289 | { |
||
290 | $serialized = (String) $this->getSerializer()->serializeCollection($collection, $this); |
||
291 | $this->validateSerialization($serialized); |
||
292 | return new Rest\RestPayload($serialized); |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * Validates that the serialized value is support by a RestPayload. |
||
297 | * |
||
298 | * @param mixed $serialized |
||
299 | * @return bool |
||
300 | * @throws AdapterException On invalid serialized value. |
||
301 | */ |
||
302 | protected function validateSerialization($serialized) |
||
303 | { |
||
304 | if (!is_string($serialized)) { |
||
305 | throw AdapterException::badRequest('Unable to create an API response payload. Invalid serialization occurred.'); |
||
306 | } |
||
307 | return true; |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * {@inheritDoc} |
||
312 | */ |
||
313 | public function getEntityMetadata($typeKey) |
||
314 | { |
||
315 | return $this->getStore()->getMetadataForType($typeKey); |
||
316 | } |
||
317 | } |
||
318 |
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.