Completed
Push — develop ( ec49e5...a553c2 )
by Bartko
01:59
created

Zend2::getPath()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 43
ccs 25
cts 25
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 25
nc 9
nop 3
crap 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace StefanoTree\NestedSet\Adapter;
6
7
use StefanoTree\NestedSet\NodeInfo;
8
use StefanoTree\NestedSet\Options;
9
use Zend\Db;
10
use Zend\Db\Adapter\Adapter as DbAdapter;
11
12
class Zend2 extends AdapterAbstract implements AdapterInterface
13
{
14
    private $dbAdapter;
15
16
    private $defaultDbSelect = null;
17
18 106
    public function __construct(Options $options, DbAdapter $dbAdapter)
19
    {
20 106
        $this->setOptions($options);
21 106
        $this->setDbAdapter($dbAdapter);
22 106
    }
23
24
    /**
25
     * @param DbAdapter $dbAdapter
26
     */
27 106
    protected function setDbAdapter(DbAdapter $dbAdapter): void
28
    {
29 106
        $this->dbAdapter = $dbAdapter;
30 106
    }
31
32
    /**
33
     * @return DbAdapter
34
     */
35 98
    protected function getDbAdapter(): DbAdapter
36
    {
37 98
        return $this->dbAdapter;
38
    }
39
40
    /**
41
     * Return base db select without any join, etc.
42
     *
43
     * @return Db\Sql\Select
44
     */
45 79
    public function getBlankDbSelect(): Db\Sql\Select
46
    {
47 79
        return new Db\Sql\Select($this->getOptions()->getTableName());
48
    }
49
50
    /**
51
     * @param Db\Sql\Select $dbSelect
52
     */
53 1
    public function setDefaultDbSelect(Db\Sql\Select $dbSelect): void
54
    {
55 1
        $this->defaultDbSelect = $dbSelect;
56 1
    }
57
58
    /**
59
     * Return default db select.
60
     *
61
     * @return Db\Sql\Select
62
     */
63 25
    public function getDefaultDbSelect()
64
    {
65 25
        if (null === $this->defaultDbSelect) {
66 24
            $this->defaultDbSelect = $this->getBlankDbSelect();
67
        }
68
69 25
        $dbSelect = clone $this->defaultDbSelect;
70
71 25
        return $dbSelect;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 31
    public function lockTree(): void
78
    {
79 31
        $options = $this->getOptions();
80
81 31
        $dbAdapter = $this->getDbAdapter();
82
83 31
        $select = $this->getBlankDbSelect();
84 31
        $select->columns(array(
85 31
            'i' => $options->getIdColumnName(),
86
        ));
87
88 31
        $sql = $select->getSqlString($dbAdapter->getPlatform()).' FOR UPDATE';
89
90 31
        $dbAdapter->query($sql, DbAdapter::QUERY_MODE_EXECUTE);
91 31
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 31
    public function beginTransaction(): void
97
    {
98 31
        $this->getDbAdapter()
99 31
             ->getDriver()
100 31
             ->getConnection()
101 31
             ->beginTransaction();
102 31
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 16
    public function commitTransaction(): void
108
    {
109 16
        $this->getDbAdapter()
110 16
             ->getDriver()
111 16
             ->getConnection()
112 16
             ->commit();
113 16
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 16
    public function rollbackTransaction(): void
119
    {
120 16
        $this->getDbAdapter()
121 16
             ->getDriver()
122 16
             ->getConnection()
123 16
             ->rollback();
124 16
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129 5
    public function update($nodeId, array $data): void
130
    {
131 5
        $options = $this->getOptions();
132
133 5
        $dbAdapter = $this->getDbAdapter();
134
135 5
        $data = $this->cleanData($data);
136
137 5
        $update = new Db\Sql\Update($options->getTableName());
138 5
        $update->set($data)
139 5
               ->where(array(
140 5
                    $options->getIdColumnName() => $nodeId,
141
               ));
142
143 5
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
144 5
                DbAdapter::QUERY_MODE_EXECUTE);
145 5
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 12
    public function insert(NodeInfo $nodeInfo, array $data)
151
    {
152 12
        $options = $this->getOptions();
153
154 12
        $dbAdapter = $this->getDbAdapter();
155
156 12
        $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
157 12
        $data[$options->getLevelColumnName()] = $nodeInfo->getLevel();
158 12
        $data[$options->getLeftColumnName()] = $nodeInfo->getLeft();
159 12
        $data[$options->getRightColumnName()] = $nodeInfo->getRight();
160
161 12
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
162 4
            $data[$options->getScopeColumnName()] = $nodeInfo->getScope();
163
        }
164
165 12
        $insert = new Db\Sql\Insert($options->getTableName());
166 12
        $insert->values($data);
167 12
        $dbAdapter->query($insert->getSqlString($dbAdapter->getPlatform()),
168 12
            DbAdapter::QUERY_MODE_EXECUTE);
169
170 12
        $lastGeneratedValue = $dbAdapter->getDriver()
171 12
                                        ->getLastGeneratedValue($options->getSequenceName());
0 ignored issues
show
Unused Code introduced by
The call to DriverInterface::getLastGeneratedValue() has too many arguments starting with $options->getSequenceName().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
172
173 12
        return $lastGeneratedValue;
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 4
    public function delete($nodeId): void
180
    {
181 4
        $options = $this->getOptions();
182
183 4
        $dbAdapter = $this->getDbAdapter();
184
185 4
        $delete = new Db\Sql\Delete($options->getTableName());
186 4
        $delete->where
187 4
               ->equalTo($options->getIdColumnName(), $nodeId);
188
189 4
        $dbAdapter->query($delete->getSqlString($dbAdapter->getPlatform()),
190 4
            DbAdapter::QUERY_MODE_EXECUTE);
191 4
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 14
    public function moveLeftIndexes($fromIndex, $shift, $scope = null): void
197
    {
198 14
        $options = $this->getOptions();
199
200 14
        if (0 == $shift) {
201
            return;
202
        }
203
204 14
        $dbAdapter = $this->getDbAdapter();
205 14
        $dbPlatform = $dbAdapter->getPlatform();
206
207 14
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
208 14
                .' SET '
209 14
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' = '
210 14
                        .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' + :shift'
211 14
                .' WHERE '
212 14
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' > :fromIndex';
213
214 14
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
215 4
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
216
        }
217
218
        $binds = array(
219 14
            ':shift' => $shift,
220 14
            ':fromIndex' => $fromIndex,
221
        );
222
223 14
        $dbAdapter->query($sql)
0 ignored issues
show
Bug introduced by
The method execute does only exist in Zend\Db\Adapter\Driver\StatementInterface, but not in Zend\Db\Adapter\Driver\R...tSet\ResultSetInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
224 14
                  ->execute($binds);
225 14
    }
226
227
    /**
228
     * {@inheritdoc}
229
     */
230 14
    public function moveRightIndexes($fromIndex, $shift, $scope = null): void
231
    {
232 14
        $options = $this->getOptions();
233
234 14
        if (0 == $shift) {
235
            return;
236
        }
237
238 14
        $dbAdapter = $this->getDbAdapter();
239 14
        $dbPlatform = $dbAdapter->getPlatform();
240
241 14
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
242 14
                .' SET '
243 14
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' = '
244 14
                        .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' + :shift'
245 14
                .' WHERE '
246 14
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' > :fromIndex';
247
248 14
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
249 4
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
250
        }
251
252
        $binds = array(
253 14
            ':shift' => $shift,
254 14
            ':fromIndex' => $fromIndex,
255
        );
256
257 14
        $dbAdapter->query($sql)
0 ignored issues
show
Bug introduced by
The method execute does only exist in Zend\Db\Adapter\Driver\StatementInterface, but not in Zend\Db\Adapter\Driver\R...tSet\ResultSetInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
258 14
                  ->execute($binds);
259 14
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264 5
    public function updateParentId($nodeId, $newParentId): void
265
    {
266 5
        $options = $this->getOptions();
267
268 5
        $dbAdapter = $this->getDbAdapter();
269
270 5
        $update = new Db\Sql\Update($options->getTableName());
271 5
        $update->set(array(
272 5
                    $options->getParentIdColumnName() => $newParentId,
273
               ))
274 5
               ->where(array(
275 5
                   $options->getIdColumnName() => $nodeId,
276
               ));
277
278 5
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
279 5
            DbAdapter::QUERY_MODE_EXECUTE);
280 5
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285 6
    public function updateLevels(int $leftIndexFrom, int $rightIndexTo, int $shift, $scope = null): void
286
    {
287 6
        $options = $this->getOptions();
288
289 6
        if (0 == $shift) {
290
            return;
291
        }
292
293 6
        $dbAdapter = $this->getDbAdapter();
294 6
        $dbPlatform = $dbAdapter->getPlatform();
295
296 6
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
297 6
            .' SET '
298 6
                .$dbPlatform->quoteIdentifier($options->getLevelColumnName()).' = '
299 6
                    .$dbPlatform->quoteIdentifier($options->getLevelColumnName()).' + :shift'
300 6
            .' WHERE '
301 6
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' >= :leftFrom'
302 6
                .' AND '.$dbPlatform->quoteIdentifier($options->getRightColumnName()).' <= :rightTo';
303
304 6
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
305 1
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
306
        }
307
308
        $binds = array(
309 6
            ':shift' => $shift,
310 6
            ':leftFrom' => $leftIndexFrom,
311 6
            ':rightTo' => $rightIndexTo,
312
        );
313
314 6
        $dbAdapter->query($sql)
0 ignored issues
show
Bug introduced by
The method execute does only exist in Zend\Db\Adapter\Driver\StatementInterface, but not in Zend\Db\Adapter\Driver\R...tSet\ResultSetInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
315 6
                  ->execute($binds);
316 6
    }
317
318
    /**
319
     * {@inheritdoc}
320
     */
321 7
    public function moveBranch(int $leftIndexFrom, int $rightIndexTo, int $shift, $scope = null): void
322
    {
323 7
        if (0 == $shift) {
324
            return;
325
        }
326
327 7
        $options = $this->getOptions();
328
329 7
        $dbAdapter = $this->getDbAdapter();
330 7
        $dbPlatform = $dbAdapter->getPlatform();
331
332 7
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
333 7
            .' SET '
334 7
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' = '
335 7
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' + :shift, '
336 7
                .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' = '
337 7
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' + :shift'
338 7
            .' WHERE '
339 7
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' >= :leftFrom'
340 7
                .' AND '.$dbPlatform->quoteIdentifier($options->getRightColumnName()).' <= :rightTo';
341
342 7
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
343 2
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
344
        }
345
346
        $binds = array(
347 7
            ':shift' => $shift,
348 7
            ':leftFrom' => $leftIndexFrom,
349 7
            ':rightTo' => $rightIndexTo,
350
        );
351
352 7
        $dbAdapter->query($sql)
0 ignored issues
show
Bug introduced by
The method execute does only exist in Zend\Db\Adapter\Driver\StatementInterface, but not in Zend\Db\Adapter\Driver\R...tSet\ResultSetInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
353 7
                  ->execute($binds);
354 7
    }
355
356
    /**
357
     * {@inheritdoc}
358
     */
359 12
    public function getRoots($scope = null): array
360
    {
361 12
        $options = $this->getOptions();
362
363 12
        $dbAdapter = $this->getDbAdapter();
364
365 12
        $select = $this->getBlankDbSelect();
366 12
        $select->where
367 12
            ->isNull($options->getParentIdColumnName());
368 12
        $select->order($options->getIdColumnName());
369
370 12
        if (null != $scope && $options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
371 3
            $select->where
372 3
                ->equalTo($options->getScopeColumnName(), $scope);
373
        }
374
375 12
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
376 12
            DbAdapter::QUERY_MODE_EXECUTE);
377
378 12
        return $result->toArray();
379
    }
380
381
    /**
382
     * {@inheritdoc}
383
     */
384 9
    public function getRoot($scope = null): array
385
    {
386 9
        $roots = $this->getRoots($scope);
387
388 9
        return (0 < count($roots)) ? $roots[0] : array();
389
    }
390
391
    /**
392
     * {@inheritdoc}
393
     */
394 5
    public function getNode($nodeId): ?array
395
    {
396 5
        $options = $this->getOptions();
397
398 5
        $nodeId = (int) $nodeId;
399
400 5
        $dbAdapter = $this->getDbAdapter();
401
402 5
        $select = $this->getDefaultDbSelect()
403 5
                       ->where(array($options->getIdColumnName() => $nodeId));
404
405 5
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
406 5
                DbAdapter::QUERY_MODE_EXECUTE);
407
408 5
        $array = $result->toArray();
409
410 5
        return (0 < count($array)) ? $array[0] : null;
411
    }
412
413
    /**
414
     * {@inheritdoc}
415
     */
416 56
    public function getNodeInfo($nodeId): ?NodeInfo
417
    {
418 56
        $options = $this->getOptions();
419
420 56
        $nodeId = (int) $nodeId;
421
422 56
        $dbAdapter = $this->getDbAdapter();
423
424 56
        $select = $this->getBlankDbSelect()
425 56
            ->where(array($options->getIdColumnName() => $nodeId));
426
427 56
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
428 56
            DbAdapter::QUERY_MODE_EXECUTE);
429
430 56
        $array = $result->toArray();
431
432 56
        $result = ($array) ? $this->_buildNodeInfoObject($array[0]) : null;
433
434 56
        return $result;
435
    }
436
437
    /**
438
     * {@inheritdoc}
439
     */
440 6
    public function getChildrenNodeInfo($parentNodeId): array
441
    {
442 6
        $dbAdapter = $this->getDbAdapter();
443 6
        $options = $this->getOptions();
444
445
        $columns = array(
446 6
            $options->getIdColumnName(),
447 6
            $options->getLeftColumnName(),
448 6
            $options->getRightColumnName(),
449 6
            $options->getParentIdColumnName(),
450 6
            $options->getLevelColumnName(),
451
        );
452
453 6
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
454 4
            $columns[] = $options->getScopeColumnName();
455
        }
456
457 6
        $select = $this->getBlankDbSelect();
458 6
        $select->columns($columns);
459 6
        $select->order($options->getLeftColumnName());
460 6
        $select->where(array(
461 6
            $options->getParentIdColumnName() => $parentNodeId,
462
        ));
463
464 6
        $data = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
465 6
            DbAdapter::QUERY_MODE_EXECUTE);
