Completed
Push — master ( 740836...6931a9 )
by Ivan
01:50
created

TableQueryIterator::current()   C

Complexity

Conditions 26
Paths 6

Size

Total Lines 79
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 58
CRAP Score 26

Importance

Changes 0
Metric Value
dl 0
loc 79
ccs 58
cts 58
cp 1
rs 5.0201
c 0
b 0
f 0
cc 26
eloc 59
nc 6
nop 0
crap 26

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace vakata\database\schema;
3
4
use vakata\collection\Collection;
5
use vakata\database\DBException;
6
7
/**
8
 * A table query iterator
9
 */
10
class TableQueryIterator implements \Iterator, \ArrayAccess
11
{
12
    const SEP = '___';
13
    /**
14
     * @var array
15
     */
16
    protected $pkey;
17
    /**
18
     * @var Collection
19
     */
20
    protected $result;
21
    /**
22
     * @var array[]
23
     */
24
    protected $relations;
25
    /**
26
     * @var array[]
27
     */
28
    protected $aliases;
29
    /**
30
     * @var string|null
31
     */
32
    protected $primary = null;
33
    /**
34
     * @var int
35
     */
36
    protected $fetched = 0;
37
38 11
    public function __construct(Collection $result, array $pkey, array $relations = [], array $aliases = [])
39
    {
40 11
        $this->pkey = $pkey;
41 11
        $this->result = $result;
42 11
        $this->relations = $relations;
43 11
        $this->aliases = $aliases;
44 11
    }
45
46 11
    public function key()
47
    {
48 11
        return $this->fetched;
49
    }
50 11
    public function current()
51
    {
52 11
        $result = null;
53 11
        $remove = [];
54 11
        while ($this->result->valid()) {
55 11
            $row = $this->result->current();
56 11
            $pk = [];
57 11
            foreach ($this->pkey as $field) {
58 11
                $pk[$field] = $row[$field];
59
            }
60 11
            $pk = json_encode($pk);
61 11
            if ($this->primary !== null && $pk !== $this->primary) {
62 8
                break;
63
            }
64 11
            $this->primary = $pk;
65 11
            if (!$result) {
66 11
                $result = $row;
67
            }
68 11
            foreach ($this->relations as $name => $relation) {
69 4
                $relation = $relation[0];
70 4
                $fields = [];
71 4
                $exists = false;
72 4
                foreach ($relation->table->getColumns() as $column) {
73 4
                    $nm = $name . static::SEP . $column;
74 4
                    if (isset($this->aliases[$nm])) {
75 4
                        $nm = $this->aliases[$nm];
76
                    }
77 4
                    $fields[$column] = $row[$nm];
78 4
                    if (!$exists && $row[$nm] !== null) {
79 4
                        $exists = true;
80
                    }
81 4
                    $remove[] = $nm; // $name . static::SEP . $column;
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
82
                }
83 4
                $temp  = &$result;
84 4
                $parts = explode(static::SEP, $name);
85 4
                $name  = array_pop($parts);
86 4
                if (!$exists && !count($parts) && !isset($temp[$name])) {
87 2
                    $temp[$name] = $relation->many ? [ '___clean' => true ] : null;
88
                }
89 4
                if ($exists) {
90 4
                    $full  = '';
91 4
                    foreach ($parts as $item) {
92 1
                        $full = $full ? $full . static::SEP . $item : $item;
93 1
                        $temp = &$temp[$item];
94 1
                        $rpk = [];
95 1
                        foreach ($this->relations[$full][0]->table->getPrimaryKey() as $pkey) {
96 1
                            $nm = $full . static::SEP . $pkey;
97 1
                            if (isset($this->aliases[$nm])) {
98 1
                                $nm = $this->aliases[$nm];
99
                            }
100 1
                            $rpk[$pkey] = $row[$nm];
101
                        }
102 1
                        $temp = &$temp[json_encode($rpk)];
103
                    }
104 4
                    if (!isset($temp[$name])) {
105 4
                        $temp[$name] = $relation->many ? [ '___clean' => true ] : null;
106
                    }
107 4
                    $temp = &$temp[$name];
108 4
                    if ($relation->many) {
109 4
                        $rpk = [];
110 4
                        foreach ($relation->table->getPrimaryKey() as $field) {
111 4
                            $rpk[$field] = $fields[$field];
112
                        }
113 4
                        $temp[json_encode($rpk)] = array_merge($temp[json_encode($rpk)] ?? [], $fields);
114
                    } else {
115 4
                        $temp = array_merge($temp ?? [], $fields);
116
                    }
117
                }
118
            }
119 11
            $this->result->next();
120
        }
121 11
        if ($result) {
122 11
            foreach ($remove as $name) {
123 4
                unset($result[$name]);
124
            }
125 11
            $result = $this->values($result);
126
        }
127 11
        return $result;
128
    }
129 11
    protected function values(array $data)
130
    {
131 11
        foreach ($data as $k => $v) {
132 11
            if (is_array($v) && isset($v['___clean']) && $v['___clean'] === true) {
133 4
                unset($v['___clean']);
134 4
                $data[$k] = array_values($v);
135 4
                foreach ($data[$k] as $kk => $vv) {
136 11
                    $data[$k][$kk] = $this->values($vv);
137
                }
138
            }
139
        }
140 11
        return $data;
141
    }
142
143 11
    public function rewind()
144
    {
145 11
        $this->fetched = 0;
146 11
        $this->primary = null;
147 11
        return $this->result->rewind();
148
    }
149 11
    public function next()
150
    {
151 11
        if ($this->primary === null) {
152
            $this->result->next();
153
            if ($this->result->valid()) {
154
                $row = $this->result->current();
155
                $temp = [];
156
                foreach ($this->pkey as $field) {
157
                    $temp[$field] = $row[$field];
158
                }
159
                $this->primary = json_encode($temp);
160
                return;
161
            }
162
        }
163 11
        $this->fetched ++;
164 11
        while ($this->result->valid()) {
165 8
            $row = $this->result->current();
166 8
            $pk = [];
167 8
            foreach ($this->pkey as $field) {
168 8
                $pk[$field] = $row[$field];
169
            }
170 8
            $pk = json_encode($pk);
171 8
            if ($this->primary !== $pk) {
172 8
                $this->primary = $pk;
173 8
                break;
174
            }
175
            $this->result->next();
176
        }
177 11
    }
178 11
    public function valid()
179
    {
180 11
        return $this->result->valid();
181
    }
182
183 9
    public function offsetGet($offset)
184
    {
185 9
        $index = $this->fetched;
186 9
        $item = null;
187 9
        foreach ($this as $k => $v) {
188 9
            if ($k === $offset) {
189 9
                $item = $v;
190
            }
191
        }
192 9
        foreach ($this as $k => $v) {
193 9
            if ($k === $index) {
194 9
                break;
195
            }
196
        }
197 9
        return $item;
198
    }
199
    public function offsetExists($offset)
200
    {
201
        $index = $this->fetched;
202
        $exists = false;
203
        foreach ($this as $k => $v) {
204
            if ($k === $offset) {
205
                $exists = true;
206
            }
207
        }
208
        foreach ($this as $k => $v) {
209
            if ($k === $index) {
210
                break;
211
            }
212
        }
213
        return $exists;
214
    }
215
    public function offsetSet($offset, $value)
216
    {
217
        throw new DBException('Invalid call to offsetSet');
218
    }
219
    public function offsetUnset($offset)
220
    {
221
        throw new DBException('Invalid call to offsetUnset');
222
    }
223
}
224