Complex classes like GravityView_Settings 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 GravityView_Settings, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class GravityView_Settings extends GFAddOn { |
||
12 | |||
13 | /** |
||
14 | * @var string Version number of the Add-On |
||
15 | */ |
||
16 | protected $_version = GravityView_Plugin::version; |
||
17 | /** |
||
18 | * @var string Gravity Forms minimum version requirement |
||
19 | */ |
||
20 | protected $_min_gravityforms_version = GV_MIN_GF_VERSION; |
||
21 | |||
22 | /** |
||
23 | * @var string Title of the plugin to be used on the settings page, form settings and plugins page. Example: 'Gravity Forms MailChimp Add-On' |
||
24 | */ |
||
25 | protected $_title = 'GravityView'; |
||
26 | |||
27 | /** |
||
28 | * @var string Short version of the plugin title to be used on menus and other places where a less verbose string is useful. Example: 'MailChimp' |
||
29 | */ |
||
30 | protected $_short_title = 'GravityView'; |
||
31 | |||
32 | /** |
||
33 | * @var string URL-friendly identifier used for form settings, add-on settings, text domain localization... |
||
34 | */ |
||
35 | protected $_slug = 'gravityview'; |
||
36 | |||
37 | /** |
||
38 | * @var string|array A string or an array of capabilities or roles that can uninstall the plugin |
||
39 | */ |
||
40 | protected $_capabilities_uninstall = 'gravityview_uninstall'; |
||
41 | |||
42 | /** |
||
43 | * @var string|array A string or an array of capabilities or roles that have access to the settings page |
||
44 | */ |
||
45 | protected $_capabilities_app_settings = 'gravityview_view_settings'; |
||
46 | |||
47 | /** |
||
48 | * @var string|array A string or an array of capabilities or roles that have access to the settings page |
||
49 | */ |
||
50 | protected $_capabilities_app_menu = 'gravityview_view_settings'; |
||
51 | |||
52 | /** |
||
53 | * @var string The hook suffix for the app menu |
||
54 | */ |
||
55 | public $app_hook_suffix = 'gravityview'; |
||
56 | |||
57 | /** |
||
58 | * @var GV_License_Handler Process license validation |
||
59 | */ |
||
60 | private $License_Handler; |
||
61 | |||
62 | /** |
||
63 | * @var GravityView_Settings |
||
64 | */ |
||
65 | private static $instance; |
||
66 | |||
67 | /** |
||
68 | * We're not able to set the __construct() method to private because we're extending the GFAddon class, so |
||
69 | * we fake it. When called using `new GravityView_Settings`, it will return get_instance() instead. We pass |
||
70 | * 'get_instance' as a test string. |
||
71 | * |
||
72 | * @see get_instance() |
||
73 | * |
||
74 | * @param string $prevent_multiple_instances |
||
75 | */ |
||
76 | public function __construct( $prevent_multiple_instances = '' ) { |
||
84 | |||
85 | /** |
||
86 | * @return GravityView_Settings |
||
87 | */ |
||
88 | public static function get_instance() { |
||
96 | |||
97 | /** |
||
98 | * Prevent uninstall tab from being shown by returning false for the uninstall capability check. Otherwise: |
||
99 | * @inheritDoc |
||
100 | * |
||
101 | * @hack |
||
102 | * |
||
103 | * @param array|string $caps |
||
104 | * |
||
105 | * @return bool |
||
106 | */ |
||
107 | public function current_user_can_any( $caps ) { |
||
115 | |||
116 | public function uninstall_warning_message() { |
||
123 | |||
124 | /** |
||
125 | * Uninstall all traces of GravityView |
||
126 | * |
||
127 | * Note: method is public because parent method is public |
||
128 | * |
||
129 | * @return bool |
||
130 | */ |
||
131 | 1 | public function uninstall() { |
|
148 | |||
149 | /** |
||
150 | * Get an array of reasons why the plugin might be uninstalled |
||
151 | * |
||
152 | * @since 1.17.5 |
||
153 | * |
||
154 | * @return array Array of reasons with the label and followup questions for each uninstall reason |
||
155 | */ |
||
156 | private function get_uninstall_reasons() { |
||
181 | |||
182 | /** |
||
183 | * Display a feedback form when the plugin is uninstalled |
||
184 | * |
||
185 | * @since 1.17.5 |
||
186 | * |
||
187 | * @return string HTML of the uninstallation form |
||
188 | */ |
||
189 | public function uninstall_form() { |
||
190 | ob_start(); |
||
191 | |||
192 | $user = wp_get_current_user(); |
||
193 | ?> |
||
194 | <style> |
||
195 | #gv-reason-details { |
||
196 | min-height: 100px; |
||
197 | } |
||
198 | .number-scale label { |
||
199 | border: 1px solid #cccccc; |
||
200 | padding: .5em .75em; |
||
201 | margin: .1em; |
||
202 | } |
||
203 | #gv-uninstall-thanks p { |
||
204 | font-size: 1.2em; |
||
205 | } |
||
206 | .scale-description ul { |
||
207 | margin-bottom: 0; |
||
208 | padding-bottom: 0; |
||
209 | } |
||
210 | .scale-description p.description { |
||
211 | margin-top: 0!important; |
||
212 | padding-top: 0!important; |
||
213 | } |
||
214 | .gv-form-field-wrapper { |
||
215 | margin-top: 30px; |
||
216 | } |
||
217 | </style> |
||
218 | |||
219 | <div class="gv-uninstall-form-wrapper" style="font-size: 110%; padding: 15px 0;"> |
||
220 | <script> |
||
221 | jQuery(function( $ ) { |
||
222 | $('#gv-uninstall-feedback').on( 'change', function( e ) { |
||
223 | |||
224 | if( ! $( e.target ).is(':input') ) { |
||
225 | return; |
||
226 | } |
||
227 | var $textarea = $('.gv-followup').find('textarea'); |
||
228 | var followup_text = $( e.target ).attr( 'data-followup' ); |
||
229 | if( ! followup_text ) { |
||
230 | followup_text = $textarea.attr('data-default'); |
||
231 | } |
||
232 | |||
233 | $textarea.attr( 'placeholder', followup_text ); |
||
234 | |||
235 | }).on( 'submit', function( e ) { |
||
236 | e.preventDefault(); |
||
237 | |||
238 | $.post( $( this ).attr( 'action' ), $( this ).serialize() ) |
||
239 | .done( function( data ) { |
||
240 | if( 'success' !== data.status ) { |
||
241 | gv_feedback_append_error_message(); |
||
242 | } else { |
||
243 | $( '#gv-uninstall-thanks' ).fadeIn(); |
||
244 | } |
||
245 | }) |
||
246 | .fail( function( data ) { |
||
247 | gv_feedback_append_error_message(); |
||
248 | }) |
||
249 | .always( function() { |
||
250 | $( e.target ).remove(); |
||
251 | }); |
||
252 | |||
253 | return false; |
||
254 | }); |
||
255 | |||
256 | function gv_feedback_append_error_message() { |
||
257 | $('#gv-uninstall-thanks').append('<div class="notice error"><?php echo esc_js( __('There was an error sharing your feedback. Sorry! Please email us at [email protected]', 'gravityview' ) ) ?></div>'); |
||
258 | } |
||
259 | }); |
||
260 | </script> |
||
261 | |||
262 | <form id="gv-uninstall-feedback" method="post" action="https://hooks.zapier.com/hooks/catch/28670/6haevn/"> |
||
263 | <h2><?php esc_html_e( 'Why did you uninstall GravityView?', 'gravityview' ); ?></h2> |
||
264 | <ul> |
||
265 | <?php |
||
266 | $reasons = $this->get_uninstall_reasons(); |
||
267 | foreach ( $reasons as $reason ) { |
||
268 | printf( '<li><label><input name="reason" type="radio" value="other" data-followup="%s"> %s</label></li>', rgar( $reason, 'followup' ), rgar( $reason, 'label' ) ); |
||
269 | } |
||
270 | ?> |
||
271 | </ul> |
||
272 | <div class="gv-followup widefat"> |
||
273 | <p><strong><label for="gv-reason-details"><?php esc_html_e( 'Comments', 'gravityview' ); ?></label></strong></p> |
||
274 | <textarea id="gv-reason-details" name="reason_details" data-default="<?php esc_attr_e('Please share your thoughts about GravityView', 'gravityview') ?>" placeholder="<?php esc_attr_e('Please share your thoughts about GravityView', 'gravityview'); ?>" class="large-text"></textarea> |
||
275 | </div> |
||
276 | <div class="scale-description"> |
||
277 | <p><strong><?php esc_html_e('How likely are you to recommend GravityView?', 'gravityview' ); ?></strong></p> |
||
278 | <ul class="inline"> |
||
279 | <?php |
||
280 | $i = 0; |
||
281 | while( $i < 11 ) { |
||
282 | echo '<li class="inline number-scale"><label><input name="likely_to_refer" id="likely_to_refer_'.$i.'" value="'.$i.'" type="radio"> '.$i.'</label></li>'; |
||
283 | $i++; |
||
284 | } |
||
285 | ?> |
||
286 | </ul> |
||
287 | <p class="description"><?php printf( esc_html_x( '%s ("Not at all likely") to %s ("Extremely likely")', 'A scale from 0 (bad) to 10 (good)', 'gravityview' ), '<label for="likely_to_refer_0"><code>0</code></label>', '<label for="likely_to_refer_10"><code>10</code></label>' ); ?></p> |
||
288 | </div> |
||
289 | |||
290 | <div class="gv-form-field-wrapper"> |
||
291 | <label><input type="checkbox" class="checkbox" name="follow_up_with_me" value="1" /> <?php esc_html_e('Please follow up with me about my feedback', 'gravityview'); ?></label> |
||
292 | </div> |
||
293 | |||
294 | <div class="submit"> |
||
295 | <input type="hidden" name="siteurl" value="<?php echo esc_url( get_bloginfo( 'url' ) ); ?>" /> |
||
296 | <input type="hidden" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" /> |
||
297 | <input type="hidden" name="display_name" value="<?php echo esc_attr( $user->display_name ); ?>" /> |
||
298 | <input type="submit" value="<?php esc_html_e( 'Send Us Your Feedback', 'gravityview' ); ?>" class="button button-primary button-hero" /> |
||
299 | </div> |
||
300 | </form> |
||
301 | |||
302 | <div id="gv-uninstall-thanks" class="notice notice-large notice-updated below-h2" style="display:none;"> |
||
303 | <h3 class="notice-title"><?php esc_html_e( 'Thank you for using GravityView!', 'gravityview' ); ?></h3> |
||
304 | <p><?php echo gravityview_get_floaty(); ?> |
||
305 | <?php echo make_clickable( esc_html__('Your feedback helps us improve GravityView. If you have any questions or comments, email us: [email protected]', 'gravityview' ) ); ?> |
||
306 | </p> |
||
307 | <div class="wp-clearfix"></div> |
||
308 | </div> |
||
309 | </div> |
||
310 | <?php |
||
311 | $form = ob_get_clean(); |
||
312 | |||
313 | return $form; |
||
314 | } |
||
315 | |||
316 | |||
317 | public function app_settings_uninstall_tab() { |
||
318 | |||
319 | if ( $this->maybe_uninstall() ) { |
||
320 | |||
321 | parent::app_settings_uninstall_tab(); |
||
322 | |||
323 | return; |
||
324 | } |
||
325 | |||
326 | if ( ! ( $this->current_user_can_any( $this->_capabilities_uninstall ) && ( ! function_exists( 'is_multisite' ) || ! is_multisite() || is_super_admin() ) ) ) { |
||
327 | return; |
||
328 | } |
||
329 | |||
330 | ?> |
||
331 | <script> |
||
332 | jQuery(document).on('click', 'a[rel="gv-uninstall-wrapper"]', function( e ) { |
||
333 | e.preventDefault(); |
||
334 | jQuery( '#gv-uninstall-wrapper' ).slideToggle(); |
||
335 | }); |
||
336 | </script> |
||
337 | |||
338 | <a rel="gv-uninstall-wrapper" href="#gv-uninstall-wrapper" class="button button-large alignright button-danger">Uninstall GravityView</a> |
||
339 | |||
340 | <div id="gv-uninstall-wrapper"> |
||
341 | <form action="" method="post"> |
||
342 | <?php wp_nonce_field( 'uninstall', 'gf_addon_uninstall' ) ?> |
||
343 | <div class="delete-alert alert_red"> |
||
344 | |||
345 | <h3> |
||
346 | <i class="fa fa-exclamation-triangle gf_invalid"></i> <?php esc_html_e( 'Delete all GravityView content and settings', 'gravityview' ); ?> |
||
347 | </h3> |
||
348 | |||
349 | <div class="gf_delete_notice"> |
||
350 | <?php echo $this->uninstall_warning_message() ?> |
||
351 | </div> |
||
352 | |||
353 | <?php |
||
354 | echo '<input type="submit" name="uninstall" value="' . sprintf( esc_attr__( 'Uninstall %s', 'gravityview' ), $this->get_short_title() ) . '" class="button button-hero" onclick="return confirm(\'' . esc_js( $this->uninstall_confirm_message() ) . '\');" onkeypress="return confirm(\'' . esc_js( $this->uninstall_confirm_message() ) . '\');"/>'; |
||
355 | ?> |
||
356 | |||
357 | </div> |
||
358 | </form> |
||
359 | </div> |
||
360 | <?php |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * Run actions when initializing admin |
||
365 | * |
||
366 | * Triggers the license key notice |
||
367 | * |
||
368 | * @return void |
||
369 | */ |
||
370 | function init_admin() { |
||
383 | |||
384 | /** |
||
385 | * Change the settings page header title to "GravityView" |
||
386 | * |
||
387 | * @param $setting_tabs |
||
388 | * |
||
389 | * @return array |
||
390 | */ |
||
391 | public function modify_app_settings_menu_title( $setting_tabs ) { |
||
397 | |||
398 | /** |
||
399 | * Load license handler in admin-ajax.php |
||
400 | */ |
||
401 | public function init_ajax() { |
||
404 | |||
405 | /** |
||
406 | * Make sure the license handler is available |
||
407 | */ |
||
408 | private function _load_license_handler() { |
||
418 | |||
419 | /** |
||
420 | * Display a notice if the plugin is inactive. |
||
421 | * @return void |
||
422 | */ |
||
423 | function license_key_notice() { |
||
488 | |||
489 | /** |
||
490 | * Add tooltip script to app settings page. Not enqueued by Gravity Forms for some reason. |
||
491 | * |
||
492 | * @since 1.21.5 |
||
493 | * |
||
494 | * @see GFAddOn::scripts() |
||
495 | * |
||
496 | * @return array Array of scripts |
||
497 | */ |
||
498 | 3 | public function scripts() { |
|
512 | |||
513 | /** |
||
514 | * Register styles in the app admin page |
||
515 | * @return array |
||
516 | */ |
||
517 | 3 | public function styles() { |
|
540 | |||
541 | /** |
||
542 | * Add global Settings page for Multisite |
||
543 | * @since 1.7.6 |
||
544 | * @return void |
||
545 | */ |
||
546 | public function add_network_menu() { |
||
551 | |||
552 | /** |
||
553 | * Add Settings link to GravityView menu |
||
554 | * @return void |
||
555 | */ |
||
556 | public function create_app_menu() { |
||
577 | |||
578 | /** |
||
579 | * The Settings title |
||
580 | * @return string |
||
581 | */ |
||
582 | public function app_settings_title() { |
||
585 | |||
586 | /** |
||
587 | * Prevent displaying of any icon |
||
588 | * @return string |
||
589 | */ |
||
590 | public function app_settings_icon() { |
||
593 | |||
594 | public function app_settings_tab() { |
||
601 | |||
602 | /** |
||
603 | * Make protected public |
||
604 | * @inheritDoc |
||
605 | * @access public |
||
606 | */ |
||
607 | public function get_app_setting( $setting_name ) { |
||
622 | |||
623 | /** |
||
624 | * Returns the currently saved plugin settings |
||
625 | * |
||
626 | * Different from GFAddon in two ways: |
||
627 | * 1. Makes protected method public |
||
628 | * 2. Use default settings if the original settings don't exist |
||
629 | * |
||
630 | * @access public |
||
631 | * |
||
632 | * @return array |
||
633 | */ |
||
634 | public function get_app_settings() { |
||
637 | |||
638 | |||
639 | /** |
||
640 | * Updates app settings with the provided settings |
||
641 | * |
||
642 | * Same as the GVAddon, except it returns the value from update_option() |
||
643 | * |
||
644 | * @param array $settings - App settings to be saved |
||
645 | * |
||
646 | * @return boolean False if value was not updated and true if value was updated. |
||
647 | */ |
||
648 | public function update_app_settings( $settings ) { |
||
651 | |||
652 | /** |
||
653 | * Make protected public |
||
654 | * @inheritDoc |
||
655 | * @access public |
||
656 | */ |
||
657 | public function set_field_error( $field, $error_message = '' ) { |
||
660 | |||
661 | /** |
||
662 | * Register the settings field for the EDD License field type |
||
663 | * @param array $field |
||
664 | * @param bool $echo Whether to echo the |
||
665 | * |
||
666 | * @return string |
||
667 | */ |
||
668 | protected function settings_edd_license( $field, $echo = true ) { |
||
682 | |||
683 | /** |
||
684 | * Allow public access to the GV_License_Handler class |
||
685 | * @since 1.7.4 |
||
686 | * |
||
687 | * @return GV_License_Handler |
||
688 | */ |
||
689 | public function get_license_handler() { |
||
692 | |||
693 | /*** |
||
694 | * Renders the save button for settings pages |
||
695 | * |
||
696 | * @param array $field - Field array containing the configuration options of this field |
||
697 | * @param bool $echo = true - true to echo the output to the screen, false to simply return the contents as a string |
||
698 | * |
||
699 | * @return string The HTML |
||
700 | */ |
||
701 | public function settings_submit( $field, $echo = true ) { |
||
732 | |||
733 | /** |
||
734 | * Allow customizing the Save field parameters |
||
735 | * |
||
736 | * @param array $field |
||
737 | * @param bool $echo |
||
738 | * |
||
739 | * @return string |
||
740 | */ |
||
741 | public function settings_save( $field, $echo = true ) { |
||
762 | |||
763 | |||
764 | /** |
||
765 | * Keep GravityView styling for `$field['description']`, even though Gravity Forms added support for it |
||
766 | * |
||
767 | * Converts `$field['description']` to `$field['gv_description']` |
||
768 | * Converts `$field['subtitle']` to `$field['description']` |
||
769 | * |
||
770 | * @see GravityView_Settings::single_setting_label Converts `gv_description` back to `description` |
||
771 | * @see http://share.gravityview.co/P28uGp/2OIRKxog for image that shows subtitle vs description |
||
772 | * |
||
773 | * @since 1.21.5.2 |
||
774 | * |
||
775 | * @param array $field |
||
776 | * |
||
777 | * @return void |
||
778 | */ |
||
779 | public function single_setting_row( $field ) { |
||
786 | |||
787 | /** |
||
788 | * The same as the parent, except added support for field descriptions |
||
789 | * @inheritDoc |
||
790 | * @param $field array |
||
791 | */ |
||
792 | public function single_setting_label( $field ) { |
||
800 | |||
801 | /** |
||
802 | * Get the default settings for the plugin |
||
803 | * |
||
804 | * Merges previous settings created when using the Redux Framework |
||
805 | * |
||
806 | * @return array Settings with defaults set |
||
807 | */ |
||
808 | private function get_default_settings() { |
||
824 | |||
825 | /** |
||
826 | * Check for the `gravityview_edit_settings` capability before saving plugin settings. |
||
827 | * Gravity Forms says you're able to edit if you're able to view settings. GravityView allows two different permissions. |
||
828 | * |
||
829 | * @since 1.15 |
||
830 | * @return void |
||
831 | */ |
||
832 | public function maybe_save_app_settings() { |
||
844 | |||
845 | /** |
||
846 | * When the settings are saved, make sure the license key matches the previously activated key |
||
847 | * |
||
848 | * @return array settings from parent::get_posted_settings(), with `license_key_response` and `license_key_status` potentially unset |
||
849 | */ |
||
850 | public function get_posted_settings() { |
||
868 | |||
869 | /** |
||
870 | * Gets the required indicator |
||
871 | * Gets the markup of the required indicator symbol to highlight fields that are required |
||
872 | * |
||
873 | * @param $field - The field meta. |
||
874 | * |
||
875 | * @return string - Returns markup of the required indicator symbol |
||
876 | */ |
||
877 | public function get_required_indicator( $field ) { |
||
880 | |||
881 | /** |
||
882 | * Specify the settings fields to be rendered on the plugin settings page |
||
883 | * @return array |
||
884 | */ |
||
885 | public function app_settings_fields() { |
||
1048 | |||
1049 | /** |
||
1050 | * Get the setting for GravityView by name |
||
1051 | * |
||
1052 | * @param string $key Option key to fetch |
||
1053 | * |
||
1054 | * @return mixed |
||
1055 | */ |
||
1056 | static public function getSetting( $key ) { |
||
1059 | |||
1060 | } |
||
1061 | |||
1062 | GravityView_Settings::get_instance(); |
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.