466
467 6
        $result = array();
468
469 6
        foreach ($data->toArray() as $nodeData) {
470 5
            $result[] = $this->_buildNodeInfoObject($nodeData);
471
        }
472
473 6
        return $result;
474
    }
475
476
    /**
477
     * {@inheritdoc}
478
     */
479 3
    public function updateNodeMetadata(NodeInfo $nodeInfo): void
480
    {
481 3
        $dbAdapter = $this->getDbAdapter();
482 3
        $options = $this->getOptions();
483
484 3
        $update = new Db\Sql\Update($options->getTableName());
485
486 3
        $update->set(array(
487 3
            $options->getRightColumnName() => $nodeInfo->getRight(),
488 3
            $options->getLeftColumnName() => $nodeInfo->getLeft(),
489 3
            $options->getLevelColumnName() => $nodeInfo->getLevel(),
490
        ));
491
492 3
        $update->where(array(
493 3
            $options->getIdColumnName() => $nodeInfo->getId(),
494
        ));
495
496 3
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
497 3
            DbAdapter::QUERY_MODE_EXECUTE);
498 3
    }
499
500
    /**
501
     * {@inheritdoc}
502
     */
503 9
    public function getAncestors($nodeId, int $startLevel = 0, bool $excludeLastNode = false): array
