Passed
Pull Request — master (#4)
by Alex
03:27
created

AbstractFilter::getAlias()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 4
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\DoctrineQueryFilter\Filter;
6
7
use Arp\DoctrineQueryFilter\Filter\Exception\FilterException;
8
use Arp\DoctrineQueryFilter\Filter\Exception\InvalidArgumentException;
9
use Arp\DoctrineQueryFilter\Filter\Exception\TypecastException;
10
use Arp\DoctrineQueryFilter\Metadata\MetadataInterface;
11
use Arp\DoctrineQueryFilter\QueryBuilderInterface;
12
use Arp\DoctrineQueryFilter\QueryFilterManagerInterface;
13
14
/**
15
 * @author  Alex Patterson <[email protected]>
16
 * @package Arp\DoctrineQueryFilter\Filter
17
 */
18
abstract class AbstractFilter implements FilterInterface
19
{
20
    /**
21
     * @var QueryFilterManagerInterface
22
     */
23
    protected QueryFilterManagerInterface $queryFilterManager;
24
25
    /**
26
     * @var TypecasterInterface
27
     */
28
    protected TypecasterInterface $typecaster;
29
30
    /**
31
     * @var array
32
     */
33
    protected array $options = [];
34
35
    /**
36
     * @param QueryFilterManagerInterface $queryFilterManager
37
     * @param TypecasterInterface         $typecaster
38
     * @param array                       $options
39
     */
40
    public function __construct(
41
        QueryFilterManagerInterface $queryFilterManager,
42
        TypecasterInterface $typecaster,
43
        array $options = []
44
    ) {
45
        $this->queryFilterManager = $queryFilterManager;
46
        $this->typecaster = $typecaster;
47
        $this->options = $options;
48
    }
49
50
    /**
51
     * @return array
52
     */
53
    public function getOptions(): array
54
    {
55
        return $this->options;
56
    }
57
58
    /**
59
     * Create a new unique parameter name
60
     *
61
     * @param string $prefix
62
     *
63
     * @return string
64
     */
65
    protected function createParamName(string $prefix = ''): string
66
    {
67
        return uniqid($prefix, false);
68
    }
69
70
    /**
71
     * @param QueryBuilderInterface $queryBuilder
72
     * @param string|null           $alias
73
     *
74
     * @return string
75
     */
76
    protected function getAlias(QueryBuilderInterface $queryBuilder, ?string $alias = null): string
77
    {
78
        $alias = empty($alias) ? $queryBuilder->getRootAlias() : $alias;
79
        if (!empty($alias)) {
80
            return $alias;
81
        }
82
83
        return $this->options['alias'] ?? 'entity';
84
    }
85
86
    /**
87
     * @param MetadataInterface $metadata
88
     * @param array             $criteria
89
     * @param string            $key
90
     *
91
     * @return string
92
     *
93
     * @throws InvalidArgumentException
94
     */
95
    protected function resolveFieldName(MetadataInterface $metadata, array $criteria, string $key = 'field'): string
96
    {
97
        if (empty($criteria[$key])) {
98
            throw new InvalidArgumentException(
99
                sprintf(
100
                    'The required \'%s\' criteria value is missing for filter \'%s\'',
101
                    $key,
102
                    static::class
103
                )
104
            );
105
        }
106
107
        if (!$metadata->hasField($criteria[$key]) && !$metadata->hasAssociation($criteria[$key])) {
108
            throw new InvalidArgumentException(
109
                sprintf(
110
                    'Unable to apply query filter \'%s\': '
111
                    . 'The entity class \'%s\' has no field or association named \'%s\'',
112
                    static::class,
113
                    $metadata->getName(),
114
                    $criteria[$key]
115
                )
116
            );
117
        }
118
119
        return $criteria[$key];
120
    }
121
122
    /**
123
     * @param MetadataInterface $metadata
124
     * @param string            $fieldName
125
     * @param mixed             $value
126
     * @param string|null       $type
127
     * @param array             $options
128
     *
129
     * @return mixed
130
     *
131
     * @throws FilterException
132
     */
133
    protected function formatValue(
134
        MetadataInterface $metadata,
135
        string $fieldName,
136
        $value,
137
        ?string $type = null,
138
        array $options = []
139
    ) {
140
        try {
141
            return $this->typecaster->typecast($metadata, $fieldName, $value, $type, $options);
142
        } catch (TypecastException $e) {
143
            throw new FilterException(
144
                sprintf(
145
                    'Failed to format the value for field \'%s::%s\': %s',
146
                    $metadata->getName(),
147
                    $fieldName,
148
                    $e->getMessage()
149
                ),
150
                $e->getCode(),
151
                $e
152
            );
153
        }
154
    }
155
}
156