Completed
Push — master ( 2b0446...afde37 )
by Bartko
04:01 queued 01:40
created

Zend2::getRoots()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 13
cts 13
cp 1
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 13
nc 2
nop 1
crap 3
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 111
    public function __construct(Options $options, DbAdapter $dbAdapter)
17
    {
18 111
        $this->setOptions($options);
19 111
        $this->setDbAdapter($dbAdapter);
20 111
    }
21
22
    /**
23
     * @param DbAdapter $dbAdapter
24
     */
25 111
    protected function setDbAdapter(DbAdapter $dbAdapter): void
26
    {
27 111
        $this->dbAdapter = $dbAdapter;
28 111
    }
29
30
    /**
31
     * @return DbAdapter
32
     */
33 103
    protected function getDbAdapter(): DbAdapter
34
    {
35 103
        return $this->dbAdapter;
36
    }
37
38
    /**
39
     * Return base db select without any join, etc.
40
     *
41
     * @return Db\Sql\Select
42
     */
43 84
    public function getBlankDbSelect(): Db\Sql\Select
44
    {
45 84
        return new Db\Sql\Select($this->getOptions()->getTableName());
46
    }
47
48
    /**
49
     * Return default db select.
50
     *
51
     * @return Db\Sql\Select
52
     */
53 28
    public function getDefaultDbSelect()
