Complex classes like GravityView_Delete_Entry 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_Delete_Entry, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | final class GravityView_Delete_Entry { |
||
23 | |||
24 | static $file; |
||
25 | static $instance; |
||
26 | var $entry; |
||
27 | var $form; |
||
28 | var $view_id; |
||
29 | var $is_valid = NULL; |
||
30 | |||
31 | function __construct() { |
||
37 | |||
38 | /** |
||
39 | * @since 1.9.2 |
||
40 | */ |
||
41 | private function add_hooks() { |
||
42 | |||
43 | add_action( 'wp', array( $this, 'process_delete' ), 10000 ); |
||
44 | |||
45 | add_filter( 'gravityview_entry_default_fields', array( $this, 'add_default_field'), 10, 3 ); |
||
46 | |||
47 | add_action( 'gravityview_before', array( $this, 'maybe_display_message' ) ); |
||
48 | |||
49 | // For the Delete Entry Link, you don't want visible to all users. |
||
50 | add_filter( 'gravityview_field_visibility_caps', array( $this, 'modify_visibility_caps'), 10, 5 ); |
||
51 | |||
52 | // Modify the field options based on the name of the field type |
||
53 | add_filter( 'gravityview_template_delete_link_options', array( $this, 'delete_link_field_options' ), 10, 5 ); |
||
54 | |||
55 | // add template path to check for field |
||
56 | add_filter( 'gravityview_template_paths', array( $this, 'add_template_path' ) ); |
||
57 | |||
58 | add_action( 'gravityview/edit-entry/publishing-action/after', array( $this, 'add_delete_button'), 10, 4 ); |
||
59 | |||
60 | add_action ( 'gravityview/delete-entry/deleted', array( $this, 'process_connected_posts' ), 10, 2 ); |
||
61 | add_action ( 'gravityview/delete-entry/trashed', array( $this, 'process_connected_posts' ), 10, 2 ); |
||
62 | |||
63 | add_filter( 'gravityview/field/is_visible', array( $this, 'maybe_not_visible' ), 10, 3 ); |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * Return the instantiated class object |
||
68 | * |
||
69 | * @since 1.5.1 |
||
70 | * @return GravityView_Delete_Entry |
||
71 | */ |
||
72 | 22 | static function getInstance() { |
|
73 | |||
74 | 22 | if( empty( self::$instance ) ) { |
|
75 | self::$instance = new self; |
||
76 | } |
||
77 | |||
78 | 22 | return self::$instance; |
|
79 | } |
||
80 | |||
81 | /** |
||
82 | * Hide the field or not. |
||
83 | * |
||
84 | * For non-logged in users. |
||
85 | * For users that have no delete rights on any of the current entries. |
||
86 | * |
||
87 | * @param bool $visible Visible or not. |
||
88 | * @param \GF\Field $field The field. |
||
89 | * @param \GV\View $view The View context. |
||
90 | * |
||
91 | * @return bool |
||
92 | */ |
||
93 | 44 | public function maybe_not_visible( $visible, $field, $view ) { |
|
94 | 44 | if ( 'delete_link' !== $field->ID ) { |
|
95 | 44 | return $visible; |
|
96 | } |
||
97 | |||
98 | if ( ! is_user_logged_in() ) { |
||
99 | return false; |
||
100 | } |
||
101 | |||
102 | if ( ! $view ) { |
||
103 | return $visible; |
||
104 | } |
||
105 | |||
106 | static $visiblity_cache_for_view = array(); |
||
107 | |||
108 | if ( ! is_null( $result = \GV\Utils::get( $visiblity_cache_for_view, $view->ID, null ) ) ) { |
||
109 | return $result; |
||
110 | } |
||
111 | |||
112 | foreach ( $view->get_entries()->all() as $entry ) { |
||
113 | if ( self::check_user_cap_delete_entry( $entry->as_entry(), $field->as_configuration(), $view ) ) { |
||
114 | // At least one entry is deletable for this user |
||
115 | $visiblity_cache_for_view[ $view->ID ] = true; |
||
116 | return true; |
||
117 | } |
||
118 | } |
||
119 | |||
120 | $visiblity_cache_for_view[ $view->ID ] = false; |
||
121 | |||
122 | return false; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Include this extension templates path |
||
127 | * |
||
128 | * @since 1.5.1 |
||
129 | * @param array $file_paths List of template paths ordered |
||
130 | */ |
||
131 | 1 | function add_template_path( $file_paths ) { |
|
132 | |||
133 | // Index 100 is the default GravityView template path. |
||
134 | // Index 110 is Edit Entry link |
||
135 | 1 | $file_paths[ 115 ] = self::$file; |
|
136 | |||
137 | 1 | return $file_paths; |
|
138 | } |
||
139 | |||
140 | /** |
||
141 | * Add "Delete Link Text" setting to the edit_link field settings |
||
142 | * |
||
143 | * @since 1.5.1 |
||
144 | * @param [type] $field_options [description] |
||
145 | * @param [type] $template_id [description] |
||
146 | * @param [type] $field_id [description] |
||
147 | * @param [type] $context [description] |
||
148 | * @param [type] $input_type [description] |
||
149 | * @return [type] [description] |
||
150 | */ |
||
151 | function delete_link_field_options( $field_options, $template_id, $field_id, $context, $input_type ) { |
||
152 | |||
153 | // Always a link, never a filter |
||
154 | unset( $field_options['show_as_link'], $field_options['search_filter'] ); |
||
155 | |||
156 | // Delete Entry link should only appear to visitors capable of editing entries |
||
157 | unset( $field_options['only_loggedin'], $field_options['only_loggedin_cap'] ); |
||
158 | |||
159 | $add_option['delete_link'] = array( |
||
160 | 'type' => 'text', |
||
161 | 'label' => __( 'Delete Link Text', 'gravityview' ), |
||
162 | 'desc' => NULL, |
||
163 | 'value' => __('Delete Entry', 'gravityview'), |
||
164 | 'merge_tags' => true, |
||
165 | ); |
||
166 | |||
167 | $field_options['allow_edit_cap'] = array( |
||
168 | 'type' => 'select', |
||
169 | 'label' => __( 'Allow the following users to delete the entry:', 'gravityview' ), |
||
170 | 'choices' => GravityView_Render_Settings::get_cap_choices( $template_id, $field_id, $context, $input_type ), |
||
171 | 'tooltip' => 'allow_edit_cap', |
||
172 | 'class' => 'widefat', |
||
173 | 'value' => 'read', // Default: entry creator |
||
174 | ); |
||
175 | |||
176 | |||
177 | return array_merge( $add_option, $field_options ); |
||
178 | } |
||
179 | |||
180 | |||
181 | /** |
||
182 | * Add Edit Link as a default field, outside those set in the Gravity Form form |
||
183 | * |
||
184 | * @since 1.5.1 |
||
185 | * @param array $entry_default_fields Existing fields |
||
186 | * @param string|array $form form_ID or form object |
||
187 | * @param string $zone Either 'single', 'directory', 'edit', 'header', 'footer' |
||
188 | */ |
||
189 | function add_default_field( $entry_default_fields, $form = array(), $zone = '' ) { |
||
190 | |||
191 | if( 'edit' !== $zone ) { |
||
192 | $entry_default_fields['delete_link'] = array( |
||
193 | 'label' => __( 'Delete Entry', 'gravityview' ), |
||
194 | 'type' => 'delete_link', |
||
195 | 'desc' => __( 'A link to delete the entry. Respects the Delete Entry permissions.', 'gravityview' ), |
||
196 | ); |
||
197 | } |
||
198 | |||
199 | return $entry_default_fields; |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Add Delete Entry Link to the Add Field dialog |
||
204 | * @since 1.5.1 |
||
205 | * @param array $available_fields |
||
206 | */ |
||
207 | function add_available_field( $available_fields = array() ) { |
||
208 | |||
209 | $available_fields['delete_link'] = array( |
||
210 | 'label_text' => __( 'Delete Entry', 'gravityview' ), |
||
211 | 'field_id' => 'delete_link', |
||
212 | 'label_type' => 'field', |
||
213 | 'input_type' => 'delete_link', |
||
214 | 'field_options' => NULL |
||
215 | ); |
||
216 | |||
217 | return $available_fields; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * Change wording for the Edit context to read Entry Creator |
||
222 | * |
||
223 | * @since 1.5.1 |
||
224 | * @param array $visibility_caps Array of capabilities to display in field dropdown. |
||
225 | * @param string $field_type Type of field options to render (`field` or `widget`) |
||
226 | * @param string $template_id Table slug |
||
227 | * @param float $field_id GF Field ID - Example: `3`, `5.2`, `entry_link`, `created_by` |
||
228 | * @param string $context What context are we in? Example: `single` or `directory` |
||
229 | * @param string $input_type (textarea, list, select, etc.) |
||
230 | * @return array Array of field options with `label`, `value`, `type`, `default` keys |
||
231 | */ |
||
232 | public function modify_visibility_caps( $visibility_caps = array(), $template_id = '', $field_id = '', $context = '', $input_type = '' ) { |
||
233 | |||
234 | $caps = $visibility_caps; |
||
235 | |||
236 | // If we're configuring fields in the edit context, we want a limited selection |
||
237 | if( $field_id === 'delete_link' ) { |
||
238 | |||
239 | // Remove other built-in caps. |
||
240 | unset( $caps['publish_posts'], $caps['gravityforms_view_entries'], $caps['delete_others_posts'] ); |
||
241 | |||
242 | $caps['read'] = _x('Entry Creator', 'User capability', 'gravityview'); |
||
243 | } |
||
244 | |||
245 | return $caps; |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * Make sure there's an entry |
||
250 | * |
||
251 | * @since 1.5.1 |
||
252 | * @param [type] $entry [description] |
||
253 | */ |
||
254 | 22 | function set_entry( $entry = null ) { |
|
257 | |||
258 | /** |
||
259 | * Generate a consistent nonce key based on the Entry ID |
||
260 | * |
||
261 | * @since 1.5.1 |
||
262 | * @param int $entry_id Entry ID |
||
263 | * @return string Key used to validate request |
||
264 | */ |
||
265 | public static function get_nonce_key( $entry_id ) { |
||
268 | |||
269 | |||
270 | /** |
||
271 | * Generate a nonce link with the base URL of the current View embed |
||
272 | * |
||
273 | * We don't want to link to the single entry, because when deleted, there would be nothing to return to. |
||
274 | * |
||
275 | * @since 1.5.1 |
||
276 | * @param array $entry Gravity Forms entry array |
||
277 | * @param int $view_id The View id. Not optional since 2.0 |
||
278 | * @return string|null If directory link is valid, the URL to process the delete request. Otherwise, `NULL`. |
||
279 | */ |
||
280 | 22 | public static function get_delete_link( $entry, $view_id = 0, $post_id = null ) { |
|
309 | |||
310 | |||
311 | /** |
||
312 | * Add a Delete button to the #publishing-action section of the Delete Entry form |
||
313 | * |
||
314 | * @since 1.5.1 |
||
315 | * @since 2.0.13 Added $post_id |
||
316 | * |
||
317 | * @param array $form Gravity Forms form array |
||
318 | * @param array $entry Gravity Forms entry array |
||
319 | * @param int $view_id GravityView View ID |
||
320 | * @param int $post_id Current post ID. May be same as View ID. |
||
321 | * |
||
322 | * @return void |
||
323 | */ |
||
324 | 22 | public function add_delete_button( $form = array(), $entry = array(), $view_id = null, $post_id = null ) { |
|
351 | |||
352 | /** |
||
353 | * Handle the deletion request, if $_GET['action'] is set to "delete" |
||
354 | * |
||
355 | * 1. Check referrer validity |
||
356 | * 2. Make sure there's an entry with the slug of $_GET['entry_id'] |
||
357 | * 3. If so, attempt to delete the entry. If not, set the error status |
||
358 | * 4. Remove `action=delete` from the URL |
||
359 | * 5. Redirect to the page using `wp_safe_redirect()` |
||
360 | * |
||
361 | * @since 1.5.1 |
||
362 | * @uses wp_safe_redirect() |
||
363 | * @return void |
||
364 | */ |
||
365 | 2 | function process_delete() { |
|
437 | |||
438 | /** |
||
439 | * Delete mode: permanently delete, or move to trash? |
||
440 | * |
||
441 | * @return string `delete` or `trash` |
||
442 | */ |
||
443 | private function get_delete_mode() { |
||
454 | |||
455 | /** |
||
456 | * @since 1.13.1 |
||
457 | * @see GFAPI::delete_entry() |
||
458 | * @return WP_Error|boolean GFAPI::delete_entry() returns a WP_Error on error |
||
459 | */ |
||
460 | private function delete_or_trash_entry( $entry ) { |
||
514 | |||
515 | /** |
||
516 | * Delete or trash a post connected to an entry |
||
517 | * |
||
518 | * @since 1.17 |
||
519 | * |
||
520 | * @param int $entry_id ID of entry being deleted/trashed |
||
521 | * @param array $entry Array of the entry being deleted/trashed |
||
522 | */ |
||
523 | public function process_connected_posts( $entry_id = 0, $entry = array() ) { |
||
555 | |||
556 | /** |
||
557 | * Is the current nonce valid for editing the entry? |
||
558 | * |
||
559 | * @since 1.5.1 |
||
560 | * @return boolean |
||
561 | */ |
||
562 | public function verify_nonce() { |
||
584 | |||
585 | /** |
||
586 | * Get the onclick attribute for the confirm dialogs that warns users before they delete an entry |
||
587 | * |
||
588 | * @since 1.5.1 |
||
589 | * @return string HTML `onclick` attribute |
||
590 | */ |
||
591 | 22 | public static function get_confirm_dialog() { |
|
603 | |||
604 | /** |
||
605 | * Check if the user can edit the entry |
||
606 | * |
||
607 | * - Is the nonce valid? |
||
608 | * - Does the user have the right caps for the entry |
||
609 | * - Is the entry in the trash? |
||
610 | * |
||
611 | * @since 1.5.1 |
||
612 | * @param array $entry Gravity Forms entry array |
||
613 | * @return boolean|WP_Error True: can edit form. WP_Error: nope. |
||
614 | */ |
||
615 | function user_can_delete_entry( $entry = array(), $view_id = null ) { |
||
644 | |||
645 | |||
646 | /** |
||
647 | * checks if user has permissions to view the link or delete a specific entry |
||
648 | * |
||
649 | * @since 1.5.1 |
||
650 | * @since 1.15 Added `$view_id` param |
||
651 | * |
||
652 | * @param array $entry Gravity Forms entry array |
||
653 | * @param array $field Field settings (optional) |
||
654 | * @param int|\GV\View $view Pass a View ID to check caps against. If not set, check against current View (@deprecated no longer optional) |
||
655 | * @return bool |
||
656 | */ |
||
657 | 23 | public static function check_user_cap_delete_entry( $entry, $field = array(), $view = 0 ) { |
|
734 | |||
735 | |||
736 | /** |
||
737 | * After processing delete entry, the user will be redirected to the referring View or embedded post/page. Display a message on redirection. |
||
738 | * |
||
739 | * If success, there will be `status` URL parameters `status=>success` |
||
740 | * If an error, there will be `status` and `message` URL parameters `status=>error&message=example` |
||
741 | * |
||
742 | * @since 1.15.2 Only show message when the URL parameter's View ID matches the current View ID |
||
743 | * @since 1.5.1 |
||
744 | * |
||
745 | * @param int $current_view_id The ID of the View being rendered |
||
746 | * @return void |
||
747 | */ |
||
748 | 37 | public function maybe_display_message( $current_view_id = 0 ) { |
|
760 | |||
761 | public function display_message() { |
||
798 | |||
799 | |||
800 | } // end class |
||
801 | |||
804 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.