Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
40 / 44
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
EntityQueryFilterFactory
90.91% covered (success)
90.91%
40 / 44
0.00% covered (danger)
0.00%
0 / 1
9.06
0.00% covered (danger)
0.00%
0 / 1
 createFilterList
90.91% covered (success)
90.91%
40 / 44
0.00% covered (danger)
0.00%
0 / 1
9.06
1<?php
2
3namespace Apie\DoctrineEntityDatalayer\Factories;
4
5use Apie\Core\BoundedContext\BoundedContextId;
6use Apie\Core\Context\ApieContext;
7use Apie\Core\Entities\RequiresRecalculatingInterface;
8use Apie\Core\Enums\ScalarType;
9use Apie\Core\Metadata\MetadataFactory;
10use Apie\Core\Permissions\RequiresPermissionsInterface;
11use Apie\DoctrineEntityDatalayer\DoctrineEntityDatalayer;
12use Apie\DoctrineEntityDatalayer\Query\EntityQueryFilterInterface;
13use Apie\DoctrineEntityDatalayer\Query\FieldTextSearchFilter;
14use Apie\DoctrineEntityDatalayer\Query\FulltextSearchFilter;
15use Apie\DoctrineEntityDatalayer\Query\OrderBySearchFilter;
16use Apie\DoctrineEntityDatalayer\Query\RequiresPermissionFilter;
17use Apie\DoctrineEntityDatalayer\Query\SearchByInternalColumnFilter;
18use Apie\StorageMetadata\Attributes\GetMethodAttribute;
19use Apie\StorageMetadata\Attributes\GetSearchIndexAttribute;
20use Apie\StorageMetadata\Attributes\PropertyAttribute;
21use Apie\StorageMetadata\Interfaces\StorageDtoInterface;
22use Apie\TypeConverter\ReflectionTypeFactory;
23use ReflectionClass;
24use ReflectionProperty;
25
26final class EntityQueryFilterFactory
27{
28    /**
29     * @param ReflectionClass<StorageDtoInterface> $doctrineClass
30     * @return EntityQueryFilterInterface[]
31     *
32     * @see DoctrineEntityDatalayer::getOrderByColumns()
33     */
34    public function createFilterList(ReflectionClass $doctrineClass, BoundedContextId $boundedContextId): array
35    {
36        $domainClass = $doctrineClass->getMethod('getClassReference')->invoke(null);
37        $filters = [];
38
39        if (in_array(RequiresRecalculatingInterface::class, $domainClass->getInterfaceNames())) {
40            $filters[] = new SearchByInternalColumnFilter(
41                'dateToRecalculate',
42                'requires_update'
43            );
44        }
45        $filters[] = new SearchByInternalColumnFilter(
46            'createdAt',
47            'created_at'
48        );
49        $filters[] = new SearchByInternalColumnFilter(
50            'updatedAt',
51            'updated_at'
52        );
53
54        foreach ($doctrineClass->getProperties(ReflectionProperty::IS_PUBLIC) as $publicProperty) {
55            if (str_starts_with($publicProperty->name, 'search_')) {
56                foreach ($publicProperty->getAttributes(GetSearchIndexAttribute::class) as $publicPropertyAttribute) {
57                    $filters[] = new FieldTextSearchFilter(
58                        substr($publicProperty->name, strlen('search_')),
59                        $publicPropertyAttribute->newInstance()->arrayValueType ?? (string) $publicProperty->getType()
60                    );
61                }
62            } else {
63                foreach ($publicProperty->getAttributes(GetMethodAttribute::class) as $publicPropertyAttribute) {
64                    $filters[] = new FieldTextSearchFilter(
65                        $publicPropertyAttribute->newInstance()->methodName,
66                        $publicProperty->name
67                    );
68                }
69                $metadata = MetadataFactory::getModificationMetadata(
70                    $publicProperty->getType() ?? ReflectionTypeFactory::createReflectionType('mixed'),
71                    new ApieContext()
72                );
73                if (in_array($metadata->toScalarType(true), ScalarType::PRIMITIVES)) {
74                    foreach ($publicProperty->getAttributes(PropertyAttribute::class) as $publicPropertyAttribute) {
75                        $filters[] = new OrderBySearchFilter(
76                            $publicPropertyAttribute->newInstance()->propertyName,
77                            $publicProperty->getName()
78                        );
79                    }
80                }
81            }
82        }
83        $filters[] = new FulltextSearchFilter(
84            $domainClass,
85            $boundedContextId
86        );
87
88        if (in_array(RequiresPermissionsInterface::class, $domainClass->getInterfaceNames())) {
89            $filters[] = new RequiresPermissionFilter($domainClass, $boundedContextId);
90        }
91
92        return $filters;
93    }
94}