Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Plugin 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 Plugin, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | final class Plugin { |
||
9 | const PLUGIN_VERSION = '3.5'; |
||
10 | |||
11 | /** |
||
12 | * @var Plugin The singleton instance. |
||
13 | */ |
||
14 | private static $instance; |
||
15 | |||
16 | /** |
||
17 | * Instantiates a new Plugin object. |
||
18 | */ |
||
19 | private function __construct() { |
||
30 | |||
31 | /** |
||
32 | * Insures we always return the same object. |
||
33 | * |
||
34 | * @return Plugin |
||
35 | */ |
||
36 | public static function get_instance() { |
||
44 | |||
45 | /** |
||
46 | * Initialize the plugin. |
||
47 | */ |
||
48 | public function plugins_loaded() { |
||
66 | |||
67 | /** |
||
68 | * Check plugin requirements. |
||
69 | * |
||
70 | * @return bool True is fails requirements. False otherwise. |
||
71 | */ |
||
72 | public function maybe_self_deactivate() { |
||
89 | |||
90 | /** |
||
91 | * Define all the constants. |
||
92 | */ |
||
93 | public function constants() { |
||
121 | |||
122 | /** |
||
123 | * Load all BackUpWordPress functions. |
||
124 | */ |
||
125 | protected function includes() { |
||
126 | |||
127 | require_once( HMBKP_PLUGIN_PATH . 'vendor/autoload.php' ); |
||
128 | |||
129 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-notices.php' ); |
||
130 | |||
131 | // Load the admin menu |
||
132 | require_once( HMBKP_PLUGIN_PATH . 'admin/menu.php' ); |
||
133 | require_once( HMBKP_PLUGIN_PATH . 'admin/actions.php' ); |
||
134 | |||
135 | // Load Backdrop if necessary. |
||
136 | if ( ! class_exists( 'HM_Backdrop_Task' ) ) { |
||
137 | require_once( HMBKP_PLUGIN_PATH . 'backdrop/hm-backdrop.php' ); |
||
138 | } |
||
139 | |||
140 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirements.php' ); |
||
141 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirement.php' ); |
||
142 | |||
143 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-path.php' ); |
||
144 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-excludes.php' ); |
||
145 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-site-size.php' ); |
||
146 | |||
147 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-utilities.php' ); |
||
148 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-status.php' ); |
||
149 | |||
150 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine.php' ); |
||
151 | |||
152 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-database.php' ); |
||
153 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-database-mysqldump.php' ); |
||
154 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-database-imysqldump.php' ); |
||
155 | |||
156 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-file.php' ); |
||
157 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-file-zip.php' ); |
||
158 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup-engine-file-zip-archive.php' ); |
||
159 | |||
160 | require_once( HMBKP_PLUGIN_PATH . 'classes/backup/class-backup.php' ); |
||
161 | |||
162 | // Load the backup scheduling classes |
||
163 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-scheduled-backup.php' ); |
||
164 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-schedules.php' ); |
||
165 | |||
166 | // Load the core functions |
||
167 | require_once( HMBKP_PLUGIN_PATH . 'functions/core.php' ); |
||
168 | require_once( HMBKP_PLUGIN_PATH . 'functions/interface.php' ); |
||
169 | |||
170 | // Load the services |
||
171 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-services.php' ); |
||
172 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-service.php' ); |
||
173 | |||
174 | // Load the email service |
||
175 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-email-service.php' ); |
||
176 | |||
177 | // Load the webhook services |
||
178 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-webhook-service.php' ); |
||
179 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-wpremote-webhook-service.php' ); |
||
180 | |||
181 | require_once( HMBKP_PLUGIN_PATH . 'classes/deprecated.php' ); |
||
182 | |||
183 | require_once( HMBKP_PLUGIN_PATH . 'classes/class-extensions.php' ); |
||
184 | |||
185 | // Load the wp cli command |
||
186 | if ( defined( 'WP_CLI' ) && WP_CLI ) { |
||
187 | include( HMBKP_PLUGIN_PATH . 'classes/class-backupwordpress-wp-cli-command.php' ); |
||
188 | } |
||
189 | |||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Hook into WordPress page lifecycle and execute BackUpWordPress functions. |
||
194 | */ |
||
195 | public function hooks() { |
||
212 | |||
213 | /** |
||
214 | * Load the Javascript in the admin. |
||
215 | * |
||
216 | * @param $hook The name of the admin page hook. |
||
217 | */ |
||
218 | public function scripts( $hook ) { |
||
250 | |||
251 | /** |
||
252 | * Loads the plugin text domain for translation. |
||
253 | * This setup allows a user to just drop his custom translation files into the WordPress language directory |
||
254 | * Files will need to be in a subdirectory with the name of the textdomain 'backupwordpress' |
||
255 | */ |
||
256 | public function text_domain() { |
||
274 | |||
275 | /** |
||
276 | * Determine if we need to run an upgrade routine. |
||
277 | */ |
||
278 | public function upgrade() { |
||
286 | |||
287 | /** |
||
288 | * Runs on every admin page load |
||
289 | */ |
||
290 | public function init() { |
||
295 | |||
296 | /** |
||
297 | * Generate a unique key. |
||
298 | * |
||
299 | * @return string |
||
300 | */ |
||
301 | protected function generate_key() { |
||
321 | |||
322 | /** |
||
323 | * Ensure BackUpWordPress is loaded before add-ons, changes the order of the serialized values in the DB field. |
||
324 | */ |
||
325 | public function load_first() { |
||
344 | |||
345 | /** |
||
346 | * Function to run when the schedule cron fires. |
||
347 | * |
||
348 | * @param $schedule_id |
||
349 | */ |
||
350 | public function schedule_hook_run( $schedule_id ) { |
||
366 | |||
367 | /** |
||
368 | * Enqueue the plugin styles. |
||
369 | * |
||
370 | * @param $hook |
||
371 | */ |
||
372 | public function styles( $hook ) { |
||
387 | |||
388 | /** |
||
389 | * Load Intercom and send across user information and server info. Only loaded if the user has opted in. |
||
390 | * |
||
391 | * @param $hook |
||
392 | */ |
||
393 | public function load_intercom_script() { |
||
426 | |||
427 | public function display_feature_message() { |
||
457 | |||
458 | } |
||
459 | |||
465 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.