Passed
Push — master ( 6d13f3...89c0f3 )
by
unknown
03:48
created

OrderFilter::getDescription()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 19
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 1
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\Elasticsearch\DataProvider\Filter;
15
16
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
17
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
18
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
19
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
20
21
/**
22
 * Order the collection by given properties.
23
 *
24
 * @see https://www.elastic.co/guide/en/elasticsearch/guide/current/_sorting.html
25
 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html
26
 *
27
 * @experimental
28
 *
29
 * @author Baptiste Meyer <[email protected]>
30
 */
31
final class OrderFilter extends AbstractFilter implements SortFilterInterface
32
{
33
    private $orderParameterName;
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, ?NameConverterInterface $nameConverter = null, string $orderParameterName = 'order', ?array $properties = null)
39
    {
40
        parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $resourceClassResolver, $nameConverter, $properties);
41
42
        $this->orderParameterName = $orderParameterName;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function apply(array $clauseBody, string $resourceClass, ?string $operationName = null, array $context = []): array
49
    {
50
        if (!\is_array($properties = $context['filters'][$this->orderParameterName] ?? [])) {
51
            return $clauseBody;
52
        }
53
54
        $orders = [];
55
56
        foreach ($properties as $property => $direction) {
57
            [$type] = $this->getMetadata($resourceClass, $property);
58
59
            if (!$type) {
60
                continue;
61
            }
62
63
            if (empty($direction) && null !== $defaultDirection = $this->properties[$property] ?? null) {
64
                $direction = $defaultDirection;
65
            }
66
67
            if (!\in_array($direction = strtolower($direction), ['asc', 'desc'], true)) {
68
                continue;
69
            }
70
71
            $order = ['order' => $direction];
72
73
            if (null !== $nestedPath = $this->getNestedFieldPath($resourceClass, $property)) {
74
                $nestedPath = null === $this->nameConverter ? $nestedPath : $this->nameConverter->normalize($nestedPath);
75
                $order['nested'] = ['path' => $nestedPath];
76
            }
77
78
            $property = null === $this->nameConverter ? $property : $this->nameConverter->normalize($property);
79
            $orders[] = [$property => $order];
80
        }
81
82
        if (!$orders) {
83
            return $clauseBody;
84
        }
85
86
        return array_merge_recursive($clauseBody, $orders);
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function getDescription(string $resourceClass): array
93
    {
94
        $description = [];
95
96
        foreach ($this->getProperties($resourceClass) as $property) {
97
            [$type] = $this->getMetadata($resourceClass, $property);
0 ignored issues
show
Bug introduced by
$property of type ApiPlatform\Core\Metadat...\PropertyNameCollection is incompatible with the type string expected by parameter $property of ApiPlatform\Core\Bridge\...ctFilter::getMetadata(). ( Ignorable by Annotation )

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

97
            [$type] = $this->getMetadata($resourceClass, /** @scrutinizer ignore-type */ $property);
Loading history...
98
99
            if (!$type) {
100
                continue;
101
            }
102
103
            $description["$this->orderParameterName[$property]"] = [
104
                'property' => $property,
105
                'type' => 'string',
106
                'required' => false,
107
            ];
108
        }
109
110
        return $description;
111
    }
112
}
113