Complex classes like IndexPage 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 IndexPage, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
32 | class IndexPage extends Widget |
||
33 | { |
||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $_layout; |
||
38 | |||
39 | /** |
||
40 | * @var Model the search model |
||
41 | */ |
||
42 | public $model; |
||
43 | |||
44 | /** |
||
45 | * @var IndexPageUiOptions |
||
46 | */ |
||
47 | private $uiModel; |
||
48 | |||
49 | /** |
||
50 | * @var object original view context. |
||
51 | * It is used to render sub-views with the same context, as IndexPage |
||
52 | */ |
||
53 | public $originalContext; |
||
54 | |||
55 | /** |
||
56 | * @var DataProviderInterface |
||
57 | */ |
||
58 | public $dataProvider; |
||
59 | |||
60 | /** |
||
61 | * @var array Hash of document blocks, that can be rendered later in the widget's views |
||
62 | * Blocks can be set explicitly on widget initialisation, or by calling [[beginContent]] and |
||
63 | * [[endContent]] |
||
64 | * |
||
65 | * @see beginContent |
||
66 | * @see endContent |
||
67 | */ |
||
68 | public $contents = []; |
||
69 | |||
70 | /** |
||
71 | * @var string the name of current content block, that is under the render |
||
72 | * @see beginContent |
||
73 | * @see endContent |
||
74 | */ |
||
75 | protected $_current = null; |
||
76 | |||
77 | /** |
||
78 | * @var array |
||
79 | */ |
||
80 | public $searchFormData = []; |
||
81 | |||
82 | /** |
||
83 | * @var array |
||
84 | */ |
||
85 | public $searchFormOptions = []; |
||
86 | |||
87 | /** |
||
88 | * @var string the name of view file that contains search fields for the index page. Defaults to `_search` |
||
89 | * @see renderSearchForm() |
||
90 | */ |
||
91 | public $searchView = '_search'; |
||
92 | |||
93 | /** {@inheritdoc} */ |
||
94 | public function init() |
||
95 | { |
||
96 | parent::init(); |
||
97 | $searchFormId = Json::htmlEncode("#{$this->getBulkFormId()}"); |
||
98 | $this->originalContext = Yii::$app->view->context; |
||
99 | $view = $this->getView(); |
||
100 | // Fix a very narrow select2 input in the search tables |
||
101 | $view->registerCss('#content-pjax .select2-dropdown--below { min-width: 170px!important; }'); |
||
102 | $view->registerJs(<<<"JS" |
||
103 | // Checkbox |
||
104 | var bulkcontainer = $('.box-bulk-actions fieldset'); |
||
105 | $($searchFormId).on('change', 'input[type="checkbox"]', function(event) { |
||
106 | var checkboxes = $('input.grid-checkbox'); |
||
107 | if (checkboxes.filter(':checked').length > 0) { |
||
108 | bulkcontainer.prop('disabled', false); |
||
109 | } else if (checkboxes.filter(':checked').length === 0) { |
||
110 | bulkcontainer.prop('disabled', true); |
||
111 | } |
||
112 | }); |
||
113 | // On/Off Actions TODO: reduce scope |
||
114 | $(document).on('click', '.box-bulk-actions a', function (event) { |
||
115 | var link = $(this); |
||
116 | var action = link.data('action'); |
||
117 | var form = $($searchFormId); |
||
118 | if (action) { |
||
119 | form.attr({'action': action, method: 'POST'}).submit(); |
||
120 | } |
||
121 | }); |
||
122 | // Do not open select2 when it is clearing |
||
123 | var comboSelector = 'div[role=grid] :input[data-combo-field], .advanced-search :input[data-combo-field]'; |
||
124 | $(document).on('select2:unselecting', comboSelector, function(e) { |
||
125 | $(e.target).data('unselecting', true); |
||
126 | }).on('select2:open', comboSelector, function(e) { // note the open event is important |
||
127 | var el = $(e.target); |
||
128 | if (el.data('unselecting')) { |
||
129 | el.removeData('unselecting'); // you need to unset this before close |
||
130 | el.select2('close'); |
||
131 | } |
||
132 | }); |
||
133 | JS |
||
134 | ); |
||
135 | } |
||
136 | |||
137 | public function getUiModel() |
||
145 | |||
146 | /** |
||
147 | * Begins output buffer capture to save data in [[contents]] with the $name key. |
||
148 | * Must not be called nested. See [[endContent]] for capture terminating. |
||
149 | * @param string $name |
||
150 | */ |
||
151 | public function beginContent($name) |
||
160 | |||
161 | /** |
||
162 | * Terminates output buffer capture started by [[beginContent()]]. |
||
163 | * @see beginContent |
||
164 | */ |
||
165 | public function endContent() |
||
174 | |||
175 | /** |
||
176 | * Returns content saved in [[content]] by $name. |
||
177 | * @param string $name |
||
178 | * @return string |
||
179 | */ |
||
180 | public function renderContent($name) |
||
184 | |||
185 | public function run() |
||
194 | |||
195 | private function horizontalClientScriptInit() |
||
238 | |||
239 | public function detectLayout() |
||
243 | |||
244 | /** |
||
245 | * @param array $data |
||
246 | * @void |
||
247 | */ |
||
248 | public function setSearchFormData($data = []) |
||
252 | |||
253 | /** |
||
254 | * @param array $options |
||
255 | * @void |
||
256 | */ |
||
257 | public function setSearchFormOptions($options = []) |
||
261 | |||
262 | public function renderSearchForm($advancedSearchOptions = []) |
||
278 | |||
279 | public function beginSearchForm($options = []) |
||
283 | |||
284 | public function renderSearchButton() |
||
288 | |||
289 | public function renderLayoutSwitcher() |
||
293 | |||
294 | public function renderPerPage() |
||
309 | |||
310 | /** |
||
311 | * Renders button to choose representation. |
||
312 | * Returns empty string when nothing to choose (less then 2 representations available). |
||
313 | * |
||
314 | * @param RepresentationCollectionInterface $collection |
||
315 | * @return string rendered HTML |
||
316 | */ |
||
317 | public function renderRepresentations($collection) |
||
342 | |||
343 | public function renderSorter(array $options) |
||
353 | |||
354 | public function renderExport() |
||
365 | |||
366 | public function getViewPath() |
||
370 | |||
371 | public function getBulkFormId() |
||
375 | |||
376 | public function beginBulkForm($action = '') |
||
380 | |||
381 | public function endBulkForm() |
||
385 | |||
386 | /** |
||
387 | * @param string|array $action |
||
388 | * @param string $text |
||
389 | * @param array $options |
||
390 | * @return string |
||
391 | */ |
||
392 | public function renderBulkButton($action, $text, array $options = []): string |
||
408 | |||
409 | /** |
||
410 | * @param string $permission |
||
411 | * @param string $button |
||
412 | * @return string|null |
||
413 | */ |
||
414 | public function withPermission(string $permission, string $button): ?string |
||
421 | |||
422 | /** |
||
423 | * @param string|array $action |
||
424 | * @param string|null $text |
||
425 | * @param array $options |
||
426 | * @return string |
||
427 | */ |
||
428 | public function renderBulkDeleteButton($action, $text = null, array $options = []): string |
||
436 | |||
437 | /** |
||
438 | * @return string |
||
439 | */ |
||
440 | public function getLayout() |
||
448 | |||
449 | /** |
||
450 | * @param string $layout |
||
451 | */ |
||
452 | public function setLayout($layout) |
||
456 | } |
||
457 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.