Completed
Push — develop ( 0f123e...6d6ae7 )
by Bartko
05:00
created

Zend1DbAdapter::getPath()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 4

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 37
ccs 26
cts 26
cp 1
rs 8.5806
cc 4
eloc 20
nc 5
nop 3
crap 4
1
<?php
2
namespace StefanoTree\NestedSet\Adapter;
3
4
use StefanoTree\NestedSet\NodeInfo;
5
use StefanoTree\NestedSet\Options;
6
use StefanoLockTable\Factory as LockSqlBuilderFactory;
7
use StefanoLockTable\Adapter\AdapterInterface as LockSqlBuilderInterface;
8
use Zend_Db_Adapter_Abstract as ZendDbAdapter;
9
10
class Zend1DbAdapter
11
    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...
12
    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...
13
{
14
    protected $options;
15
16
    protected $dbAdapter;
17
18
    protected $defaultDbSelect;
19
20
    protected $lockSqlBuilder;
21
22 21
    public function __construct(Options $options, ZendDbAdapter $dbAdapter) {
23 21
        $this->options = $options;
24 21
        $this->dbAdapter = $dbAdapter;
25 21
    }
26
27
    /**
28
     * @return Options
29
     */
30 20
    private function getOptions() {
31 20
        return $this->options;
32
    }
33
34
    /**
35
     * @return ZendDbAdapter
36
     */
37 17
    public function getDbAdapter() {
38 17
        return $this->dbAdapter;
39
    }
40
41
    /**
42
     * @return LockSqlBuilderInterface
43
     */
44 12
    private function getLockSqlBuilder() {
45 12
        if (null == $this->lockSqlBuilder) {
46 12
            $adapterClassName = get_class($this->getDbAdapter());
47 12
            $parts = explode('_', $adapterClassName);
48 12
            $vendorName = end($parts);
49
50 12
            $factory = new LockSqlBuilderFactory();
51 12
            $this->lockSqlBuilder = $factory->createAdapter($vendorName);
52 12
        }
53
54 12
        return $this->lockSqlBuilder;
55
    }
56
57 12
    public function lockTable() {
58 12
        $options = $this->getOptions();
59 12
        $sql = $this->getLockSqlBuilder()->getLockSqlString($options->getTableName());
60
61 12
        if (null != $sql) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $sql of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
62 12
            $this->getDbAdapter()->query($sql);
63 12
        }
64 12
    }
65
66 12
    public function unlockTable() {
67 12
        $sql = $this->getLockSqlBuilder()->getUnlockSqlString();
68
69 12
        if (null != $sql) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $sql of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
70
            $this->getDbAdapter()->query($sql);
71
        }
72 12
    }
73
74 12
    protected function _isInTransaction() {
75 12
        return $this->getDbAdapter()
76 12
                    ->getConnection()
77 12
                    ->inTransaction();
78
    }
79
80 12
    protected function _beginTransaction() {
81 12
        $this->getDbAdapter()->beginTransaction();
82 12
    }
83
84 12
    protected function _commitTransaction() {
85 12
        $this->getDbAdapter()->commit();
86 12
    }
87
88
    protected function _rollbackTransaction() {
89
        $this->getDbAdapter()->rollBack();
90
    }
91
92 2
    public function update($nodeId, array $data, NodeInfo $nodeInfo = null) {
93 2
        $options = $this->getOptions();
94
95 2
        $dbAdapter = $this->getDbAdapter();
96
97 2
        if (null == $nodeInfo) {
98 1
            $data = $this->cleanData($data);
99 1
        } else {
100 1
            $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
101 1
            $data[$options->getLevelColumnName()] = $nodeInfo->getLevel();
102 1
            $data[$options->getLeftColumnName()] = $nodeInfo->getLeft();
103 1
            $data[$options->getRightColumnName()] = $nodeInfo->getRight();
104
        }
105
106
        $where = array(
107 2
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' = ?' => $nodeId,
108 2
        );
109 2
        $dbAdapter->update($options->getTableName(), $data, $where);
110 2
    }
