Passed
Pull Request — master (#2144)
by Alan
03:18
created

OrderExtension::applyToCollection()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 20
nc 12
nop 4
dl 0
loc 34
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension;
15
16
use ApiPlatform\Core\Bridge\Doctrine\Common\PropertyHelperTrait;
17
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\PropertyHelperTrait as MongoDbOdmPropertyHelperTrait;
18
use ApiPlatform\Core\Exception\InvalidArgumentException;
19
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
20
use Doctrine\Common\Persistence\ManagerRegistry;
21
use Doctrine\ODM\MongoDB\Aggregation\Builder;
22
23
/**
24
 * Applies selected ordering while querying resource collection.
25
 *
26
 * @author Kévin Dunglas <[email protected]>
27
 * @author Samuel ROZE <[email protected]>
28
 * @author Vincent Chalamon <[email protected]>
29
 * @author Alan Poulain <[email protected]>
30
 */
31
final class OrderExtension implements AggregationCollectionExtensionInterface
32
{
33
    use PropertyHelperTrait;
34
    use MongoDbOdmPropertyHelperTrait;
35
36
    private $order;
37
    private $resourceMetadataFactory;
38
39
    public function __construct(string $order = null, ResourceMetadataFactoryInterface $resourceMetadataFactory = null, ManagerRegistry $managerRegistry = null)
40
    {
41
        $this->resourceMetadataFactory = $resourceMetadataFactory;
42
        $this->order = $order;
43
        $this->managerRegistry = $managerRegistry;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function applyToCollection(Builder $aggregationBuilder, string $resourceClass = null, string $operationName = null, array &$context = [])
50
    {
51
        if (null === $resourceClass) {
52
            throw new InvalidArgumentException('The "$resourceClass" parameter must not be null');
53
        }
54
55
        $classMetaData = $this->getClassMetadata($resourceClass);
56
        $identifiers = $classMetaData->getIdentifier();
57
        if (null !== $this->resourceMetadataFactory) {
58
            $defaultOrder = $this->resourceMetadataFactory->create($resourceClass)->getAttribute('order');
59
            if (null !== $defaultOrder) {
60
                foreach ($defaultOrder as $field => $order) {
61
                    if (\is_int($field)) {
62
                        // Default direction
63
                        $field = $order;
64
                        $order = 'ASC';
65
                    }
66
67
                    if ($this->isPropertyNested($field, $resourceClass)) {
68
                        [$field] = $this->addLookupsForNestedProperty($field, $aggregationBuilder, $resourceClass);
69
                    }
70
                    $aggregationBuilder->sort(
71
                        $context['mongodb_odm_sort_fields'] = ($context['mongodb_odm_sort_fields'] ?? []) + [$field => $order]
72
                    );
73
                }
74
75
                return;
76
            }
77
        }
78
79
        if (null !== $this->order) {
80
            foreach ($identifiers as $identifier) {
81
                $aggregationBuilder->sort(
82
                    $context['mongodb_odm_sort_fields'] = ($context['mongodb_odm_sort_fields'] ?? []) + [$identifier => $this->order]
83
                );
84
            }
85
        }
86
    }
87
}
88