Complex classes like Jetpack_Sync_WP_Replicastore 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_Sync_WP_Replicastore, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 9 | class Jetpack_Sync_WP_Replicastore implements iJetpack_Sync_Replicastore { |
||
| 10 | |||
| 11 | public function reset() { |
||
| 12 | global $wpdb; |
||
| 13 | |||
| 14 | $wpdb->query( "DELETE FROM $wpdb->posts" ); |
||
| 15 | $wpdb->query( "DELETE FROM $wpdb->comments" ); |
||
| 16 | |||
| 17 | // also need to delete terms from cache |
||
| 18 | $term_ids = $wpdb->get_col( "SELECT term_id FROM $wpdb->terms" ); |
||
| 19 | foreach ( $term_ids as $term_id ) { |
||
| 20 | wp_cache_delete( $term_id, 'terms' ); |
||
| 21 | } |
||
| 22 | |||
| 23 | $wpdb->query( "DELETE FROM $wpdb->terms" ); |
||
| 24 | |||
| 25 | $wpdb->query( "DELETE FROM $wpdb->term_taxonomy" ); |
||
| 26 | $wpdb->query( "DELETE FROM $wpdb->term_relationships" ); |
||
| 27 | |||
| 28 | // callables and constants |
||
| 29 | $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'jetpack_%'" ); |
||
| 30 | $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key NOT LIKE '\_%'" ); |
||
| 31 | } |
||
| 32 | |||
| 33 | function full_sync_start() { |
||
| 34 | $this->reset(); |
||
| 35 | } |
||
| 36 | |||
| 37 | function full_sync_end( $checksum ) { |
||
| 38 | // noop right now |
||
| 39 | } |
||
| 40 | |||
| 41 | public function post_count( $status = null ) { |
||
| 42 | return count( $this->get_posts( $status ) ); |
||
| 43 | } |
||
| 44 | |||
| 45 | public function get_posts( $status = null ) { |
||
| 46 | $args = array( 'orderby' => 'ID' ); |
||
| 47 | |||
| 48 | if ( $status ) { |
||
| 49 | $args['post_status'] = $status; |
||
| 50 | } else { |
||
| 51 | $args['post_status'] = 'any'; |
||
| 52 | } |
||
| 53 | |||
| 54 | return get_posts( $args ); |
||
| 55 | } |
||
| 56 | |||
| 57 | public function get_post( $id ) { |
||
| 58 | return get_post( $id ); |
||
| 59 | } |
||
| 60 | |||
| 61 | public function upsert_post( $post, $silent = false ) { |
||
| 62 | global $wpdb; |
||
| 63 | |||
| 64 | // reject the post if it's not a WP_Post |
||
| 65 | if ( ! $post instanceof WP_Post ) { |
||
|
|
|||
| 66 | return; |
||
| 67 | } |
||
| 68 | |||
| 69 | $post = $post->to_array(); |
||
| 70 | |||
| 71 | // reject posts without an ID |
||
| 72 | if ( ! isset( $post['ID'] ) ) { |
||
| 73 | return; |
||
| 74 | } |
||
| 75 | |||
| 76 | $now = current_time( 'mysql' ); |
||
| 77 | $now_gmt = get_gmt_from_date( $now ); |
||
| 78 | |||
| 79 | $defaults = array( |
||
| 80 | 'ID' => 0, |
||
| 81 | 'post_author' => '0', |
||
| 82 | 'post_content' => '', |
||
| 83 | 'post_content_filtered' => '', |
||
| 84 | 'post_title' => '', |
||
| 85 | 'post_name' => '', |
||
| 86 | 'post_excerpt' => '', |
||
| 87 | 'post_status' => 'draft', |
||
| 88 | 'post_type' => 'post', |
||
| 89 | 'comment_status' => 'closed', |
||
| 90 | 'comment_count' => '0', |
||
| 91 | 'ping_status' => '', |
||
| 92 | 'post_password' => '', |
||
| 93 | 'to_ping' => '', |
||
| 94 | 'pinged' => '', |
||
| 95 | 'post_parent' => 0, |
||
| 96 | 'menu_order' => 0, |
||
| 97 | 'guid' => '', |
||
| 98 | 'post_date' => $now, |
||
| 99 | 'post_date_gmt' => $now_gmt, |
||
| 100 | 'post_modified' => $now, |
||
| 101 | 'post_modified_gmt' => $now_gmt, |
||
| 102 | ); |
||
| 103 | |||
| 104 | $post = array_intersect_key( $post, $defaults ); |
||
| 105 | |||
| 106 | $post = sanitize_post( $post, 'db' ); |
||
| 107 | |||
| 108 | unset( $post['filter'] ); |
||
| 109 | |||
| 110 | $exists = $wpdb->get_var( $wpdb->prepare( "SELECT EXISTS( SELECT 1 FROM $wpdb->posts WHERE ID = %d )", $post['ID'] ) ); |
||
| 111 | |||
| 112 | if ( $exists ) { |
||
| 113 | $wpdb->update( $wpdb->posts, $post, array( 'ID' => $post['ID'] ) ); |
||
| 114 | } else { |
||
| 115 | $wpdb->insert( $wpdb->posts, $post ); |
||
| 116 | } |
||
| 117 | |||
| 118 | clean_post_cache( $post['ID'] ); |
||
| 119 | } |
||
| 120 | |||
| 121 | public function delete_post( $post_id ) { |
||
| 122 | wp_delete_post( $post_id, true ); |
||
| 123 | } |
||
| 124 | |||
| 125 | public function posts_checksum() { |
||
| 126 | global $wpdb; |
||
| 127 | |||
| 128 | $post_type_sql = Jetpack_Sync_Defaults::get_blacklisted_post_types_sql(); |
||
| 129 | |||
| 130 | $query = <<<ENDSQL |
||
| 131 | SELECT CONV(BIT_XOR(CRC32(CONCAT(ID,post_modified))), 10, 16) |
||
| 132 | FROM $wpdb->posts |
||
| 133 | WHERE $post_type_sql |
||
| 134 | ENDSQL; |
||
| 135 | |||
| 136 | return $wpdb->get_var( $query ); |
||
| 137 | } |
||
| 138 | |||
| 139 | public function comment_count( $status = null ) { |
||
| 140 | global $wpdb; |
||
| 141 | |||
| 142 | $comment_approved = $this->comment_status_to_approval_value( $status ); |
||
| 143 | |||
| 144 | if ( $comment_approved !== false ) { |
||
| 145 | return $wpdb->get_var( $wpdb->prepare( |
||
| 146 | "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = %s", |
||
| 147 | $comment_approved |
||
| 148 | ) ); |
||
| 149 | } else { |
||
| 150 | return $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments" ); |
||
| 151 | } |
||
| 152 | } |
||
| 153 | |||
| 154 | private function comment_status_to_approval_value( $status ) { |
||
| 155 | switch ( $status ) { |
||
| 156 | case 'approve': |
||
| 157 | return "1"; |
||
| 158 | case 'hold': |
||
| 159 | return "0"; |
||
| 160 | case 'spam': |
||
| 161 | return 'spam'; |
||
| 162 | case 'trash': |
||
| 163 | return 'trash'; |
||
| 164 | case 'any': |
||
| 165 | return false; |
||
| 166 | case 'all': |
||
| 167 | return false; |
||
| 168 | default: |
||
| 169 | return false; |
||
| 170 | } |
||
| 171 | } |
||
| 172 | |||
| 173 | public function get_comments( $status = null ) { |
||
| 174 | $args = array( 'orderby' => 'ID', 'status' => 'all' ); |
||
| 175 | |||
| 176 | if ( $status ) { |
||
| 177 | $args['status'] = $status; |
||
| 178 | } |
||
| 179 | |||
| 180 | return get_comments( $args ); |
||
| 181 | } |
||
| 182 | |||
| 183 | public function get_comment( $id ) { |
||
| 184 | return WP_Comment::get_instance( $id ); |
||
| 185 | } |
||
| 186 | |||
| 187 | public function upsert_comment( $comment ) { |
||
| 188 | global $wpdb, $wp_version; |
||
| 189 | |||
| 190 | if ( version_compare( $wp_version, '4.4', '<' ) ) { |
||
| 191 | $comment = (array) $comment; |
||
| 192 | } else { |
||
| 193 | // WP 4.4 introduced the WP_Comment Class |
||
| 194 | $comment = $comment->to_array(); |
||
| 195 | } |
||
| 196 | |||
| 197 | // filter by fields on comment table |
||
| 198 | $comment_fields_whitelist = array( |
||
| 199 | 'comment_ID', |
||
| 200 | 'comment_post_ID', |
||
| 201 | 'comment_author', |
||
| 202 | 'comment_author_email', |
||
| 203 | 'comment_author_url', |
||
| 204 | 'comment_author_IP', |
||
| 205 | 'comment_date', |
||
| 206 | 'comment_date_gmt', |
||
| 207 | 'comment_content', |
||
| 208 | 'comment_karma', |
||
| 209 | 'comment_approved', |
||
| 210 | 'comment_agent', |
||
| 211 | 'comment_type', |
||
| 212 | 'comment_parent', |
||
| 213 | 'user_id' |
||
| 214 | ); |
||
| 215 | |||
| 216 | foreach ( $comment as $key => $value ) { |
||
| 217 | if ( ! in_array( $key, $comment_fields_whitelist ) ) { |
||
| 218 | unset( $comment[ $key ] ); |
||
| 219 | } |
||
| 220 | } |
||
| 221 | |||
| 222 | $exists = $wpdb->get_var( |
||
| 223 | $wpdb->prepare( |
||
| 224 | "SELECT EXISTS( SELECT 1 FROM $wpdb->comments WHERE comment_ID = %d )", |
||
| 225 | $comment['comment_ID'] |
||
| 226 | ) |
||
| 227 | ); |
||
| 228 | |||
| 229 | if ( $exists ) { |
||
| 230 | $wpdb->update( $wpdb->comments, $comment, array( 'comment_ID' => $comment['comment_ID'] ) ); |
||
| 231 | } else { |
||
| 232 | $wpdb->insert( $wpdb->comments, $comment ); |
||
| 233 | } |
||
| 234 | |||
| 235 | wp_update_comment_count( $comment['comment_post_ID'] ); |
||
| 236 | } |
||
| 237 | |||
| 238 | public function trash_comment( $comment_id ) { |
||
| 239 | wp_delete_comment( $comment_id ); |
||
| 240 | } |
||
| 241 | |||
| 242 | public function delete_comment( $comment_id ) { |
||
| 243 | wp_delete_comment( $comment_id, true ); |
||
| 244 | } |
||
| 245 | |||
| 246 | public function spam_comment( $comment_id ) { |
||
| 247 | wp_spam_comment( $comment_id ); |
||
| 248 | } |
||
| 249 | |||
| 250 | public function comments_checksum() { |
||
| 251 | global $wpdb; |
||
| 252 | |||
| 253 | $query = <<<ENDSQL |
||
| 254 | SELECT CONV(BIT_XOR(CRC32(CONCAT(comment_ID,comment_content))), 10, 16) FROM $wpdb->comments |
||
| 255 | ENDSQL; |
||
| 256 | |||
| 257 | return $wpdb->get_var( $query ); |
||
| 258 | } |
||
| 259 | |||
| 260 | public function update_option( $option, $value ) { |
||
| 261 | return update_option( $option, $value ); |
||
| 262 | } |
||
| 263 | |||
| 264 | public function get_option( $option ) { |
||
| 265 | return get_option( $option ); |
||
| 266 | } |
||
| 267 | |||
| 268 | public function delete_option( $option ) { |
||
| 269 | return delete_option( $option ); |
||
| 270 | } |
||
| 271 | |||
| 272 | public function set_theme_support( $theme_support ) { |
||
| 273 | // noop |
||
| 274 | } |
||
| 275 | |||
| 276 | public function current_theme_supports( $feature ) { |
||
| 277 | return current_theme_supports( $feature ); |
||
| 278 | } |
||
| 279 | |||
| 280 | public function get_metadata( $type, $object_id, $meta_key = '', $single = false ) { |
||
| 281 | return get_metadata( $type, $object_id, $meta_key, $single ); |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * |
||
| 286 | * Stores remote meta key/values alongside an ID mapping key |
||
| 287 | * |
||
| 288 | * @param $type |
||
| 289 | * @param $object_id |
||
| 290 | * @param $meta_key |
||
| 291 | * @param $meta_value |
||
| 292 | * @param $meta_id |
||
| 293 | * |
||
| 294 | * @return bool |
||
| 295 | */ |
||
| 296 | public function upsert_metadata( $type, $object_id, $meta_key, $meta_value, $meta_id ) { |
||
| 297 | |||
| 298 | $table = _get_meta_table( $type ); |
||
| 299 | if ( ! $table ) { |
||
| 300 | return false; |
||
| 301 | } |
||
| 302 | |||
| 303 | global $wpdb; |
||
| 304 | |||
| 305 | $exists = $wpdb->get_var( $wpdb->prepare( |
||
| 306 | "SELECT EXISTS( SELECT 1 FROM $table WHERE meta_id = %d )", |
||
| 307 | $meta_id |
||
| 308 | ) ); |
||
| 309 | |||
| 310 | if ( $exists ) { |
||
| 311 | $wpdb->update( $table, array( 'meta_key' => $meta_key, |
||
| 312 | 'meta_value' => serialize( $meta_value ) |
||
| 313 | ), array( 'meta_id' => $meta_id ) ); |
||
| 314 | } else { |
||
| 315 | $object_id_field = $type . '_id'; |
||
| 316 | $wpdb->insert( $table, array( 'meta_id' => $meta_id, |
||
| 317 | $object_id_field => $object_id, |
||
| 318 | 'meta_key' => $meta_key, |
||
| 319 | 'meta_value' => serialize( $meta_value ) |
||
| 320 | ) ); |
||
| 321 | } |
||
| 322 | |||
| 323 | wp_cache_delete( $object_id, $type . '_meta' ); |
||
| 324 | |||
| 325 | return true; |
||
| 326 | } |
||
| 327 | |||
| 328 | public function delete_metadata( $type, $object_id, $meta_ids ) { |
||
| 329 | global $wpdb; |
||
| 330 | |||
| 331 | $table = _get_meta_table( $type ); |
||
| 332 | if ( ! $table ) { |
||
| 333 | return false; |
||
| 334 | } |
||
| 335 | |||
| 336 | foreach ( $meta_ids as $meta_id ) { |
||
| 337 | $wpdb->query( $wpdb->prepare( "DELETE FROM $table WHERE meta_id = %d", $meta_id ) ); |
||
| 338 | } |
||
| 339 | |||
| 340 | // if we don't have an object ID what do we do - invalidate ALL meta? |
||
| 341 | if ( $object_id ) { |
||
| 342 | wp_cache_delete( $object_id, $type . '_meta' ); |
||
| 343 | } |
||
| 344 | } |
||
| 345 | |||
| 346 | // constants |
||
| 347 | public function get_constant( $constant ) { |
||
| 348 | $value = get_option( 'jetpack_constant_' . $constant ); |
||
| 349 | |||
| 350 | if ( $value ) { |
||
| 351 | return $value; |
||
| 352 | } |
||
| 353 | |||
| 354 | return null; |
||
| 355 | } |
||
| 356 | |||
| 357 | public function set_constant( $constant, $value ) { |
||
| 360 | |||
| 361 | public function get_updates( $type ) { |
||
| 362 | $all_updates = get_option( 'jetpack_updates', array() ); |
||
| 363 | |||
| 364 | if ( isset( $all_updates[ $type ] ) ) { |
||
| 365 | return $all_updates[ $type ]; |
||
| 366 | } else { |
||
| 367 | return null; |
||
| 368 | } |
||
| 369 | } |
||
| 370 | |||
| 371 | public function set_updates( $type, $updates ) { |
||
| 372 | $all_updates = get_option( 'jetpack_updates', array() ); |
||
| 373 | $all_updates[ $type ] = $updates; |
||
| 374 | update_option( 'jetpack_updates', $all_updates ); |
||
| 375 | } |
||
| 376 | |||
| 377 | // functions |
||
| 378 | public function get_callable( $name ) { |
||
| 379 | $value = get_option( 'jetpack_' . $name ); |
||
| 380 | |||
| 381 | if ( $value ) { |
||
| 382 | return $value; |
||
| 383 | } |
||
| 384 | |||
| 385 | return null; |
||
| 386 | } |
||
| 387 | |||
| 388 | public function set_callable( $name, $value ) { |
||
| 389 | update_option( 'jetpack_' . $name, $value ); |
||
| 390 | } |
||
| 391 | |||
| 392 | // network options |
||
| 393 | public function get_site_option( $option ) { |
||
| 396 | |||
| 397 | public function update_site_option( $option, $value ) { |
||
| 400 | |||
| 401 | public function delete_site_option( $option ) { |
||
| 404 | |||
| 405 | // terms |
||
| 406 | // terms |
||
| 407 | public function get_terms( $taxonomy ) { |
||
| 410 | |||
| 411 | public function get_term( $taxonomy, $term_id, $is_term_id = true ) { |
||
| 419 | |||
| 420 | private function ensure_taxonomy( $taxonomy ) { |
||
| 439 | |||
| 440 | public function get_the_terms( $object_id, $taxonomy ) { |
||
| 443 | |||
| 444 | public function update_term( $term_object ) { |
||
| 477 | |||
| 478 | public function delete_term( $term_id, $taxonomy ) { |
||
| 481 | |||
| 482 | public function update_object_terms( $object_id, $taxonomy, $terms, $append ) { |
||
| 485 | |||
| 486 | public function delete_object_terms( $object_id, $tt_ids ) { |
||
| 526 | |||
| 527 | // users |
||
| 528 | public function user_count() { |
||
| 531 | |||
| 532 | public function get_user( $user_id ) { |
||
| 535 | |||
| 536 | public function upsert_user( $user ) { |
||
| 539 | |||
| 540 | public function delete_user( $user_id ) { |
||
| 543 | |||
| 544 | public function checksum_all() { |
||
| 550 | |||
| 551 | private function invalid_call() { |
||
| 556 | } |
||
| 557 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.