AbstractFilterHandler::getRelationClass()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 5
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bugloos\QueryFilterBundle\FilterHandler\Contract;
6
7
use Bugloos\QueryFilterBundle\Enum\ColumnType;
8
use Bugloos\QueryFilterBundle\Service\AttributeReader;
9
use Bugloos\QueryFilterBundle\TypeHandler\Contract\FilterValueInterface;
10
use Bugloos\QueryFilterBundle\TypeHandler\Factory\TypeFactory;
11
use Doctrine\Common\Annotations\AnnotationReader;
12
use Doctrine\ORM\EntityManagerInterface;
13
use Doctrine\ORM\Mapping as ORM;
14
use Doctrine\ORM\Mapping\ClassMetadata;
15
16
/**
17
 * @author Milad Ghofrani <[email protected]>
18
 */
19
abstract class AbstractFilterHandler
20
{
21
    protected EntityManagerInterface $entityManager;
22
    protected string $fieldType;
23
24
    public function __construct(EntityManagerInterface $entityManager)
25
    {
26
        $this->entityManager = $entityManager;
27
    }
28
29
    abstract public function filterParameter(
30
        $rootAlias,
31
        $rootClass,
32
        $relationsAndFieldName,
33
        $type
34
    ): string;
35
36
    abstract public function filterWhereClause(
37
        $rootAlias,
38
        $relationsAndFieldName,
39
        $filterParameter,
40
        $strategy,
41
        $value
42
    ): string;
43
44
    public function filterValue($value, $strategy)
45
    {
46
        $this->fieldType = (\is_array($value)) ? ColumnType::ARRAY : $this->fieldType;
47
48
        $typeHandler = TypeFactory::createTypeHandler($this->fieldType);
49
        if ($typeHandler instanceof FilterValueInterface) {
50
            return $typeHandler->filterValue($value, $strategy);
51
        }
52
53
        return $value;
54
    }
55
56
    protected function validateFieldNames($field, $class): void
57
    {
58
        if (!\in_array($field, $class->getFieldNames(), true)) {
59
            throw new \InvalidArgumentException(
60
                'You have selected the wrong field for filtering'
61
            );
62
        }
63
    }
64
65
    protected function validateRelationNames($relationProperty, $class): void
66
    {
67
        if (!\in_array($relationProperty, $class->getAssociationNames(), true)) {
68
            throw new \InvalidArgumentException(
69
                'You have selected the wrong relation for filtering'
70
            );
71
        }
72
    }
73
74
    protected function getRelationClass($class, $alias): ClassMetadata
75
    {
76
        $relationEntity = $class->getAssociationMapping($alias)['targetEntity'];
77
78
        return $this->entityManager->getClassMetadata($relationEntity);
79
    }
80
81
    protected function addRelationJoin($relationJoins, $alias, $property)
82
    {
83
        $relationJoins[sprintf('%s.%s', $alias, $property)] = $property;
84
85
        return $relationJoins;
86
    }
87
88
    protected function createParameterName($alias, $column): string
89
    {
90
        $random = mt_rand(1111, 9999);
91
92
        return sprintf('%s_%s_%s', $alias, $column, $random);
93
    }
94
95
    /**
96
     * @param mixed $field
97
     * @param mixed $rootClass
98
     *
99
     * @throws \ReflectionException
100
     */
101
    protected function getFieldTypeFromAnnotation(mixed $field, mixed $rootClass)
102
    {
103
        $rootEntityRef = new \ReflectionClass($rootClass->getName());
104
        $property = $rootEntityRef->getProperty($field);
105
106
        $annotationReader = new AnnotationReader();
107
        $propertyAnnotation = $annotationReader->getPropertyAnnotation($property, ORM\Column::class);
108
109
        if (null !== $propertyAnnotation) {
110
            return $propertyAnnotation->type;
111
        }
112
113
        $attributeReader = new AttributeReader();
114
        $propertyAttribute = $attributeReader->getPropertyAnnotation($property, ORM\Column::class);
115
116
        if (null === $propertyAttribute->type && null !== $propertyAttribute->length) {
117
            return ColumnType::STRING;
118
        }
119
120
        return $propertyAttribute->type;
121
    }
122
}
123