111
112 1
    public function deleteAll($expectNodeId) {
113 1
        $options = $this->getOptions();
114 1
        $dbAdapter = $this->getDbAdapter();
115
116
        $where = array(
117 1
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' != ?' => $expectNodeId,
118 1
        );
119 1
        $dbAdapter->delete($options->getTableName(), $where);
120 1
    }
121
122 9
    public function moveLeftIndexes($fromIndex, $shift) {
123 9
        $options = $this->getOptions();
124
125 9
        if (0 == $shift) {
126
            return null;
127
        }
128
129 9
        $dbAdapter = $this->getDbAdapter();
130 9
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
131 9
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
132 9
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' + :shift'
133 9
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' > :fromIndex';
134
135
        $binds = array(
136 9
            ':shift' => $shift,
137 9
            ':fromIndex' => $fromIndex,
138 9
        );
139 9
        $dbAdapter->prepare($sql)->execute($binds);
140 9
    }
141
142 9
    public function moveRightIndexes($fromIndex, $shift) {
143 9
        $options = $this->getOptions();
144
145 9
        if (0 == $shift) {
146
            return null;
147
        }
148
149 9
        $dbAdapter = $this->getDbAdapter();
150
151 9
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
152 9
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getRightColumnName())
153 9
                . ' = ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
154 9
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' > :fromIndex';
155
156
        $binds = array(
157 9
            ':shift' => $shift,
158 9
            ':fromIndex' => $fromIndex,
159 9
        );
160
161 9
        $dbAdapter->prepare($sql)->execute($binds);
162 9
    }
163
164 4
    public function updateParentId($nodeId, $newParentId) {
165 4
        $options = $this->getOptions();
166
167 4
        $dbAdapter = $this->getDbAdapter();
168
169
        $bind = array(
170 4
            $options->getParentIdColumnName() => $newParentId,
171 4
        );
172
173
        $where = array(
174 4
            $dbAdapter->quoteIdentifier($options->getIdColumnName()) . ' = ?' => $nodeId,
175 4
        );
176 4
        $dbAdapter->update($options->getTableName(), $bind, $where);
177 4
    }
178
179 15
    public function getNode($nodeId) {
180 15
        $options = $this->getOptions();
181
182 15
        $nodeId = (int) $nodeId;
183
184 15
        $dbAdapter = $this->getDbAdapter();
185
186 15
        $select = $this->getDefaultDbSelect()
187 15
                       ->where($options->getIdColumnName() . ' = ?', $nodeId);
188
189 15
        $row = $dbAdapter->fetchRow($select);
190 15
        return $row ? $row : null;
191
    }
192
193 14
    public function getNodeInfo($nodeId) {
194 14
        $options = $this->getOptions();
195 14
        $result = $this->getNode($nodeId);
196
197 14
        if (null == $result) {
198 6
            $result = null;
199 6
        } else {
200 13
            $id = $result[$options->getIdColumnName()];
201 13
            $parentId = $result[$options->getParentIdColumnName()];
202 13
            $level = $result[$options->getLevelColumnName()];
203 13
            $left = $result[$options->getLeftColumnName()];
204 13
            $right = $result[$options->getRightColumnName()];
205
206 13
            $result = new NodeInfo($id, $parentId, $level, $left, $right);
207
        }
208
209 14
        return $result;
210
    }
211
212
    /**
213
     * Return clone of default select
214
     *
215
     * @return \Zend_Db_Select
216
     */
217 18
    public function getDefaultDbSelect() {
218 18
        $options = $this->getOptions();
219
220 18
        if (null == $this->defaultDbSelect) {
221 17
            $this->defaultDbSelect = $this->dbAdapter->select()
222 17
                                          ->from($options->getTableName());
223 17
        }
224
225 18
        $dbSelect = clone $this->defaultDbSelect;
226
227 18
        return $dbSelect;
228
    }
