Completed
Push — master ( 5e6003...ff6361 )
by Matthew
03:07
created

AbstractEndpointController::createItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace Ps2alerts\Api\Controller\Endpoint;
4
5
use League\Fractal\Resource\Collection;
6
use League\Fractal\Resource\Item;
7
use Ps2alerts\Api\Contract\DatabaseAwareInterface;
8
use Ps2alerts\Api\Contract\DatabaseAwareTrait;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
12
abstract class AbstractEndpointController implements
13
    DatabaseAwareInterface
14
{
15
    use DatabaseAwareTrait;
16
17
    /**
18
     * Contains the repository used for interfacing with the database
19
     *
20
     * @var \Ps2alerts\Api\Repository\AbstractEndpointRepository
21
     */
22
    protected $repository;
23
24
    /**
25
     * Stores the status code
26
     *
27
     * @var integer
28
     */
29
    protected $statusCode = 200;
30
31
    /**
32
     * Holds Fractal
33
     *
34
     * @var \League\Fractal\Manager
35
     */
36
    protected $fractal;
37
38
    /**
39
     * Holds the transformer we're going to use
40
     *
41
     * @var mixed|\Leage\Fractal\TransformerAbstract
42
     */
43
    protected $transformer;
44
45
    const CODE_WRONG_ARGS     = 'API-MALFORMED-REQUEST';
46
    const CODE_NOT_FOUND      = 'API-NOT-FOUND';
47
    const CODE_INTERNAL_ERROR = 'API-DOH';
48
    const CODE_UNAUTHORIZED   = 'API-UNAUTHORIZED';
49
    const CODE_FORBIDDEN      = 'API-DENIED';
50
    const CODE_EMPTY          = 'API-EMPTY';
51
52
    /**
53
     * Getter for statusCode
54
     *
55
     * @return int
56
     */
57
    public function getStatusCode()
58
    {
59
        return $this->statusCode;
60
    }
61
62
    /**
63
     * Setter for statusCode
64
     *
65
     * @param int $statusCode Value to set
66
     *
67
     * @return self
68
     */
69
    public function setStatusCode($statusCode)
70
    {
71
        $this->statusCode = $statusCode;
72
        return $this;
73
    }
74
75
    /**
76
     * Master function to split out appropiate calls
77
     *
78
     * @param  string                                     $kind     The kind of data we wish to return
79
     * @param  array                                      $data     The data itself
80
     * @param  \League\Fractal\TransformerAbstract        $callback The transformer class to call
81
     * @param  \Symfony\Component\HttpFoundation\Request  $request  The request itself
82
     * @param  \Symfony\Component\HttpFoundation\Response $response The response object to eventually call
83
     *
84
     * @return \Symfony\Component\HttpFoundation\Response
85
     */
86
    protected function respond($kind, $data, $callback, Request $request, Response $response)
87
    {
88
        // Detect what embeds we need
89
        $this->getIncludesFromRequest($request);
90
        switch ($kind) {
91
            case 'item':
92
                return $this->respondWithItem($data, $callback, $response);
93
            case 'collection':
94
                return $this->respondWithCollection($data, $callback, $response);
95
            default:
96
                return $this->errorInternalError('No Response was defined. Please report this.');
0 ignored issues
show
Documentation introduced by
'No Response was defined. Please report this.' is of type string, but the function expects a object<Symfony\Component\HttpFoundation\Response>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
97
        }
98
    }
99
100
    /**
101
     * Builds an item response in Fractal then hands off to the responder
102
     *
103
     * @param  array                                      $item     The item to transform
104
     * @param  \League\Fractal\TransformerAbstract        $transformer The Transformer to pass through to Fractal
105
     * @param  \Symfony\Component\HttpFoundation\Response $response The client's response
106
     *
107
     * @return array
108
     */
109
    protected function respondWithItem($item, $transformer, Response $response)
110
    {
111
        return $this->respondWithArray($response, $this->createItem($item, $transformer));
112
    }
113
114
    /**
115
     * Creates the item array and returns it hence it came.
116
     *
117
     * @param  array                               $item     The data to parse
118
     * @param  \League\Fractal\TransformerAbstract $transformer
119
     *
120
     * @return array
121
     */
122
    public function createItem($item, $transformer)
123
    {
124
        $resource = new Item($item, $transformer);
125
        $rootScope = $this->fractal->createData($resource);
126
127
        return $rootScope->toArray();
128
    }
129
130
    /**
131
     * Builds a collection of items from Fractal then hands off to the responder
132
     *
133
     * @param  array                                      $collection  The collection to transform
134
     * @param  \League\Fractal\TransformerAbstract        $transformer The Transformer to pass through to Fractal
135
     * @param  \Symfony\Component\HttpFoundation\Response $response    The client's response
136
     *
137
     * @return array
138
     */
139
    protected function respondWithCollection($collection, $transformer, Response $response)
140
    {
141
        return $this->respondWithArray($response, $this->createCollection($collection, $transformer));
142
    }
143
144
    /**
145
     * Creates a collection array and sends it back to hence it came.
146
     *
147
     * @param  array                               $collection
148
     * @param  \League\Fractal\TransformerAbstract $transformer
149
     *
150
     * @return array
151
     */
152
    public function createCollection($collection, $transformer)
153
    {
154
        $resource = new Collection($collection, $transformer);
155
        $rootScope = $this->fractal->createData($resource);
156
157
        return $rootScope->toArray();
158
    }
159
160
    /**
161
     * The final step where the formatted array is now sent back as a response in JSON form
162
     *
163
     * @param  \Symfony\Component\HttpFoundation\Response $response
164
     * @param  array                                      $array
165
     *
166
     * @return \Symfony\Component\HttpFoundation\Response
167
     */
168
    protected function respondWithArray(Response $response, array $array)
169
    {
170
        $response->setStatusCode($this->getStatusCode());
171
        $response->setContent(json_encode($array));
172
        $response->headers->set('Content-Type', 'application/json');
173
174
        // This is the end of the road. FIRE ZE RESPONSE!
175
        return $response;
176
    }
177
178
    /**
179
     * Responds gracefully with an error.
180
     *
181
     * @param  \Symfony\Component\HttpFoundation\Response $response
182
     * @param  string                                     $message   Response message to put in the error
183
     * @param  int                                        $errorCode Error code to set
184
     *
185
     * @return array
186
     */
187
    protected function respondWithError(Response $response, $message, $errorCode)
188
    {
189
        if ($this->statusCode === 200) {
190
            trigger_error(
191
                "This Error code 200 should never be sent. Please report this to the developer.",
192
                E_USER_WARNING
193
            );
194
        }
195
196
        // Pass to responder
197
        return $this->respondWithArray($response, [
198
            'error' => [
199
                'code'      => $errorCode,
200
                'http_code' => $this->statusCode,
201
                'message'   => $message,
202
            ]
203
        ]);
204
    }
205
206
    /**
207
     * Generates a response with a 404 HTTP error and a given message.
208
     *
209
     * @param  \Symfony\Component\HttpFoundation\Response $response
210
     * @param  string                                     $message
211
     *
212
     * @return void
213
     */
214
    public function errorEmpty(Response $response, $message = 'No data / Empty')
215
    {
216
        return $this->setStatusCode(404)
217
                    ->respondWithError($response, $message, self::CODE_EMPTY);
218
    }
219
220
    /**
221
     * Generates a Response with a 403 HTTP header and a given message.
222
     *
223
     * @param  \Symfony\Component\HttpFoundation\Response $response
224
     * @param  string                                     $message
225
     *
226
     * @return void
227
     */
228
    public function errorForbidden(Response $response, $message = 'Forbidden')
229
    {
230
        return $this->setStatusCode(403)
231
                    ->respondWithError($response, $message, self::CODE_FORBIDDEN);
232
    }
233
234
    /**
235
     * Generates a Response with a 500 HTTP header and a given message.
236
     *
237
     * @param  \Symfony\Component\HttpFoundation\Response $response
238
     * @param  string                                     $message
239
     *
240
     * @return void
241
     */
242
    public function errorInternalError(Response $response, $message = 'Internal Error')
243
    {
244
        return $this->setStatusCode(500)
245
                    ->respondWithError($response, $message, self::CODE_INTERNAL_ERROR);
246
    }
247
248
    /**
249
     * Generates a Response with a 404 HTTP header and a given message.
250
     *
251
     * @param  \Symfony\Component\HttpFoundation\Response $response
252
     * @param  string                                     $message
253
     *
254
     * @return void
255
     */
256
    public function errorNotFound(Response $response, $message = 'Resource Not Found')
257
    {
258
        return $this->setStatusCode(404)
259
                    ->respondWithError($response, $message, self::CODE_NOT_FOUND);
260
    }
261
262
    /**
263
     * Generates a Response with a 401 HTTP header and a given message.
264
     *
265
     * @param  \Symfony\Component\HttpFoundation\Response $response
266
     * @param  string                                     $message
267
     *
268
     * @return void
269
     */
270
    public function errorUnauthorized(Response $response, $message = 'Unauthorized')
271
    {
272
        return $this->setStatusCode(401)
273
                    ->respondWithError($response, $message, self::CODE_UNAUTHORIZED);
274
    }
275
276
    /**
277
     * Generates a Response with a 400 HTTP header and a given message.
278
     *
279
     * @param \Symfony\Component\HttpFoundation\Response $response
280
     * @param string                                     $message
281
     *
282
     * @return \Symfony\Component\HttpFoundation\Response
283
     */
284
    public function errorWrongArgs(Response $response, $message = 'Wrong Arguments')
285
    {
286
        return $this->setStatusCode(400)
287
                    ->respondWithError($response, $message, self::CODE_WRONG_ARGS);
288
    }
289
290
    /**
291
     * Reads any requested includes and adds them to the item / collection
292
     *
293
     * @param  Symfony\Component\HttpFoundation\Request $request
294
     *
295
     * @return void
296
     */
297
    public function getIncludesFromRequest(Request $request)
298
    {
299
        $queryString = $request->query->get('embed');
300
301
        if (! empty($queryString)) {
302
            $this->fractal->parseIncludes($request->query->get('embed'));
303
        }
304
    }
305
}
306