54
    {
55 28
        return $this->getDbSelectBuilder()();
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 31
    public function lockTree(): void
62
    {
63 31
        $options = $this->getOptions();
64
65 31
        $dbAdapter = $this->getDbAdapter();
66
67 31
        $select = $this->getBlankDbSelect();
68 31
        $select->columns(array(
69 31
            'i' => $options->getIdColumnName(),
70
        ));
71
72 31
        $sql = $select->getSqlString($dbAdapter->getPlatform()).' FOR UPDATE';
73
74 31
        $dbAdapter->query($sql, DbAdapter::QUERY_MODE_EXECUTE);
75 31
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 31
    public function beginTransaction(): void
81
    {
82 31
        $this->getDbAdapter()
83 31
             ->getDriver()
84 31
             ->getConnection()
85 31
             ->beginTransaction();
86 31
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 16
    public function commitTransaction(): void
92
    {
93 16
        $this->getDbAdapter()
94 16
             ->getDriver()
95 16
             ->getConnection()
96 16
             ->commit();
97 16
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 16
    public function rollbackTransaction(): void
103
    {
104 16
        $this->getDbAdapter()
105 16
             ->getDriver()
106 16
             ->getConnection()
107 16
             ->rollback();
108 16
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 5
    public function update($nodeId, array $data): void
114
    {
115 5
        $options = $this->getOptions();
116
117 5
        $dbAdapter = $this->getDbAdapter();
118
119 5
        $data = $this->cleanData($data);
120
121 5
        $update = new Db\Sql\Update($options->getTableName());
122 5
        $update->set($data)
123 5
               ->where(array(
124 5
                    $options->getIdColumnName() => $nodeId,
125
               ));
126
127 5
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
128 5
                DbAdapter::QUERY_MODE_EXECUTE);
129 5
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134 12
    public function insert(NodeInfo $nodeInfo, array $data)
135
    {
136 12
        $options = $this->getOptions();
137
138 12
        $dbAdapter = $this->getDbAdapter();
139
140 12
        $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
141 12
        $data[$options->getLevelColumnName()] = $nodeInfo->getLevel();
142 12
        $data[$options->getLeftColumnName()] = $nodeInfo->getLeft();
143 12
        $data[$options->getRightColumnName()] = $nodeInfo->getRight();
144
145 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...
146 4
            $data[$options->getScopeColumnName()] = $nodeInfo->getScope();
147
        }
148
149 12
        $insert = new Db\Sql\Insert($options->getTableName());
150 12
        $insert->values($data);
151 12
        $dbAdapter->query($insert->getSqlString($dbAdapter->getPlatform()),
152 12
            DbAdapter::QUERY_MODE_EXECUTE);
153
154 12
        $lastGeneratedValue = $dbAdapter->getDriver()
155 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...
156
157 12
        return $lastGeneratedValue;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163 4
    public function delete($nodeId): void
164
    {
165 4
        $options = $this->getOptions();
166
167 4
        $dbAdapter = $this->getDbAdapter();
168
169 4
        $delete = new Db\Sql\Delete($options->getTableName());
170 4
        $delete->where
171 4
               ->equalTo($options->getIdColumnName(), $nodeId);
172
173 4
        $dbAdapter->query($delete->getSqlString($dbAdapter->getPlatform()),
174 4
            DbAdapter::QUERY_MODE_EXECUTE);
175 4
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180 14
    public function moveLeftIndexes($fromIndex, $shift, $scope = null): void
181
    {
182 14
        $options = $this->getOptions();
183
184 14
        if (0 == $shift) {
185
            return;
186
        }
187
188 14
        $dbAdapter = $this->getDbAdapter();
189 14
        $dbPlatform = $dbAdapter->getPlatform();
190
191 14
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
192 14
                .' SET '
193 14
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' = '
194 14
                        .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' + :shift'
195 14
                .' WHERE '
196 14
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' > :fromIndex';
197
198 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...
199 4
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
200
        }
201
202
        $binds = array(
203 14
            ':shift' => $shift,
204 14
            ':fromIndex' => $fromIndex,
205
        );
206
207 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...
208 14
                  ->execute($binds);
209 14
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214 14
    public function moveRightIndexes($fromIndex, $shift, $scope = null): void
215
    {
216 14
        $options = $this->getOptions();
217
218 14
        if (0 == $shift) {
219
            return;
220
        }
221
222 14
        $dbAdapter = $this->getDbAdapter();
223 14
        $dbPlatform = $dbAdapter->getPlatform();
224
225 14
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
226 14
                .' SET '
227 14
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' = '
228 14
                        .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' + :shift'
229 14
                .' WHERE '
230 14
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' > :fromIndex';
231
232 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...
233 4
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
234
        }
235
236
        $binds = array(
237 14
            ':shift' => $shift,
238 14
            ':fromIndex' => $fromIndex,
239
        );
240
241 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...
242 14
                  ->execute($binds);
243 14
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 5
    public function updateParentId($nodeId, $newParentId): void
249
    {
250 5
        $options = $this->getOptions();
251
252 5
        $dbAdapter = $this->getDbAdapter();
253
254 5
        $update = new Db\Sql\Update($options->getTableName());
255 5
        $update->set(array(
256 5
                    $options->getParentIdColumnName() => $newParentId,
257
               ))
258 5
               ->where(array(
259 5
                   $options->getIdColumnName() => $nodeId,
260
               ));
261
262 5
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
263 5
            DbAdapter::QUERY_MODE_EXECUTE);
264 5
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269 6
    public function updateLevels(int $leftIndexFrom, int $rightIndexTo, int $shift, $scope = null): void
270
    {
271 6
        $options = $this->getOptions();
272
273 6
        if (0 == $shift) {
274
            return;
275
        }
276
277 6
        $dbAdapter = $this->getDbAdapter();
278 6
        $dbPlatform = $dbAdapter->getPlatform();
279
280 6
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
281 6
            .' SET '
282 6
                .$dbPlatform->quoteIdentifier($options->getLevelColumnName()).' = '
283 6
                    .$dbPlatform->quoteIdentifier($options->getLevelColumnName()).' + :shift'
284 6
            .' WHERE '
285 6
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' >= :leftFrom'
286 6
                .' AND '.$dbPlatform->quoteIdentifier($options->getRightColumnName()).' <= :rightTo';
287
288 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...
289 1
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
290
        }
291
292
        $binds = array(
293 6
            ':shift' => $shift,
294 6
            ':leftFrom' => $leftIndexFrom,
295 6
            ':rightTo' => $rightIndexTo,
296
        );
297
298 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...
299 6
                  ->execute($binds);
300 6
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305 7
    public function moveBranch(int $leftIndexFrom, int $rightIndexTo, int $shift, $scope = null): void
306
    {
307 7
        if (0 == $shift) {
308
            return;
309
        }
310
311 7
        $options = $this->getOptions();
312
313 7
        $dbAdapter = $this->getDbAdapter();
314 7
        $dbPlatform = $dbAdapter->getPlatform();
315
316 7
        $sql = 'UPDATE '.$dbPlatform->quoteIdentifier($options->getTableName())
317 7
            .' SET '
318 7
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' = '
319 7
                    .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' + :shift, '
320 7
                .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' = '
321 7
                    .$dbPlatform->quoteIdentifier($options->getRightColumnName()).' + :shift'
322 7
            .' WHERE '
323 7
                .$dbPlatform->quoteIdentifier($options->getLeftColumnName()).' >= :leftFrom'
324 7
                .' AND '.$dbPlatform->quoteIdentifier($options->getRightColumnName()).' <= :rightTo';
325
326 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...
327 2
            $sql .= ' AND '.$dbPlatform->quoteIdentifier($options->getScopeColumnName()).' = '.$dbPlatform->quoteValue($scope);
328
        }
329
330
        $binds = array(
331 7
            ':shift' => $shift,
332 7
            ':leftFrom' => $leftIndexFrom,
333 7
            ':rightTo' => $rightIndexTo,
334
        );
335
336 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...
337 7
                  ->execute($binds);
338 7
    }
339
340
    /**
341
     * {@inheritdoc}
342
     */
343 12
    public function getRoots($scope = null): array
344
    {
345 12
        $options = $this->getOptions();
346
347 12
        $dbAdapter = $this->getDbAdapter();
348
349 12
        $select = $this->getBlankDbSelect();
350 12
        $select->where
351 12
            ->isNull($options->getParentIdColumnName(true));
352 12
        $select->order($options->getIdColumnName(true));
353
354 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...
355 3
            $select->where
356 3
                ->equalTo($options->getScopeColumnName(true), $scope);
357
        }
358
359 12
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
360 12
            DbAdapter::QUERY_MODE_EXECUTE);
361
362 12
        return $result->toArray();
363
    }
364
365
    /**
366
     * {@inheritdoc}
367
     */
368 9
    public function getRoot($scope = null): array
369
    {
370 9
        $roots = $this->getRoots($scope);
371
372 9
        return (0 < count($roots)) ? $roots[0] : array();
373
    }
374
375
    /**
376
     * {@inheritdoc}
377
     */
378 5
    public function getNode($nodeId): ?array
379
    {
380 5
        $options = $this->getOptions();
381
382 5
        $nodeId = (int) $nodeId;
383
384 5
        $dbAdapter = $this->getDbAdapter();
385
386 5
        $select = $this->getDefaultDbSelect()
387 5
                       ->where(array($options->getIdColumnName(true) => $nodeId));
388
389 5
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
390 5
                DbAdapter::QUERY_MODE_EXECUTE);
391
392 5
        $array = $result->toArray();
393
394 5
        return (0 < count($array)) ? $array[0] : null;
395
    }
396
397
    /**
398
     * {@inheritdoc}
399
     */
400 60
    public function getNodeInfo($nodeId): ?NodeInfo
401
    {
402 60
        $options = $this->getOptions();
403
404 60
        $nodeId = (int) $nodeId;
405
406 60
        $dbAdapter = $this->getDbAdapter();
407
408 60
        $select = $this->getBlankDbSelect()
409 60
            ->where(array($options->getIdColumnName(true) => $nodeId));
410
411 60
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
412 60
            DbAdapter::QUERY_MODE_EXECUTE);
413
414 60
        $array = $result->toArray();
415
416 60
        $result = ($array) ? $this->_buildNodeInfoObject($array[0]) : null;
417
418 60
        return $result;
419
    }
420
421
    /**
422
     * {@inheritdoc}
423
     */
424 7
    public function getChildrenNodeInfo($parentNodeId): array
425
    {
426 7
        $dbAdapter = $this->getDbAdapter();
427 7
        $options = $this->getOptions();
428
429
        $columns = array(
430 7
            $options->getIdColumnName(),
431 7
            $options->getLeftColumnName(),
432 7
            $options->getRightColumnName(),
433 7
            $options->getParentIdColumnName(),
434 7
            $options->getLevelColumnName(),
435
        );
436
437 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...
438 5
            $columns[] = $options->getScopeColumnName();
439
        }
440
441 7
        $select = $this->getBlankDbSelect();
442 7
        $select->columns($columns);
443 7
        $select->order($options->getLeftColumnName(true));
444 7
        $select->where(array(
445 7
            $options->getParentIdColumnName(true) => $parentNodeId,
446
        ));
447
448 7
        $data = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
449 7
            DbAdapter::QUERY_MODE_EXECUTE);
