RequiredFieldsExtractor   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 3
dl 0
loc 106
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A extractRequiredFields() 0 12 2
A extractTransformerRequiredFields() 0 13 4
B recursivelyAddDependantAliasFields() 0 19 6
A getField() 0 10 3
1
<?php
2
namespace Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\QueryBuilder;
3
4
use Netdudes\DataSourceryBundle\DataSource\Configuration\Field;
5
use Netdudes\DataSourceryBundle\Query\Query;
6
use Netdudes\DataSourceryBundle\Transformers\TransformerInterface;
7
8
class RequiredFieldsExtractor
9
{
10
    /**
11
     * @var array[][]
12
     */
13
    protected $fieldsCache = [];
14
15
    /**
16
     * @var \Netdudes\DataSourceryBundle\DataSource\Configuration\Field[]
17
     */
18
    private $queryBuilderDataSourceFields;
19
20
    /**
21
     * @var array
22
     */
23
    private $transformers;
24
25
    public function __construct(array $queryBuilderDataSourceFields, array $transformers)
26
    {
27
        $this->queryBuilderDataSourceFields = $queryBuilderDataSourceFields;
28
        $this->transformers = $transformers;
29
    }
30
31
    /**
32
     * Collect all required fields that *must* be SELECTed
33
     *
34
     * @param Query $query
35
     *
36
     * @return array
37
     */
38
    public function extractRequiredFields(Query $query)
39
    {
40
        $uniqueId = spl_object_hash($query);
41
        if (!isset($this->fieldsCache[$uniqueId])) {
42
            $queryRequiredFields = $query->extractRequiredFields();
43
            $transformerRequiredFields = $this->extractTransformerRequiredFields($this->transformers);
44
            $firstLevelRequiredFields = array_unique(array_merge($queryRequiredFields, $transformerRequiredFields));
45
            $this->fieldsCache[$uniqueId] = $this->recursivelyAddDependantAliasFields($firstLevelRequiredFields);
46
        }
47
48
        return $this->fieldsCache[$uniqueId];
49
    }
50
51
    /**
52
     * Finds all required fields that stem from the logic inside transformers
53
     *
54
     * @param TransformerInterface[] $transformers
55
     *
56
     * @return array
57
     */
58
    private function extractTransformerRequiredFields(array $transformers)
59
    {
60
        $transformersRequiredFields = [];
61
        foreach ($transformers as $transformer) {
62
            foreach ($transformer->getRequiredFieldNames() as $fieldName) {
63
                if (!in_array($fieldName, $transformersRequiredFields, true)) {
64
                    $transformersRequiredFields[] = $fieldName;
65
                }
66
            }
67
        }
68
69
        return $transformersRequiredFields;
70
    }
71
72
    /**
73
     * @param array $fieldNames
74
     *
75
     * @return array
76
     * @throws \Exception
77
     */
78
    private function recursivelyAddDependantAliasFields(array $fieldNames)
79
    {
80
        $dependantFields = [];
81
        foreach ($fieldNames as $fieldName) {
82
            $field = $this->getField($fieldName);
83
            if ($field !== null && is_array($field->getDatabaseSelectAlias())) {
84
                foreach ($field->getDatabaseSelectAlias() as $secondLevelRequiredField) {
85
                    $dependantFields[] = $secondLevelRequiredField;
86
                }
87
            }
88
        }
89
90
        $newFieldsHaveBeenFound = count($dependantFields) != count(array_intersect($fieldNames, $dependantFields));
91
        if ($newFieldsHaveBeenFound) {
92
            return $this->recursivelyAddDependantAliasFields(array_unique(array_merge($fieldNames, $dependantFields)));
93
        }
94
95
        return $fieldNames;
96
    }
97
98
    /**
99
     * @param $fieldName
100
     *
101
     * @return Field
102
     */
103
    private function getField($fieldName)
104
    {
105
        foreach ($this->queryBuilderDataSourceFields as $queryBuilderDataSourceField) {
106
            if ($queryBuilderDataSourceField->getUniqueName() == $fieldName) {
107
                return $queryBuilderDataSourceField;
108
            }
109
        }
110
111
        return null;
112
    }
113
}
114