504
    {
505 9
        $options = $this->getOptions();
506
507 9
        $startLevel = (int) $startLevel;
508
509
        // node does not exist
510 9
        $nodeInfo = $this->getNodeInfo($nodeId);
511 9
        if (!$nodeInfo) {
512 2
            return array();
513
        }
514
515 7
        $dbAdapter = $this->getDbAdapter();
516
517 7
        $select = $this->getDefaultDbSelect();
518
519 7
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
520 2
            $select->where
521 2
                ->equalTo($options->getScopeColumnName(), $nodeInfo->getScope());
522
        }
523
524 7
        $select->where
525 7
               ->lessThanOrEqualTo($options->getLeftColumnName(), $nodeInfo->getLeft())
526 7
               ->AND
527 7
               ->greaterThanOrEqualTo($options->getRightColumnName(), $nodeInfo->getRight());
528
529 7
        $select->order($options->getLeftColumnName().' ASC');
530
531 7
        if (0 < $startLevel) {
532 2
            $select->where
533 2
                   ->greaterThanOrEqualTo($options->getLevelColumnName(), $startLevel);
534
        }
535
536 7
        if (true == $excludeLastNode) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
537 3
            $select->where
538 3
                   ->lessThan($options->getLevelColumnName(), $nodeInfo->getLevel());
