Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
EntityQueryFilterFactory
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
1 / 1
9
100.00% covered (success)
100.00%
1 / 1
 createFilterList
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
1 / 1
9
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 ReflectionAttribute;
24use ReflectionClass;
25use ReflectionProperty;
26
27final class EntityQueryFilterFactory
28{
29    /**
30     * @param ReflectionClass<StorageDtoInterface> $doctrineClass
31     * @return EntityQueryFilterInterface[]
32     *
33     * @see DoctrineEntityDatalayer::getOrderByColumns()
34     */
35    public function createFilterList(ReflectionClass $doctrineClass, BoundedContextId $boundedContextId): array
36    {
37        $domainClass = $doctrineClass->getMethod('getClassReference')->invoke(null);
38        $filters = [];
39
40        if (in_array(RequiresRecalculatingInterface::class, $domainClass->getInterfaceNames())) {
41            $filters[] = new SearchByInternalColumnFilter(
42                'dateToRecalculate',
43                'requires_update'
44            );
45        }
46        $filters[] = new SearchByInternalColumnFilter(
47            'createdAt',
48            'created_at'
49        );
50        $filters[] = new SearchByInternalColumnFilter(
51            'updatedAt',
52            'updated_at'
53        );
54
55        foreach ($doctrineClass->getProperties(ReflectionProperty::IS_PUBLIC) as $publicProperty) {
56            if (str_starts_with($publicProperty->name, 'search_')) {
57                foreach ($publicProperty->getAttributes(GetSearchIndexAttribute::class) as $publicPropertyAttribute) {
58                    $filters[] = new FieldTextSearchFilter(
59                        substr($publicProperty->name, strlen('search_')),
60                        $publicPropertyAttribute->newInstance()->arrayValueType ?? (string) $publicProperty->getType()
61                    );
62                }
63            } else {
64                foreach ($publicProperty->getAttributes(GetMethodAttribute::class) as $publicPropertyAttribute) {
65                    $filters[] = new FieldTextSearchFilter(
66                        $publicPropertyAttribute->newInstance()->methodName,
67                        $publicProperty->name
68                    );
69                }
70                $metadata = MetadataFactory::getModificationMetadata(
71                    $publicProperty->getType() ?? ReflectionTypeFactory::createReflectionType('mixed'),
72                    new ApieContext()
73                );
74                if (in_array($metadata->toScalarType(true), ScalarType::PRIMITIVES)) {
75                    foreach ($publicProperty->getAttributes(PropertyAttribute::class, ReflectionAttribute::IS_INSTANCEOF) as $publicPropertyAttribute) {
76                        $filters[] = new OrderBySearchFilter(
77                            $publicPropertyAttribute->newInstance()->propertyName,
78                            $publicProperty->getName()
79                        );
80                    }
81                }
82            }
83        }
84        $filters[] = new FulltextSearchFilter(
85            $domainClass,
86            $boundedContextId
87        );
88
89        if (in_array(RequiresPermissionsInterface::class, $domainClass->getInterfaceNames())) {
90            $filters[] = new RequiresPermissionFilter($domainClass, $boundedContextId);
91        }
92
93        return $filters;
94    }
95}