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 |
||
17 | final class Plugin { |
||
18 | /** |
||
19 | * @var string The plugin version. |
||
20 | * |
||
21 | * @api |
||
22 | * @since 2.0 |
||
23 | */ |
||
24 | public static $version = GV_PLUGIN_VERSION; |
||
25 | |||
26 | /** |
||
27 | * @var string Minimum WordPress version. |
||
28 | * |
||
29 | * GravityView requires at least this version of WordPress to function properly. |
||
30 | */ |
||
31 | private static $min_wp_version = GV_MIN_WP_VERSION; |
||
32 | |||
33 | /** |
||
34 | * @var string Minimum Gravity Forms version. |
||
35 | * |
||
36 | * GravityView requires at least this version of Gravity Forms to function properly. |
||
37 | */ |
||
38 | public static $min_gf_version = GV_MIN_GF_VERSION; |
||
39 | |||
40 | /** |
||
41 | * @var string Minimum PHP version. |
||
42 | * |
||
43 | * GravityView requires at least this version of PHP to function properly. |
||
44 | */ |
||
45 | private static $min_php_version = GV_MIN_PHP_VERSION; |
||
46 | |||
47 | /** |
||
48 | * @var string|bool Minimum future PHP version. |
||
49 | * |
||
50 | * GravityView will require this version of PHP soon. False if no future PHP version changes are planned. |
||
51 | */ |
||
52 | private static $future_min_php_version = GV_FUTURE_MIN_PHP_VERSION; |
||
53 | |||
54 | /** |
||
55 | * @var string|bool Minimum future Gravity Forms version. |
||
56 | * |
||
57 | * GravityView will require this version of Gravity Forms soon. False if no future Gravity Forms version changes are planned. |
||
58 | */ |
||
59 | private static $future_min_gf_version = GV_FUTURE_MIN_GF_VERSION; |
||
60 | |||
61 | /** |
||
62 | * @var \GV\Plugin The \GV\Plugin static instance. |
||
63 | */ |
||
64 | private static $__instance = null; |
||
65 | |||
66 | /** |
||
67 | * @var \GV\Addon_Settings The plugin "addon" settings. |
||
68 | * |
||
69 | * @api |
||
70 | * @since 2.0 |
||
71 | */ |
||
72 | public $settings; |
||
73 | |||
74 | /** |
||
75 | * @var string The GFQuery functionality identifier. |
||
76 | */ |
||
77 | const FEATURE_GFQUERY = 'gfquery'; |
||
78 | |||
79 | /** |
||
80 | * @var string The joins functionality identifier. |
||
81 | */ |
||
82 | const FEATURE_JOINS = 'joins'; |
||
83 | |||
84 | /** |
||
85 | * @var string The REST API functionality identifier. |
||
86 | */ |
||
87 | const FEATURE_REST = 'rest_api'; |
||
88 | |||
89 | /** |
||
90 | * Get the global instance of \GV\Plugin. |
||
91 | * |
||
92 | * @return \GV\Plugin The global instance of GravityView Plugin. |
||
93 | */ |
||
94 | public static function get() { |
||
100 | |||
101 | |||
102 | private function __construct() { |
||
118 | |||
119 | public function load_license_settings() { |
||
129 | |||
130 | /** |
||
131 | * Check whether GravityView is network activated. |
||
132 | * |
||
133 | * @return bool Whether it's network activated or not. |
||
134 | */ |
||
135 | 1 | public static function is_network_activated() { |
|
138 | |||
139 | /** |
||
140 | * Include more legacy stuff. |
||
141 | * |
||
142 | * @param boolean $force Whether to force the includes. |
||
143 | * |
||
144 | * @return void |
||
145 | */ |
||
146 | public function include_legacy_frontend( $force = false ) { |
||
167 | |||
168 | /** |
||
169 | * Load more legacy core files. |
||
170 | * |
||
171 | * @return void |
||
172 | */ |
||
173 | public function include_legacy_core() { |
||
228 | |||
229 | /** |
||
230 | * Load the translations. |
||
231 | * |
||
232 | * @return void |
||
233 | */ |
||
234 | public function load_textdomain() { |
||
235 | $loaded = load_plugin_textdomain( 'gravityview', false, $this->dir( 'languages' ) ); |
||
236 | |||
237 | if ( ! $loaded ) { |
||
238 | $loaded = load_muplugin_textdomain( 'gravityview', '/languages/' ); |
||
239 | } |
||
240 | if ( ! $loaded ) { |
||
241 | $loaded = load_theme_textdomain( 'gravityview', '/languages/' ); |
||
242 | } |
||
243 | if ( ! $loaded ) { |
||
244 | |||
245 | $locale = get_locale(); |
||
246 | |||
247 | if ( function_exists('get_user_locale') && is_admin() ) { |
||
248 | $locale = get_user_locale(); |
||
249 | } |
||
250 | |||
251 | $locale = apply_filters( 'plugin_locale', $locale, 'gravityview' ); |
||
252 | $mofile = $this->dir( 'languages' ) . '/gravityview-'. $locale .'.mo'; |
||
253 | load_textdomain( 'gravityview', $mofile ); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Register hooks that are fired when the plugin is activated and deactivated. |
||
259 | * |
||
260 | * @return void |
||
261 | */ |
||
262 | public function register_activation_hooks() { |
||
263 | register_activation_hook( $this->dir( 'gravityview.php' ), array( $this, 'activate' ) ); |
||
264 | register_deactivation_hook( $this->dir( 'gravityview.php' ), array( $this, 'deactivate' ) ); |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * Plugin activation function. |
||
269 | * |
||
270 | * @internal |
||
271 | * @return void |
||
272 | */ |
||
273 | 1 | public function activate() { |
|
274 | 1 | gravityview(); |
|
275 | |||
276 | /** Register the gravityview post type upon WordPress core init. */ |
||
277 | 1 | require_once $this->dir( 'future/includes/class-gv-view.php' ); |
|
278 | 1 | View::register_post_type(); |
|
279 | |||
280 | /** Add the entry rewrite endpoint. */ |
||
281 | 1 | require_once $this->dir( 'future/includes/class-gv-entry.php' ); |
|
282 | 1 | Entry::add_rewrite_endpoint(); |
|
283 | |||
284 | /** Flush all URL rewrites. */ |
||
285 | 1 | flush_rewrite_rules(); |
|
286 | |||
287 | 1 | update_option( 'gv_version', self::$version ); |
|
288 | |||
289 | /** Add the transient to redirect to configuration page. */ |
||
290 | 1 | set_transient( '_gv_activation_redirect', true, 60 ); |
|
291 | |||
292 | /** Clear settings transient. */ |
||
293 | 1 | delete_transient( 'gravityview_edd-activate_valid' ); |
|
294 | |||
295 | 1 | \GravityView_Roles_Capabilities::get_instance()->add_caps(); |
|
296 | 1 | } |
|
297 | |||
298 | /** |
||
299 | * Plugin deactivation function. |
||
300 | * |
||
301 | * @internal |
||
302 | * @return void |
||
303 | */ |
||
304 | public function deactivate() { |
||
305 | flush_rewrite_rules(); |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Retrieve an absolute path within the Gravity Forms plugin directory. |
||
310 | * |
||
311 | * @api |
||
312 | * @since 2.0 |
||
313 | * |
||
314 | * @param string $path Optional. Append this extra path component. |
||
315 | * @return string The absolute path to the plugin directory. |
||
316 | */ |
||
317 | 69 | public function dir( $path = '' ) { |
|
318 | 69 | return GRAVITYVIEW_DIR . ltrim( $path, '/' ); |
|
319 | } |
||
320 | |||
321 | /** |
||
322 | * Retrieve a URL within the Gravity Forms plugin directory. |
||
323 | * |
||
324 | * @api |
||
325 | * @since 2.0 |
||
326 | * |
||
327 | * @param string $path Optional. Extra path appended to the URL. |
||
328 | * @return string The URL to this plugin, with trailing slash. |
||
329 | */ |
||
330 | 1 | public function url( $path = '/' ) { |
|
331 | 1 | return plugins_url( $path, $this->dir( 'gravityview.php' ) ); |
|
332 | } |
||
333 | |||
334 | /** |
||
335 | * Is everything compatible with this version of GravityView? |
||
336 | * |
||
337 | * @api |
||
338 | * @since 2.0 |
||
339 | * |
||
340 | * @return bool |
||
341 | */ |
||
342 | 2 | public function is_compatible() { |
|
343 | return |
||
344 | 2 | $this->is_compatible_php() |
|
345 | 2 | && $this->is_compatible_wordpress() |
|
346 | 2 | && $this->is_compatible_gravityforms(); |
|
347 | } |
||
348 | |||
349 | /** |
||
350 | * Is this version of GravityView compatible with the current version of PHP? |
||
351 | * |
||
352 | * @api |
||
353 | * @since 2.0 |
||
354 | * |
||
355 | * @return bool true if compatible, false otherwise. |
||
356 | */ |
||
357 | 2 | public function is_compatible_php() { |
|
358 | 2 | return version_compare( $this->get_php_version(), self::$min_php_version, '>=' ); |
|
359 | } |
||
360 | |||
361 | /** |
||
362 | * Is this version of GravityView compatible with the future required version of PHP? |
||
363 | * |
||
364 | * @api |
||
365 | * @since 2.0 |
||
366 | * |
||
367 | * @return bool true if compatible, false otherwise. |
||
368 | */ |
||
369 | public function is_compatible_future_php() { |
||
370 | return version_compare( $this->get_php_version(), self::$future_min_php_version, '>=' ); |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * Is this version of GravityView compatible with the current version of WordPress? |
||
375 | * |
||
376 | * @api |
||
377 | * @since 2.0 |
||
378 | * |
||
379 | * @param string $version Version to check against; otherwise uses GV_MIN_WP_VERSION |
||
380 | * |
||
381 | * @return bool true if compatible, false otherwise. |
||
382 | */ |
||
383 | 2 | public function is_compatible_wordpress( $version = null ) { |
|
384 | |||
385 | 2 | if( ! $version ) { |
|
386 | 2 | $version = self::$min_wp_version; |
|
387 | } |
||
388 | |||
389 | 2 | return version_compare( $this->get_wordpress_version(), $version, '>=' ); |
|
390 | } |
||
391 | |||
392 | /** |
||
393 | * Is this version of GravityView compatible with the current version of Gravity Forms? |
||
394 | * |
||
395 | * @api |
||
396 | * @since 2.0 |
||
397 | * |
||
398 | * @return bool true if compatible, false otherwise (or not active/installed). |
||
399 | */ |
||
400 | 2 | public function is_compatible_gravityforms() { |
|
401 | 2 | $version = $this->get_gravityforms_version(); |
|
402 | 2 | return $version ? version_compare( $version, self::$min_gf_version, '>=' ) : false; |
|
403 | } |
||
404 | |||
405 | /** |
||
406 | * Is this version of GravityView compatible with the future version of Gravity Forms? |
||
407 | * |
||
408 | * @api |
||
409 | * @since 2.0 |
||
410 | * |
||
411 | * @return bool true if compatible, false otherwise (or not active/installed). |
||
412 | */ |
||
413 | public function is_compatible_future_gravityforms() { |
||
414 | $version = $this->get_gravityforms_version(); |
||
415 | return $version ? version_compare( $version, self::$future_min_gf_version, '>=' ) : false; |
||
416 | } |
||
417 | |||
418 | /** |
||
419 | * Retrieve the current PHP version. |
||
420 | * |
||
421 | * Overridable with GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE during testing. |
||
422 | * |
||
423 | * @return string The version of PHP. |
||
424 | */ |
||
425 | 1 | private function get_php_version() { |
|
426 | 1 | return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] ) ? |
|
427 | 1 | $GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] : phpversion(); |
|
428 | } |
||
429 | |||
430 | /** |
||
431 | * Retrieve the current WordPress version. |
||
432 | * |
||
433 | * Overridable with GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE during testing. |
||
434 | * |
||
435 | * @return string The version of WordPress. |
||
436 | */ |
||
437 | 1 | private function get_wordpress_version() { |
|
438 | 1 | return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] ) ? |
|
439 | 1 | $GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] : $GLOBALS['wp_version']; |
|
440 | } |
||
441 | |||
442 | /** |
||
443 | * Retrieve the current Gravity Forms version. |
||
444 | * |
||
445 | * Overridable with GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE during testing. |
||
446 | * |
||
447 | * @return string|null The version of Gravity Forms or null if inactive. |
||
448 | */ |
||
449 | 1 | private function get_gravityforms_version() { |
|
450 | 1 | if ( ! class_exists( '\GFCommon' ) || ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_INACTIVE_OVERRIDE'] ) ) { |
|
451 | gravityview()->log->error( 'Gravity Forms is inactive or not installed.' ); |
||
452 | return null; |
||
453 | } |
||
454 | |||
455 | 1 | return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] ) ? |
|
456 | 1 | $GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] : \GFCommon::$version; |
|
457 | } |
||
458 | |||
459 | /** |
||
460 | * Feature support detection. |
||
461 | * |
||
462 | * @param string $feature Feature name. Check FEATURE_* class constants. |
||
463 | * |
||
464 | * @return boolean |
||
465 | */ |
||
466 | 83 | public function supports( $feature ) { |
|
467 | 83 | if ( ! is_null( $supports = apply_filters( "gravityview/plugin/feature/$feature", null ) ) ) { |
|
468 | return $supports; |
||
469 | } |
||
470 | |||
471 | switch ( $feature ): |
||
472 | 83 | case self::FEATURE_GFQUERY: |
|
473 | 83 | case self::FEATURE_JOINS: |
|
474 | 71 | return class_exists( '\GF_Query' ); |
|
475 | 83 | case self::FEATURE_REST: |
|
476 | 83 | return class_exists( '\WP_REST_Controller' ); |
|
477 | default: |
||
478 | return false; |
||
479 | endswitch; |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * Delete GravityView Views, settings, roles, caps, etc. |
||
484 | * |
||
485 | * @return void |
||
486 | */ |
||
487 | public function uninstall() { |
||
488 | global $wpdb; |
||
489 | |||
490 | $suppress = $wpdb->suppress_errors(); |
||
491 | |||
492 | /** |
||
493 | * Posts. |
||
494 | */ |
||
495 | $items = get_posts( array( |
||
496 | 'post_type' => 'gravityview', |
||
497 | 'post_status' => 'any', |
||
498 | 'numberposts' => -1, |
||
499 | 'fields' => 'ids' |
||
500 | ) ); |
||
501 | |||
502 | foreach ( $items as $item ) { |
||
503 | wp_delete_post( $item, true ); |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Meta. |
||
508 | */ |
||
509 | $tables = array(); |
||
510 | |||
511 | if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) ) { |
||
512 | $tables []= \GFFormsModel::get_entry_meta_table_name(); |
||
513 | } |
||
514 | $tables []= \GFFormsModel::get_lead_meta_table_name(); |
||
515 | |||
516 | foreach ( $tables as $meta_table ) { |
||
517 | $sql = " |
||
518 | DELETE FROM $meta_table |
||
519 | WHERE ( |
||
520 | `meta_key` = 'is_approved' |
||
521 | ); |
||
522 | "; |
||
523 | $wpdb->query( $sql ); |
||
524 | } |
||
525 | |||
526 | /** |
||
527 | * Notes. |
||
528 | */ |
||
529 | $tables = array(); |
||
530 | |||
531 | if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) && method_exists( 'GFFormsModel', 'get_entry_notes_table_name' ) ) { |
||
532 | $tables[] = \GFFormsModel::get_entry_notes_table_name(); |
||
533 | } |
||
534 | |||
535 | $tables[] = \GFFormsModel::get_lead_notes_table_name(); |
||
536 | |||
537 | $disapproved = __('Disapproved the Entry for GravityView', 'gravityview'); |
||
538 | $approved = __('Approved the Entry for GravityView', 'gravityview'); |
||
539 | |||
540 | $suppress = $wpdb->suppress_errors(); |
||
541 | foreach ( $tables as $notes_table ) { |
||
542 | $sql = $wpdb->prepare( " |
||
543 | DELETE FROM $notes_table |
||
544 | WHERE ( |
||
545 | `note_type` = 'gravityview' OR |
||
546 | `value` = %s OR |
||
547 | `value` = %s |
||
548 | ); |
||
549 | ", $approved, $disapproved ); |
||
550 | $wpdb->query( $sql ); |
||
551 | } |
||
552 | |||
553 | $wpdb->suppress_errors( $suppress ); |
||
554 | |||
555 | /** |
||
556 | * Capabilities. |
||
557 | */ |
||
558 | \GravityView_Roles_Capabilities::get_instance()->remove_caps(); |
||
559 | |||
560 | /** |
||
561 | * Options. |
||
562 | */ |
||
563 | delete_option( 'gravityview_cache_blacklist' ); |
||
564 | delete_option( 'gv_version_upgraded_from' ); |
||
565 | delete_transient( 'gravityview_edd-activate_valid' ); |
||
566 | delete_transient( 'gravityview_edd-deactivate_valid' ); |
||
567 | delete_transient( 'gravityview_dismissed_notices' ); |
||
568 | delete_site_transient( 'gravityview_related_plugins' ); |
||
569 | } |
||
570 | |||
571 | private function __clone() { } |
||
572 | |||
573 | private function __wakeup() { } |
||
574 | } |
||
575 |
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.