Complex classes like Jetpack_Geo_Location 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 Jetpack_Geo_Location, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 33 | class Jetpack_Geo_Location { |
||
| 34 | private static $instance; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Whether dashicons are enqueued. |
||
| 38 | * |
||
| 39 | * @since 6.6.0 |
||
| 40 | * |
||
| 41 | * @var bool |
||
| 42 | */ |
||
| 43 | private static $style_enqueued = false; |
||
| 44 | |||
| 45 | public static function init() { |
||
| 52 | |||
| 53 | /** |
||
| 54 | * This is mostly just used for testing purposes. |
||
| 55 | */ |
||
| 56 | public static function reset_instance() { |
||
| 59 | |||
| 60 | public function __construct() { |
||
| 67 | |||
| 68 | /** |
||
| 69 | * Register support for the geo-location feature on pages and posts. Register the meta |
||
| 70 | * fields managed by this plugin so that they are properly sanitized during save. |
||
| 71 | */ |
||
| 72 | public function wordpress_init() { |
||
| 121 | |||
| 122 | /** |
||
| 123 | * Filter "public" input to always be either 1 or 0. |
||
| 124 | * |
||
| 125 | * @param mixed $public |
||
| 126 | * |
||
| 127 | * @return int |
||
| 128 | */ |
||
| 129 | public function sanitize_public( $public ) { |
||
| 132 | |||
| 133 | /** |
||
| 134 | * Filter geo coordinates and normalize them to floats with 7 digits of precision. |
||
| 135 | * |
||
| 136 | * @param mixed $coordinate |
||
| 137 | * |
||
| 138 | * @return float|null |
||
| 139 | */ |
||
| 140 | public function sanitize_coordinate( $coordinate ) { |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Render geo.position and ICBM meta tags with public geo meta values when rendering |
||
| 150 | * a single post. |
||
| 151 | */ |
||
| 152 | public function wp_head() { |
||
| 192 | |||
| 193 | /** |
||
| 194 | * Append public meta values in the Geo microformat (https://en.wikipedia.org/wiki/Geo_(microformat) |
||
| 195 | * to the supplied content. |
||
| 196 | * |
||
| 197 | * Note that we cannot render the microformat in the context of an excerpt because tags are stripped |
||
| 198 | * in that context, making our microformat data visible. |
||
| 199 | * |
||
| 200 | * @param string $content |
||
| 201 | * |
||
| 202 | * @return string |
||
| 203 | */ |
||
| 204 | public function the_content_microformat( $content ) { |
||
| 234 | |||
| 235 | /** |
||
| 236 | * Register a range of hooks for integrating geo data with various feeds. |
||
| 237 | */ |
||
| 238 | public function register_rss_hooks() { |
||
| 247 | |||
| 248 | /** |
||
| 249 | * Add the georss namespace during RSS generation. |
||
| 250 | */ |
||
| 251 | public function rss_namespace() { |
||
| 254 | |||
| 255 | /** |
||
| 256 | * Output georss data for RSS items, assuming we have data for the currently rendered post and |
||
| 257 | * that data as marked as public. |
||
| 258 | */ |
||
| 259 | public function rss_item() { |
||
| 275 | |||
| 276 | /** |
||
| 277 | * Enqueue CSS for rendering post flair with geo-location. |
||
| 278 | */ |
||
| 279 | private static function enqueue_scripts() { |
||
| 282 | |||
| 283 | /** |
||
| 284 | * If we're rendering a single post and public geo-location data is available for it, |
||
| 285 | * include the human-friendly location label in the output. |
||
| 286 | * |
||
| 287 | * @param string $content |
||
| 288 | * |
||
| 289 | * @return string |
||
| 290 | */ |
||
| 291 | public function the_content_location_display( $content ) { |
||
| 298 | |||
| 299 | /** |
||
| 300 | * Get the HTML for displaying a label representing the location associated with the |
||
| 301 | * supplied post ID. If no post ID is given, we'll use the global $post variable, if |
||
| 302 | * it is available. |
||
| 303 | * |
||
| 304 | * @param integer|null $post_id |
||
| 305 | * |
||
| 306 | * @return string |
||
| 307 | */ |
||
| 308 | public function get_location_label( $post_id = null ) { |
||
| 337 | |||
| 338 | /** |
||
| 339 | * Get the ID of the current global post object, if available. Otherwise, return null. |
||
| 340 | * |
||
| 341 | * This isolates the access of the global scope to this single method, making it easier to |
||
| 342 | * safeguard against unexpected missing $post objects in other hook functions. |
||
| 343 | * |
||
| 344 | * @return int|null |
||
| 345 | */ |
||
| 346 | public function get_post_id() { |
||
| 355 | |||
| 356 | /** |
||
| 357 | * This method always returns an array with the following structure: |
||
| 358 | * |
||
| 359 | * array(is_public => bool, latitude => float, longitude => float, label => string, is_populated => bool) |
||
| 360 | * |
||
| 361 | * So, regardless of whether your post actually has values in postmeta for the geo-location fields, |
||
| 362 | * you can be sure that you can reference those array keys in calling code without having to juggle |
||
| 363 | * isset(), array_key_exists(), etc. |
||
| 364 | * |
||
| 365 | * Mocking this method during testing can also be useful for testing output and logic in various |
||
| 366 | * hook functions. |
||
| 367 | * |
||
| 368 | * @param integer $post_id |
||
| 369 | * |
||
| 370 | * @return array A predictably structured array representing the meta values for the supplied post ID. |
||
| 371 | */ |
||
| 372 | public function get_meta_values( $post_id ) { |
||
| 387 | |||
| 388 | /** |
||
| 389 | * This function wraps get_post_meta() to enable us to keep the "geo_" prefix isolated to a single |
||
| 390 | * location in the code and to assist in mocking during testing. |
||
| 391 | * |
||
| 392 | * @param integer $post_id |
||
| 393 | * @param string $meta_field_name |
||
| 394 | * |
||
| 395 | * @return mixed |
||
| 396 | */ |
||
| 397 | public function get_meta_value( $post_id, $meta_field_name ) { |
||
| 404 | |||
| 405 | /** |
||
| 406 | * Check to see if the current filter is the get_the_excerpt filter. |
||
| 407 | * |
||
| 408 | * Just checking current_filter() here is not adequate because current_filter() only looks |
||
| 409 | * at the last element in the $wp_current_filter array. In the context of rendering an |
||
| 410 | * excerpt, however, both get_the_excerpt and the_content are present in that array. |
||
| 411 | * |
||
| 412 | * @return bool |
||
| 413 | */ |
||
| 414 | public function is_currently_excerpt_filter() { |
||
| 423 | } |
||
| 424 | |||
| 426 |