539
        }
540
541 7
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
542 7
            DbAdapter::QUERY_MODE_EXECUTE);
543
544 7
        return $result->toArray();
545
    }
546
547
    /**
548
     * {@inheritdoc}
549
     */
550 14
    public function getDescendants($nodeId, int $startLevel = 0, ?int $levels = null, ?int $excludeBranch = null): array
551
    {
552 14
        $options = $this->getOptions();
553
554 14
        if (!$nodeInfo = $this->getNodeInfo($nodeId)) {
555 3
            return array();
556
        }
557
558 11
        $dbAdapter = $this->getDbAdapter();
559 11
        $select = $this->getDefaultDbSelect();
560 11
        $select->order($options->getLeftColumnName().' ASC');
561
562 11
        if ($options->getScopeColumnName()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getScopeColumnName() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
563 2
            $select->where
564 2
                   ->equalTo($options->getScopeColumnName(), $nodeInfo->getScope());
565
        }
566
567 11
        if (0 != $startLevel) {
568 6
            $level = $nodeInfo->getLevel() + (int) $startLevel;
569 6
            $select->where
570 6
                   ->greaterThanOrEqualTo($options->getLevelColumnName(), $level);
571
        }
572
573 11
        if (null != $levels) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $levels of type null|integer against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
574 4
            $endLevel = $nodeInfo->getLevel() + (int) $startLevel + abs($levels);
575 4
            $select->where
576 4
                   ->lessThan($options->getLevelColumnName(), $endLevel);
577
        }
578
579 11
        if (null != $excludeBranch && null != ($excludeNodeInfo = $this->getNodeInfo($excludeBranch))) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $excludeBranch of type null|integer against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
580 2
            $select->where
581 2
                   ->NEST
582 2
                   ->between($options->getLeftColumnName(),
583 2
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
584 2
                   ->OR
585 2
                   ->between($options->getLeftColumnName(),
586 2
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
587 2
                   ->UNNEST
588 2
                   ->AND
589 2
                   ->NEST
590 2
                   ->between($options->getRightColumnName(),
591 2
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
592 2
                   ->OR
593 2
                   ->between($options->getRightColumnName(),
594 2
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
595 2
                   ->UNNEST;
596
        } else {
597 10
            $select->where
598 10
                   ->greaterThanOrEqualTo($options->getLeftColumnName(), $nodeInfo->getLeft())
599 10
                   ->AND
600 10
                   ->lessThanOrEqualTo($options->getRightColumnName(), $nodeInfo->getRight());
601
        }
602
603 11
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
604 11
            DbAdapter::QUERY_MODE_EXECUTE);
605
606 11
        $resultArray = $result->toArray();
607
608 11
        return (0 < count($resultArray)) ? $resultArray : array();
609
    }
610
}
611