Complex classes like DataTableAbstract 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 DataTableAbstract, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
25 | abstract class DataTableAbstract implements DataTable, Arrayable, Jsonable |
||
26 | { |
||
27 | use Macroable; |
||
28 | |||
29 | /** |
||
30 | * DataTables Request object. |
||
31 | * |
||
32 | * @var \Yajra\DataTables\Utilities\Request |
||
33 | */ |
||
34 | public $request; |
||
35 | |||
36 | /** |
||
37 | * @var \Psr\Log\LoggerInterface |
||
38 | */ |
||
39 | protected $logger; |
||
40 | |||
41 | /** |
||
42 | * Array of result columns/fields. |
||
43 | * |
||
44 | * @var array |
||
45 | */ |
||
46 | protected $columns = []; |
||
47 | |||
48 | /** |
||
49 | * DT columns definitions container (add/edit/remove/filter/order/escape). |
||
50 | * |
||
51 | * @var array |
||
52 | */ |
||
53 | protected $columnDef = [ |
||
54 | 'index' => false, |
||
55 | 'append' => [], |
||
56 | 'edit' => [], |
||
57 | 'filter' => [], |
||
58 | 'order' => [], |
||
59 | 'only' => null, |
||
60 | 'hidden' => [], |
||
61 | 'visible' => [], |
||
62 | ]; |
||
63 | |||
64 | /** |
||
65 | * Extra/Added columns. |
||
66 | * |
||
67 | * @var array |
||
68 | */ |
||
69 | protected $extraColumns = []; |
||
70 | |||
71 | /** |
||
72 | * Total records. |
||
73 | * |
||
74 | * @var int |
||
75 | */ |
||
76 | protected $totalRecords = 0; |
||
77 | |||
78 | /** |
||
79 | * Total filtered records. |
||
80 | * |
||
81 | * @var int |
||
82 | */ |
||
83 | protected $filteredRecords = 0; |
||
84 | |||
85 | /** |
||
86 | * Auto-filter flag. |
||
87 | * |
||
88 | * @var bool |
||
89 | */ |
||
90 | protected $autoFilter = true; |
||
91 | |||
92 | /** |
||
93 | * Callback to override global search. |
||
94 | * |
||
95 | * @var callable |
||
96 | */ |
||
97 | protected $filterCallback; |
||
98 | |||
99 | /** |
||
100 | * DT row templates container. |
||
101 | * |
||
102 | * @var array |
||
103 | */ |
||
104 | protected $templates = [ |
||
105 | 'DT_RowId' => '', |
||
106 | 'DT_RowClass' => '', |
||
107 | 'DT_RowData' => [], |
||
108 | 'DT_RowAttr' => [], |
||
109 | ]; |
||
110 | |||
111 | /** |
||
112 | * [internal] Track if any filter was applied for at least one column. |
||
113 | * |
||
114 | * @var bool |
||
115 | */ |
||
116 | protected $isFilterApplied = false; |
||
117 | |||
118 | /** |
||
119 | * Custom ordering callback. |
||
120 | * |
||
121 | * @var callable |
||
122 | */ |
||
123 | protected $orderCallback; |
||
124 | |||
125 | /** |
||
126 | * Skip paginate as needed. |
||
127 | * |
||
128 | * @var bool |
||
129 | */ |
||
130 | protected $skipPaging = false; |
||
131 | |||
132 | /** |
||
133 | * Array of data to append on json response. |
||
134 | * |
||
135 | * @var array |
||
136 | */ |
||
137 | protected $appends = []; |
||
138 | |||
139 | /** |
||
140 | * @var \Yajra\DataTables\Utilities\Config |
||
141 | */ |
||
142 | protected $config; |
||
143 | |||
144 | /** |
||
145 | * @var mixed |
||
146 | */ |
||
147 | protected $serializer; |
||
148 | |||
149 | /** |
||
150 | * @var array |
||
151 | */ |
||
152 | protected $searchPanes = []; |
||
153 | |||
154 | /** |
||
155 | * Can the DataTable engine be created with these parameters. |
||
156 | * |
||
157 | * @param mixed $source |
||
158 | * @return bool |
||
159 | */ |
||
160 | public static function canCreate($source) |
||
164 | |||
165 | /** |
||
166 | * Factory method, create and return an instance for the DataTable engine. |
||
167 | * |
||
168 | * @param mixed $source |
||
169 | * @return DataTableAbstract |
||
170 | */ |
||
171 | public static function create($source) |
||
175 | |||
176 | /** |
||
177 | * Add column in collection. |
||
178 | * |
||
179 | * @param string $name |
||
180 | * @param string|callable $content |
||
181 | * @param bool|int $order |
||
182 | * @return $this |
||
183 | */ |
||
184 | public function addColumn($name, $content, $order = false) |
||
192 | |||
193 | /** |
||
194 | * @param string|array $columns |
||
195 | * @param mixed|\Yajra\DataTables\Contracts\Formatter $formatter |
||
196 | * @return $this |
||
197 | * @throws \Exception |
||
198 | */ |
||
199 | public function formatColumn($columns, $formatter) |
||
215 | |||
216 | /** |
||
217 | * Add DT row index column on response. |
||
218 | * |
||
219 | * @return $this |
||
220 | */ |
||
221 | public function addIndexColumn() |
||
227 | |||
228 | /** |
||
229 | * Edit column's content. |
||
230 | * |
||
231 | * @param string $name |
||
232 | * @param string|callable $content |
||
233 | * @return $this |
||
234 | */ |
||
235 | public function editColumn($name, $content) |
||
241 | |||
242 | /** |
||
243 | * Remove column from collection. |
||
244 | * |
||
245 | * @return $this |
||
246 | */ |
||
247 | public function removeColumn() |
||
254 | |||
255 | /** |
||
256 | * Get only selected columns in response. |
||
257 | * |
||
258 | * @param array $columns |
||
259 | * @return $this |
||
260 | */ |
||
261 | public function only(array $columns = []) |
||
267 | |||
268 | /** |
||
269 | * Declare columns to escape values. |
||
270 | * |
||
271 | * @param string|array $columns |
||
272 | * @return $this |
||
273 | */ |
||
274 | public function escapeColumns($columns = '*') |
||
280 | |||
281 | /** |
||
282 | * Add a makeHidden() to the row object. |
||
283 | * |
||
284 | * @param array $attributes |
||
285 | * @return $this |
||
286 | */ |
||
287 | public function makeHidden(array $attributes = []) |
||
293 | |||
294 | /** |
||
295 | * Add a makeVisible() to the row object. |
||
296 | * |
||
297 | * @param array $attributes |
||
298 | * @return $this |
||
299 | */ |
||
300 | public function makeVisible(array $attributes = []) |
||
306 | |||
307 | /** |
||
308 | * Set columns that should not be escaped. |
||
309 | * Optionally merge the defaults from config. |
||
310 | * |
||
311 | * @param array $columns |
||
312 | * @param bool $merge |
||
313 | * @return $this |
||
314 | */ |
||
315 | public function rawColumns(array $columns, $merge = false) |
||
327 | |||
328 | /** |
||
329 | * Sets DT_RowClass template. |
||
330 | * result: <tr class="output_from_your_template">. |
||
331 | * |
||
332 | * @param string|callable $content |
||
333 | * @return $this |
||
334 | */ |
||
335 | public function setRowClass($content) |
||
341 | |||
342 | /** |
||
343 | * Sets DT_RowId template. |
||
344 | * result: <tr id="output_from_your_template">. |
||
345 | * |
||
346 | * @param string|callable $content |
||
347 | * @return $this |
||
348 | */ |
||
349 | public function setRowId($content) |
||
355 | |||
356 | /** |
||
357 | * Set DT_RowData templates. |
||
358 | * |
||
359 | * @param array $data |
||
360 | * @return $this |
||
361 | */ |
||
362 | public function setRowData(array $data) |
||
368 | |||
369 | /** |
||
370 | * Add DT_RowData template. |
||
371 | * |
||
372 | * @param string $key |
||
373 | * @param string|callable $value |
||
374 | * @return $this |
||
375 | */ |
||
376 | public function addRowData($key, $value) |
||
382 | |||
383 | /** |
||
384 | * Set DT_RowAttr templates. |
||
385 | * result: <tr attr1="attr1" attr2="attr2">. |
||
386 | * |
||
387 | * @param array $data |
||
388 | * @return $this |
||
389 | */ |
||
390 | public function setRowAttr(array $data) |
||
396 | |||
397 | /** |
||
398 | * Add DT_RowAttr template. |
||
399 | * |
||
400 | * @param string $key |
||
401 | * @param string|callable $value |
||
402 | * @return $this |
||
403 | */ |
||
404 | public function addRowAttr($key, $value) |
||
410 | |||
411 | /** |
||
412 | * Append data on json response. |
||
413 | * |
||
414 | * @param mixed $key |
||
415 | * @param mixed $value |
||
416 | * @return $this |
||
417 | */ |
||
418 | public function with($key, $value = '') |
||
430 | |||
431 | /** |
||
432 | * Add with query callback value on response. |
||
433 | * |
||
434 | * @param string $key |
||
435 | * @param callable $value |
||
436 | * @return $this |
||
437 | */ |
||
438 | public function withQuery($key, callable $value) |
||
444 | |||
445 | /** |
||
446 | * Override default ordering method with a closure callback. |
||
447 | * |
||
448 | * @param callable $closure |
||
449 | * @return $this |
||
450 | */ |
||
451 | public function order(callable $closure) |
||
457 | |||
458 | /** |
||
459 | * Update list of columns that is not allowed for search/sort. |
||
460 | * |
||
461 | * @param array $blacklist |
||
462 | * @return $this |
||
463 | */ |
||
464 | public function blacklist(array $blacklist) |
||
470 | |||
471 | /** |
||
472 | * Update list of columns that is allowed for search/sort. |
||
473 | * |
||
474 | * @param string|array $whitelist |
||
475 | * @return $this |
||
476 | */ |
||
477 | public function whitelist($whitelist = '*') |
||
483 | |||
484 | /** |
||
485 | * Set smart search config at runtime. |
||
486 | * |
||
487 | * @param bool $state |
||
488 | * @return $this |
||
489 | */ |
||
490 | public function smart($state = true) |
||
496 | |||
497 | /** |
||
498 | * Set starts_with search config at runtime. |
||
499 | * |
||
500 | * @param bool $state |
||
501 | * @return $this |
||
502 | */ |
||
503 | public function startsWithSearch($state = true) |
||
509 | |||
510 | /** |
||
511 | * Set total records manually. |
||
512 | * |
||
513 | * @param int $total |
||
514 | * @return $this |
||
515 | */ |
||
516 | public function setTotalRecords($total) |
||
522 | |||
523 | /** |
||
524 | * Set filtered records manually. |
||
525 | * |
||
526 | * @param int $total |
||
527 | * @return $this |
||
528 | */ |
||
529 | public function setFilteredRecords($total) |
||
535 | |||
536 | /** |
||
537 | * Skip pagination as needed. |
||
538 | * |
||
539 | * @return $this |
||
540 | */ |
||
541 | public function skipPaging() |
||
547 | |||
548 | /** |
||
549 | * Push a new column name to blacklist. |
||
550 | * |
||
551 | * @param string $column |
||
552 | * @return $this |
||
553 | */ |
||
554 | public function pushToBlacklist($column) |
||
562 | |||
563 | /** |
||
564 | * Check if column is blacklisted. |
||
565 | * |
||
566 | * @param string $column |
||
567 | * @return bool |
||
568 | */ |
||
569 | protected function isBlacklisted($column) |
||
583 | |||
584 | /** |
||
585 | * Get columns definition. |
||
586 | * |
||
587 | * @return array |
||
588 | */ |
||
589 | protected function getColumnsDefinition() |
||
596 | |||
597 | /** |
||
598 | * Perform sorting of columns. |
||
599 | */ |
||
600 | public function ordering() |
||
608 | |||
609 | /** |
||
610 | * Resolve callback parameter instance. |
||
611 | * |
||
612 | * @return mixed |
||
613 | */ |
||
614 | abstract protected function resolveCallbackParameter(); |
||
615 | |||
616 | /** |
||
617 | * Perform default query orderBy clause. |
||
618 | */ |
||
619 | abstract protected function defaultOrdering(); |
||
620 | |||
621 | /** |
||
622 | * Set auto filter off and run your own filter. |
||
623 | * Overrides global search. |
||
624 | * |
||
625 | * @param callable $callback |
||
626 | * @param bool $globalSearch |
||
627 | * @return $this |
||
628 | */ |
||
629 | public function filter(callable $callback, $globalSearch = false) |
||
637 | |||
638 | /** |
||
639 | * Convert instance to array. |
||
640 | * |
||
641 | * @return array |
||
642 | */ |
||
643 | public function toArray() |
||
647 | |||
648 | /** |
||
649 | * Convert the object to its JSON representation. |
||
650 | * |
||
651 | * @param int $options |
||
652 | * @return \Illuminate\Http\JsonResponse |
||
653 | */ |
||
654 | public function toJson($options = 0) |
||
662 | |||
663 | /** |
||
664 | * Count filtered items. |
||
665 | * |
||
666 | * @return int |
||
667 | */ |
||
668 | protected function filteredCount() |
||
672 | |||
673 | /** |
||
674 | * Perform necessary filters. |
||
675 | * |
||
676 | * @return void |
||
677 | */ |
||
678 | protected function filterRecords() |
||
692 | |||
693 | /** |
||
694 | * Perform search using search pane values. |
||
695 | */ |
||
696 | protected function searchPanesSearch() |
||
700 | |||
701 | /** |
||
702 | * Perform global search. |
||
703 | * |
||
704 | * @return void |
||
705 | */ |
||
706 | public function filtering() |
||
718 | |||
719 | /** |
||
720 | * Perform multi-term search by splitting keyword into |
||
721 | * individual words and searches for each of them. |
||
722 | * |
||
723 | * @param string $keyword |
||
724 | */ |
||
725 | protected function smartGlobalSearch($keyword) |
||
735 | |||
736 | /** |
||
737 | * Perform global search for the given keyword. |
||
738 | * |
||
739 | * @param string $keyword |
||
740 | */ |
||
741 | abstract protected function globalSearch($keyword); |
||
742 | |||
743 | /** |
||
744 | * Apply pagination. |
||
745 | * |
||
746 | * @return void |
||
747 | */ |
||
748 | protected function paginate() |
||
754 | |||
755 | /** |
||
756 | * Transform output. |
||
757 | * |
||
758 | * @param mixed $results |
||
759 | * @param mixed $processed |
||
760 | * @return array |
||
761 | */ |
||
762 | protected function transform($results, $processed) |
||
774 | |||
775 | /** |
||
776 | * Get processed data. |
||
777 | * |
||
778 | * @param mixed $results |
||
779 | * @param bool $object |
||
780 | * @return array |
||
781 | */ |
||
782 | protected function processResults($results, $object = false) |
||
793 | |||
794 | /** |
||
795 | * Render json response. |
||
796 | * |
||
797 | * @param array $data |
||
798 | * @return \Illuminate\Http\JsonResponse |
||
799 | */ |
||
800 | protected function render(array $data) |
||
824 | |||
825 | /** |
||
826 | * Attach custom with meta on response. |
||
827 | * |
||
828 | * @param array $data |
||
829 | * @return array |
||
830 | */ |
||
831 | protected function attachAppends(array $data) |
||
835 | |||
836 | /** |
||
837 | * Append debug parameters on output. |
||
838 | * |
||
839 | * @param array $output |
||
840 | * @return array |
||
841 | */ |
||
842 | protected function showDebugger(array $output) |
||
848 | |||
849 | /** |
||
850 | * Return an error json response. |
||
851 | * |
||
852 | * @param \Exception $exception |
||
853 | * @return \Illuminate\Http\JsonResponse |
||
854 | * @throws \Yajra\DataTables\Exceptions\Exception |
||
855 | */ |
||
856 | protected function errorResponse(\Exception $exception) |
||
875 | |||
876 | /** |
||
877 | * Get monolog/logger instance. |
||
878 | * |
||
879 | * @return \Psr\Log\LoggerInterface |
||
880 | */ |
||
881 | public function getLogger() |
||
887 | |||
888 | /** |
||
889 | * Set monolog/logger instance. |
||
890 | * |
||
891 | * @param \Psr\Log\LoggerInterface $logger |
||
892 | * @return $this |
||
893 | */ |
||
894 | public function setLogger(LoggerInterface $logger) |
||
900 | |||
901 | /** |
||
902 | * Setup search keyword. |
||
903 | * |
||
904 | * @param string $value |
||
905 | * @return string |
||
906 | */ |
||
907 | protected function setupKeyword($value) |
||
922 | |||
923 | /** |
||
924 | * Get column name to be use for filtering and sorting. |
||
925 | * |
||
926 | * @param int $index |
||
927 | * @param bool $wantsAlias |
||
928 | * @return string |
||
929 | */ |
||
930 | protected function getColumnName($index, $wantsAlias = false) |
||
945 | |||
946 | /** |
||
947 | * Get column name by order column index. |
||
948 | * |
||
949 | * @param int $index |
||
950 | * @return string |
||
951 | */ |
||
952 | protected function getColumnNameByIndex($index) |
||
959 | |||
960 | /** |
||
961 | * If column name could not be resolved then use primary key. |
||
962 | * |
||
963 | * @return string |
||
964 | */ |
||
965 | protected function getPrimaryKeyName() |
||
969 | |||
970 | /** |
||
971 | * Add a search pane options on response. |
||
972 | * |
||
973 | * @param string $column |
||
974 | * @param mixed $options |
||
975 | * @param callable|null $builder |
||
976 | * @return $this |
||
977 | */ |
||
978 | public function searchPane($column, $options, callable $builder = null) |
||
991 | } |
||
992 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.