Complex classes like Widget 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 Widget, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | abstract class Widget { |
||
15 | /** |
||
16 | * Widget admin label |
||
17 | * @var string |
||
18 | */ |
||
19 | protected $widget_label = ''; |
||
20 | |||
21 | /** |
||
22 | * Widget description, shown on the "+ Add Widget" picker |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $widget_description = ''; |
||
26 | |||
27 | /** |
||
28 | * Widget details, shown in the widget lightbox |
||
29 | * @since 1.8 |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $widget_subtitle = ''; |
||
33 | |||
34 | /** |
||
35 | * Widget admin ID |
||
36 | * @var string |
||
37 | */ |
||
38 | protected $widget_id = ''; |
||
39 | |||
40 | /** |
||
41 | * Default configuration for header and footer |
||
42 | * @var array |
||
43 | */ |
||
44 | protected $defaults = array(); |
||
45 | |||
46 | /** |
||
47 | * Widget admin advanced settings |
||
48 | * @var array |
||
49 | */ |
||
50 | protected $settings = array(); |
||
51 | |||
52 | /** |
||
53 | * Allow class to automatically add widget_text filter for you in shortcode |
||
54 | * @var string |
||
55 | */ |
||
56 | protected $shortcode_name; |
||
57 | |||
58 | /** |
||
59 | * Hold the widget options. |
||
60 | * @var array() |
||
61 | */ |
||
62 | private $widget_options = array(); |
||
63 | |||
64 | /** |
||
65 | * The position of the widget. |
||
66 | * @api |
||
67 | * @since 2.0 |
||
68 | * @var string |
||
69 | */ |
||
70 | public $position = ''; |
||
71 | |||
72 | /** |
||
73 | * A unique ID for this widget. |
||
74 | * @api |
||
75 | * @since 2.0 |
||
76 | * @var string |
||
77 | */ |
||
78 | public $UID = ''; |
||
79 | |||
80 | /** |
||
81 | * The actual configuration for this widget instance. |
||
82 | * |
||
83 | * @api |
||
84 | * @since 2.0 |
||
85 | * @var \GV\Settings |
||
86 | */ |
||
87 | public $configuration; |
||
88 | |||
89 | /** |
||
90 | * Constructor. |
||
91 | * |
||
92 | * @param string $label The Widget label as shown in the admin. |
||
93 | * @param string $id The Widget ID, make this something unique. |
||
94 | * @param array $defaults Default footer/header Widget configuration. |
||
95 | * @param array $settings Advanced Widget settings. |
||
96 | * |
||
97 | * @return \GV\Widget |
||
98 | */ |
||
99 | 7 | public function __construct( $label, $id, $defaults = array(), $settings = array() ) { |
|
137 | |||
138 | /** |
||
139 | * Define general widget settings |
||
140 | * @since 1.5.4 |
||
141 | * @return array $settings Default settings |
||
142 | */ |
||
143 | 7 | protected function get_default_settings() { |
|
165 | |||
166 | /** |
||
167 | * Get the Widget ID. |
||
168 | * |
||
169 | * @return string The Widget ID. |
||
170 | */ |
||
171 | 7 | public function get_widget_id() { |
|
174 | |||
175 | /** |
||
176 | * Get the widget settings |
||
177 | * |
||
178 | * @return array|null Settings array; NULL if not set for some reason. |
||
179 | */ |
||
180 | 1 | public function get_settings() { |
|
183 | |||
184 | /** |
||
185 | * Get a setting by the setting key. |
||
186 | * |
||
187 | * @param string $key Key for the setting |
||
188 | * |
||
189 | * @todo Use the \GV\Settings class later. For now subclasses may still expect and array instead. |
||
190 | * |
||
191 | * @return mixed|null Value of the setting; NULL if not set |
||
192 | */ |
||
193 | 1 | public function get_setting( $key ) { |
|
196 | |||
197 | /** |
||
198 | * Default widget areas. |
||
199 | * |
||
200 | * Usually overridden by the selected template. |
||
201 | * |
||
202 | * @return array The default areas where widgets can be rendered. |
||
203 | */ |
||
204 | 3 | public static function get_default_widget_areas() { |
|
223 | |||
224 | /** |
||
225 | * Register widget to become available in admin. And for lookup. |
||
226 | * |
||
227 | * @param array $widgets Usually just empty. Used to gather them all up. |
||
228 | * |
||
229 | * @return array $widgets |
||
230 | */ |
||
231 | 7 | public function register_widget( $widgets ) { |
|
245 | |||
246 | /** |
||
247 | * Assign template specific widget options |
||
248 | * |
||
249 | * @access protected |
||
250 | * |
||
251 | * @param array $options (default: array()) |
||
252 | * @param string $template (default: '') |
||
253 | * |
||
254 | * @return array |
||
255 | */ |
||
256 | 1 | public function assign_widget_options( $options = array(), $template = '', $widget = '' ) { |
|
264 | |||
265 | /** |
||
266 | * Do shortcode if the Widget's shortcode exists. |
||
267 | * |
||
268 | * @param string $text Widget text to check |
||
269 | * @param null|WP_Widget Empty if not called by WP_Widget, or a WP_Widget instance |
||
270 | * |
||
271 | * @return string Widget text |
||
272 | */ |
||
273 | 1 | public function maybe_do_shortcode( $text, $widget = null ) { |
|
279 | |||
280 | /** |
||
281 | * Add $this->shortcode_name shortcode to output self::render_frontend() |
||
282 | * |
||
283 | * @return void |
||
284 | */ |
||
285 | 1 | public function add_shortcode() { |
|
311 | |||
312 | /** |
||
313 | * Frontend logic. |
||
314 | * |
||
315 | * Override in child class. |
||
316 | * |
||
317 | * @param array $widget_args The Widget shortcode args. |
||
318 | * @param string $content The content. |
||
319 | * @param string|\GV\Template_Context $context The context, if available. |
||
320 | * |
||
321 | * @return void |
||
322 | */ |
||
323 | public function render_frontend( $widget_args, $content = '', $context = '' ) { |
||
325 | |||
326 | /** |
||
327 | * General validations when rendering the widget |
||
328 | * |
||
329 | * Always call this from your `render_frontend()` override! |
||
330 | * |
||
331 | * @return boolean True: render frontend; False: don't render frontend |
||
332 | */ |
||
333 | 3 | public function pre_render_frontend() { |
|
354 | |||
355 | /** |
||
356 | * Shortcode. |
||
357 | * |
||
358 | * @param array $atts The Widget shortcode args. |
||
359 | * @param string $content The content. |
||
360 | * @param string $context The context, if available. |
||
361 | * |
||
362 | * @return string Whatever the widget echoed. |
||
363 | */ |
||
364 | 1 | public function render_shortcode( $atts, $content = '', $context = '' ) { |
|
369 | |||
370 | /** |
||
371 | * Create the needed widget from a configuration array. |
||
372 | * |
||
373 | * @param array $configuration The configuration array. |
||
374 | * @see \GV\Widget::as_configuration() |
||
375 | * @internal |
||
376 | * @since 2.0 |
||
377 | * |
||
378 | * @return \GV\Widget|null The widget implementation from configuration or none. |
||
379 | */ |
||
380 | 6 | public static function from_configuration( $configuration ) { |
|
400 | |||
401 | /** |
||
402 | * Return an array of the old format. |
||
403 | * |
||
404 | * 'id' => string |
||
405 | * + whatever else specific fields may have |
||
406 | * |
||
407 | * @internal |
||
408 | * @since 2.0 |
||
409 | * |
||
410 | * @return array |
||
411 | */ |
||
412 | 3 | public function as_configuration() { |
|
417 | |||
418 | /** |
||
419 | * Return all registered widgets. |
||
420 | * |
||
421 | * @api |
||
422 | * @since 2.0 |
||
423 | * |
||
424 | * @return array |
||
425 | */ |
||
426 | 7 | public static function registered() { |
|
440 | |||
441 | /** |
||
442 | * Whether this Widget's been registered already or not. |
||
443 | * |
||
444 | * @api |
||
445 | * @since 2.0 |
||
446 | * |
||
447 | * @return bool |
||
448 | */ |
||
449 | 7 | public function is_registered() { |
|
456 | } |
||
457 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.