ResultSet   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 94.57%

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 7
dl 0
loc 255
ccs 87
cts 92
cp 0.9457
rs 9.52
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getColumnModel() 0 9 2
A setSource() 0 6 1
A getSource() 0 4 1
A setHydrationOptions() 0 6 1
A getHydrationOptions() 0 4 1
A getPaginator() 0 20 3
A setTotalRows() 0 6 1
A getTotalRows() 0 4 1
B initColumnModelHydration() 0 39 7
B current() 0 38 10
A toArray() 0 19 5
A valid() 0 9 2
A rewind() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * soluble-flexstore library
7
 *
8
 * @author    Vanvelthem Sébastien
9
 * @link      https://github.com/belgattitude/soluble-flexstore
10
 * @copyright Copyright (c) 2016-2017 Vanvelthem Sébastien
11
 * @license   MIT License https://github.com/belgattitude/soluble-flexstore/blob/master/LICENSE.md
12
 *
13
 */
14
15
namespace Soluble\FlexStore\ResultSet;
16
17
use Soluble\FlexStore\Exception\InvalidUsageException;
18
use Soluble\FlexStore\Source\AbstractSource;
19
use Soluble\FlexStore\Helper\Paginator;
20
use Soluble\FlexStore\Options\HydrationOptions;
21
use Soluble\FlexStore\Column\ColumnModel;
22
use ArrayObject;
23
24
class ResultSet extends AbstractResultSet
25
{
26
    /**
27
     * @var Paginator
28
     */
29
    protected $paginator;
30
31
    /**
32
     * @var int|null
33
     */
34
    protected $totalRows;
35
36
    /**
37
     * @var AbstractSource
38
     */
39
    protected $source;
40
41
    /**
42
     * @var HydrationOptions|null
43
     */
44
    protected $hydrationOptions;
45
46
    /**
47
     * @var bool
48
     */
49
    protected $hydrate_options_initialized = false;
50
51
    /**
52
     * @var ArrayObject
53
     */
54
    protected $hydration_formatters;
55
56
    /**
57
     * @var ArrayObject
58
     */
59
    protected $hydration_renderers;
60
61
    /**
62
     * @var ArrayObject|null
63
     */
64
    protected $hydrated_columns;
65
66
    /**
67
     * Return source column model.
68
     *
69
     * @throws Exception\RuntimeException
70
     */
71 10
    public function getColumnModel(): ColumnModel
72
    {
73 10
        if ($this->source === null) {
74 1
            throw new Exception\RuntimeException(__METHOD__ . ' Prior to get column model, a source must be set.');
75
        }
76 9
        $this->hydrate_options_initialized = false;
77
78 9
        return $this->source->getColumnModel();
79
    }
80
81
    /**
82
     * @param AbstractSource $source
83
     */
84 40
    public function setSource(AbstractSource $source): self
85
    {
86 40
        $this->source = $source;
87
88 40
        return $this;
89
    }
90
91 9
    public function getSource(): AbstractSource
92
    {
93 9
        return $this->source;
94
    }
95
96 40
    public function setHydrationOptions(HydrationOptions $hydrationOptions): self
97
    {
98 40
        $this->hydrationOptions = $hydrationOptions;
99
100 40
        return $this;
101
    }
102
103 9
    public function getHydrationOptions(): ?HydrationOptions
104
    {
105 9
        return $this->hydrationOptions;
106
    }
107
108 2
    public function getPaginator(): Paginator
109
    {
110 2
        if ($this->paginator === null) {
111 2
            $limit = $this->getSource()->getOptions()->getLimit();
112 2
            $totalRows = $this->getTotalRows() ?? 0;
0 ignored issues
show
Unused Code introduced by
$totalRows is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
113 2
            if (!is_int($limit)) {
114 1
                throw new InvalidUsageException(sprintf(
115 1
                    'Paginator requires a limit to be set.'
116
                ));
117
            }
118
119 1
            $this->paginator = new Paginator(
120 1
                $this->getTotalRows(),
121 1
                $limit,
122 1
                $this->getSource()->getOptions()->getOffset()
123
            );
124
        }
125
126 1
        return $this->paginator;
127
    }
128
129
    /**
130
     * Set the total rows.
131
     */
132 40
    public function setTotalRows(int $totalRows): self
133
    {
134 40
        $this->totalRows = $totalRows;
135
136 40
        return $this;
137
    }
138
139 13
    public function getTotalRows(): ?int
140
    {
141 13
        return $this->totalRows;
142
    }
143
144 27
    protected function initColumnModelHydration(ArrayObject $row): void
145
    {
146 27
        $this->hydration_formatters = new ArrayObject();
147 27
        $this->hydration_renderers = new ArrayObject();
148 27
        $this->hydrated_columns = null;
149
150 27
        if ($this->source->hasColumnModel()) {
151 9
            $cm = $this->getColumnModel();
152
153
            // 1. Initialize columns hydrators
154 9
            if ($this->getHydrationOptions()->isFormattersEnabled()) {
155 9
                $formatters = $cm->getUniqueFormatters();
156 9
                if ($formatters->count() > 0) {
157 2
                    $this->hydration_formatters = $formatters;
158
                }
159
            }
160
161
            // 2. Initialize hydrated columns
162
163 9
            if ($this->getHydrationOptions()->isColumnExclusionEnabled()) {
164 9
                $columns = $cm->getColumns();
165
166
                // Performance:
167
                // Only if column model definition differs from originating
168
                // source row definition.
169 9
                $hydrated_columns = array_keys((array) $columns);
170 9
                $row_columns = array_keys((array) $row);
171 9
                if ($hydrated_columns != $row_columns) {
172 5
                    $this->hydrated_columns = new ArrayObject($hydrated_columns);
173
                }
174
            }
175
176
            // 3. Initialize row renderers
177 9
            if ($this->getHydrationOptions()->isRenderersEnabled()) {
178 9
                $this->hydration_renderers = $cm->getRowRenderers();
179
            }
180
        }
181 27
        $this->hydrate_options_initialized = true;
182 27
    }
183
184
    /**
185
     * Return the current row as an array|ArrayObject.
186
     * If setLimitColumns() have been set, will only return
187
     * the limited columns.
188
     *
189
     * @throws Exception\UnknownColumnException
190
     *
191
     * @return array|ArrayObject|null
192
     */
193 27
    public function current()
194
    {
195 27
        $row = $this->zfResultSet->current();
196 27
        if ($row === null) {
197
            return null;
198
        }
199
200 27
        if (!$this->hydrate_options_initialized) {
201 27
            $this->initColumnModelHydration($row);
202
        }
203
204
        // 1. Row renderers
205 27
        foreach ($this->hydration_renderers as $renderer) {
206 5
            $renderer->apply($row);
207
        }
208
209
        // 2. Formatters
210 26
        foreach ($this->hydration_formatters as $formatters) {
211 2
            foreach ($formatters['columns'] as $column) {
212 2
                $row[$column] = $formatters['formatter']->format($row[$column], $row);
213
            }
214
        }
215
216
        // 3. Process column hydration
217 26
        if ($this->hydrated_columns !== null) {
218 4
            $d = new ArrayObject();
219 4
            foreach ($this->hydrated_columns as $column) {
220 4
                $d->offsetSet($column, isset($row[$column]) ? $row[$column] : null);
221
            }
222 4
            $row->exchangeArray($d);
223
        }
224
225 26
        if ($this->returnType === self::TYPE_ARRAY) {
226
            return (array) $row;
227
        }
228
229 26
        return $row;
230
    }
231
232
    /**
233
     * Cast result set to array of arrays.
234
     *
235
     * @throws Exception\RuntimeException if any row cannot be casted to an array
236
     */
237 26
    public function toArray(): array
238
    {
239 26
        $return = [];
240 26
        foreach ($this as $row) {
241 24
            if (is_array($row)) {
242
                $return[] = $row;
243 24
            } elseif (method_exists($row, 'toArray')) {
244
                $return[] = $row->toArray();
245 24
            } elseif (method_exists($row, 'getArrayCopy')) {
246 24
                $return[] = $row->getArrayCopy();
247
            } else {
248
                throw new Exception\RuntimeException(
249 24
                    __METHOD__ . ': Rows as part of this DataSource, with type ' . gettype($row) . ' cannot be cast to an array'
250
                );
251
            }
252
        }
253
254 25
        return $return;
255
    }
256
257
    /**
258
     * Iterator: is pointer valid?
259
     */
260 26
    public function valid(): bool
261
    {
262 26
        $valid = $this->zfResultSet->valid();
263 26
        if (!$valid) {
264 25
            $this->hydrate_options_initialized = false;
265
        }
266
267 26
        return $valid;
268
    }
269
270
    /**
271
     * Iterator: rewind.
272
     */
273 26
    public function rewind(): void
274
    {
275 26
        $this->hydrate_options_initialized = false;
276 26
        $this->zfResultSet->rewind();
277 26
    }
278
}
279