Passed
Branch master (056094)
by Andreas
04:47
created

midgard_collector::execute()   D

Complexity

Conditions 9
Paths 24

Size

Total Lines 45
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 9.0164

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 9
eloc 28
c 2
b 0
f 0
nc 24
nop 0
dl 0
loc 45
ccs 32
cts 34
cp 0.9412
crap 9.0164
rs 4.909
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
8
use midgard\portable\api\error\exception;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, exception. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use midgard\portable\storage\connection;
10
11
class midgard_collector extends midgard_query_builder
12
{
13
    /**
14
     * the results determined by execute
15
     *
16
     * @var array
17
     */
18
    private $_results = null;
19
20
    /**
21
     *
22
     * @var string
23
     */
24
    private $key_property = "guid";
25
26
    private $value_properties = [];
27
28 11
    public function __construct($class, $field = null, $value = null)
29
    {
30 11
        parent::__construct($class);
31 11
        if ($field) {
32 11
            $this->add_constraint($field, '=', $value);
33 11
        }
34 11
    }
35
36
    /**
37
     * @param string $property
38
     * @return boolean
39
     */
40 5
    public function set_key_property($property)
41
    {
42
        // after execute there is no sense in changing the key property
43 5
        if ($this->_results !== null) {
44
            return false;
45
        }
46 5
        $this->key_property = $property;
47
48 5
        return true;
49
    }
50
51
    /**
52
     * @param string $property
53
     * @return boolean
54
     */
55 6
    public function add_value_property($property)
56
    {
57 6
        if ($this->_results !== null) {
58
            return false;
59
        }
60
61 6
        if (!isset($this->value_properties[$property])) {
62
            try {
63 6
                $this->value_properties[$property] = $this->build_property_select($property);
64 6
            } catch (exception $e) {
65 1
                return false;
66
            }
67 5
        }
68 5
        return true;
69
    }
70
71 10
    protected function build_property_select($property)
72
    {
73 10
        $parsed = $this->parse_constraint_name($property);
74
75
        // for properties like up.name
76 9
        if (   strpos($property, ".") !== false
77 9
            && !(strpos($property, "metadata") === 0)) {
78 1
            return $parsed['name'] . " as " . str_replace(".", "_", $property);
79
        }
80
81 9
        $cm = connection::get_em()->getClassMetadata($this->classname);
82 9
        if (array_key_exists($property, $cm->midgard['field_aliases'])) {
83 1
            return $parsed['name'] . " as " . str_replace(".", "_", $property);
84
        }
85
86 9
        if ($cm->hasAssociation($property)) {
87 1
            return 'IDENTITY(' . $parsed['name'] . ") as " . $property;
88
        }
89
90 9
        return $parsed['name'];
91
    }
92
93
    /**
94
     * @return boolean
95
     */
96 8
    public function execute()
97
    {
98 8
        if ($this->_results !== null) {
99
            return false;
100
        }
101 8
        $this->check_groups();
102 8
        $properties = $this->value_properties;
103 8
        if (!isset($this->value_properties[$this->key_property])) {
104
            try {
105 7
                $properties[] = $this->build_property_select($this->key_property);
106 7
            } catch (exception $e) {
107
                throw new exception('Property "' . $this->key_property . '" not found in "' . $this->classname . '"', exception::INVALID_PROPERTY);
108
            }
109 7
        }
110
111 8
        $this->qb->addSelect(implode(", ", $properties));
112 8
        $this->pre_execution();
113 8
        $results = $this->qb->getQuery()->getArrayResult();
114 8
        $this->post_execution();
115
116 8
        $cm = connection::get_em()->getClassMetadata($this->classname);
117
        // map results by current key property
118 8
        $results_map = [];
119 8
        foreach ($results as $result) {
120 8
            foreach ($result as $key => &$value) {
121
                // for metadata fields remove the "metadata_" prefix
122 8
                if (strpos($key, "metadata_") !== false) {
123 1
                    $result[str_replace("metadata_", "", $key)] = $value;
124 1
                    unset($result[$key]);
125 1
                }
126
                // TODO: find out why Doctrine doesn't do this on its own
127 8
                if ($cm->hasAssociation($key)) {
128 1
                    $value = (int) $value;
129 1
                }
130 8
            }
131 8
            $key = $result[$this->key_property];
132 8
            if (!isset($this->value_properties[$this->key_property])) {
133 7
                unset($result[$this->key_property]);
134 7
            }
135
136 8
            $results_map[$key] = $result;
137 8
        }
138
139 8
        $this->_results = $results_map;
140 8
        return true;
141
    }
142
143
    /**
144
     *
145
     * @param string $key
146
     * @return array
147
     */
148 2
    public function get($key)
149
    {
150 2
        if (   !$this->_has_results()
151 2
            || !isset($this->_results[$key])) {
152 1
            return false;
153
        }
154 2
        return $this->_results[$key];
155
    }
156
157
    /**
158
     *
159
     * @param string $key
160
     * @param string $property
161
     */
162 2
    public function get_subkey($key, $property)
163
    {
164 2
        if (!$this->_has_results() || !isset($this->_results[$key]) || !isset($this->_results[$key][$property])) {
165 1
            return false;
166
        }
167 2
        return $this->_results[$key][$property];
168
    }
169
170
    /**
171
     * check whether we got any results to work on
172
     *
173
     * @return boolean
174
     */
175 8
    private function _has_results()
176
    {
177
        // execute was not called or we got an empty resultset
178 8
        return !($this->_results === null || count($this->_results) == 0);
179
    }
180
181
    /**
182
     * @return array
183
     */
184 8
    public function list_keys()
185
    {
186 8
        if (!$this->_has_results()) {
187 1
            return [];
188
        }
189
190 8
        $keys = [];
191 8
        foreach ($this->_results as $key => $result) {
192 8
            $keys[$key] = '';
193 8
        }
194 8
        return $keys;
195
    }
196
}
197