Completed
Push — branch-4.2 ( f12916...1c7f7d )
by Jeremy
11:38
created

Jetpack_Sync_WP_Replicastore::upsert_post()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 59
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 4
eloc 41
c 3
b 1
f 0
nc 4
nop 2
dl 0
loc 59
rs 8.9846

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
require_once 'interface.jetpack-sync-replicastore.php';
4
5
/**
6
 * An implementation of iJetpack_Sync_Replicastore which returns data stored in a WordPress.org DB.
7
 * This is useful to compare values in the local WP DB to values in the synced replica store
8
 */
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 ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to 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 require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
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 ) {
358
		update_option( 'jetpack_constant_' . $constant, $value );
359
	}
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 ) {
394
		return get_option( 'jetpack_network_' . $option );
395
	}
396
397
	public function update_site_option( $option, $value ) {
398
		return update_option( 'jetpack_network_' . $option, $value );
399
	}
400
401
	public function delete_site_option( $option ) {
402
		return delete_option( 'jetpack_network_' . $option );
403
	}
404
405
	// terms
406
	// terms
407
	public function get_terms( $taxonomy ) {
408
		return get_terms( $taxonomy );
409
	}
410
411
	public function get_term( $taxonomy, $term_id, $is_term_id = true ) {
412
		$t = $this->ensure_taxonomy( $taxonomy );
413
		if ( ! $t || is_wp_error( $t ) ) {
414
			return $t;
415
		}
416
417
		return get_term( $term_id, $taxonomy );
418
	}
419
420
	private function ensure_taxonomy( $taxonomy ) {
421
		if ( ! taxonomy_exists( $taxonomy ) ) {
422
			// try re-registering synced taxonomies
423
			$taxonomies = $this->get_callable( 'taxonomies' );
424
			if ( ! isset( $taxonomies[ $taxonomy ] ) ) {
425
				// doesn't exist, or somehow hasn't been synced
426
				return new WP_Error( 'invalid_taxonomy', "The taxonomy '$taxonomy' doesn't exist" );
427
			}
428
			$t = $taxonomies[ $taxonomy ];
429
430
			return register_taxonomy(
431
				$taxonomy,
432
				$t->object_type,
433
				(array) $t
434
			);
435
		}
436
437
		return true;
438
	}
439
440
	public function get_the_terms( $object_id, $taxonomy ) {
441
		return get_the_terms( $object_id, $taxonomy );
442
	}
443
444
	public function update_term( $term_object ) {
445
		$taxonomy = $term_object->taxonomy;
446
		global $wpdb;
447
		$exists = $wpdb->get_var( $wpdb->prepare(
448
			"SELECT EXISTS( SELECT 1 FROM $wpdb->terms WHERE term_id = %d )",
449
			$term_object->term_id
450
		) );
451
		if ( ! $exists ) {
452
			$term_object   = sanitize_term( clone( $term_object ), $taxonomy, 'db' );
453
			$term          = array(
454
				'term_id'    => $term_object->term_id,
455
				'name'       => $term_object->name,
456
				'slug'       => $term_object->slug,
457
				'term_group' => $term_object->term_group,
458
			);
459
			$term_taxonomy = array(
460
				'term_taxonomy_id' => $term_object->term_taxonomy_id,
461
				'term_id'          => $term_object->term_id,
462
				'taxonomy'         => $term_object->taxonomy,
463
				'description'      => $term_object->description,
464
				'parent'           => (int) $term_object->parent,
465
				'count'            => (int) $term_object->count,
466
			);
467
			$wpdb->insert( $wpdb->terms, $term );
468
			$wpdb->insert( $wpdb->term_taxonomy, $term_taxonomy );
469
470
//			clean_term_cache( $term_object->term_id, $taxonomy );
471
472
			return true;
473
		}
474
475
		return wp_update_term( $term_object->term_id, $taxonomy, (array) $term_object );
476
	}
477
478
	public function delete_term( $term_id, $taxonomy ) {
479
		return wp_delete_term( $term_id, $taxonomy );
480
	}
481
482
	public function update_object_terms( $object_id, $taxonomy, $terms, $append ) {
483
		wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
484
	}
485
486
	public function delete_object_terms( $object_id, $tt_ids ) {
487
		global $wpdb;
488
489
		if ( is_array( $tt_ids ) && ! empty( $tt_ids ) ) {
490
			$taxonomies = array();
491
			foreach ( $tt_ids as $tt_id ) {
492
				$term                            = get_term_by( 'term_taxonomy_id', $tt_id );
493
				$taxonomies[ $term->taxonomy ][] = $tt_id;
494
			}
495
			$in_tt_ids = "'" . implode( "', '", $tt_ids ) . "'";
496
497
			/**
498
			 * Fires immediately before an object-term relationship is deleted.
499
			 *
500
			 * @since 2.9.0
501
			 *
502
			 * @param int $object_id Object ID.
503
			 * @param array $tt_ids An array of term taxonomy IDs.
504
			 */
505
			do_action( 'delete_term_relationships', $object_id, $tt_ids );
506
			$deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) );
507
			foreach ( $taxonomies as $taxonomy => $taxonomy_tt_ids ) {
508
				wp_cache_delete( $object_id, $taxonomy . '_relationships' );
509
				/**
510
				 * Fires immediately after an object-term relationship is deleted.
511
				 *
512
				 * @since 2.9.0
513
				 *
514
				 * @param int $object_id Object ID.
515
				 * @param array $tt_ids An array of term taxonomy IDs.
516
				 */
517
				do_action( 'deleted_term_relationships', $object_id, $taxonomy_tt_ids );
518
				wp_update_term_count( $taxonomy_tt_ids, $taxonomy );
519
			}
520
521
			return (bool) $deleted;
522
		}
523
524
		return false;
525
	}
526
527
	// users
528
	public function user_count() {
529
530
	}
531
532
	public function get_user( $user_id ) {
533
		return WP_User::get_instance( $user_id );
534
	}
535
536
	public function upsert_user( $user ) {
537
		$this->invalid_call();
538
	}
539
540
	public function delete_user( $user_id ) {
541
		$this->invalid_call();
542
	}
543
544
	public function checksum_all() {
545
		return array(
546
			'posts'    => $this->posts_checksum(),
547
			'comments' => $this->comments_checksum()
548
		);
549
	}
550
551
	private function invalid_call() {
552
		$backtrace = debug_backtrace();
553
		$caller    = $backtrace[1]['function'];
554
		throw new Exception( "This function $caller is not supported on the WP Replicastore" );
555
	}
556
}
557