FilterFactory   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 48
c 2
b 0
f 0
dl 0
loc 97
rs 10
wmc 9

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A getClassMap() 0 3 1
A create() 0 29 4
A setClassMap() 0 3 1
A addToClassMap() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\DoctrineQueryFilter\Filter;
6
7
use Arp\DoctrineQueryFilter\Filter\Exception\FilterFactoryException;
8
use Arp\DoctrineQueryFilter\Metadata\ParamNameGeneratorInterface;
9
use Arp\DoctrineQueryFilter\Metadata\Typecaster;
10
use Arp\DoctrineQueryFilter\Metadata\TypecasterInterface;
11
use Arp\DoctrineQueryFilter\Metadata\UniqidParamNameGenerator;
12
use Arp\DoctrineQueryFilter\QueryFilterManagerInterface;
13
14
final class FilterFactory implements FilterFactoryInterface
15
{
16
    /**
17
     * @var array<string, class-string<FilterInterface>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, class-string<FilterInterface>> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string, class-string<FilterInterface>>.
Loading history...
18
     */
19
    private array $classMap = [
20
        'eq' => IsEqual::class,
21
        'neq' => IsNotEqual::class,
22
        'gt' => IsGreaterThan::class,
23
        'gte' => IsGreaterThanOrEqual::class,
24
        'lt' => IsLessThan::class,
25
        'lte' => IsLessThanOrEqual::class,
26
        'is_null' => IsNull::class,
27
        'not_null' => IsNotNull::class,
28
        'member_of' => IsMemberOf::class,
29
        'between' => IsBetween::class,
30
        'and' => AndX::class,
31
        'or' => OrX::class,
32
        'left_join' => LeftJoin::class,
33
        'inner_join' => InnerJoin::class,
34
        'like' => IsLike::class,
35
        'not_like' => IsNotLike::class,
36
        'in' => IsIn::class,
37
        'not_in' => IsNotIn::class,
38
        'begins_with' => BeginsWith::class,
39
        'ends_with' => EndsWith::class,
40
        'empty' => IsEmpty::class,
41
    ];
42
43
    /**
44
     * @param array<string, class-string<FilterInterface>> $classMap
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, class-string<FilterInterface>> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string, class-string<FilterInterface>>.
Loading history...
45
     */
46
    public function __construct(
47
        private ?TypecasterInterface $typecaster = null,
48
        private ?ParamNameGeneratorInterface $paramNameGenerator = null,
49
        array $classMap = [],
50
        private readonly array $options = []
51
    ) {
52
        $this->typecaster = $typecaster ?? new Typecaster();
53
        $this->paramNameGenerator = $this->paramNameGenerator ?? new UniqidParamNameGenerator();
54
        $this->classMap = empty($classMap) ? $this->classMap : $classMap;
55
    }
56
57
    /**
58
     * Create the $name query filter with the provided $options.
59
     *
60
     * @throws FilterFactoryException
61
     */
62
    public function create(QueryFilterManagerInterface $manager, string $name, array $options = []): FilterInterface
63
    {
64
        $className = $this->classMap[$name] ?? $name;
65
66
        if (!class_exists($className) || !is_a($className, FilterInterface::class, true)) {
67
            throw new FilterFactoryException(
68
                sprintf(
69
                    'The query filter \'%s\' must be an object of type \'%s\'; '
70
                    . 'The resolved class \'%s\' is invalid or cannot be found',
71
                    $name,
72
                    FilterInterface::class,
73
                    $className
74
                )
75
            );
76
        }
77
78
        $options = array_replace_recursive(
79
            $this->options['default_filter_options'] ?? [],
80
            $options
81
        );
82
83
        try {
84
            /** @throws \Exception */
85
            return new $className($manager, $this->typecaster, $this->paramNameGenerator, $options);
86
        } catch (\Exception $e) {
87
            throw new FilterFactoryException(
88
                sprintf('Failed to create query filter \'%s\': %s', $name, $e->getMessage()),
89
                $e->getCode(),
90
                $e
91
            );
92
        }
93
    }
94
95
    public function getClassMap(): array
96
    {
97
        return $this->classMap;
98
    }
99
100
    public function setClassMap(array $classMap): void
101
    {
102
        $this->classMap = $classMap;
103
    }
104
105
    /**
106
     * @param class-string<FilterInterface> $className
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<FilterInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<FilterInterface>.
Loading history...
107
     */
108
    public function addToClassMap(string $alias, string $className): void
109
    {
110
        $this->classMap[$alias] = $className;
111
    }
112
}
113