Complex classes like Give_License 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 Give_License, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class Give_License { |
||
21 | |||
22 | /** |
||
23 | * File |
||
24 | * |
||
25 | * @access private |
||
26 | * |
||
27 | * @var string |
||
28 | */ |
||
29 | private $file; |
||
30 | |||
31 | /** |
||
32 | * License |
||
33 | * |
||
34 | * @access private |
||
35 | * |
||
36 | * @var string |
||
37 | */ |
||
38 | private $license; |
||
39 | |||
40 | /** |
||
41 | * Item name |
||
42 | * |
||
43 | * @access private |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | private $item_name; |
||
48 | |||
49 | /** |
||
50 | * License Information object. |
||
51 | * |
||
52 | * @access private |
||
53 | * |
||
54 | * @var object |
||
55 | */ |
||
56 | private $license_data; |
||
57 | |||
58 | /** |
||
59 | * Item shortname |
||
60 | * |
||
61 | * @access private |
||
62 | * |
||
63 | * @var string |
||
64 | */ |
||
65 | private $item_shortname; |
||
66 | |||
67 | /** |
||
68 | * Version |
||
69 | * |
||
70 | * @access private |
||
71 | * |
||
72 | * @var string |
||
73 | */ |
||
74 | private $version; |
||
75 | |||
76 | /** |
||
77 | * Author |
||
78 | * |
||
79 | * @access private |
||
80 | * |
||
81 | * @var string |
||
82 | */ |
||
83 | private $author; |
||
84 | |||
85 | /** |
||
86 | * API URL |
||
87 | * |
||
88 | * @access private |
||
89 | * |
||
90 | * @var string |
||
91 | */ |
||
92 | private $api_url = 'https://givewp.com/edd-sl-api/'; |
||
93 | private $account_url = 'http://givewp.com/my-account/'; |
||
94 | private $checkout_url = 'http://givewp.com/checkout/'; |
||
95 | |||
96 | /** |
||
97 | * Class Constructor |
||
98 | * |
||
99 | * Set up the Give License Class. |
||
100 | * |
||
101 | * @access public |
||
102 | * @param string $_file |
||
103 | * @param string $_item_name |
||
104 | * @param string $_version |
||
105 | * @param string $_author |
||
106 | * @param string $_optname |
||
107 | * @param string $_api_url |
||
108 | * @param string $_checkout_url |
||
109 | * @param string $_account_url |
||
110 | */ |
||
111 | public function __construct( $_file, $_item_name, $_version, $_author, $_optname = null, $_api_url = null, $_checkout_url = null, $_account_url = null ) { |
||
130 | |||
131 | /** |
||
132 | * Includes |
||
133 | * |
||
134 | * Include the updater class. |
||
135 | * |
||
136 | * @access private |
||
137 | * |
||
138 | * @return void |
||
139 | */ |
||
140 | private function includes() { |
||
145 | |||
146 | /** |
||
147 | * Hooks |
||
148 | * |
||
149 | * Setup license hooks. |
||
150 | * |
||
151 | * @access private |
||
152 | * |
||
153 | * @return void |
||
154 | */ |
||
155 | private function hooks() { |
||
156 | |||
157 | // Register settings |
||
158 | add_filter( 'give_settings_licenses', array( $this, 'settings' ), 1 ); |
||
159 | |||
160 | // Activate license key on settings save |
||
161 | add_action( 'admin_init', array( $this, 'activate_license' ) ); |
||
162 | |||
163 | // Deactivate license key |
||
164 | add_action( 'admin_init', array( $this, 'deactivate_license' ) ); |
||
165 | |||
166 | // Updater |
||
167 | add_action( 'admin_init', array( $this, 'auto_updater' ), 0 ); |
||
168 | |||
169 | add_action( 'admin_notices', array( $this, 'notices' ) ); |
||
170 | |||
171 | // Check license weekly. |
||
172 | add_action( 'give_weekly_scheduled_events', array( $this, 'weekly_license_check' ) ); |
||
173 | |||
174 | // Check subscription weekly. |
||
175 | add_action( 'give_weekly_scheduled_events', array( $this, 'weekly_subscription_check' ) ); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Auto Updater |
||
180 | * |
||
181 | * @access private |
||
182 | * |
||
183 | * @return bool |
||
184 | */ |
||
185 | public function auto_updater() { |
||
203 | |||
204 | /** |
||
205 | * License Settings |
||
206 | * |
||
207 | * Add license field to settings. |
||
208 | * |
||
209 | * @access public |
||
210 | * |
||
211 | * @param array $settings License settings. |
||
212 | * |
||
213 | * @return array License settings. |
||
214 | */ |
||
215 | public function settings( $settings ) { |
||
216 | |||
217 | $give_license_settings = array( |
||
218 | array( |
||
219 | 'name' => $this->item_name, |
||
220 | 'id' => $this->item_shortname . '_license_key', |
||
221 | 'desc' => '', |
||
222 | 'type' => 'license_key', |
||
223 | 'options' => array( |
||
224 | 'license' => get_option( $this->item_shortname . '_license_active' ), |
||
225 | 'shortname' => $this->item_shortname, |
||
226 | 'item_name' => $this->item_name, |
||
227 | 'api_url' => $this->api_url, |
||
228 | 'checkout_url' => $this->checkout_url, |
||
229 | 'account_url' => $this->account_url |
||
230 | ), |
||
231 | 'size' => 'regular' |
||
232 | ) |
||
233 | ); |
||
234 | |||
235 | return array_merge( $settings, $give_license_settings ); |
||
236 | } |
||
237 | |||
238 | /** |
||
239 | * License Settings Content |
||
240 | * |
||
241 | * Add Some Content to the Licensing Settings. |
||
242 | * |
||
243 | * @access public |
||
244 | * |
||
245 | * @param array $settings License settings content. |
||
246 | * |
||
247 | * @return array License settings content. |
||
248 | */ |
||
249 | public function license_settings_content( $settings ) { |
||
262 | |||
263 | /** |
||
264 | * Activate License |
||
265 | * |
||
266 | * Activate the license key. |
||
267 | * |
||
268 | * @access public |
||
269 | * |
||
270 | * @return void |
||
271 | */ |
||
272 | public function activate_license() { |
||
273 | // Bailout: Check if license key set of not. |
||
274 | if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) { |
||
275 | return; |
||
276 | } |
||
277 | |||
278 | // Security check. |
||
279 | if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) { |
||
280 | |||
281 | wp_die( esc_html__( 'Nonce verification failed.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) ); |
||
282 | |||
283 | } |
||
284 | |||
285 | // Check if user have correct permissions. |
||
286 | if ( ! current_user_can( 'manage_give_settings' ) ) { |
||
287 | return; |
||
288 | } |
||
289 | |||
290 | // Allow third party addon developers to handle license activation. |
||
291 | if( $this->__is_third_party_addon() ){ |
||
292 | do_action( 'give_activate_license', $this ); |
||
293 | return; |
||
294 | } |
||
295 | |||
296 | // Delete previous license setting if a empty license key submitted. |
||
297 | if ( empty( $_POST[ $this->item_shortname . '_license_key' ] ) ) { |
||
298 | delete_option( $this->item_shortname . '_license_active' ); |
||
299 | return; |
||
300 | } |
||
301 | |||
302 | // Do not simultaneously activate any addon if user want to deactivate any addon. |
||
303 | foreach ( $_POST as $key => $value ) { |
||
304 | if ( false !== strpos( $key, 'license_key_deactivate' ) ) { |
||
305 | // Don't activate a key when deactivating a different key |
||
306 | return; |
||
307 | } |
||
308 | } |
||
309 | |||
310 | |||
311 | // Check if plugin previously installed. |
||
312 | if ( $this->is_valid_license() ) { |
||
313 | return; |
||
314 | } |
||
315 | |||
316 | // Get license key. |
||
317 | $license = sanitize_text_field( $_POST[ $this->item_shortname . '_license_key' ] ); |
||
318 | |||
319 | // Bailout. |
||
320 | if( empty( $license ) ) { |
||
321 | return; |
||
322 | } |
||
323 | |||
324 | // Delete previous license key from subscription if previously added. |
||
325 | $this->__remove_license_key_from_subscriptions(); |
||
326 | |||
327 | // Data to send to the API |
||
328 | $api_params = array( |
||
329 | 'edd_action' => 'activate_license', //never change from "edd_" to "give_"! |
||
330 | 'license' => $license, |
||
331 | 'item_name' => urlencode( $this->item_name ), |
||
332 | 'url' => home_url() |
||
333 | ); |
||
334 | |||
335 | // Call the API |
||
336 | $response = wp_remote_post( |
||
337 | $this->api_url, |
||
338 | array( |
||
339 | 'timeout' => 15, |
||
340 | 'sslverify' => false, |
||
341 | 'body' => $api_params |
||
342 | ) |
||
343 | ); |
||
344 | |||
345 | // Make sure there are no errors |
||
346 | if ( is_wp_error( $response ) ) { |
||
347 | return; |
||
348 | } |
||
349 | |||
350 | // Tell WordPress to look for updates |
||
351 | set_site_transient( 'update_plugins', null ); |
||
352 | |||
353 | // Decode license data |
||
354 | $license_data = json_decode( wp_remote_retrieve_body( $response ) ); |
||
355 | update_option( $this->item_shortname . '_license_active', $license_data ); |
||
356 | |||
357 | // Check subscription for license key and store this to db (if any). |
||
358 | $this->__single_subscription_check(); |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Deactivate License |
||
363 | * |
||
364 | * Deactivate the license key. |
||
365 | * |
||
366 | * @access public |
||
367 | * |
||
368 | * @return void |
||
369 | */ |
||
370 | public function deactivate_license() { |
||
371 | |||
372 | if ( ! isset( $_POST[ $this->item_shortname . '_license_key' ] ) ) { |
||
373 | return; |
||
374 | } |
||
375 | |||
376 | if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce' ], $this->item_shortname . '_license_key-nonce' ) ) { |
||
377 | |||
378 | wp_die( esc_html__( 'Nonce verification failed.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) ); |
||
379 | |||
380 | } |
||
381 | |||
382 | if ( ! current_user_can( 'manage_give_settings' ) ) { |
||
383 | return; |
||
384 | } |
||
385 | |||
386 | // Allow third party addon developers to handle license deactivation. |
||
387 | if( $this->__is_third_party_addon() ){ |
||
388 | do_action( 'give_deactivate_license', $this ); |
||
389 | return; |
||
390 | } |
||
391 | |||
392 | // Run on deactivate button press |
||
393 | if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) { |
||
394 | |||
395 | // Data to send to the API |
||
396 | $api_params = array( |
||
397 | 'edd_action' => 'deactivate_license', //never change from "edd_" to "give_"! |
||
398 | 'license' => $this->license, |
||
399 | 'item_name' => urlencode( $this->item_name ), |
||
400 | 'url' => home_url() |
||
401 | ); |
||
402 | |||
403 | // Call the API |
||
404 | $response = wp_remote_post( |
||
405 | $this->api_url, |
||
406 | array( |
||
407 | 'timeout' => 15, |
||
408 | 'sslverify' => false, |
||
409 | 'body' => $api_params |
||
410 | ) |
||
411 | ); |
||
412 | |||
413 | |||
414 | // Make sure there are no errors |
||
415 | if ( is_wp_error( $response ) ) { |
||
416 | return; |
||
417 | } |
||
418 | |||
419 | // Decode the license data |
||
420 | $license_data = json_decode( wp_remote_retrieve_body( $response ) ); |
||
421 | |||
422 | |||
423 | // Remove license data. |
||
424 | delete_option( $this->item_shortname . '_license_active' ); |
||
425 | |||
426 | // Remove license key from subscriptions if exist. |
||
427 | $this->__remove_license_key_from_subscriptions(); |
||
428 | } |
||
429 | } |
||
430 | |||
431 | |||
432 | /** |
||
433 | * Check if license key is valid once per week |
||
434 | * |
||
435 | * @access public |
||
436 | * @since 1.7 |
||
437 | * |
||
438 | * @return bool/void |
||
439 | */ |
||
440 | public function weekly_license_check() { |
||
441 | |||
442 | if( ! empty( $_POST['give_settings'] ) ) { |
||
443 | // Don't fire when saving settings |
||
444 | return false; |
||
445 | } |
||
446 | |||
447 | if( empty( $this->license ) ) { |
||
448 | return false; |
||
449 | } |
||
450 | |||
451 | // Allow third party addon developers to handle there license check. |
||
452 | if( $this->__is_third_party_addon() ){ |
||
453 | do_action( 'give_weekly_license_check', $this ); |
||
454 | return false; |
||
455 | } |
||
456 | |||
457 | // Data to send in our API request. |
||
458 | $api_params = array( |
||
459 | 'edd_action'=> 'check_license', |
||
460 | 'license' => $this->license, |
||
461 | 'item_name' => urlencode( $this->item_name ), |
||
462 | 'url' => home_url() |
||
463 | ); |
||
464 | |||
465 | // Call the API |
||
466 | $response = wp_remote_post( |
||
467 | $this->api_url, |
||
468 | array( |
||
469 | 'timeout' => 15, |
||
470 | 'sslverify' => false, |
||
471 | 'body' => $api_params |
||
472 | ) |
||
473 | ); |
||
474 | |||
475 | // Make sure the response came back okay. |
||
476 | if ( is_wp_error( $response ) ) { |
||
477 | return false; |
||
478 | } |
||
479 | |||
480 | $license_data = json_decode( wp_remote_retrieve_body( $response ) ); |
||
481 | update_option( $this->item_shortname . '_license_active', $license_data ); |
||
482 | } |
||
483 | |||
484 | |||
485 | /** |
||
486 | * Check subscription validation once per week |
||
487 | * |
||
488 | * @access public |
||
489 | * @since 1.7 |
||
490 | * |
||
491 | * @return bool/void |
||
492 | */ |
||
493 | public function weekly_subscription_check() { |
||
564 | |||
565 | /** |
||
566 | * Check if license key is part of subscription or not |
||
567 | * |
||
568 | * @since 1.7 |
||
569 | * @access private |
||
570 | * |
||
571 | * @return bool/void |
||
572 | * |
||
573 | */ |
||
574 | private function __single_subscription_check() { |
||
629 | |||
630 | |||
631 | /** |
||
632 | * Admin notices for errors |
||
633 | * |
||
634 | * @access public |
||
635 | * @return void |
||
636 | */ |
||
637 | public function notices() { |
||
730 | |||
731 | |||
732 | /** |
||
733 | * Check if license is valid or not. |
||
734 | * |
||
735 | * @since 1.7 |
||
736 | * |
||
737 | * @return bool |
||
738 | */ |
||
739 | public function is_valid_license() { |
||
746 | |||
747 | /** |
||
748 | * Check if license is valid or not. |
||
749 | * |
||
750 | * @since 1.7 |
||
751 | * @access private |
||
752 | * |
||
753 | * @return bool |
||
754 | */ |
||
755 | private function __is_third_party_addon() { |
||
758 | |||
759 | |||
760 | /** |
||
761 | * Remove license keyy from subscription |
||
762 | * |
||
763 | * This function mainly uses when admin user deactivate license key, |
||
764 | * then we do not need subscription information for that license key. |
||
765 | * |
||
766 | * @since 1.7 |
||
767 | * @access private |
||
768 | * |
||
769 | * @return void|bool |
||
770 | */ |
||
771 | private function __remove_license_key_from_subscriptions(){ |
||
796 | |||
797 | /** |
||
798 | * Remove license notices show blocker. |
||
799 | * |
||
800 | * @since 1.7 |
||
801 | * @access private |
||
802 | * |
||
803 | * @return void |
||
804 | */ |
||
805 | private function __remove_license_notices_show_blocker(){ |
||
832 | |||
833 | /** |
||
834 | * Check if notice dismissed by admin user or not. |
||
835 | * |
||
836 | * @since 1.7 |
||
837 | * @access private |
||
838 | * |
||
839 | * @param int $notice_id notice ID. |
||
840 | * |
||
841 | * @return bool |
||
842 | */ |
||
843 | private function __is_notice_dismissed( $notice_id ){ |
||
859 | } |
||
860 | |||
862 |
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.