Completed
Push — feature/other-validation ( 994f75...586e28 )
by Narcotic
10:05
created

RestController::deserialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.108

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 7
cts 10
cp 0.7
rs 9.2
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 2
crap 2.108
1
<?php
2
/**
3
 * basic rest controller
4
 */
5
6
namespace Graviton\RestBundle\Controller;
7
8
use Graviton\ExceptionBundle\Exception\DeserializationException;
9
use Graviton\ExceptionBundle\Exception\InvalidJsonPatchException;
10
use Graviton\ExceptionBundle\Exception\MalformedInputException;
11
use Graviton\ExceptionBundle\Exception\NotFoundException;
12
use Graviton\ExceptionBundle\Exception\SerializationException;
13
use Graviton\JsonSchemaBundle\Exception\ValidationException;
14
use Graviton\RestBundle\Model\DocumentModel;
15
use Graviton\RestBundle\Model\PaginatorAwareInterface;
16
use Graviton\SchemaBundle\SchemaUtils;
17
use Graviton\RestBundle\Service\RestUtilsInterface;
18
use Symfony\Component\Security\Core\User\UserInterface;
19
use Knp\Component\Pager\Paginator;
20
use Symfony\Component\DependencyInjection\ContainerInterface;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
24
use Symfony\Component\Routing\Exception\RouteNotFoundException;
25
use Symfony\Component\Form\FormFactory;
26
use Symfony\Bundle\FrameworkBundle\Routing\Router;
27
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
28
use Symfony\Component\Validator\Validator\ValidatorInterface;
29
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
30
use Rs\Json\Patch;
31
use Rs\Json\Patch\InvalidPatchDocumentJsonException;
32
use Rs\Json\Patch\InvalidTargetDocumentJsonException;
33
use Rs\Json\Patch\InvalidOperationException;
34
use Rs\Json\Patch\FailedTestException;
35
use Graviton\RestBundle\Service\JsonPatchValidator;
36
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
37
38
/**
39
 * This is a basic rest controller. It should fit the most needs but if you need to add some
40
 * extra functionality you can extend it and overwrite single/all actions.
41
 * You can also extend the model class to add some extra logic before save
42
 *
43
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
44
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
45
 * @link     http://swisscom.ch
46
 */
