SelectQueryBuilder::buildMultiClassSelectQuery()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 41
rs 8.6417
c 0
b 0
f 0
cc 6
nc 5
nop 2
1
<?php
2
3
namespace Mdiyakov\DoctrineSolrBundle\Query;
4
5
use Mdiyakov\DoctrineSolrBundle\Exception\SchemaNotFoundException;
6
use Mdiyakov\DoctrineSolrBundle\Query\Select\ClassSelectQuery;
7
use Mdiyakov\DoctrineSolrBundle\Query\Select\MultiClassSelectQuery;
8
use Nelmio\SolariumBundle\ClientRegistry;
9
use Mdiyakov\DoctrineSolrBundle\Config\Config;
10
use Mdiyakov\DoctrineSolrBundle\Exception\EntityNotIndexedException;
11
use Mdiyakov\DoctrineSolrBundle\Exception\SchemaConfigException;
12
use Mdiyakov\DoctrineSolrBundle\Query\Hydrator\HydratorBuilder;
13
use Mdiyakov\DoctrineSolrBundle\Query\Hydrator\SelectQueryHydrator;
14
use Mdiyakov\DoctrineSolrBundle\Schema\Schema;
15
16
class SelectQueryBuilder
17
{
18
    /**
19
     * @var Config
20
     */
21
    private $config;
22
23
    /**
24
     * @var ClientRegistry
25
     */
26
    private $clientRegistry;
27
28
    /**
29
     * @var SelectQueryHydrator[]
30
     */
31
    private $hydrators;
32
33
    public function __construct(
34
        Config $config,
35
        ClientRegistry $clientRegistry,
36
        HydratorBuilder $hydratorBuilder
37
    )
38
    {
39
        $this->config = $config;
40
        $this->clientRegistry = $clientRegistry;
41
42
        foreach($config->getIndexedEntities() as $entityConfig) {
43
            $this->hydrators[$entityConfig['class']] = $hydratorBuilder->buildSelectQueryHydratorByClass($entityConfig['class']);
44
        }
45
    }
46
47
48
    /**
49
     * @param string $class
50
     * @return ClassSelectQuery
51
     */
52
    public function buildClassSelectQuery($class)
53
    {
54
        $entityConfig = $this->config->getEntityConfig($class);
55
        if (!$entityConfig) {
56
            throw new EntityNotIndexedException(
57
                sprintf('""%s" is not indexed. Check bundle config in config.yml', $class)
58
            );
59
        }
60
        $schema = $this->config->getSchemaByEntityClass($class);
61
62
        return new ClassSelectQuery(
63
            $this->clientRegistry->getClient(
64
                $this->config->getSolariumClient($schema->getClient())
65
            ),
66
            $schema,
67
            $entityConfig,
0 ignored issues
show
Bug introduced by
$entityConfig of type array<mixed,string[]> is incompatible with the type string[] expected by parameter $entityConfig of Mdiyakov\DoctrineSolrBun...ectQuery::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
            /** @scrutinizer ignore-type */ $entityConfig,
Loading history...
68
            $this->hydrators[$class]
69
        );
70
    }
71
72
    /**
73
     * @param string $schemaName
74
     * @param string[] $classes
75
     * @return MultiClassSelectQuery
76
     * @throws \InvalidArgumentException
77
     * @throws SchemaNotFoundException
78
     */
79
    public function buildMultiClassSelectQueryBySchemaName($schemaName, $classes)
80
    {
81
        if (!is_string($schemaName)) {
0 ignored issues
show
introduced by
The condition is_string($schemaName) is always true.
Loading history...
82
            throw new \InvalidArgumentException('Argument $schemaName must be a string');
83
        }
84
85
        $schema = $this->config->getSchemaByName($schemaName);
86
        if (!$schema) {
87
            throw new SchemaNotFoundException(
88
                sprintf('Schema "%s" is not found', $schemaName)
89
            );
90
        }
91
92
        return $this->buildMultiClassSelectQuery($schema, $classes);
93
    }
94
95
96
    /**
97
     * @param Schema $schema
98
     * @param string[] $classes
99
     * @return MultiClassSelectQuery
100
     */
101
    public function buildMultiClassSelectQuery(Schema $schema, $classes)
102
    {
103
        if (!is_array($classes) || empty($classes)) {
0 ignored issues
show
introduced by
The condition is_array($classes) is always true.
Loading history...
104
            throw new \InvalidArgumentException(sprintf('Argument must be an array of classes'));
105
        }
106
107
        $multiClassQueryConfig = [
108
            'entityConfigs' => [],
109
            'hydrators' => []
110
        ];
111
112
        $discriminatorConfigField = $schema->getDiscriminatorConfigField();
113
114
        foreach ($classes as $class) {
115
            $entityConfig = $this->config->getEntityConfig($class);
116
            if (!$entityConfig) {
117
                throw new EntityNotIndexedException(
118
                    sprintf('""%s" is not indexed. Check bundle config in config.yml', $class)
119
                );
120
            }
121
122
            if ($schema->getName() != $entityConfig['schema'])
123
            {
124
                throw new SchemaConfigException(
125
                    'Entity class %s doesn\'t support scheme %s',
126
                    $entityConfig['class'],
0 ignored issues
show
Bug introduced by
$entityConfig['class'] of type string[] is incompatible with the type integer expected by parameter $code of Mdiyakov\DoctrineSolrBun...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
                    /** @scrutinizer ignore-type */ $entityConfig['class'],
Loading history...
127
                    $schema->getName()
0 ignored issues
show
Bug introduced by
$schema->getName() of type string is incompatible with the type Throwable|null expected by parameter $previous of Mdiyakov\DoctrineSolrBun...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
                    /** @scrutinizer ignore-type */ $schema->getName()
Loading history...
128
                );
129
            }
130
131
            $multiClassQueryConfig['entityConfigs'][] = $entityConfig;
132
            $multiClassQueryConfig['hydrators'][$discriminatorConfigField->getValue($entityConfig)] = $this->hydrators[$class];
133
        }
134
135
        return new MultiClassSelectQuery(
136
            $schema,
137
            $this->clientRegistry->getClient(
138
                $this->config->getSolariumClient($schema->getClient())
139
            ),
140
            $multiClassQueryConfig['entityConfigs'],
141
            $multiClassQueryConfig['hydrators']
142
        );
143
    }
144
145
}