Complex classes like FS_Api 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 FS_Api, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | class FS_Api { |
||
23 | /** |
||
24 | * @var FS_Api[] |
||
25 | */ |
||
26 | private static $_instances = array(); |
||
27 | |||
28 | /** |
||
29 | * @var FS_Option_Manager Freemius options, options-manager. |
||
30 | */ |
||
31 | private static $_options; |
||
32 | |||
33 | /** |
||
34 | * @var FS_Cache_Manager API Caching layer |
||
35 | */ |
||
36 | private static $_cache; |
||
37 | |||
38 | /** |
||
39 | * @var int Clock diff in seconds between current server to API server. |
||
40 | */ |
||
41 | private static $_clock_diff; |
||
42 | |||
43 | /** |
||
44 | * @var Freemius_Api_WordPress |
||
45 | */ |
||
46 | private $_api; |
||
47 | |||
48 | /** |
||
49 | * @var string |
||
50 | */ |
||
51 | private $_slug; |
||
52 | |||
53 | /** |
||
54 | * @var FS_Logger |
||
55 | * @since 1.0.4 |
||
56 | */ |
||
57 | private $_logger; |
||
58 | |||
59 | /** |
||
60 | * @param string $slug |
||
61 | * @param string $scope 'app', 'developer', 'user' or 'install'. |
||
62 | * @param number $id Element's id. |
||
63 | * @param string $public_key Public key. |
||
64 | * @param bool $is_sandbox |
||
65 | * @param bool|string $secret_key Element's secret key. |
||
66 | * |
||
67 | * @return FS_Api |
||
68 | */ |
||
69 | static function instance( $slug, $scope, $id, $public_key, $is_sandbox, $secret_key = false ) { |
||
80 | |||
81 | private static function _init() { |
||
100 | |||
101 | /** |
||
102 | * @param string $slug |
||
103 | * @param string $scope 'app', 'developer', 'user' or 'install'. |
||
104 | * @param number $id Element's id. |
||
105 | * @param string $public_key Public key. |
||
106 | * @param bool|string $secret_key Element's secret key. |
||
107 | * @param bool $is_sandbox |
||
108 | */ |
||
109 | private function __construct( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox ) { |
||
115 | |||
116 | /** |
||
117 | * Find clock diff between server and API server, and store the diff locally. |
||
118 | * |
||
119 | * @param bool|int $diff |
||
120 | * |
||
121 | * @return bool|int False if clock diff didn't change, otherwise returns the clock diff in seconds. |
||
122 | */ |
||
123 | private function _sync_clock_diff( $diff = false ) { |
||
145 | |||
146 | /** |
||
147 | * Override API call to enable retry with servers' clock auto sync method. |
||
148 | * |
||
149 | * @param string $path |
||
150 | * @param string $method |
||
151 | * @param array $params |
||
152 | * @param bool $retry Is in retry or first call attempt. |
||
153 | * |
||
154 | * @return array|mixed|string|void |
||
155 | */ |
||
156 | private function _call( $path, $method = 'GET', $params = array(), $retry = false ) { |
||
190 | |||
191 | /** |
||
192 | * Override API call to wrap it in servers' clock sync method. |
||
193 | * |
||
194 | * @param string $path |
||
195 | * @param string $method |
||
196 | * @param array $params |
||
197 | * |
||
198 | * @return array|mixed|string|void |
||
199 | * @throws Freemius_Exception |
||
200 | */ |
||
201 | function call( $path, $method = 'GET', $params = array() ) { |
||
204 | |||
205 | /** |
||
206 | * Get API request URL signed via query string. |
||
207 | * |
||
208 | * @param string $path |
||
209 | * |
||
210 | * @return string |
||
211 | */ |
||
212 | function get_signed_url( $path ) { |
||
215 | |||
216 | /** |
||
217 | * @param string $path |
||
218 | * @param bool $flush |
||
219 | * @param int $expiration (optional) Time until expiration in seconds from now, defaults to 24 hours |
||
220 | * |
||
221 | * @return stdClass|mixed |
||
222 | */ |
||
223 | function get( $path = '/', $flush = false, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) { |
||
276 | |||
277 | /** |
||
278 | * Check if there's a cached version of the API request. |
||
279 | * |
||
280 | * @author Vova Feldman (@svovaf) |
||
281 | * @since 1.2.1 |
||
282 | * |
||
283 | * @param string $path |
||
284 | * @param string $method |
||
285 | * @param array $params |
||
286 | * |
||
287 | * @return bool |
||
288 | */ |
||
289 | function is_cached( $path, $method = 'GET', $params = array() ) { |
||
294 | |||
295 | /** |
||
296 | * Invalidate a cached version of the API request. |
||
297 | * |
||
298 | * @author Vova Feldman (@svovaf) |
||
299 | * @since 1.2.1.5 |
||
300 | * |
||
301 | * @param string $path |
||
302 | * @param string $method |
||
303 | * @param array $params |
||
304 | */ |
||
305 | function purge_cache( $path, $method = 'GET', $params = array() ) { |
||
312 | |||
313 | /** |
||
314 | * Invalidate a cached version of the API request. |
||
315 | * |
||
316 | * @author Vova Feldman (@svovaf) |
||
317 | * @since 2.0.0 |
||
318 | * |
||
319 | * @param string $path |
||
320 | * @param int $expiration |
||
321 | * @param string $method |
||
322 | * @param array $params |
||
323 | */ |
||
324 | function update_cache_expiration( $path, $expiration = WP_FS__TIME_24_HOURS_IN_SEC, $method = 'GET', $params = array() ) { |
||
331 | |||
332 | /** |
||
333 | * @param string $path |
||
334 | * @param string $method |
||
335 | * @param array $params |
||
336 | * |
||
337 | * @return string |
||
338 | * @throws \Freemius_Exception |
||
339 | */ |
||
340 | private function get_cache_key( $path, $method = 'GET', $params = array() ) { |
||
346 | |||
347 | /** |
||
348 | * Test API connectivity. |
||
349 | * |
||
350 | * @author Vova Feldman (@svovaf) |
||
351 | * @since 1.0.9 If fails, try to fallback to HTTP. |
||
352 | * @since 1.1.6 Added a 5-min caching mechanism, to prevent from overloading the server if the API if |
||
353 | * temporary down. |
||
354 | * |
||
355 | * @return bool True if successful connectivity to the API. |
||
356 | */ |
||
357 | static function test() { |
||
391 | |||
392 | /** |
||
393 | * Check if API is temporary down. |
||
394 | * |
||
395 | * @author Vova Feldman (@svovaf) |
||
396 | * @since 1.1.6 |
||
397 | * |
||
398 | * @return bool |
||
399 | */ |
||
400 | static function is_temporary_down() { |
||
407 | |||
408 | /** |
||
409 | * @author Vova Feldman (@svovaf) |
||
410 | * @since 1.1.6 |
||
411 | * |
||
412 | * @return object |
||
413 | */ |
||
414 | private function get_temporary_unavailable_error() { |
||
424 | |||
425 | /** |
||
426 | * Ping API for connectivity test, and return result object. |
||
427 | * |
||
428 | * @author Vova Feldman (@svovaf) |
||
429 | * @since 1.0.9 |
||
430 | * |
||
431 | * @param null|string $unique_anonymous_id |
||
432 | * @param array $params |
||
433 | * |
||
434 | * @return object |
||
435 | */ |
||
436 | function ping( $unique_anonymous_id = null, $params = array() ) { |
||
474 | |||
475 | /** |
||
476 | * Check if based on the API result we should try |
||
477 | * to re-run the same request with HTTP instead of HTTPS. |
||
478 | * |
||
479 | * @author Vova Feldman (@svovaf) |
||
480 | * @since 1.1.6 |
||
481 | * |
||
482 | * @param $result |
||
483 | * |
||
484 | * @return bool |
||
485 | */ |
||
486 | private static function should_try_with_http( $result ) { |
||
503 | |||
504 | /** |
||
505 | * Check if valid ping request result. |
||
506 | * |
||
507 | * @author Vova Feldman (@svovaf) |
||
508 | * @since 1.1.1 |
||
509 | * |
||
510 | * @param mixed $pong |
||
511 | * |
||
512 | * @return bool |
||
513 | */ |
||
514 | function is_valid_ping( $pong ) { |
||
517 | |||
518 | function get_url( $path = '' ) { |
||
521 | |||
522 | /** |
||
523 | * Clear API cache. |
||
524 | * |
||
525 | * @author Vova Feldman (@svovaf) |
||
526 | * @since 1.0.9 |
||
527 | */ |
||
528 | static function clear_cache() { |
||
534 | |||
535 | #---------------------------------------------------------------------------------- |
||
536 | #region Error Handling |
||
537 | #---------------------------------------------------------------------------------- |
||
538 | |||
539 | /** |
||
540 | * @author Vova Feldman (@svovaf) |
||
541 | * @since 1.2.1.5 |
||
542 | * |
||
543 | * @param mixed $result |
||
544 | * |
||
545 | * @return bool Is API result contains an error. |
||
546 | */ |
||
547 | static function is_api_error( $result ) { |
||
551 | |||
552 | /** |
||
553 | * @author Vova Feldman (@svovaf) |
||
554 | * @since 2.0.0 |
||
555 | * |
||
556 | * @param mixed $result |
||
557 | * |
||
558 | * @return bool Is API result contains an error. |
||
559 | */ |
||
560 | static function is_api_error_object( $result ) { |
||
567 | |||
568 | /** |
||
569 | * Checks if given API result is a non-empty and not an error object. |
||
570 | * |
||
571 | * @author Vova Feldman (@svovaf) |
||
572 | * @since 1.2.1.5 |
||
573 | * |
||
574 | * @param mixed $result |
||
575 | * @param string|null $required_property Optional property we want to verify that is set. |
||
576 | * |
||
577 | * @return bool |
||
578 | */ |
||
579 | static function is_api_result_object( $result, $required_property = null ) { |
||
586 | |||
587 | /** |
||
588 | * Checks if given API result is a non-empty entity object with non-empty ID. |
||
589 | * |
||
590 | * @author Vova Feldman (@svovaf) |
||
591 | * @since 1.2.1.5 |
||
592 | * |
||
593 | * @param mixed $result |
||
594 | * |
||
595 | * @return bool |
||
596 | */ |
||
597 | static function is_api_result_entity( $result ) { |
||
601 | |||
602 | /** |
||
603 | * Get API result error code. If failed to get code, returns an empty string. |
||
604 | * |
||
605 | * @author Vova Feldman (@svovaf) |
||
606 | * @since 2.0.0 |
||
607 | * |
||
608 | * @param mixed $result |
||
609 | * |
||
610 | * @return string |
||
611 | */ |
||
612 | static function get_error_code( $result ) { |
||
623 | |||
624 | #endregion |
||
625 | } |
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.