47
class RestController
48
{
49
    /**
50
     * @var DocumentModel
51
     */
52
    private $model;
53
54
    /**
55
     * @var ContainerInterface service_container
56
     */
57
    private $container;
58
59
    /**
60
     * @var Response
61
     */
62
    private $response;
63
64
    /**
65
     * @var RestUtilsInterface
66
     */
67
    private $restUtils;
68
69
    /**
70
     * @var SchemaUtils
71
     */
72
    private $schemaUtils;
73
74
    /**
75
     * @var Router
76
     */
77
    private $router;
78
79
    /**
80
     * @var EngineInterface
81
     */
82
    private $templating;
83
84
    /**
85
     * @var JsonPatchValidator
86
     */
87
    private $jsonPatchValidator;
88
89
    /**
90
     * @var TokenStorage
91
     */
92
    protected $tokenStorage;
93
94
    /**
95
     * @param Response           $response    Response
96
     * @param RestUtilsInterface $restUtils   Rest utils
97
     * @param Router             $router      Router
98
     * @param EngineInterface    $templating  Templating
99
     * @param ContainerInterface $container   Container
100
     * @param SchemaUtils        $schemaUtils Schema utils
101
     */
102 4
    public function __construct(
103
        Response $response,
104
        RestUtilsInterface $restUtils,
105
        Router $router,
106
        EngineInterface $templating,
107
        ContainerInterface $container,
108
        SchemaUtils $schemaUtils
109
    ) {
110 4
        $this->response = $response;
111 4
        $this->restUtils = $restUtils;
112 4
        $this->router = $router;
113 4
        $this->templating = $templating;
114 4
        $this->container = $container;
115 4
        $this->schemaUtils = $schemaUtils;
116 4
    }
117
118
    /**
119
     * Setter for the tokenStorage
120
     *
121
     * @param TokenStorage $tokenStorage The token storage
122
     * @return void
123
     */
124 4
    public function setTokenStorage(TokenStorage $tokenStorage)
125
    {
126 4
        $this->tokenStorage = $tokenStorage;
127 4
    }
128
129
    /**
130
     * @param JsonPatchValidator $jsonPatchValidator Service for validation json patch
131
     * @return void
132
     */
133 4
    public function setJsonPatchValidator(JsonPatchValidator $jsonPatchValidator)
134
    {
135 4
        $this->jsonPatchValidator = $jsonPatchValidator;
136 4
    }
137
138
    /**
139
     * Get the container object
140
     *
141
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
142
     *
143
     * @obsolete
144
     */
145
    public function getContainer()
146
    {
147
        return $this->container;
148
    }
149
150
    /**
151
     * Returns a single record
152
     *
153
     * @param Request $request Current http request
154
     * @param string  $id      ID of record
155
     *
156
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
157
     */
158 4
    public function getAction(Request $request, $id)
159
    {
160 4
        $response = $this->getResponse()
161 4
            ->setStatusCode(Response::HTTP_OK);
162
163 4
        $record = $this->findRecord($id);
164
165 4
        return $this->render(
166 4
            'GravitonRestBundle:Main:index.json.twig',
167 4
            ['response' => $this->serialize($record)],
0 ignored issues
show
Bug introduced by
It seems like $record defined by $this->findRecord($id) on line 163 can also be of type null; however, Graviton\RestBundle\Cont...Controller::serialize() does only seem to accept object|array<integer,object>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
168
            $response
169 2
        );
170
    }
171
172
    /**
173
     * Get the response object
174
     *
175
     * @return \Symfony\Component\HttpFoundation\Response $response Response object
176
     */
177 4
    public function getResponse()
178
    {
179 4
        return $this->response;
180
    }
181
182
    /**
183
     * Get a single record from database or throw an exception if it doesn't exist
184
     *
185
     * @param mixed $id Record id
186
     *
187
     * @throws \Graviton\ExceptionBundle\Exception\NotFoundException
188
     *
189
     * @return object $record Document object
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
190
     */
191 4
    protected function findRecord($id)
192
    {
193 4
        $response = $this->getResponse();
194
195 4
        if (!($this->getModel()->recordExists($id))) {
196
            $e = new NotFoundException("Entry with id " . $id . " not found!");
197
            $e->setResponse($response);
198
            throw $e;
199
        }
200
201 4
        return $this->getModel()->find($id);
202
    }
203
204
    /**
205
     * Return the model
206
     *
207
     * @throws \Exception in case no model was defined.
208
     *
209
     * @return DocumentModel $model Model
210
     */
211 4
    public function getModel()
212
    {
213 4
        if (!$this->model) {
214
            throw new \Exception('No model is set for this controller');
215
        }
216
217 4
        return $this->model;
218
    }
219
220
    /**
221
     * Set the model class
222
     *
223
     * @param DocumentModel $model Model class
224
     *
225
     * @return self
226
     */
227 4
    public function setModel(DocumentModel $model)
228
    {
229 4
        $this->model = $model;
230
231 4
        return $this;
232
    }
233
234
    /**
235
     * Serialize the given record and throw an exception if something went wrong
236
     *
237
     * @param object|object[] $result Record(s)
238
     *
239
     * @throws \Graviton\ExceptionBundle\Exception\SerializationException
240
     *
241
     * @return string $content Json content
242
     */
243 4
    protected function serialize($result)
244
    {
245 4
        $response = $this->getResponse();
246
247
        try {
248
            // array is serialized as an object {"0":{...},"1":{...},...} when data contains an empty objects
249
            // we serialize each item because we can assume this bug affects only root array element
250 4
            if (is_array($result) && array_keys($result) === range(0, count($result) - 1)) {
251
                $result = array_map(
252
                    function ($item) {
253
                        return $this->getRestUtils()->serializeContent($item);
254
                    },
255
                    $result
256
                );
257
258
                /*
259
                 * clean up:
260
                 *
261
                 * - remove empty entries
262
                 */
263
                $result = array_filter($result);
264
265
                return '['.implode(',', $result).']';
266
            }
267
268 4
            return $this->getRestUtils()->serializeContent($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by parameter $result on line 243 can also be of type array; however, Graviton\RestBundle\Serv...ils::serializeContent() does only seem to accept object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
269
        } catch (\Exception $e) {
270
            $exception = new SerializationException($e);
271
            $exception->setResponse($response);
272
            throw $exception;
273
        }
274
    }
275
276
    /**
277
     * Get RestUtils service
278
     *
279
     * @return \Graviton\RestBundle\Service\RestUtils
280
     */
281 4
    public function getRestUtils()
282
    {
283 4
        return $this->restUtils;
284
    }
285
286
    /**
287
     * Returns all records
288
     *
289
     * @param Request $request Current http request
290
     *
291
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
292
     */
293
    public function allAction(Request $request)
294
    {
295
        $model = $this->getModel();
296
297
        list(, , , $modelName, ) = explode('.', $request->attributes->get('_route'));
298
299
        $schema = $this->schemaUtils->getModelSchema($modelName, $model);
300
301
        // Security is optional configured in Parameters
302
        try {
303
            /** @var SecurityUser $securityUser */
304
            $securityUser = $this->getSecurityUser();
305
        } catch (PreconditionRequiredHttpException $e) {
306
            $securityUser = null;
307
        }
308
309
        if ($model instanceof PaginatorAwareInterface && !$model->hasPaginator()) {
310
            $paginator = new Paginator();
311
            $model->setPaginator($paginator);
312
        }
313
314
        $response = $this->getResponse()
315
            ->setStatusCode(Response::HTTP_OK);
316
317
        return $this->render(
318
            'GravitonRestBundle:Main:index.json.twig',
319
            ['response' => $this->serialize($model->findAll($request, $securityUser, $schema))],
320
            $response
321
        );
322
    }
323
324
    /**
325
     * Writes a new Entry to the database
326
     *
327
     * @param Request $request Current http request
328
     *
329
     * @return \Symfony\Component\HttpFoundation\Response $response Result of action with data (if successful)
330
     */
331
    public function postAction(Request $request)
332
    {
333
        // Get the response object from container
334
        $response = $this->getResponse();
335
        $model = $this->getModel();
336
337
        $this->restUtils->checkJsonRequest($request, $response, $this->getModel());
338
339
        $record = $this->validateRequest($request->getContent(), $model);
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, Graviton\RestBundle\Cont...ller::validateRequest() does only seem to accept object|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
340
341
        // Insert the new record
342
        $record = $this->getModel()->insertRecord($record);
343
344
        // store id of new record so we dont need to reparse body later when needed
345
        $request->attributes->set('id', $record->getId());
346
347
        // Set status code
348
        $response->setStatusCode(Response::HTTP_CREATED);
349
350
        $response->headers->set(
351
            'Location',
352
            $this->getRouter()->generate($this->getRouteName($request), array('id' => $record->getId()))
353
        );
354
355
        return $response;
356
    }
357
358
    /**
359
     * Validates the current request on schema violations. If there are errors,
360
     * the exception is thrown. If not, the deserialized record is returned.
361
     *
362
     * @param object|string $content \stdClass of the request content
363
     * @param DocumentModel $model   the model to check the schema for
364
     *
365
     * @return \Graviton\JsonSchemaBundle\Exception\ValidationExceptionError[]
0 ignored issues
show
Documentation introduced by
Should the return type not be object|array|integer|double|string|boolean? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
366
     * @throws \Exception
367
     */
368 4
    protected function validateRequest($content, DocumentModel $model)
369
    {
370 4
        $errors = $this->restUtils->validateContent($content, $model);
371 4
        if (!empty($errors)) {
372 2
            throw new ValidationException($errors);
373
        }
374 2
        return $this->deserialize($content, $model->getEntityClass());
0 ignored issues
show
Bug introduced by
It seems like $content defined by parameter $content on line 368 can also be of type object; however, Graviton\RestBundle\Cont...ntroller::deserialize() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
375
    }
376
377
    /**
378
     * Deserialize the given content throw an exception if something went wrong
379
     *
380
     * @param string $content       Request content
381
     * @param string $documentClass Document class
382
     *
383
     * @throws DeserializationException
384
     *
385
     * @return object $record Document
0 ignored issues
show
Documentation introduced by
Should the return type not be object|array|integer|double|string|boolean? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
386
     */
387 2
    protected function deserialize($content, $documentClass)
388
    {
389 2
        $response = $this->getResponse();
390
391
        try {
392 2
            $record = $this->getRestUtils()->deserializeContent(
393 1
                $content,
394
                $documentClass
395 1
            );
396 1
        } catch (\Exception $e) {
397
            // pass the previous exception in this case to get the error message in the handler
398
            // http://php.net/manual/de/exception.getprevious.php
399
            $exception = new DeserializationException("Deserialization failed", $e);
400
401
            // at the moment, the response has to be set on the exception object.
402
            // try to refactor this and return the graviton.rest.response if none is set...
403
            $exception->setResponse($response);
404
            throw $exception;
405
        }
406
407 2
        return $record;
408
    }
409
410
    /**
411
     * Get the router from the dic
412
     *
413
     * @return Router
414
     */
415
    public function getRouter()
416
    {
417
        return $this->router;
418
    }
419
420
    /**
421
     * Update a record
422
     *
423
     * @param Number  $id      ID of record
424
     * @param Request $request Current http request
425
     *
426
     * @throws MalformedInputException
427
     *
428
     * @return Response $response Result of action with data (if successful)
429
     */
430 4
    public function putAction($id, Request $request)
431
    {
432 4
        $response = $this->getResponse();
433 4
        $model = $this->getModel();
434
435 4
        $this->restUtils->checkJsonRequest($request, $response, $this->getModel());
436
437 4
        $record = $this->validateRequest($request->getContent(), $model);
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, Graviton\RestBundle\Cont...ller::validateRequest() does only seem to accept object|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
438
439
        // handle missing 'id' field in input to a PUT operation
440
        // if it is settable on the document, let's set it and move on.. if not, inform the user..
441 2
        if ($record->getId() != $id) {
442
            // try to set it..
443
            if (is_callable(array($record, 'setId'))) {
444
                $record->setId($id);
445
            } else {
446
                throw new MalformedInputException('No ID was supplied in the request payload.');
447
            }
448
        }
449
450
        // And update the record, if everything is ok
451 2
        if (!$this->getModel()->recordExists($id)) {
452
            $this->getModel()->insertRecord($record, false);
453
        } else {
454 2
            $this->getModel()->updateRecord($id, $record, false);
455
        }
456
457
        // Set status code
458 2
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
459
460
        // store id of new record so we dont need to reparse body later when needed
461 2
        $request->attributes->set('id', $record->getId());
462
463 2
        return $response;
464
    }
465
466
    /**
467
     * Patch a record
468
     *
469
     * @param Number  $id      ID of record
470
     * @param Request $request Current http request
471
     *
472
     * @throws MalformedInputException
473
     *
474
     * @return Response $response Result of action with data (if successful)
475
     */
476
    public function patchAction($id, Request $request)
477
    {
478
        $response = $this->getResponse();
479
480
        // Check JSON Patch request
481
        $this->restUtils->checkJsonRequest($request, $response, $this->getModel());
482
        $this->restUtils->checkJsonPatchRequest(json_decode($request->getContent(), 1));
483
484
        // Find record && apply $ref converter
485
        $record = $this->findRecord($id);
486
        $jsonDocument = $this->serialize($record);
0 ignored issues
show
Bug introduced by
It seems like $record defined by $this->findRecord($id) on line 485 can also be of type null; however, Graviton\RestBundle\Cont...Controller::serialize() does only seem to accept object|array<integer,object>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
487
488
        // Check/validate JSON Patch
489
        if (!$this->jsonPatchValidator->validate($jsonDocument, $request->getContent())) {
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, Graviton\RestBundle\Serv...chValidator::validate() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
490
            throw new InvalidJsonPatchException($this->jsonPatchValidator->getException()->getMessage());
491
        }
492
493
        try {
494
            // Apply JSON patches
495
            $patch = new Patch($jsonDocument, $request->getContent());
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, Rs\Json\Patch::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
496
            $patchedDocument = $patch->apply();
497
        } catch (InvalidPatchDocumentJsonException $e) {
498
            throw new InvalidJsonPatchException($e->getMessage());
499
        } catch (InvalidTargetDocumentJsonException $e) {
500
            throw new InvalidJsonPatchException($e->getMessage());
501
        } catch (InvalidOperationException $e) {
502
            throw new InvalidJsonPatchException($e->getMessage());
503
        } catch (FailedTestException $e) {
504
            throw new InvalidJsonPatchException($e->getMessage());
505
        }
506
507
        // Validate result object
508
        $model = $this->getModel();
509
        $record = $this->validateRequest($patchedDocument, $model);
510
511
        // Update object
512
        $this->getModel()->updateRecord($id, $record);
513
514
        // Set status code
515
        $response->setStatusCode(Response::HTTP_OK);
516
517
        // Set Content-Location header
518
        $response->headers->set(
519
            'Content-Location',
520
            $this->getRouter()->generate($this->getRouteName($request), array('id' => $record->getId()))
521
        );
522
523
        return $response;
524
    }
525
526
    /**
527
     * Deletes a record
528
     *
529
     * @param Number $id ID of record
530
     *
531
     * @return Response $response Result of the action
532
     */
533
    public function deleteAction($id)
534
    {
535
        $response = $this->getResponse();
536
537
        // does this record exist?
538
        $this->findRecord($id);
539
540
        $this->getModel()->deleteRecord($id);
541
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
542
543
        return $response;
544
    }
545
546
    /**
547
     * Return OPTIONS results.
548
     *
549
     * @param Request $request Current http request
550
     *
551
     * @throws SerializationException
552
     * @return \Symfony\Component\HttpFoundation\Response $response Result of the action
553
     */
554
    public function optionsAction(Request $request)
555
    {
556
        list($app, $module, , $modelName) = explode('.', $request->attributes->get('_route'));
557
558
        $response = $this->response;
559
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
560
561
        // enabled methods for CorsListener
562
        $corsMethods = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
563
        try {
564
            $router = $this->getRouter();
565
            // if post route is available we assume everything is readable
566
            $router->generate(implode('.', array($app, $module, 'rest', $modelName, 'post')));
567
        } catch (RouteNotFoundException $exception) {
568
            // only allow read methods
569
            $corsMethods = 'GET, OPTIONS';
570
        }
571
        $request->attributes->set('corsMethods', $corsMethods);
572
573
        return $response;
574
    }
575
576
577
    /**
578
     * Return schema GET results.
579
     *
580
     * @param Request $request Current http request
581
     * @param string  $id      ID of record
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
582
     *
583
     * @throws SerializationException
584
     * @return \Symfony\Component\HttpFoundation\Response $response Result of the action
585
     */
586
    public function schemaAction(Request $request, $id = null)
587
    {
588
        $request->attributes->set('schemaRequest', true);
589
590
        list($app, $module, , $modelName, $schemaType) = explode('.', $request->attributes->get('_route'));
591
592
        $response = $this->response;
593
        $response->setStatusCode(Response::HTTP_OK);
594
        $response->setPublic();
595
596
        if (!$id && $schemaType != 'canonicalIdSchema') {
597
            $schema = $this->schemaUtils->getCollectionSchema($modelName, $this->getModel());
598
        } else {
599
            $schema = $this->schemaUtils->getModelSchema($modelName, $this->getModel());
600
        }
601
602
        // enabled methods for CorsListener
603
        $corsMethods = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
604
        try {
605
            $router = $this->getRouter();
606
            // if post route is available we assume everything is readable
607
            $router->generate(implode('.', array($app, $module, 'rest', $modelName, 'post')));
608
        } catch (RouteNotFoundException $exception) {
609
            // only allow read methods
610
            $corsMethods = 'GET, OPTIONS';
611
        }
612
        $request->attributes->set('corsMethods', $corsMethods);
613
614
615
        return $this->render(
616
            'GravitonRestBundle:Main:index.json.twig',
617
            ['response' => $this->serialize($schema)],
618
            $response
619
        );
620
    }
621
622
    /**
623
     * Renders a view.
624
     *
625
     * @param string   $view       The view name
626
     * @param array    $parameters An array of parameters to pass to the view
627
     * @param Response $response   A response instance
0 ignored issues
show
Documentation introduced by
Should the type for parameter $response not be null|Response?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
628
     *
629
     * @return Response A Response instance
630
     */
631 4
    public function render($view, array $parameters = array(), Response $response = null)
632
    {
633 4
        return $this->templating->renderResponse($view, $parameters, $response);
634
    }
635
636
    /**
637
     * @param Request $request request
638
     * @return string
639
     */
640
    private function getRouteName(Request $request)
641
    {
642
        $routeName = $request->get('_route');
643
        $routeParts = explode('.', $routeName);
644
        $routeType = end($routeParts);
645
646
        if ($routeType == 'post') {
647
            $routeName = substr($routeName, 0, -4) . 'get';
648
        }
649
650
        return $routeName;
651
    }
652
653
    /**
654
     * Security needs to be enabled to get Object.
655
     *
656
     * @return SecurityUser
0 ignored issues
show
Documentation introduced by
Should the return type not be UserInterface?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
657
     * @throws PreconditionRequiredHttpException
658
     */
659
    public function getSecurityUser()
660
    {
661
        /** @var PreAuthenticatedToken $token */
662
        if (($token = $this->tokenStorage->getToken())
663
            && ($user = $token->getUser()) instanceof UserInterface ) {
664
            return $user;
665
        }
666
667
        throw new PreconditionRequiredHttpException('Not allowed');
668
    }
669
}
670