Complex classes like QueryBuilder 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 QueryBuilder, and based on these observations, apply Extract Interface, too.
| 1 | <?php namespace Arcanedev\LaravelNestedSet\Eloquent; |
||
| 19 | class QueryBuilder extends Builder |
||
| 20 | { |
||
| 21 | /* ----------------------------------------------------------------- |
||
| 22 | | Properties |
||
| 23 | | ----------------------------------------------------------------- |
||
| 24 | */ |
||
| 25 | /** |
||
| 26 | * The model being queried. |
||
| 27 | * |
||
| 28 | * @var \Arcanedev\LaravelNestedSet\Contracts\Nodeable |
||
| 29 | */ |
||
| 30 | protected $model; |
||
| 31 | |||
| 32 | /* ----------------------------------------------------------------- |
||
| 33 | | Main Methods |
||
| 34 | | ----------------------------------------------------------------- |
||
| 35 | */ |
||
| 36 | /** |
||
| 37 | * Get node's `lft` and `rgt` values. |
||
| 38 | * |
||
| 39 | * @param mixed $id |
||
| 40 | * @param bool $required |
||
| 41 | * |
||
| 42 | * @return array |
||
| 43 | */ |
||
| 44 | 60 | public function getNodeData($id, $required = false) |
|
| 61 | |||
| 62 | /** |
||
| 63 | * Get plain node data. |
||
| 64 | * |
||
| 65 | * @param mixed $id |
||
| 66 | * @param bool $required |
||
| 67 | * |
||
| 68 | * @return array |
||
| 69 | */ |
||
| 70 | 39 | public function getPlainNodeData($id, $required = false) |
|
| 74 | |||
| 75 | /** |
||
| 76 | * Scope limits query to select just root node. |
||
| 77 | * |
||
| 78 | * @return self |
||
| 79 | */ |
||
| 80 | 15 | public function whereIsRoot() |
|
| 86 | |||
| 87 | /** |
||
| 88 | * Limit results to ancestors of specified node. |
||
| 89 | * |
||
| 90 | * @param mixed $id |
||
| 91 | * |
||
| 92 | * @return self |
||
| 93 | */ |
||
| 94 | 15 | public function whereAncestorOf($id) |
|
| 127 | |||
| 128 | /** |
||
| 129 | * Get ancestors of specified node. |
||
| 130 | * |
||
| 131 | * @param mixed $id |
||
| 132 | * @param array $columns |
||
| 133 | * |
||
| 134 | * @return self|\Illuminate\Database\Eloquent\Collection |
||
| 135 | */ |
||
| 136 | 9 | public function ancestorsOf($id, array $columns = ['*']) |
|
| 140 | |||
| 141 | /** |
||
| 142 | * Add node selection statement between specified range. |
||
| 143 | * |
||
| 144 | * @param array $values |
||
| 145 | * @param string $boolean |
||
| 146 | * @param bool $not |
||
| 147 | * |
||
| 148 | * @return self |
||
| 149 | */ |
||
| 150 | 36 | public function whereNodeBetween($values, $boolean = 'and', $not = false) |
|
| 156 | |||
| 157 | /** |
||
| 158 | * Add node selection statement between specified range joined with `or` operator. |
||
| 159 | * |
||
| 160 | * @param array $values |
||
| 161 | * |
||
| 162 | * @return self |
||
| 163 | */ |
||
| 164 | public function orWhereNodeBetween($values) |
||
| 168 | |||
| 169 | /** |
||
| 170 | * @param mixed $id |
||
| 171 | * |
||
| 172 | * @return self |
||
| 173 | */ |
||
| 174 | public function whereNotDescendantOf($id) |
||
| 178 | |||
| 179 | /** |
||
| 180 | * @param mixed $id |
||
| 181 | * |
||
| 182 | * @return self |
||
| 183 | */ |
||
| 184 | 3 | public function orWhereDescendantOf($id) |
|
| 188 | |||
| 189 | /** |
||
| 190 | * @param mixed $id |
||
| 191 | * |
||
| 192 | * @return self |
||
| 193 | */ |
||
| 194 | public function orWhereNotDescendantOf($id) |
||
| 198 | |||
| 199 | /** |
||
| 200 | * Add constraint statement to descendants of specified node or self. |
||
| 201 | * |
||
| 202 | * @param mixed $id |
||
| 203 | * @param string $boolean |
||
| 204 | * @param bool $not |
||
| 205 | * |
||
| 206 | * @return self |
||
| 207 | */ |
||
| 208 | public function whereDescendantOrSelf($id, $boolean = 'and', $not = false) |
||
| 212 | |||
| 213 | /** |
||
| 214 | * Add constraint statement to descendants of specified node. |
||
| 215 | * |
||
| 216 | * @param mixed $id |
||
| 217 | * @param string $boolean |
||
| 218 | * @param bool $not |
||
| 219 | * @param bool $andSelf |
||
| 220 | * |
||
| 221 | * @return self |
||
| 222 | */ |
||
| 223 | 39 | public function whereDescendantOf($id, $boolean = 'and', $not = false, $andSelf = false) |
|
| 233 | |||
| 234 | /** |
||
| 235 | * Get descendants of specified node. |
||
| 236 | * |
||
| 237 | * @param mixed $id |
||
| 238 | * @param array $columns |
||
| 239 | * @param bool $andSelf |
||
| 240 | * |
||
| 241 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection|\Illuminate\Database\Eloquent\Collection |
||
| 242 | */ |
||
| 243 | 3 | public function descendantsOf($id, array $columns = ['*'], $andSelf = false) |
|
| 252 | |||
| 253 | /** |
||
| 254 | * Get descendants of self node. |
||
| 255 | * |
||
| 256 | * @param mixed $id |
||
| 257 | * @param array $columns |
||
| 258 | * |
||
| 259 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection |
||
| 260 | */ |
||
| 261 | 3 | public function descendantsAndSelf($id, array $columns = ['*']) |
|
| 265 | |||
| 266 | /** |
||
| 267 | * @param mixed $id |
||
| 268 | * @param string $operator |
||
| 269 | * @param string $boolean |
||
| 270 | * |
||
| 271 | * @return self |
||
| 272 | */ |
||
| 273 | protected function whereIsBeforeOrAfter($id, $operator, $boolean) |
||
| 299 | |||
| 300 | /** |
||
| 301 | * Constraint nodes to those that are after specified node. |
||
| 302 | * |
||
| 303 | * @param mixed $id |
||
| 304 | * @param string $boolean |
||
| 305 | * |
||
| 306 | * @return self |
||
| 307 | */ |
||
| 308 | public function whereIsAfter($id, $boolean = 'and') |
||
| 312 | |||
| 313 | /** |
||
| 314 | * Constraint nodes to those that are before specified node. |
||
| 315 | * |
||
| 316 | * @param mixed $id |
||
| 317 | * @param string $boolean |
||
| 318 | * |
||
| 319 | * @return self |
||
| 320 | */ |
||
| 321 | public function whereIsBefore($id, $boolean = 'and') |
||
| 325 | |||
| 326 | /** |
||
| 327 | * Include depth level into the result. |
||
| 328 | * |
||
| 329 | * @param string $as |
||
| 330 | * |
||
| 331 | * @return self |
||
| 332 | */ |
||
| 333 | 12 | public function withDepth($as = 'depth') |
|
| 354 | |||
| 355 | /** |
||
| 356 | * Get wrapped `lft` and `rgt` column names. |
||
| 357 | * |
||
| 358 | * @return array |
||
| 359 | */ |
||
| 360 | 36 | protected function wrappedColumns() |
|
| 369 | |||
| 370 | /** |
||
| 371 | * Get a wrapped table name. |
||
| 372 | * |
||
| 373 | * @return string |
||
| 374 | */ |
||
| 375 | 21 | protected function wrappedTable() |
|
| 379 | |||
| 380 | /** |
||
| 381 | * Wrap model's key name. |
||
| 382 | * |
||
| 383 | * @return string |
||
| 384 | */ |
||
| 385 | 9 | protected function wrappedKey() |
|
| 389 | |||
| 390 | /** |
||
| 391 | * Exclude root node from the result. |
||
| 392 | * |
||
| 393 | * @return self |
||
| 394 | */ |
||
| 395 | 6 | public function withoutRoot() |
|
| 401 | |||
| 402 | /** |
||
| 403 | * Order by node position. |
||
| 404 | * |
||
| 405 | * @param string $dir |
||
| 406 | * |
||
| 407 | * @return self |
||
| 408 | */ |
||
| 409 | 39 | public function defaultOrder($dir = 'asc') |
|
| 416 | |||
| 417 | /** |
||
| 418 | * Order by reversed node position. |
||
| 419 | * |
||
| 420 | * @return self |
||
| 421 | */ |
||
| 422 | 3 | public function reversed() |
|
| 426 | |||
| 427 | /** |
||
| 428 | * Move a node to the new position. |
||
| 429 | * |
||
| 430 | * @param mixed $key |
||
| 431 | * @param int $position |
||
| 432 | * |
||
| 433 | * @return int |
||
| 434 | */ |
||
| 435 | 30 | public function moveNode($key, $position) |
|
| 478 | |||
| 479 | /** |
||
| 480 | * Make or remove gap in the tree. Negative height will remove gap. |
||
| 481 | * |
||
| 482 | * @param int $cut |
||
| 483 | * @param int $height |
||
| 484 | * |
||
| 485 | * @return int |
||
| 486 | */ |
||
| 487 | 36 | public function makeGap($cut, $height) |
|
| 498 | |||
| 499 | /** |
||
| 500 | * Get patch for columns. |
||
| 501 | * |
||
| 502 | * @param array $params |
||
| 503 | * |
||
| 504 | * @return array |
||
| 505 | */ |
||
| 506 | 63 | protected function patch(array $params) |
|
| 517 | |||
| 518 | /** |
||
| 519 | * Get patch for single column. |
||
| 520 | * |
||
| 521 | * @param string $col |
||
| 522 | * @param array $params |
||
| 523 | * |
||
| 524 | * @return string |
||
| 525 | */ |
||
| 526 | 63 | protected function columnPatch($col, array $params) |
|
| 555 | |||
| 556 | /** |
||
| 557 | * Get statistics of errors of the tree. |
||
| 558 | * |
||
| 559 | * @return array |
||
| 560 | */ |
||
| 561 | 9 | public function countErrors() |
|
| 581 | |||
| 582 | /** |
||
| 583 | * Get the oddness errors query. |
||
| 584 | * |
||
| 585 | * @return \Illuminate\Database\Query\Builder |
||
| 586 | */ |
||
| 587 | 9 | protected function getOddnessQuery() |
|
| 599 | |||
| 600 | /** |
||
| 601 | * Get the duplicates errors query. |
||
| 602 | * |
||
| 603 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder|\Illuminate\Database\Query\Builder |
||
| 604 | */ |
||
| 605 | 9 | protected function getDuplicatesQuery() |
|
| 625 | |||
| 626 | /** |
||
| 627 | * Get the wrong parent query. |
||
| 628 | * |
||
| 629 | * @return \Illuminate\Database\Query\Builder |
||
| 630 | */ |
||
| 631 | 9 | protected function getWrongParentQuery() |
|
| 655 | |||
| 656 | /** |
||
| 657 | * Get the missing parent query. |
||
| 658 | * |
||
| 659 | * @return \Illuminate\Database\Query\Builder |
||
| 660 | */ |
||
| 661 | 9 | protected function getMissingParentQuery() |
|
| 685 | |||
| 686 | /** |
||
| 687 | * Get the number of total errors of the tree. |
||
| 688 | * |
||
| 689 | * @return int |
||
| 690 | */ |
||
| 691 | 6 | public function getTotalErrors() |
|
| 695 | |||
| 696 | /** |
||
| 697 | * Get whether the tree is broken. |
||
| 698 | * |
||
| 699 | * @return bool |
||
| 700 | */ |
||
| 701 | 6 | public function isBroken() |
|
| 705 | |||
| 706 | /** |
||
| 707 | * Fixes the tree based on parentage info. |
||
| 708 | * Nodes with invalid parent are saved as roots. |
||
| 709 | * |
||
| 710 | * @return int The number of fixed nodes |
||
| 711 | */ |
||
| 712 | 3 | public function fixTree() |
|
| 726 | |||
| 727 | /** |
||
| 728 | * Rebuild the tree based on raw data. |
||
| 729 | * If item data does not contain primary key, new node will be created. |
||
| 730 | * |
||
| 731 | * @param array $data |
||
| 732 | * @param bool $delete Whether to delete nodes that exists but not in the data array |
||
| 733 | * |
||
| 734 | * @return int |
||
| 735 | */ |
||
| 736 | 9 | public function rebuildTree(array $data, $delete = false) |
|
| 742 | |||
| 743 | /** |
||
| 744 | * Get the root node. |
||
| 745 | * |
||
| 746 | * @param array $columns |
||
| 747 | * |
||
| 748 | * @return \Illuminate\Database\Eloquent\Model|\Arcanedev\LaravelNestedSet\Contracts\Nodeable|null |
||
| 749 | */ |
||
| 750 | 12 | public function root(array $columns = ['*']) |
|
| 754 | } |
||
| 755 |