Completed
Push — standalone ( 787e4c...e35bae )
by Philip
07:04
created

RestResourceController::deleteAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 5
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
crap 2
1
<?php
2
3
namespace Dontdrinkandroot\RestBundle\Controller;
4
5
use Doctrine\Common\Util\Inflector;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Doctrine\ORM\Tools\Pagination\Paginator;
8
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Method;
9
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Right;
10
use Dontdrinkandroot\RestBundle\Metadata\ClassMetadata;
11
use Dontdrinkandroot\RestBundle\Metadata\PropertyMetadata;
12
use Dontdrinkandroot\RestBundle\Service\Normalizer;
13
use Dontdrinkandroot\RestBundle\Service\RestRequestParser;
14
use Dontdrinkandroot\Service\CrudServiceInterface;
15
use Metadata\MetadataFactoryInterface;
16
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
17
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\RequestStack;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
23
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
24
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
25
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
26
use Symfony\Component\Validator\ConstraintViolationInterface;
27
use Symfony\Component\Validator\ConstraintViolationListInterface;
28
use Symfony\Component\Validator\Validator\ValidatorInterface;
29
30
class RestResourceController implements ContainerAwareInterface, RestResourceControllerInterface
31
{
32
    use ContainerAwareTrait;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 10
    public function listAction(Request $request)
38
    {
39 10
        $page = $request->query->get('page', 1);
40 10
        $perPage = $request->query->get('perPage', 50);
41
42 10
        $this->assertListGranted();
43
44 6
        $listResult = $this->listEntities($page, $perPage);
45
46 6
        $response = new JsonResponse();
47
48 6
        if ($listResult instanceof Paginator) {
49 6
            $entities = $listResult->getIterator()->getArrayCopy();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method getArrayCopy() does only exist in the following implementations of said interface: ArrayIterator, ArrayObject, DoctrineTest\Instantiato...tAsset\ArrayObjectAsset, DoctrineTest\Instantiato...lizableArrayObjectAsset, DoctrineTest\Instantiato...ceptionArrayObjectAsset, DoctrineTest\Instantiato...sset\WakeUpNoticesAsset, Issue523, RecursiveArrayIterator, Symfony\Component\Finder...rator\InnerNameIterator, Symfony\Component\Finder...rator\InnerSizeIterator, Symfony\Component\Finder...rator\InnerTypeIterator, Symfony\Component\Finder...or\MockFileListIterator, Symfony\Component\Proper...ss\PropertyPathIterator.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
50 6
            $total = $listResult->count();
51 6
            $this->addPaginationHeaders($response, $page, $perPage, $total);
52
        } else {
53
            $entities = $listResult;
54
        }
55
56 6
        $content = $this->getNormalizer()->normalize($entities, $this->parseIncludes($request));
57
58 6
        $response->setData($content);
59
60 6
        return $response;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function postAction(Request $request)
67
    {
68
        $this->assertPostGranted();
69
        $entity = $this->getRequestParser()->parseEntity($request, $this->getEntityClass());
70
        $entity = $this->postProcessPostedEntity($entity);
71
72
        $errors = $this->getValidator()->validate($entity);
73
        if ($errors->count() > 0) {
74
            return new JsonResponse($this->parseConstraintViolations($errors), Response::HTTP_BAD_REQUEST);
75
        }
76
77
        $entity = $this->createEntity($entity);
78
79
        $content = $this->getNormalizer()->normalize($entity);
80
81
        return new JsonResponse($content, Response::HTTP_CREATED);
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 10
    public function getAction(Request $request, $id)
88
    {
89 10
        $entity = $this->fetchEntity($id);
90 10
        $this->assertGetGranted($entity);
91
92 8
        $content = $this->getNormalizer()->normalize($entity, $this->parseIncludes($request, ['details']));
93
94 8
        return new JsonResponse($content);
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 4
    public function putAction(Request $request, $id)
101
    {
102 4
        $entity = $this->fetchEntity($id);
103 4
        $this->assertPutGranted($entity);
104 2
        $entity = $this->getRequestParser()->parseEntity($request, $this->getEntityClass(), $entity);
105 2
        $entity = $this->postProcessPuttedEntity($entity);
106
107 2
        $errors = $this->getValidator()->validate($entity);
108 2
        if ($errors->count() > 0) {
109
            return new JsonResponse($this->parseConstraintViolations($errors), Response::HTTP_BAD_REQUEST);
110
        }
111
112 2
        $entity = $this->updateEntity($entity);
113
114 2
        $content = $this->getNormalizer()->normalize($entity);
115
116 2
        return new JsonResponse($content);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function deleteAction(Request $request, $id)
123
    {
124
        $entity = $this->fetchEntity($id);
125
        $this->assertDeleteGranted($entity);
126
        $this->getService()->remove($entity);
127
128
        return new JsonResponse(null, Response::HTTP_NO_CONTENT);
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134 6
    public function listSubresourceAction(Request $request, $id)
135
    {
136 6
        $page = $request->query->get('page', 1);
137 6
        $perPage = $request->query->get('perPage', 50);
138
139 6
        $subresource = $this->getSubresource();
140 6
        $entity = $this->fetchEntity($id);
141 6
        $this->assertSubresourceListGranted($entity, $subresource);
142
143 6
        $listResult = $this->listSubresource($entity, $subresource, $page, $perPage);
144
145 6
        $response = new JsonResponse();
146
147 6
        if ($listResult instanceof Paginator) {
148 6
            $entities = $listResult->getIterator()->getArrayCopy();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method getArrayCopy() does only exist in the following implementations of said interface: ArrayIterator, ArrayObject, DoctrineTest\Instantiato...tAsset\ArrayObjectAsset, DoctrineTest\Instantiato...lizableArrayObjectAsset, DoctrineTest\Instantiato...ceptionArrayObjectAsset, DoctrineTest\Instantiato...sset\WakeUpNoticesAsset, Issue523, RecursiveArrayIterator, Symfony\Component\Finder...rator\InnerNameIterator, Symfony\Component\Finder...rator\InnerSizeIterator, Symfony\Component\Finder...rator\InnerTypeIterator, Symfony\Component\Finder...or\MockFileListIterator, Symfony\Component\Proper...ss\PropertyPathIterator.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
149 6
            $total = $listResult->count();
150 6
            $this->addPaginationHeaders($response, $page, $perPage, $total);
151
        } else {
152
            $entities = $listResult;
153
        }
154
155 6
        $content = $this->getNormalizer()->normalize($entities, $this->parseIncludes($request));
156
157 6
        $response->setData($content);
158
159 6
        return $response;
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165 4
    public function postSubresourceAction(Request $request, $id)
166
    {
167 4
        $subresource = $this->getSubresource();
168 4
        $parent = $this->fetchEntity($id);
169 4
        $this->assertSubresourcePostGranted($parent, $subresource);
170 2
        $entity = $this->getRequestParser()->parseEntity(
171
            $request,
172 2
            $this->getSubResourceEntityClass($subresource)
173
        );
174 2
        $entity = $this->postProcessSubResourcePostedEntity($subresource, $entity, $parent);
175
176 2
        $errors = $this->getValidator()->validate($entity);
177
178 2
        if ($errors->count() > 0) {
179
            return new JsonResponse($this->parseConstraintViolations($errors), Response::HTTP_BAD_REQUEST);
180
        }
181
182 2
        $entity = $this->createSubResource($parent, $subresource, $entity);
183
184 2
        $content = $this->getNormalizer()->normalize($entity, ['details']);
185
186 2
        return new JsonResponse($content, Response::HTTP_CREATED);
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192 2
    public function putSubresourceAction(Request $request, $id, $subId)
193
    {
194 2
        $subresource = $this->getSubresource();
195 2
        $parent = $this->fetchEntity($id);
196 2
        $this->assertSubresourcePutGranted($parent, $subresource);
197 2
        $this->getService()->addToCollection($parent, $subresource, $subId);
198
199 2
        return new JsonResponse(null, Response::HTTP_NO_CONTENT);
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205 2
    public function deleteSubresourceAction(Request $request, $id, $subId)
206
    {
207 2
        $subresource = $this->getSubresource();
208 2
        $parent = $this->fetchEntity($id);
209 2
        $this->assertSubresourceDeleteGranted($parent, $subresource);
210 2
        $this->getService()->removeFromCollection($parent, $subresource, $subId);
211
212 2
        return new JsonResponse(null, Response::HTTP_NO_CONTENT);
213
    }
214
215
    /**
216
     * @return CrudServiceInterface
217
     */
218 30
    protected function getService(): CrudServiceInterface
219
    {
220 30
        $serviceId = $this->getServiceId();
221 30
        if (null === $serviceId) {
222 28
            $entityClass = $this->getEntityClass();
223 28
            if (null === $entityClass) {
224
                throw new \RuntimeException('No service or entity class given');
225
            }
226
            /** @var EntityManagerInterface $entityManager */
227 28
            $entityManager = $this->container->get('doctrine.orm.entity_manager');
228 28
            $repository = $entityManager->getRepository($entityClass);
229 28
            if (!$repository instanceof CrudServiceInterface) {
230
                throw new \RuntimeException(
231
                    'Your Entity Repository needs to be an instance of ' . CrudServiceInterface::class . '.'
232
                );
233
            }
234
235 28
            return $repository;
236
        } else {
237
            /** @var CrudServiceInterface $service */
238 2
            $service = $this->container->get($serviceId);
239
240 2
            return $service;
241
        }
242
    }
243
244
    /**
245
     * @param object $entity
246
     *
247
     * @return object
248
     */
249
    protected function postProcessPostedEntity($entity)
250
    {
251
        return $entity;
252
    }
253
254
    /**
255
     * @param object $entity
256
     *
257
     * @return object
258
     */
259 2
    protected function postProcessPuttedEntity($entity)
260
    {
261 2
        return $entity;
262
    }
263
264
    /**
265
     * @param string $subresource
266
     * @param object $parent
267
     * @param object $entity
268
     *
269
     * @return object
270
     */
271 2
    protected function postProcessSubResourcePostedEntity($subresource, $entity, $parent)
2 ignored issues
show
Unused Code introduced by
The parameter $subresource is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $parent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
272
    {
273 2
        return $entity;
274
    }
275
276 24
    protected function fetchEntity($id)
277
    {
278 24
        $entity = $this->getService()->find($id);
279 24
        if (null === $entity) {
280
            throw new NotFoundHttpException();
281
        }
282
283 24
        return $entity;
284
    }
285
286
    /**
287
     * @param int $page
288
     * @param int $perPage
289
     *
290
     * @return Paginator|array
291
     */
292 6
    protected function listEntities(int $page = 1, int $perPage = 50)
293
    {
294 6
        return $this->getService()->findAllPaginated($page, $perPage);
295
    }
296
297
    protected function createEntity($entity)
298
    {
299
        return $this->getService()->create($entity);
300
    }
301
302 2
    protected function updateEntity($entity)
303
    {
304 2
        return $this->getService()->update($entity);
305
    }
306
307
    /**
308
     * @param object $entity
309
     * @param string $property
310
     * @param int    $page
311
     * @param int    $perPage
312
     *
313
     * @return Paginator|array
314
     */
315 6
    protected function listSubresource($entity, string $property, int $page = 1, int $perPage = 50)
316
    {
317 6
        return $this->getService()->findAssociationPaginated($entity, $property, $page, $perPage);
318
    }
319
320 34
    protected function getEntityClass()
321
    {
322 34
        return $this->getCurrentRequest()->attributes->get('_entityClass');
323
    }
324
325
    protected function getShortName()
326
    {
327
        return Inflector::tableize($this->getClassMetadata()->reflection->getShortName());
328
    }
329
330 30
    protected function getServiceId()
331
    {
332 30
        return $this->getCurrentRequest()->attributes->get('_service');
333
    }
334
335 34
    protected function getCurrentRequest()
336
    {
337 34
        return $this->getRequestStack()->getCurrentRequest();
338
    }
339
340 10
    protected function assertListGranted()
341
    {
342 10
        $method = $this->getClassMetadata()->getMethod(Method::LIST);
343 10
        if ($method !== null && null !== $right = $method->right) {
344 8
            $this->denyAccessUnlessGranted($right->attributes);
345
        }
346 6
    }
347
348
    protected function assertPostGranted()
349
    {
350
        $method = $this->getClassMetadata()->getMethod(Method::POST);
351
        $right = $method->right;
352
        if (null === $right) {
353
            throw new AccessDeniedException();
354
        }
355
356
        $this->denyAccessUnlessGranted($right->attributes);
357
    }
358
359 10
    protected function assertGetGranted($entity)
360
    {
361 10
        $method = $this->getClassMetadata()->getMethod(Method::GET);
362 10
        if ($method !== null && null !== $right = $method->right) {
363 6
            $this->assertRightGranted($entity, $right);
364
        }
365 8
    }
366
367 4
    protected function assertPutGranted($entity)
368
    {
369 4
        $method = $this->getClassMetadata()->getMethod(Method::PUT);
370 4
        $right = $method->right;
371 4
        if (null === $right) {
372
            throw new AccessDeniedException();
373
        }
374
375 4
        $this->assertRightGranted($entity, $right);
376 2
    }
377
378
    protected function assertDeleteGranted($entity)
379
    {
380
        $method = $this->getClassMetadata()->getMethod(Method::POST);
381
        $right = $method->right;
382
        if (null === $right) {
383
            throw new AccessDeniedException();
384
        }
385
386
        $this->assertRightGranted($entity, $right);
387
    }
388
389 6
    protected function assertSubresourceListGranted($entity, $subresource)
390
    {
391 6
        $classMetadata = $this->getClassMetadata();
392
        /** @var PropertyMetadata $propertyMetadata */
393 6
        $propertyMetadata = $classMetadata->propertyMetadata[$subresource];
394 6
        $right = $propertyMetadata->getSubResourceListRight();
395 6
        if (null === $right) {
396 6
            return;
397
        }
398
399
        $this->assertRightGranted($entity, $right);
400
    }
401
402 4
    protected function assertSubresourcePostGranted($entity, $subresource)
403
    {
404 4
        $classMetadata = $this->getClassMetadata();
405
        /** @var PropertyMetadata $propertyMetadata */
406 4
        $propertyMetadata = $classMetadata->propertyMetadata[$subresource];
407 4
        $right = $propertyMetadata->getSubResourcePostRight();
408 4
        if (null === $right) {
409
            throw new AccessDeniedException();
410
        }
411
412 4
        $this->assertRightGranted($entity, $right);
413 2
    }
414
415 2
    protected function assertSubresourcePutGranted($entity, $subresource)
416
    {
417 2
        $classMetadata = $this->getClassMetadata();
418
        /** @var PropertyMetadata $propertyMetadata */
419 2
        $propertyMetadata = $classMetadata->propertyMetadata[$subresource];
420 2
        $right = $propertyMetadata->getSubResourcePutRight();
421 2
        if (null === $right) {
422
            throw new AccessDeniedException();
423
        }
424
425 2
        $this->assertRightGranted($entity, $right);
426 2
    }
427
428 2
    protected function assertSubresourceDeleteGranted($entity, $subresource)
429
    {
430 2
        $classMetadata = $this->getClassMetadata();
431
        /** @var PropertyMetadata $propertyMetadata */
432 2
        $propertyMetadata = $classMetadata->propertyMetadata[$subresource];
433 2
        $right = $propertyMetadata->getSubResourceDeleteRight();
434 2
        if (null === $right) {
435
            throw new AccessDeniedException();
436
        }
437
438 2
        $this->assertRightGranted($entity, $right);
439 2
    }
440
441
    /**
442
     * @return ClassMetadata
443
     */
444 34
    protected function getClassMetadata()
445
    {
446 34
        $metaDataFactory = $this->getMetadataFactory();
447
        /** @var ClassMetadata $classMetaData */
448 34
        $classMetaData = $metaDataFactory->getMetadataForClass($this->getEntityClass());
449
450 34
        return $classMetaData;
451
    }
452
453 2
    protected function getSubResourceEntityClass($subresource)
454
    {
455
        /** @var PropertyMetadata $propertyMetadata */
456 2
        $propertyMetadata = $this->getClassMetadata()->propertyMetadata[$subresource];
457
458 2
        return $propertyMetadata->getType();
459
    }
460
461
    protected function resolveSubject($entity, $propertyPath)
462
    {
463
        if ('this' === $propertyPath) {
464
            return $entity;
465
        }
466
        $propertyAccessor = $this->getPropertyAccessor();
467
468
        return $propertyAccessor->getValue($entity, $propertyPath);
469
    }
470
471
    /**
472
     * @param object $entity
473
     * @param Right  $right
474
     */
475 18
    protected function assertRightGranted($entity, Right $right)
476
    {
477 18
        $propertyPath = $right->propertyPath;
478 18
        if (null === $propertyPath) {
479 18
            $this->denyAccessUnlessGranted($right->attributes);
480
        } else {
481
            $subject = $this->resolveSubject($entity, $propertyPath);
482
            $this->denyAccessUnlessGranted($right->attributes, $subject);
483
        }
484 12
    }
485
486
    /**
487
     * @param object $parent
488
     * @param string $subresource
489
     * @param object $entity
490
     *
491
     * @return
492
     */
493 2
    protected function createSubResource($parent, $subresource, $entity)
494
    {
495 2
        return $this->getService()->createAssociation($parent, $subresource, $entity);
496
    }
497
498
    /**
499
     * @return string|null
500
     */
501 10
    protected function getSubresource()
502
    {
503 10
        return $this->getCurrentRequest()->attributes->get('_subresource');
504
    }
505
506 20
    protected function parseIncludes(Request $request, array $defaultIncludes = [])
507
    {
508 20
        $includeString = $request->query->get('include');
509 20
        if (empty($includeString)) {
510 18
            return $defaultIncludes;
511
        }
512
513 2
        return explode(',', $includeString);
514
    }
515
516
    private function parseConstraintViolations(ConstraintViolationListInterface $errors)
517
    {
518
        $data = [];
519
        /** @var ConstraintViolationInterface $error */
520
        foreach ($errors as $error) {
521
            $data[] = [
522
                'propertyPath' => $error->getPropertyPath(),
523
                'message'      => $error->getMessage(),
524
                'value'        => $error->getInvalidValue()
525
            ];
526
        }
527
528
        return $data;
529
    }
530
531 12
    private function addPaginationHeaders(Response $response, int $page, int $perPage, int $total)
532
    {
533 12
        $response->headers->add(
534
            [
535 12
                'x-pagination-current-page' => $page,
536 12
                'x-pagination-per-page'     => $perPage,
537 12
                'x-pagination-total'        => $total,
538 12
                'x-pagination-total-pages'  => (int)(($total - 1) / $perPage + 1)
539
            ]
540
        );
541 12
    }
542
543 26
    protected function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.')
544
    {
545 26
        if (!$this->getAuthorizationChecker()->isGranted($attributes, $object)) {
546 10
            throw new AccessDeniedException($message);
547
        }
548 16
    }
549
550
    /**
551
     * @return Normalizer
552
     */
553 24
    protected function getNormalizer()
554
    {
555 24
        return $this->container->get('ddr_rest.normalizer');
556
    }
557
558
    /**
559
     * @return ValidatorInterface
560
     */
561 4
    protected function getValidator()
562
    {
563 4
        return $this->container->get('validator');
564
    }
565
566
    /**
567
     * @return RestRequestParser
568
     */
569 4
    protected function getRequestParser()
570
    {
571 4
        return $this->container->get('ddr.rest.parser.request');
572
    }
573
574
    /**
575
     * @return RequestStack
576
     */
577 34
    protected function getRequestStack()
578
    {
579 34
        return $this->container->get('request_stack');
580
    }
581
582
    /**
583
     * @return MetadataFactoryInterface
584
     */
585 34
    protected function getMetadataFactory()
586
    {
587 34
        return $this->container->get('ddr_rest.metadata.factory');
588
    }
589
590
    /**
591
     * @return PropertyAccessorInterface
592
     */
593
    protected function getPropertyAccessor()
594
    {
595
        return $this->container->get('property_accessor');
596
    }
597
598
    /**
599
     * @return AuthorizationCheckerInterface
600
     */
601 26
    protected function getAuthorizationChecker()
602
    {
603 26
        return $this->container->get('security.authorization_checker');
604
    }
605
}
606