1 | <?php |
||
17 | abstract class BaseApiController extends Controller |
||
18 | { |
||
19 | /** |
||
20 | * @param int $statusCode |
||
21 | * |
||
22 | * @return JsonResponse |
||
23 | */ |
||
24 | 10 | protected function createResponse($statusCode = Response::HTTP_OK) |
|
25 | 1 | { |
|
26 | 10 | $response = new JsonResponse(); |
|
27 | 10 | $response->setStatusCode($statusCode); |
|
28 | 10 | $response->headers->set('Access-Control-Allow-Origin', $this->container->getParameter('tree_house.api.allowed_origins')); |
|
29 | |||
30 | 10 | return $response; |
|
31 | } |
||
32 | |||
33 | /** |
||
34 | * Renders an successful Api call. |
||
35 | * |
||
36 | * @see renderResponse() |
||
37 | * |
||
38 | * @param Request $request |
||
39 | * @param mixed $result The result of the call. |
||
40 | * @param int $code The response code. |
||
41 | * @param array $groups JMS\Serializer groups |
||
42 | * @param array $metadata Extra metadata to put in the response |
||
43 | * @param SerializationContext $context The context to use for serializing the result data |
||
44 | * |
||
45 | * @return JsonResponse |
||
46 | */ |
||
47 | 2 | protected function renderOk(Request $request, $result, $code = 200, array $groups = [], array $metadata = [], SerializationContext $context = null) |
|
48 | 1 | { |
|
49 | 2 | $data = array(); |
|
50 | |||
51 | 2 | if (!empty($metadata)) { |
|
52 | 2 | $data['metadata'] = $metadata; |
|
53 | 1 | } |
|
54 | |||
55 | 2 | if (null !== $result) { |
|
56 | 2 | $data['result'] = $result; |
|
57 | 1 | } |
|
58 | |||
59 | 2 | return $this->renderResponse($request, $data, true, $code, $groups, $context); |
|
60 | } |
||
61 | |||
62 | /** |
||
63 | * Renders an Api error. |
||
64 | * |
||
65 | * @see renderResponse() |
||
66 | * |
||
67 | * @param Request $request |
||
68 | * @param int $code The response code |
||
69 | * @param string|array $error The error |
||
70 | * @param array $groups JMS\Serializer groups |
||
71 | * @param SerializationContext $context The context to use for serializing the result data |
||
72 | * |
||
73 | * @return JsonResponse |
||
74 | */ |
||
75 | 4 | protected function renderError( |
|
76 | Request $request, |
||
77 | $code = 400, |
||
78 | $error, |
||
79 | array $groups = [], |
||
80 | SerializationContext $context = null |
||
81 | ) { |
||
82 | 4 | return $this->renderResponse($request, ['error' => $error], false, $code, $groups, $context); |
|
83 | } |
||
84 | |||
85 | /** |
||
86 | * Renders a JSON response in a generic structure: |
||
87 | * |
||
88 | * <code> |
||
89 | * { |
||
90 | * "ok": true, |
||
91 | * "result": { |
||
92 | * [...] |
||
93 | * } |
||
94 | * } |
||
95 | * </code> |
||
96 | * |
||
97 | * Or in case of an error: |
||
98 | * |
||
99 | * <code> |
||
100 | * { |
||
101 | * "ok": false, |
||
102 | * "error": "message" |
||
103 | * } |
||
104 | * </code> |
||
105 | * |
||
106 | * @param Request $request |
||
107 | * @param array $result The result of the call. |
||
108 | * @param bool $ok Whether the call was successful or not. |
||
109 | * @param int $statusCode The response code. |
||
110 | * @param array $groups JMS\Serializer groups |
||
111 | * @param SerializationContext $context The context to use for serializing the result data |
||
112 | * |
||
113 | * @return JsonResponse |
||
114 | */ |
||
115 | 6 | protected function renderResponse( |
|
116 | Request $request, |
||
117 | array $result = [], |
||
118 | $ok, |
||
119 | $statusCode, |
||
120 | array $groups = [], |
||
121 | SerializationContext $context = null |
||
122 | ) { |
||
123 | 6 | $response = $this->createResponse($statusCode); |
|
124 | |||
125 | 6 | $data = array_merge( |
|
126 | 6 | ['ok' => $ok], |
|
127 | $result |
||
128 | 3 | ); |
|
129 | |||
130 | 6 | if ($context === null) { |
|
131 | 6 | $context = SerializationContext::create(); |
|
132 | 3 | } |
|
133 | |||
134 | 6 | if ($groups) { |
|
|
|||
135 | $context->setGroups($groups); |
||
136 | } |
||
137 | |||
138 | 6 | $context->setSerializeNull(true); |
|
139 | |||
140 | // the json response needs to have data set as an array, rather than setting the content directly. |
||
141 | // this is because other options use that to overwrite the content (like jsonp). |
||
142 | // so unfortunately we have to double-convert the data, since the serializer won't convert to |
||
143 | // arrays just yet :( |
||
144 | 6 | $json = $this->getSerializer()->serialize($data, 'json', $context); |
|
145 | 6 | $response->setData(json_decode($json, true)); |
|
146 | |||
147 | // handle JSON-P requests |
||
148 | 6 | $callback = $request->query->get('callback', ''); |
|
149 | 6 | if (!empty($callback)) { |
|
150 | try { |
||
151 | 4 | $response->setCallback($callback); |
|
152 | 3 | } catch (\InvalidArgumentException $e) { |
|
153 | // remove the callback from the query parameters, and render an error |
||
154 | 2 | $request->query->remove('callback'); |
|
155 | |||
156 | 2 | return $this->renderError($request, Response::HTTP_BAD_REQUEST, $e->getMessage(), $groups, $context); |
|
157 | } |
||
158 | 1 | } |
|
159 | |||
160 | 6 | return $response; |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * @param Request $request |
||
165 | * @param string $serializeType |
||
166 | * |
||
167 | * @return ParameterBag|object |
||
168 | */ |
||
169 | 4 | protected function getRequestData(Request $request, $serializeType = null) |
|
170 | { |
||
171 | 4 | $data = null; |
|
172 | |||
173 | 4 | switch ($request->getMethod()) { |
|
174 | 4 | case 'GET': |
|
175 | 4 | $data = $request->query; |
|
176 | 4 | break; |
|
177 | |||
178 | 2 | case 'POST': |
|
179 | 2 | case 'PUT': |
|
180 | 2 | case 'DELETE': |
|
181 | 2 | $data = $request->getContent(); |
|
182 | 2 | break; |
|
183 | |||
184 | 1 | default: |
|
185 | 2 | $data = $request->query; |
|
186 | 2 | break; |
|
187 | 2 | } |
|
188 | |||
189 | 4 | if ($serializeType) { |
|
190 | 2 | $data = $this->getSerializer()->deserialize($data, $serializeType, 'json'); |
|
191 | 1 | } |
|
192 | |||
193 | 4 | return $data; |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * Validates an API request |
||
198 | * |
||
199 | * @param object $request |
||
200 | * |
||
201 | * @throws ValidationException |
||
202 | */ |
||
203 | 4 | protected function validate($request) |
|
211 | |||
212 | /** |
||
213 | * @return UserInterface |
||
214 | */ |
||
215 | 4 | protected function getApiUser() |
|
223 | |||
224 | /** |
||
225 | * @return SecurityContext |
||
226 | */ |
||
227 | 4 | protected function getSecurityContext() |
|
231 | |||
232 | /** |
||
233 | * @return SerializerInterface |
||
234 | */ |
||
235 | 8 | protected function getSerializer() |
|
239 | |||
240 | /** |
||
241 | * @return ValidatorInterface |
||
242 | */ |
||
243 | 4 | protected function getValidator() |
|
247 | } |
||
248 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.