Completed
Push — develop ( c7250c...c08e7b )
by Bartko
07:18 queued 03:02
created

Zend1   C

Complexity

Total Complexity 60

Size/Duplication

Total Lines 531
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.1%

Importance

Changes 0
Metric Value
wmc 60
lcom 1
cbo 4
dl 0
loc 531
ccs 309
cts 315
cp 0.981
rs 6.0975
c 0
b 0
f 0

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getOptions() 0 4 1
A getDbAdapter() 0 4 1
A getBlankDbSelect() 0 4 1
A setDefaultDbSelect() 0 4 1
A cleanData() 0 15 1
A getDefaultDbSelect() 0 10 2
A lockTree() 0 13 1
A beginTransaction() 0 4 1
A commitTransaction() 0 4 1
A rollbackTransaction() 0 4 1
A update() 0 13 1
A delete() 0 12 1
B moveLeftIndexes() 0 24 3
B moveRightIndexes() 0 26 3
A updateParentId() 0 15 1
B updateLevels() 0 29 3
B moveBranch() 0 30 3
A getRoots() 0 16 3
A getRoot() 0 6 2
A getNode() 0 14 2
A _buildNodeInfoObject() 0 18 2
A getNodeInfo() 0 19 3
B getChildrenNodeInfo() 0 33 3
A updateNodeMetadata() 0 17 1
B getPath() 0 41 5
B getDescendants() 0 55 8
A getWhereBetween() 0 8 1
A insert() 0 23 3

How to fix   Complexity   

Complex Class

Complex classes like Zend1 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Zend1, and based on these observations, apply Extract Interface, too.

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