Completed
Push — master ( 2e5d0e...583994 )
by Bartko
06:02
created

Zend1DbAdapter::getDescendants()   B

Complexity

Conditions 8
Paths 33

Size

Total Lines 55
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 8

Importance

Changes 6
Bugs 2 Features 1
Metric Value
c 6
b 2
f 1
dl 0
loc 55
ccs 34
cts 34
cp 1
rs 7.4033
cc 8
eloc 35
nc 33
nop 4
crap 8

How to fix   Long Method   

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 StefanoTree\NestedSet\Adapter;
3
4
use StefanoTree\NestedSet\NodeInfo;
5
use StefanoTree\NestedSet\Options;
6
use Zend_Db_Adapter_Abstract as ZendDbAdapter;
7
8
class Zend1DbAdapter
9
    extends NestedTransactionDbAdapterAbstract
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "NestedTransactionDbAdapterAbstract" and comma; 1 found
Loading history...
10
    implements AdapterInterface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
11
{
12
    protected $options;
13
14
    protected $dbAdapter;
15
16
    protected $defaultDbSelect;
17
18 38
    public function __construct(Options $options, ZendDbAdapter $dbAdapter)
19
    {
20 38
        $this->options = $options;
21 38
        $this->dbAdapter = $dbAdapter;
22 38
    }
23
24
    /**
25
     * @return Options
26
     */
27 37
    private function getOptions()
28
    {
29 37
        return $this->options;
30
    }
31
32
    /**
33
     * @return ZendDbAdapter
34
     */
35 34
    public function getDbAdapter()
36
    {
37 34
        return $this->dbAdapter;
38
    }
39
40 14
    public function lockTree($scope)
41
    {
42 14
        $options = $this->getOptions();
43
44 14
        $dbAdapter = $this->getDbAdapter();
45
46 14
        $select = $this->getDefaultDbSelect()
47 14
                       ->reset(\Zend_Db_Select::COLUMNS)
48 14
                       ->columns(array('i' => $options->getIdColumnName()))
49 14
                       ->forUpdate(true);
50
51 14
        if ($options->getScopeColumnName()) {
52 4
            $select->where($options->getScopeColumnName() . ' = ?', $scope);
53
        }
54
55 14
        $dbAdapter->fetchAll($select);
56 14
    }
57
58 15
    protected function _isInTransaction()
59
    {
60 15
        return $this->getDbAdapter()
61 15
                    ->getConnection()
62 15
                    ->inTransaction();
63
    }
64
65 15
    protected function _beginTransaction()
66
    {
67 15
        $this->getDbAdapter()->beginTransaction();
68 15
    }
69
70 14
    protected function _commitTransaction()
71
    {
72 14
        $this->getDbAdapter()->commit();
73 14
    }
74
75 1
    protected function _rollbackTransaction()
76
    {
77 1
        $this->getDbAdapter()->rollBack();
78 1
    }
79
80 2
    public function update($nodeId, array $data, NodeInfo $nodeInfo = null)
81
    {
82 2
        $options = $this->getOptions();
83
84 2
        $dbAdapter = $this->getDbAdapter();
85
86 2
        $data = $this->cleanData($data);
87
88
        $where = array(
89 2
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' = ?' => $nodeId,
90
        );
91 2
        $dbAdapter->update($options->getTableName(), $data, $where);
92 2
    }
93
94 12
    public function moveLeftIndexes($fromIndex, $shift, $scope = null)
95
    {
96 12
        $options = $this->getOptions();
97
98 12
        if (0 == $shift) {
99
            return;
100
        }
101
102 12
        $dbAdapter = $this->getDbAdapter();
103 12
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
104 12
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
105 12
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' + :shift'
106 12
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' > :fromIndex';
107
108 12
        if ($options->getScopeColumnName()) {
109 3
            $sql .= ' AND '. $dbAdapter->quoteIdentifier($options->getScopeColumnName()) . ' = ' . $dbAdapter->quote($scope);
110
        }
111
112
        $binds = array(
113 12
            ':shift' => $shift,
114 12
            ':fromIndex' => $fromIndex,
115
        );
116 12
        $dbAdapter->prepare($sql)->execute($binds);
117 12
    }
118
119 12
    public function moveRightIndexes($fromIndex, $shift, $scope = null)
120
    {
121 12
        $options = $this->getOptions();
122
123 12
        if (0 == $shift) {
124
            return;
125
        }
126
127 12
        $dbAdapter = $this->getDbAdapter();
128
129 12
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
130 12
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getRightColumnName())
131 12
                . ' = ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
132 12
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' > :fromIndex';
133
134 12
        if ($options->getScopeColumnName()) {
135 3
            $sql .= ' AND '. $dbAdapter->quoteIdentifier($options->getScopeColumnName()) . ' = ' . $dbAdapter->quote($scope);
136
        }
137
138
        $binds = array(
139 12
            ':shift' => $shift,
140 12
            ':fromIndex' => $fromIndex,
141
        );
142
143 12
        $dbAdapter->prepare($sql)->execute($binds);
144 12
    }
