Complex classes like Zend1DbAdapter 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 Zend1DbAdapter, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class Zend1DbAdapter |
||
9 | extends NestedTransactionDbAdapterAbstract |
||
10 | implements AdapterInterface |
||
11 | { |
||
12 | protected $options; |
||
13 | |||
14 | protected $dbAdapter; |
||
15 | |||
16 | protected $defaultDbSelect; |
||
17 | |||
18 | 38 | public function __construct(Options $options, ZendDbAdapter $dbAdapter) |
|
23 | |||
24 | /** |
||
25 | * @return Options |
||
26 | */ |
||
27 | 37 | private function getOptions() |
|
31 | |||
32 | /** |
||
33 | * @return ZendDbAdapter |
||
34 | */ |
||
35 | 34 | public function getDbAdapter() |
|
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() |
|
64 | |||
65 | 15 | protected function _beginTransaction() |
|
69 | |||
70 | 14 | protected function _commitTransaction() |
|
74 | |||
75 | 1 | protected function _rollbackTransaction() |
|
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) |
|
184 | |||
185 | 25 | public function getNode($nodeId) |
|
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) |
|
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) |
|
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) { |
|
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) { |
|
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))) { |
|
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) |
|
534 | } |
||
535 |