Completed
Push — master ( 0be8e1...585ca2 )
by Daniel
59:26 queued 46:02
created

CollectionModifier::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 5
1
<?php
2
3
namespace Silverback\ApiComponentBundle\DataModifier;
4
5
use ApiPlatform\Core\Api\OperationType;
6
use ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator;
7
use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
8
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
9
use ApiPlatform\Core\PathResolver\OperationPathResolverInterface;
10
use Psr\Container\ContainerInterface;
11
use Silverback\ApiComponentBundle\Entity\Component\Collection\Collection;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\RequestStack;
14
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
15
16
class CollectionModifier extends AbstractModifier
17
{
18
    private $resourceMetadataFactory;
19
    private $operationPathResolver;
20
    private $itemNormalizer;
21
    private $requestStack;
22
23
    public function __construct(
24
        ContainerInterface $container,
25
        ResourceMetadataFactoryInterface $resourceMetadataFactory,
26
        OperationPathResolverInterface $operationPathResolver,
27
        NormalizerInterface $itemNormalizer,
28
        RequestStack $requestStack
29
    ) {
30
        parent::__construct($container);
31
        $this->resourceMetadataFactory = $resourceMetadataFactory;
32
        $this->operationPathResolver = $operationPathResolver;
33
        $this->itemNormalizer = $itemNormalizer;
34
        $this->requestStack = $requestStack;
35
    }
36
37
    /**
38
     * @param Collection $collectionEntity
39
     * @param array $context
40
     * @param null|string $format
41
     * @return object|void
42
     */
43
    public function process($collectionEntity, array $context = array(), ?string $format = null)
44
    {
45
        $resourceMetadata = $this->resourceMetadataFactory->create($collectionEntity->getResource());
46
        $requestUri = null;
47
48
        $collectionOperations = $resourceMetadata->getCollectionOperations();
49
        if ($collectionOperations && ($shortName = $resourceMetadata->getShortName())) {
50
            $collectionOperations = array_change_key_case($collectionOperations, CASE_LOWER);
51
            $baseRoute = trim(trim($resourceMetadata->getAttribute('route_prefix', '')), '/');
52
            $methods = ['post', 'get'];
53
            foreach ($methods as $method) {
54
                if (array_key_exists($method, $collectionOperations)) {
55
                    $path = $baseRoute . $this->operationPathResolver->resolveOperationPath(
56
                            $shortName,
57
                            $collectionOperations[$method],
58
                            OperationType::COLLECTION,
59
                            $method
0 ignored issues
show
Unused Code introduced by
The call to ApiPlatform\Core\PathRes...:resolveOperationPath() has too many arguments starting with $method. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

59
                    $path = $baseRoute . $this->operationPathResolver->/** @scrutinizer ignore-call */ resolveOperationPath(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
60
                    );
61
                    $finalPath = preg_replace('/{_format}$/', $format, $path);
62
                    $collectionEntity->addCollectionRoute(
63
                        $method,
64
                        $finalPath
65
                    );
66
                    if ($method === 'get') {
67
                        $requestUri = $finalPath;
68
                    }
69
                }
70
            }
71
        }
72
73
        /** @var ContextAwareCollectionDataProviderInterface $dataProvider */
74
        $dataProvider = $this->container->get(ContextAwareCollectionDataProviderInterface::class);
75
        $isPaginated = (bool) $collectionEntity->getPerPage();
76
        if (!$isPaginated) {
77
            $dataProviderContext = [];
78
        } else {
79
            $dataProviderContext = [
80
                'filters' => [
81
                    'pagination' => $isPaginated,
82
                    'itemsPerPage' => $collectionEntity->getPerPage(),
83
                    '_page' => 1
84
                ]
85
            ];
86
            if ($collectionEntity->getPerPage() !== null && ($request = $this->requestStack->getCurrentRequest())) {
87
                $request->attributes->set('_api_pagination', [
88
                    'itemsPerPage' => $collectionEntity->getPerPage(),
89
                    'pagination' => 'true'
90
                ]);
91
            }
92
        }
93
94
        /** @var Paginator $collection */
95
        $collection = $dataProvider->getCollection($collectionEntity->getResource(), Request::METHOD_GET, $dataProviderContext);
96
97
        $forcedContext = [
98
            'resource_class' => $collectionEntity->getResource(),
99
            'request_uri' => $requestUri,
100
            'jsonld_has_context' => false,
101
            'api_sub_level' => null
102
        ];
103
        $mergedContext = array_merge($context, $forcedContext);
104
        $normalizedCollection = $this->itemNormalizer->normalize(
105
            $collection,
106
            $format,
107
            $mergedContext
108
        );
109
        if (\is_array($normalizedCollection)) {
110
            $collectionEntity->setCollection($normalizedCollection);
111
        }
112
    }
113
114
    public function supportsData($data): bool
115
    {
116
        return $data instanceof Collection;
117
    }
118
119
    public static function getSubscribedServices(): array
120
    {
121
        return [
122
            '?' . ContextAwareCollectionDataProviderInterface::class,
123
            RequestStack::class
124
        ];
125
    }
126
}
127