145
146 4
    public function updateParentId($nodeId, $newParentId)
147
    {
148 4
        $options = $this->getOptions();
149
150 4
        $dbAdapter = $this->getDbAdapter();
151
152
        $bind = array(
153 4
            $options->getParentIdColumnName() => $newParentId,
154
        );
155
156
        $where = array(
157 4
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' = ?' => $nodeId,
158
        );
159 4
        $dbAdapter->update($options->getTableName(), $bind, $where);
160 4
    }
161
162 8
    public function getRoots($scope = null)
163
    {
164 8
        $options = $this->getOptions();
165
166 8
        $dbAdapter = $this->getDbAdapter();
167
168 8
        $select = $this->getDefaultDbSelect()
169 8
            ->where($options->getParentIdColumnName() . ' = ?', 0);
170
171 8
        if (null != $scope && $options->getScopeColumnName()) {
172 2
            $select->where($options->getScopeColumnName() . ' = ?', $scope);
173
        }
174
175 8
        return $dbAdapter->fetchAll($select);
176
    }
177
178 7
    public function getRoot($scope = null)
179
    {
180 7
        $result = $this->getRoots($scope);
181
182 7
        return ($result) ? $result[0] : array();
183
    }
184
185 25
    public function getNode($nodeId)
186
    {
187 25
        $options = $this->getOptions();
188
189 25
        $nodeId = (int) $nodeId;
190
191 25
        $dbAdapter = $this->getDbAdapter();
192
193 25
        $select = $this->getDefaultDbSelect()
194 25
                       ->where($options->getIdColumnName() . ' = ?', $nodeId);
195
196 25
        $row = $dbAdapter->fetchRow($select);
197 25
        return $row ? $row : null;
198
    }
199
200
    /**
201
     * @param array $data
202
     * @return NodeInfo
203
     */
204 22
    private function _buildNodeInfoObject(array $data)
205
    {
206 22
        $options = $this->getOptions();
207
208 22
        $id        = $data[$options->getIdColumnName()];
209 22
        $parentId  = $data[$options->getParentIdColumnName()];
210 22
        $level     = $data[$options->getLevelColumnName()];
211 22
        $left      = $data[$options->getLeftColumnName()];
212 22
        $right     = $data[$options->getRightColumnName()];
213
214 22
        if (isset($data[$options->getScopeColumnName()])) {
215 9
            $scope = $data[$options->getScopeColumnName()];
216
        } else {
217 13
            $scope = null;
218
        }
219
220 22
        return new NodeInfo($id, $parentId, $level, $left, $right, $scope);
221
    }
222
223 23
    public function getNodeInfo($nodeId)
224
    {
225 23
        $data = $this->getNode($nodeId);
226
227 23
        $result = ($data) ? $this->_buildNodeInfoObject($data) : null;
228
229 23
        return $result;
230
    }
231
232 3
    public function getChildrenNodeInfo($parentNodeId)
233
    {
234 3
        $dbAdapter = $this->getDbAdapter();
235 3
        $options = $this->getOptions();
236
237
        $columns = array(
238 3
            $options->getIdColumnName(),
239 3
            $options->getLeftColumnName(),
240 3
            $options->getRightColumnName(),
241 3
            $options->getParentIdColumnName(),
242 3
            $options->getLevelColumnName(),
243
        );
244
245 3
        if ($options->getScopeColumnName()) {
246 3
            $columns[] = $options->getScopeColumnName();
247
        }
248
249 3
        $select = $this->getDefaultDbSelect();
250 3
        $select->reset(\Zend_Db_Select::COLUMNS);
251 3
        $select->columns($columns);
252 3
        $select->order($options->getLeftColumnName());
253 3
        $select->where($options->getParentIdColumnName() . ' = ?', $parentNodeId);
254
255 3
        $data = $dbAdapter->fetchAll($select);
256
257 3
        $result = array();
258
259 3
        foreach ($data as $nodeData) {
260 3
            $result[] = $this->_buildNodeInfoObject($nodeData);
261
        }
262
263 3
        return $result;
264
    }
265
266 1
    public function updateNodeMetadata(NodeInfo $nodeInfo)
