Completed
Push — feature/other-validation ( 38b732...170da2 )
by Narcotic
107:06 queued 42:20
created

RestController::putAction()   B

Complexity

Conditions 7
Paths 22

Size

Total Lines 63
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 63
ccs 0
cts 33
cp 0
rs 7.2689
cc 7
eloc 33
nc 22
nop 2
crap 56

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * basic rest controller
4
 */
5
6
namespace Graviton\RestBundle\Controller;
7
8
use Graviton\DocumentBundle\Service\FormDataMapperInterface;
9
use Graviton\ExceptionBundle\Exception\DeserializationException;
10
use Graviton\ExceptionBundle\Exception\InvalidJsonPatchException;
11
use Graviton\ExceptionBundle\Exception\MalformedInputException;
12
use Graviton\ExceptionBundle\Exception\NotFoundException;
13
use Graviton\ExceptionBundle\Exception\SerializationException;
14
use Graviton\JsonSchemaBundle\Exception\ValidationException;
15
use Graviton\JsonSchemaBundle\Schema\RefResolver;
16
use Graviton\JsonSchemaBundle\Schema\SchemaFactory;
17
use Graviton\JsonSchemaBundle\Validator\Validator;
18
use Graviton\RestBundle\Validator\Form;
19
use Graviton\RestBundle\Model\DocumentModel;
20
use Graviton\RestBundle\Model\PaginatorAwareInterface;
21
use Graviton\SchemaBundle\SchemaUtils;
22
use Graviton\DocumentBundle\Form\Type\DocumentType;
23
use Graviton\RestBundle\Service\RestUtilsInterface;
24
use HadesArchitect\JsonSchemaBundle\Validator\ValidatorService;
25
use Symfony\Component\Security\Core\User\UserInterface;
26
use Knp\Component\Pager\Paginator;
27
use Symfony\Component\DependencyInjection\ContainerInterface;
28
use Symfony\Component\HttpFoundation\Request;
29
use Symfony\Component\HttpFoundation\Response;
30
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
31
use Symfony\Component\Routing\Exception\RouteNotFoundException;
32
use Symfony\Component\Form\FormFactory;
33
use Symfony\Bundle\FrameworkBundle\Routing\Router;
34
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
35
use Symfony\Component\Validator\Validator\ValidatorInterface;
36
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
37
use Rs\Json\Patch;
38
use Rs\Json\Patch\InvalidPatchDocumentJsonException;
39
use Rs\Json\Patch\InvalidTargetDocumentJsonException;
40
use Rs\Json\Patch\InvalidOperationException;
41
use Rs\Json\Patch\FailedTestException;
42
use Graviton\RestBundle\Service\JsonPatchValidator;
43
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
44
45
/**
46
 * This is a basic rest controller. It should fit the most needs but if you need to add some
47
 * extra functionality you can extend it and overwrite single/all actions.
48
 * You can also extend the model class to add some extra logic before save
49
 *
50
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
51
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
52
 * @link     http://swisscom.ch
53
 */