229
230
    /**
231
     * @param \Zend_Db_Select $dbSelect
232
     * @return void
233
     */
234 1
    public function setDefaultDbSelect(\Zend_Db_Select $dbSelect) {
235 1
        $this->defaultDbSelect = $dbSelect;
236 1
    }
237
238 1
    private function cleanData(array $data) {
239 1
        $options = $this->getOptions();
240
241
        $disallowedDataKeys = array(
242 1
            $options->getIdColumnName(),
243 1
            $options->getLeftColumnName(),
244 1
            $options->getRightColumnName(),
245 1
            $options->getLevelColumnName(),
246 1
            $options->getParentIdColumnName(),
247 1
        );
248
249 1
        return array_diff_key($data, array_flip($disallowedDataKeys));
250
    }
251
252 4
    public function insert(NodeInfo $nodeInfo, array $data) {
253 4
        $options = $this->getOptions();
254 4
        $dbAdapter = $this->getDbAdapter();
255
256 4
        $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
257 4
        $data[$options->getLevelColumnName()] = $nodeInfo->getLevel();
258 4
        $data[$options->getLeftColumnName()] = $nodeInfo->getLeft();
259 4
        $data[$options->getRightColumnName()] = $nodeInfo->getRight();
260
261 4
        $dbAdapter->insert($options->getTableName(), $data);
262 4
        if('' != $options->getSequenceName()) {
263 4
            $lastGeneratedValue = $dbAdapter->lastSequenceId($options->getSequenceName());
264 4
        } else {
265
            $lastGeneratedValue = $dbAdapter->lastInsertId();
266
        }
267
268 4
        return $lastGeneratedValue;
269
    }
270
271 1
    public function delete($leftIndex, $rightIndex) {
272 1
        $options = $this->getOptions();
273
274 1
        $dbAdapter = $this->getDbAdapter();
275
276
        $where = array(
277 1
            $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= ?' => $leftIndex,
278 1
            $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= ?' => $rightIndex,
279 1
        );
280
281 1
        $dbAdapter->delete($options->getTableName(), $where);
282 1
    }
283
284 4
    public function updateLevels($leftIndexFrom, $rightIndexTo, $shift) {
285 4
        $options = $this->getOptions();
286
287 4
        if (0 == $shift) {
288
            return null;
289
        }
290
291 4
        $dbAdapter = $this->getDbAdapter();
292
293 4
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
294 4
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLevelColumnName())
295 4
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' + :shift'
296 4
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
297 4
                . ' >= :leftFrom' . ' AND ' . $dbAdapter->quoteIdentifier($options->getRightColumnName())
298 4
                . ' <= :rightTo';
299
300
        $binds = array(
301 4
            ':shift' => $shift,
302 4
            ':leftFrom' => $leftIndexFrom,
303 4
            ':rightTo' => $rightIndexTo,
304 4
        );
305
306 4
        $dbAdapter->prepare($sql)->execute($binds);
307 4
    }
308
309 4
    public function moveBranch($leftIndexFrom, $rightIndexTo, $shift) {
310 4
        if (0 == $shift) {
311
            return;
312
        }
313
314 4
        $options = $this->getOptions();
315
316 4
        $dbAdapter = $this->getDbAdapter();
317
318 4
        $sql = 'UPDATE ' . $dbAdapter->quoteIdentifier($options->getTableName())
319 4
            . ' SET ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName())
320 4
                . ' = ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' + :shift, '
321 4
            . $dbAdapter->quoteIdentifier($options->getRightColumnName())
322 4
                . ' = ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
323 4
            . ' WHERE ' . $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= :leftFrom'
324 4
                . ' AND ' . $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= :rightTo';
325
326
        $binds = array(
327 4
            ':shift' => $shift,
328 4
            ':leftFrom' => $leftIndexFrom,
329 4
            ':rightTo' => $rightIndexTo,
330 4
        );
331
332 4
        $dbAdapter->prepare($sql)->execute($binds);
333 4
    }