267
    {
268 1
        $dbAdapter = $this->getDbAdapter();
269 1
        $options = $this->getOptions();
270
271
        $bind = array(
272 1
            $options->getRightColumnName() => $nodeInfo->getRight(),
273 1
            $options->getLeftColumnName() => $nodeInfo->getLeft(),
274 1
            $options->getLevelColumnName() => $nodeInfo->getLevel(),
275
        );
276
277
        $where = array(
278 1
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' = ?' => $nodeInfo->getId(),
279
        );
280
281 1
        $dbAdapter->update($options->getTableName(), $bind, $where);
282 1
    }
283
284
    /**
285
     * Return clone of default select
286
     *
287
     * @return \Zend_Db_Select
288
     */
289 36
    public function getDefaultDbSelect()
290
    {
291 36
        $options = $this->getOptions();
292
293 36
        if (null == $this->defaultDbSelect) {
294 35
            $this->defaultDbSelect = $this->dbAdapter->select()
295 35
                                          ->from($options->getTableName());
296
        }
297
298 36
        $dbSelect = clone $this->defaultDbSelect;
299
300 36
        return $dbSelect;
301
    }
302
303
    /**
304
     * @param \Zend_Db_Select $dbSelect
305
     * @return void
306
     */
307 1
    public function setDefaultDbSelect(\Zend_Db_Select $dbSelect)
308
    {
309 1
        $this->defaultDbSelect = $dbSelect;
310 1
    }
311
312 2
    private function cleanData(array $data)
313
    {
314 2
        $options = $this->getOptions();
315
316
        $disallowedDataKeys = array(
317 2
            $options->getIdColumnName(),
318 2
            $options->getLeftColumnName(),
319 2
            $options->getRightColumnName(),
320 2
            $options->getLevelColumnName(),
321 2
            $options->getParentIdColumnName(),
322 2
            $options->getScopeColumnName(),
323
        );
324
325 2
        return array_diff_key($data, array_flip($disallowedDataKeys));
326
    }
327
328 9
    public function insert(NodeInfo $nodeInfo, array $data)
329
    {
330 9
        $options = $this->getOptions();
331 9
        $dbAdapter = $this->getDbAdapter();
332
333 9
        $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
334 9
        $data[$options->getLevelColumnName()] = $nodeInfo->getLevel();
335 9
        $data[$options->getLeftColumnName()] = $nodeInfo->getLeft();
336 9
        $data[$options->getRightColumnName()] = $nodeInfo->getRight();
337
338 9
        if ($options->getScopeColumnName()) {
339 3
            $data[$options->getScopeColumnName()] = $nodeInfo->getScope();
340
        }
341
342 9
        $dbAdapter->insert($options->getTableName(), $data);
343 9
        if ('' != $options->getSequenceName()) {
344
            $lastGeneratedValue = $dbAdapter->lastSequenceId($options->getSequenceName());
345
        } else {
346 9
            $lastGeneratedValue = $dbAdapter->lastInsertId();
347
        }
348
349 9
        return $lastGeneratedValue;
350
    }
351
352 2
    public function delete($leftIndex, $rightIndex, $scope = null)
353
    {
354 2
        $options = $this->getOptions();
355
356 2
        $dbAdapter = $this->getDbAdapter();
357
358
        $where = array(
359 2
            $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= ?' => $leftIndex,
360 2
            $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= ?' => $rightIndex,
361
        );
362
363 2
        if ($options->getScopeColumnName()) {
364 1
            $where[$dbAdapter->quoteIdentifier($options->getScopeColumnName()) . ' = ?'] = $scope;
365
        }
366
367 2
        $dbAdapter->delete($options->getTableName(), $where);
368 2
    }
369
370 5
    public function updateLevels($leftIndexFrom, $rightIndexTo, $shift, $scope = null)
371
    {
372 5
        $options = $this->getOptions();
373
374 5
        if (0 == $shift) {
375 1
            return null;
376
        }
377
378 4
        $dbAdapter = $this->getDbAdapter();
379
380 4
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
381 4
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLevelColumnName())
382 4
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' + :shift'
383 4
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
384 4
                . ' >= :leftFrom' . ' AND ' . $dbAdapter->quoteIdentifier($options->getRightColumnName())
385 4
                . ' <= :rightTo';
386
387 4
        if ($options->getScopeColumnName()) {
388
            $sql .= ' AND '. $dbAdapter->quoteIdentifier($options->getScopeColumnName()) . ' = ' . $dbAdapter->quote($scope);
389
        }
390
391
        $binds = array(
392 4
            ':shift' => $shift,
393 4
            ':leftFrom' => $leftIndexFrom,
394 4
            ':rightTo' => $rightIndexTo,
395
        );
396
397 4
        $dbAdapter->prepare($sql)->execute($binds);
398 4
    }
399
400 5
    public function moveBranch($leftIndexFrom, $rightIndexTo, $shift, $scope = null)