450
451 7
        $result = array();
452
453 7
        foreach ($data->toArray() as $nodeData) {
454 6
            $result[] = $this->_buildNodeInfoObject($nodeData);
455
        }
456
457 7
        return $result;
458
    }
459
460
    /**
461
     * {@inheritdoc}
462
     */
463 3
    public function updateNodeMetadata(NodeInfo $nodeInfo): void
464
    {
465 3
        $dbAdapter = $this->getDbAdapter();
466 3
        $options = $this->getOptions();
467
468 3
        $update = new Db\Sql\Update($options->getTableName());
469
470 3
        $update->set(array(
471 3
            $options->getRightColumnName() => $nodeInfo->getRight(),
472 3
            $options->getLeftColumnName() => $nodeInfo->getLeft(),
473 3
            $options->getLevelColumnName() => $nodeInfo->getLevel(),
474
        ));
475
476 3
        $update->where(array(
477 3
            $options->getIdColumnName() => $nodeInfo->getId(),
478
        ));
479
480 3
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
481 3
            DbAdapter::QUERY_MODE_EXECUTE);
482 3
    }
483
484
    /**
485
     * {@inheritdoc}
486
     */
487 10
    public function getAncestors($nodeId, int $startLevel = 0, int $excludeLastNLevels = 0): array