334
335 1
    public function getPath($nodeId, $startLevel = 0, $excludeLastNode = false) {
336 1
        $options = $this->getOptions();
337
338 1
        $startLevel = (int) $startLevel;
339
340
        // node does not exist
341 1
        if (!$nodeInfo = $this->getNodeInfo($nodeId)) {
342 1
            return null;
343
        }
344
345 1
        $dbAdapter = $this->getDbAdapter();
346
347 1
        $select = $this->getDefaultDbSelect();
348 1
        $select->where(
349 1
            $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' <= ?', $nodeInfo->getLeft()
350 1
        );
351 1
        $select->where(
352 1
            $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' >= ?', $nodeInfo->getRight()
353 1
        );
354 1
        $select->order($options->getLeftColumnName() . ' ASC');
355
356 1
        if (0 < $startLevel) {
357 1
            $select->where(
358 1
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' >= ?', $startLevel
359 1
            );
360 1
        }
361
362 1
        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...
363 1
            $select->where(
364 1
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' < ?', $nodeInfo->getLevel()
365 1
            );
366 1
        }
367
368 1
        $result = $dbAdapter->fetchAll($select);
369
370 1
        return $result;
371
    }
372
373 2
    public function getDescendants($nodeId = 1, $startLevel = 0, $levels = null, $excludeBranch = null) {
374 2
        $options = $this->getOptions();
375
376 2
        if(!$nodeInfo = $this->getNodeInfo($nodeId)) {
377 2
            return null;
378
        }
379
380 2
        $dbAdapter = $this->getDbAdapter();
381 2
        $select = $this->getDefaultDbSelect();
382 2
        $select->order($options->getLeftColumnName() . ' ASC');
383
384
385 2
        if(0 != $startLevel) {
386 2
            $level = $nodeInfo->getLevel() + (int) $startLevel;
387 2
            $select->where(
388 2
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' >= ?', $level
389 2
            );
390 2
        }
391
392 2
        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...
393 2
            $endLevel = $nodeInfo->getLevel() + (int) $startLevel + abs($levels);
394 2
            $select->where(
395 2
                $dbAdapter->quoteIdentifier($options->getLevelColumnName()) . ' < ?', $endLevel
396 2
            );
397 2
        }
398
399 2
        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...
400 1
            $where = sprintf(
401 1
                "(%s OR %s) AND (%s OR %s)",
402 1
                $this->getWhereBetween($options->getLeftColumnName(),$nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1),
403 1
                $this->getWhereBetween($options->getLeftColumnName(),
404 1
                    $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight()),
405 1
                $this->getWhereBetween($options->getRightColumnName(),
406 1
                    $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight()),
407 1
                $this->getWhereBetween($options->getRightColumnName(),
408 1
                    $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
409 1
            );
410 1
            $select->where($where);
411 1
        } else {
412 2
            $select->where(
413 2
                $dbAdapter->quoteIdentifier($options->getLeftColumnName()) . ' >= ?', $nodeInfo->getLeft()
414 2
            );
415 2
            $select->where(
416 2
                $dbAdapter->quoteIdentifier($options->getRightColumnName()) . ' <= ?', $nodeInfo->getRight()
417 2
            );
418
        }
419
420 2
        $resultArray = $dbAdapter->fetchAll($select);
421
422 2
        if(0 < count($resultArray)) {
423 2
            return $resultArray;
424
        }
425 1
    }
426
427 1
    protected function getWhereBetween($column, $first, $second) {
428 1
        $dbAdapter = $this->getDbAdapter();
429 1
        $quotedColumn = $dbAdapter->quoteIdentifier($column);
430 1
        $quotedFirst = $dbAdapter->quote($first);
431 1
        $quotedSecond = $dbAdapter->quote($second);
432 1
        return sprintf('(%s BETWEEN %s AND %s)', $quotedColumn, $quotedFirst, $quotedSecond);
433
    }
434
}
435