401
    {
402 5
        if (0 == $shift) {
403
            return null;
404
        }
405
406 5
        $options = $this->getOptions();
407
408 5
        $dbAdapter = $this->getDbAdapter();
409
410 5
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
411 5
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
412 5
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' + :shift, '
413 5
            . $dbAdapter->quoteIdentifier($options->getRightColumnName())
414 5
                . ' = ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
415 5
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= :leftFrom'
416 5
                . ' AND ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= :rightTo';
417
418 5
        if ($options->getScopeColumnName()) {
419 1
            $sql .= ' AND '. $dbAdapter->quoteIdentifier($options->getScopeColumnName()) . ' = ' . $dbAdapter->quote($scope);
420
        }
421
422
        $binds = array(
423 5
            ':shift' => $shift,
424 5
            ':leftFrom' => $leftIndexFrom,
425 5
            ':rightTo' => $rightIndexTo,
426
        );
427
428 5
        $dbAdapter->prepare($sql)->execute($binds);
429 5
    }
430
431 2
    public function getPath($nodeId, $startLevel = 0, $excludeLastNode = false)
432
    {
433 2
        $options = $this->getOptions();
434
435 2
        $startLevel = (int) $startLevel;
436
437
        // node does not exist
438 2
        if (!$nodeInfo = $this->getNodeInfo($nodeId)) {
439 1
            return null;
440
        }
441
442 2
        $dbAdapter = $this->getDbAdapter();
443
444 2
        $select = $this->getDefaultDbSelect();
445 2
        $select->where(
446 2
            $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' <= ?', $nodeInfo->getLeft()
447
        );
448 2
        $select->where(
449 2
            $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' >= ?', $nodeInfo->getRight()
450
        );
451 2
        $select->order($options->getLeftColumnName() . ' ASC');
452
453 2
        if (0 < $startLevel) {
454 1
            $select->where(
455 1
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' >= ?', $startLevel
456
            );
457
        }
458
459 2
        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...
460 1
            $select->where(
461 1
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' < ?', $nodeInfo->getLevel()
462
            );
463
        }
464
465 2
        $result = $dbAdapter->fetchAll($select);
466
467 2
        return $result;
468
    }
469
470 3
    public function getDescendants($nodeId = 1, $startLevel = 0, $levels = null, $excludeBranch = null)
471
    {
472 3
        $options = $this->getOptions();
473
474 3
        if (!$nodeInfo = $this->getNodeInfo($nodeId)) {
475 2
            return null;
476
        }
477
478 3
        $dbAdapter = $this->getDbAdapter();
479 3
        $select = $this->getDefaultDbSelect();
480 3
        $select->order($options->getLeftColumnName() . ' ASC');
481
482 3
        if ($options->getScopeColumnName()) {
483 1
            $select->where($options->getScopeColumnName() . ' = ?', $nodeInfo->getScope());
484
        }
485
486 3
        if (0 != $startLevel) {
487 2
            $level = $nodeInfo->getLevel() + (int) $startLevel;
488 2
            $select->where(
489 2
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' >= ?', $level
490
            );
491
        }
492
493 3
        if (null != $levels) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $levels of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
494 2
            $endLevel = $nodeInfo->getLevel() + (int) $startLevel + abs($levels);
495 2
            $select->where(
496 2
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' < ?', $endLevel
497
            );
498
        }
499
500 3
        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 integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
501 1
            $where = sprintf(
502 1
                "(%s OR %s) AND (%s OR %s)",
503 1
                $this->getWhereBetween($options->getLeftColumnName(), $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1),
504 1
                $this->getWhereBetween($options->getLeftColumnName(),
505 1
                    $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight()),
506 1
                $this->getWhereBetween($options->getRightColumnName(),
507 1
                    $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight()),
508 1
                $this->getWhereBetween($options->getRightColumnName(),
509 1
                    $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
510
            );
511 1
            $select->where($where);
512
        } else {
513 3
            $select->where(
514 3
                $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= ?', $nodeInfo->getLeft()
515
            );
516 3
            $select->where(
517 3
                $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= ?', $nodeInfo->getRight()
518
            );
519
        }
520
521 3
        $resultArray = $dbAdapter->fetchAll($select);
522
523 3
        return (0 < count($resultArray)) ? $resultArray : null;
524
    }
525
526 1
    protected function getWhereBetween($column, $first, $second)
527
    {
528 1
        $dbAdapter = $this->getDbAdapter();
529 1
        $quotedColumn = $dbAdapter->quoteIdentifier($column);
530 1
        $quotedFirst = $dbAdapter->quote($first);
531 1
        $quotedSecond = $dbAdapter->quote($second);
532 1
        return sprintf('(%s BETWEEN %s AND %s)', $quotedColumn, $quotedFirst, $quotedSecond);
533
    }
534
}
535