488
    {
489 10
        $options = $this->getOptions();
490
491 10
        $startLevel = (int) $startLevel;
492
493
        // node does not exist
494 10
        $nodeInfo = $this->getNodeInfo($nodeId);
495 10
        if (!$nodeInfo) {
496 2
            return array();
497
        }
498
499 8
        $dbAdapter = $this->getDbAdapter();
500
501 8
        $select = $this->getDefaultDbSelect();
502
503 8
        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...
504 3
            $select->where
505 3
                ->equalTo($options->getScopeColumnName(true), $nodeInfo->getScope());
506
        }
507
508 8
        $select->where
509 8
               ->lessThanOrEqualTo($options->getLeftColumnName(true), $nodeInfo->getLeft())
510 8
               ->AND
511 8
               ->greaterThanOrEqualTo($options->getRightColumnName(true), $nodeInfo->getRight());
512
513 8
        $select->order($options->getLeftColumnName(true).' ASC');
514
515 8
        if (0 < $startLevel) {
516 3
            $select->where
517 3
                   ->greaterThanOrEqualTo($options->getLevelColumnName(true), $startLevel);
518
        }
519
520 8
        if (0 < $excludeLastNLevels) {
521 4
            $select->where
522 4
                   ->lessThanOrEqualTo($options->getLevelColumnName(true), $nodeInfo->getLevel() - $excludeLastNLevels);
523
        }
524
525 8
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
526 8
            DbAdapter::QUERY_MODE_EXECUTE);
527
528 8
        return $result->toArray();
529
    }
530
531
    /**
532
     * {@inheritdoc}
533
     */
534 16
    public function getDescendants($nodeId, int $startLevel = 0, ?int $levels = null, $excludeBranch = null): array
535
    {
536 16
        $options = $this->getOptions();
537
538 16
        if (!$nodeInfo = $this->getNodeInfo($nodeId)) {
539 3
            return array();
540
        }
541
542 13
        $dbAdapter = $this->getDbAdapter();
543 13
        $select = $this->getDefaultDbSelect();
544 13
        $select->order($options->getLeftColumnName(true).' ASC');
545
546 13
        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...
547 4
            $select->where
548 4
                   ->equalTo($options->getScopeColumnName(true), $nodeInfo->getScope());
549
        }
550
551 13
        if (0 != $startLevel) {
552 7
            $level = $nodeInfo->getLevel() + (int) $startLevel;
553 7
            $select->where
554 7
                   ->greaterThanOrEqualTo($options->getLevelColumnName(true), $level);
555
        }
556
557 13
        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...
558 5
            $endLevel = $nodeInfo->getLevel() + (int) $startLevel + abs($levels);
559 5
            $select->where
560 5
                   ->lessThan($options->getLevelColumnName(true), $endLevel);
561
        }
562
563 13
        if (null != $excludeBranch && null != ($excludeNodeInfo = $this->getNodeInfo($excludeBranch))) {
564 3
            $select->where
565 3
                   ->NEST
566 3
                   ->between($options->getLeftColumnName(true),
567 3
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
568 3
                   ->OR
569 3
                   ->between($options->getLeftColumnName(true),
570 3
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
571 3
                   ->UNNEST
572 3
                   ->AND
573 3
                   ->NEST
574 3
                   ->between($options->getRightColumnName(true),
575 3
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
576 3
                   ->OR
577 3
                   ->between($options->getRightColumnName(true),
578 3
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
579 3
                   ->UNNEST;
580
        } else {
581 11
            $select->where
582 11
                   ->greaterThanOrEqualTo($options->getLeftColumnName(true), $nodeInfo->getLeft())
583 11
                   ->AND
584 11
                   ->lessThanOrEqualTo($options->getRightColumnName(true), $nodeInfo->getRight());
585
        }
586
587 13
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
588 13
            DbAdapter::QUERY_MODE_EXECUTE);
589
590 13
        $resultArray = $result->toArray();
591
592 13
        return (0 < count($resultArray)) ? $resultArray : array();
593
    }
594
}
595