54
class RestController
55
{
56
    /**
57
     * @var DocumentModel
58
     */
59
    private $model;
60
61
    /**
62
     * @var ContainerInterface service_container
63
     */
64
    private $container;
65
66
    /**
67
     * @var Response
68
     */
69
    private $response;
70
71
    /**
72
     * @var FormFactory
73
     */
74
    private $formFactory;
75
76
    /**
77
     * @var DocumentType
78
     */
79
    private $formType;
80
81
    /**
82
     * @var RestUtilsInterface
83
     */
84
    private $restUtils;
85
86
    /**
87
     * @var SchemaUtils
88
     */
89
    private $schemaUtils;
90
91
    /**
92
     * @var FormDataMapperInterface
93
     */
94
    protected $formDataMapper;
95
96
    /**
97
     * @var Router
98
     */
99
    private $router;
100
101
    /**
102
     * @var ValidatorInterface
103
     */
104
    private $validator;
105
106
    /**
107
     * @var EngineInterface
108
     */
109
    private $templating;
110
111
    /**
112
     * @var JsonPatchValidator
113
     */
114
    private $jsonPatchValidator;
115
116
    /**
117
     * @var Form
118
     */
119
    protected $formValidator;
120
121
    /**
122
     * @var TokenStorage
123
     */
124
    protected $tokenStorage;
125
126
    /**
127
     * @param Response           $response    Response
128
     * @param RestUtilsInterface $restUtils   Rest utils
129
     * @param Router             $router      Router
130
     * @param ValidatorInterface $validator   Validator
131
     * @param EngineInterface    $templating  Templating
132
     * @param FormFactory        $formFactory form factory
133
     * @param DocumentType       $formType    generic form
134
     * @param ContainerInterface $container   Container
135
     * @param SchemaUtils        $schemaUtils Schema utils
136
     */
137
    public function __construct(
138
        Response $response,
139
        RestUtilsInterface $restUtils,
140
        Router $router,
141
        ValidatorInterface $validator,
142
        EngineInterface $templating,
143
        FormFactory $formFactory,
144
        DocumentType $formType,
145
        ContainerInterface $container,
146
        SchemaUtils $schemaUtils
147
    ) {
148
        $this->response = $response;
149
        $this->restUtils = $restUtils;
150
        $this->router = $router;
151
        $this->validator = $validator;
152
        $this->templating = $templating;
153
        $this->formFactory = $formFactory;
154
        $this->formType = $formType;
155
        $this->container = $container;
156
        $this->schemaUtils = $schemaUtils;
157
    }
158
159
    /**
160
     * Setter for the tokenStorage
161
     *
162
     * @param TokenStorage $tokenStorage The token storage
163
     * @return void
164
     */
165
    public function setTokenStorage(TokenStorage $tokenStorage)
166
    {
167
        $this->tokenStorage = $tokenStorage;
168
    }
169
170
    /**
171
     * Set form data mapper
172
     *
173
     * @param FormDataMapperInterface $formDataMapper Form data mapper
174
     * @return void
175
     */
176
    public function setFormDataMapper(FormDataMapperInterface $formDataMapper)
177
    {
178
        $this->formDataMapper = $formDataMapper;
179
    }
180
181
    /**
182
     * @param JsonPatchValidator $jsonPatchValidator Service for validation json patch
183
     * @return void
184
     */
185
    public function setJsonPatchValidator(JsonPatchValidator $jsonPatchValidator)
186
    {
187
        $this->jsonPatchValidator = $jsonPatchValidator;
188
    }
189
190
    /**
191
     * Defines the Form validator to be used.
192
     *
193
     * @param Form $validator Validator to be used
194
     *
195
     * @return void
196
     */
197
    public function setFormValidator(Form $validator)
198
    {
199
        $this->formValidator = $validator;
200
    }
201
202
    /**
203
     * Get the container object
204
     *
205
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
206
     *
207
     * @obsolete
208
     */
209
    public function getContainer()
210
    {
211
        return $this->container;
212
    }
213
214
    /**
215
     * Returns a single record
216
     *
217
     * @param Request $request Current http request
218
     * @param string  $id      ID of record
219
     *
220
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
221
     */
222
    public function getAction(Request $request, $id)
223
    {
224
        $response = $this->getResponse()
225
            ->setStatusCode(Response::HTTP_OK);
226
227
        $record = $this->findRecord($id);
228
229
        return $this->render(
230
            'GravitonRestBundle:Main:index.json.twig',
231
            ['response' => $this->serialize($record)],
232
            $response
233
        );
234
    }
235
236
    /**
237
     * Get the response object
238
     *
239
     * @return \Symfony\Component\HttpFoundation\Response $response Response object
240
     */
241
    public function getResponse()
242
    {
243
        return $this->response;
244
    }
245
246
    /**
247
     * Get a single record from database or throw an exception if it doesn't exist
248
     *
249
     * @param mixed $id Record id
250
     *
251
     * @throws \Graviton\ExceptionBundle\Exception\NotFoundException
252
     *
253
     * @return object $record Document object
254
     */
255
    protected function findRecord($id)
256
    {
257
        $response = $this->getResponse();
258
259
        if (!($record = $this->getModel()->find($id))) {
260
            $e = new NotFoundException("Entry with id " . $id . " not found!");
261
            $e->setResponse($response);
262
            throw $e;
263
        }
264
265
        return $record;
266
    }
267
268
    /**
269
     * Return the model
270
     *
271
     * @throws \Exception in case no model was defined.
272
     *
273
     * @return DocumentModel $model Model
274
     */
275
    public function getModel()
276
    {
277
        if (!$this->model) {
278
            throw new \Exception('No model is set for this controller');
279
        }
280
281
        return $this->model;
282
    }
283
284
    /**
285
     * Set the model class
286
     *
287
     * @param DocumentModel $model Model class
288
     *
289
     * @return self
290
     */
291
    public function setModel(DocumentModel $model)
292
    {
293
        $this->model = $model;
294
295
        return $this;
296
    }
297
298
    /**
299
     * Serialize the given record and throw an exception if something went wrong
300
     *
301
     * @param object|object[] $result Record(s)
302
     *
303
     * @throws \Graviton\ExceptionBundle\Exception\SerializationException
304
     *
305
     * @return string $content Json content
306
     */
307
    protected function serialize($result)
308
    {
309
        $response = $this->getResponse();
310
311
        try {
312
            // array is serialized as an object {"0":{...},"1":{...},...} when data contains an empty objects
313
            // we serialize each item because we can assume this bug affects only root array element
314
            if (is_array($result) && array_keys($result) === range(0, count($result) - 1)) {
315
                $result = array_map(
316
                    function ($item) {
317
                        return $this->getRestUtils()->serializeContent($item);
318
                    },
319
                    $result
320
                );
321
322
                /*
323
                 * clean up:
324
                 *
325
                 * - remove empty entries
326
                 */
327
                $result = array_filter($result);
328
329
                return '['.implode(',', $result).']';
330
            }
331
332
            return $this->getRestUtils()->serializeContent($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by parameter $result on line 307 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...
333
        } catch (\Exception $e) {
334
            $exception = new SerializationException($e);
335
            $exception->setResponse($response);
336
            throw $exception;
337
        }
338
    }
339
340
    /**
341
     * Get RestUtils service
342
     *
343
     * @return \Graviton\RestBundle\Service\RestUtils
344
     */
345
    public function getRestUtils()
346
    {
347
        return $this->restUtils;
348
    }
349
350
    /**
351
     * Returns all records
352
     *
353
     * @param Request $request Current http request
354
     *
355
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
356
     */
357
    public function allAction(Request $request)
358
    {
359
        $model = $this->getModel();
360
361
        list($app, $module, , $modelName, $schemaType) = explode('.', $request->attributes->get('_route'));
362
363
        $schema = $this->schemaUtils->getModelSchema($modelName, $model);
364
365
        // Security is optional configured in Parameters
366
        try {
367
            /** @var SecurityUser $securityUser */
368
            $securityUser = $this->getSecurityUser();
369
        } catch (PreconditionRequiredHttpException $e) {
370
            $securityUser = null;
371
        }
372
373
        if ($model instanceof PaginatorAwareInterface && !$model->hasPaginator()) {
374
            $paginator = new Paginator();
375
            $model->setPaginator($paginator);
376
        }
377
378
        $response = $this->getResponse()
379
            ->setStatusCode(Response::HTTP_OK);
380
381
        return $this->render(
382
            'GravitonRestBundle:Main:index.json.twig',
383
            ['response' => $this->serialize($model->findAll($request, $securityUser, $schema))],
384
            $response
385
        );
386
    }
387
388
    /**
389
     * Writes a new Entry to the database
390
     *
391
     * @param Request $request Current http request
392
     *
393
     * @return \Symfony\Component\HttpFoundation\Response $response Result of action with data (if successful)
394
     */
395
    public function postAction(Request $request)
396
    {
397
        // Get the response object from container
398
        $response = $this->getResponse();
399
        $model = $this->getModel();
400
401
        $this->formValidator->checkJsonRequest($request, $response);
402
        $record = $this->formValidator->checkForm(
403
            $this->formValidator->getForm($request, $model),
404
            $model,
405
            $this->formDataMapper,
406
            $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\Validator\Form::checkForm() 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...
407
        );
408
409
        // Insert the new record
410
        $record = $this->getModel()->insertRecord($record);
411
412
        // store id of new record so we dont need to reparse body later when needed
413
        $request->attributes->set('id', $record->getId());
414
415
        // Set status code
416
        $response->setStatusCode(Response::HTTP_CREATED);
417
418
        $response->headers->set(
419
            'Location',
420
            $this->getRouter()->generate($this->getRouteName($request), array('id' => $record->getId()))
421
        );
422
423
        return $response;
424
    }
425
426
    /**
427
     * Deserialize the given content throw an exception if something went wrong
428
     *
429
     * @param string $content       Request content
430
     * @param string $documentClass Document class
431
     *
432
     * @throws DeserializationException
433
     *
434
     * @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...
435
     */
436
    protected function deserialize($content, $documentClass)
437
    {
438
        $response = $this->getResponse();
439
440
        try {
441
            $record = $this->getRestUtils()->deserializeContent(
442
                $content,
443
                $documentClass
444
            );
445
        } catch (\Exception $e) {
446
            // pass the previous exception in this case to get the error message in the handler
447
            // http://php.net/manual/de/exception.getprevious.php
448
            $exception = new DeserializationException("Deserialization failed", $e);
449
450
            // at the moment, the response has to be set on the exception object.
451
            // try to refactor this and return the graviton.rest.response if none is set...
452
            $exception->setResponse($response);
453
            throw $exception;
454
        }
455
456
        return $record;
457
    }
458
459
    /**
460
     * Get the router from the dic
461
     *
462
     * @return Router
463
     */
464
    public function getRouter()
465
    {
466
        return $this->router;
467
    }
468
469
    /**
470
     * Update a record
471
     *
472
     * @param Number  $id      ID of record
473
     * @param Request $request Current http request
474
     *
475
     * @throws MalformedInputException
476
     *
477
     * @return Response $response Result of action with data (if successful)
478
     */
479
    public function putAction($id, Request $request)
480
    {
481
        $response = $this->getResponse();
482
        $model = $this->getModel();
483
484
        $this->formValidator->checkJsonRequest($request, $response);
485
486
        list(, , , $modelName, ) = explode('.', $request->attributes->get('_route'));
487
488
        $file = '/tmp/hans-'.$modelName;
489
490
        if (!file_exists($file)) {
491
            $schema = $this->getRestUtils()->serializeContent($this->schemaUtils->getModelSchema($modelName, $this->getModel()));
492
            file_put_contents($file, $schema);
493
        } else {
494
            $schema = file_get_contents($file);
495
        }
496
497
        // put on DIC dep asap
498
        $validator = $this->container->get('graviton.jsonschema.validator');
499
        $errors = $validator->validate(json_decode($request->getContent()), json_decode($schema));
500
501
        if (!empty($errors)) {
502
            throw new ValidationException($errors);
503
        }
504
505
        $record = $this->getRestUtils()->deserializeContent($request->getContent(), $model->getEntityClass());
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...s::deserializeContent() 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...
506
507
        // does it really exist??
508
        $upsert = false;
509
        try {
510
            $this->findRecord($id);
511
        } catch (NotFoundException $e) {
512
            // who cares, we'll upsert it
513
            $upsert = true;
514
        }
515
516
        // handle missing 'id' field in input to a PUT operation
517
        // if it is settable on the document, let's set it and move on.. if not, inform the user..
518
        if ($record->getId() != $id) {
519
            // try to set it..
520
            if (is_callable(array($record, 'setId'))) {
521
                $record->setId($id);
522
            } else {
523
                throw new MalformedInputException('No ID was supplied in the request payload.');
524
            }
525
        }
526
527
        // And update the record, if everything is ok
528
        if ($upsert) {
529
            $this->getModel()->insertRecord($record);
530
        } else {
531
            $this->getModel()->updateRecord($id, $record);
532
        }
533
534
        // Set status code
535
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
536
537
        // store id of new record so we dont need to reparse body later when needed
538
        $request->attributes->set('id', $record->getId());
539
540
        return $response;
541
    }
542
543
    /**
544
     * Patch a record
545
     *
546
     * @param Number  $id      ID of record
547
     * @param Request $request Current http request
548
     *
549
     * @throws MalformedInputException
550
     *
551
     * @return Response $response Result of action with data (if successful)
552
     */
553
    public function patchAction($id, Request $request)
554
    {
555
        $response = $this->getResponse();
556
        $this->formValidator->checkJsonRequest($request, $response);
557
558
        // Check JSON Patch request
559
        $this->formValidator->checkJsonPatchRequest(json_decode($request->getContent(), 1));
560
561
        // Find record && apply $ref converter
562
        $record = $this->findRecord($id);
563
        $jsonDocument = $this->serialize($record);
564
565
        // Check/validate JSON Patch
566
        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...
567
            throw new InvalidJsonPatchException($this->jsonPatchValidator->getException()->getMessage());
568
        }
569
570
        try {
571
            // Apply JSON patches
572
            $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...
573
            $patchedDocument = $patch->apply();
574
        } catch (InvalidPatchDocumentJsonException $e) {
575
            throw new InvalidJsonPatchException($e->getMessage());
576
        } catch (InvalidTargetDocumentJsonException $e) {
577
            throw new InvalidJsonPatchException($e->getMessage());
578
        } catch (InvalidOperationException $e) {
579
            throw new InvalidJsonPatchException($e->getMessage());
580
        } catch (FailedTestException $e) {
581
            throw new InvalidJsonPatchException($e->getMessage());
582
        }
583
584
        // Validate result object
585
        $model = $this->getModel();
586
        $record = $this->formValidator->checkForm(
587
            $this->formValidator->getForm($request, $model),
588
            $model,
589
            $this->formDataMapper,
590
            $patchedDocument
591
        );
592
593
        // Update object
594
        $this->getModel()->updateRecord($id, $record);
595
596
        // Set status code
597
        $response->setStatusCode(Response::HTTP_OK);
598
599
        // Set Content-Location header
600
        $response->headers->set(
601
            'Content-Location',
602
            $this->getRouter()->generate($this->getRouteName($request), array('id' => $record->getId()))
603
        );
604
605
        return $response;
606
    }
607
608
    /**
609
     * Deletes a record
610
     *
611
     * @param Number $id ID of record
612
     *
613
     * @return Response $response Result of the action
614
     */
615
    public function deleteAction($id)
616
    {
617
        $response = $this->getResponse();
618
619
        // does this record exist?
620
        $this->findRecord($id);
621
622
        $this->getModel()->deleteRecord($id);
623
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
624
625
        return $response;
626
    }
627
628
    /**
629
     * Return OPTIONS results.
630
     *
631
     * @param Request $request Current http request
632
     *
633
     * @throws SerializationException
634
     * @return \Symfony\Component\HttpFoundation\Response $response Result of the action
635
     */
636
    public function optionsAction(Request $request)
637
    {
638
        list($app, $module, , $modelName) = explode('.', $request->attributes->get('_route'));
639
640
        $response = $this->response;
641
        $response->setStatusCode(Response::HTTP_NO_CONTENT);
642
643
        // enabled methods for CorsListener
644
        $corsMethods = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
645
        try {
646
            $router = $this->getRouter();
647
            // if post route is available we assume everything is readable
648
            $router->generate(implode('.', array($app, $module, 'rest', $modelName, 'post')));
649
        } catch (RouteNotFoundException $exception) {
650
            // only allow read methods
651
            $corsMethods = 'GET, OPTIONS';
652
        }
653
        $request->attributes->set('corsMethods', $corsMethods);
654
655
        return $response;
656
    }
657
658
659
    /**
660
     * Return schema GET results.
661
     *
662
     * @param Request $request Current http request
663
     * @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...
664
     *
665
     * @throws SerializationException
666
     * @return \Symfony\Component\HttpFoundation\Response $response Result of the action
667
     */
668
    public function schemaAction(Request $request, $id = null)
669
    {
670
        $request->attributes->set('schemaRequest', true);
671
672
        list($app, $module, , $modelName, $schemaType) = explode('.', $request->attributes->get('_route'));
673
674
        $response = $this->response;
675
        $response->setStatusCode(Response::HTTP_OK);
676
        $response->setPublic();
677
678
        if (!$id && $schemaType != 'canonicalIdSchema') {
679
            $schema = $this->schemaUtils->getCollectionSchema($modelName, $this->getModel());
680
        } else {
681
            $schema = $this->schemaUtils->getModelSchema($modelName, $this->getModel());
682
        }
683
684
        // enabled methods for CorsListener
685
        $corsMethods = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
686
        try {
687
            $router = $this->getRouter();
688
            // if post route is available we assume everything is readable
689
            $router->generate(implode('.', array($app, $module, 'rest', $modelName, 'post')));
690
        } catch (RouteNotFoundException $exception) {
691
            // only allow read methods
692
            $corsMethods = 'GET, OPTIONS';
693
        }
694
        $request->attributes->set('corsMethods', $corsMethods);
695
696
697
        return $this->render(
698
            'GravitonRestBundle:Main:index.json.twig',
699
            ['response' => $this->serialize($schema)],
700
            $response
701
        );
702
    }
703
704
    /**
705
     * Get the validator
706
     *
707
     * @return ValidatorInterface
708
     */
709
    public function getValidator()
710
    {
711
        return $this->validator;
712
    }
713
714
    /**
715
     * Renders a view.
716
     *
717
     * @param string   $view       The view name
718
     * @param array    $parameters An array of parameters to pass to the view
719
     * @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...
720
     *
721
     * @return Response A Response instance
722
     */
723
    public function render($view, array $parameters = array(), Response $response = null)
724
    {
725
        return $this->templating->renderResponse($view, $parameters, $response);
726
    }
727
728
    /**
729
     * @param Request $request request
730
     * @return string
731
     */
732
    private function getRouteName(Request $request)
733
    {
734
        $routeName = $request->get('_route');
735
        $routeParts = explode('.', $routeName);
736
        $routeType = end($routeParts);
737
738
        if ($routeType == 'post') {
739
            $routeName = substr($routeName, 0, -4) . 'get';
740
        }
741
742
        return $routeName;
743
    }
744
745
    /**
746
     * Security needs to be enabled to get Object.
747
     *
748
     * @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...
749
     * @throws PreconditionRequiredHttpException
750
     */
751
    public function getSecurityUser()
752
    {
753
        /** @var PreAuthenticatedToken $token */
754
        if (($token = $this->tokenStorage->getToken())
755
            && ($user = $token->getUser()) instanceof UserInterface ) {
756
            return $user;
757
        }
758
759
        throw new PreconditionRequiredHttpException('Not allowed');
760
    }
761
}
762