Completed
Push — add/sync-action ( 625fbd...9c2804 )
by
unknown
177:42 queued 169:06
created

Jetpack_Sync_WP_Replicastore::get_term()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 3
eloc 5
c 2
b 1
f 0
nc 2
nop 3
dl 0
loc 8
rs 9.4285
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
	public function set_wp_version( $version ) {
11
		// makes no sense here?
12
	}
13
14
	public function get_wp_version() {
15
		global $wp_version;
16
17
		return $wp_version;
18
	}
19
20
	public function reset() {
21
		global $wpdb;
22
23
		$wpdb->query( "DELETE FROM $wpdb->posts" );
24
		$wpdb->query( "DELETE FROM $wpdb->comments" );
25
26
		// also need to delete terms from cache
27
		$term_ids = $wpdb->get_col( "SELECT term_id FROM $wpdb->terms" );
28
		foreach ( $term_ids as $term_id ) {
29
			wp_cache_delete( $term_id, 'terms' );
30
		}
31
32
		$wpdb->query( "DELETE FROM $wpdb->terms" );
33
34
		$wpdb->query( "DELETE FROM $wpdb->term_taxonomy" );
35
		$wpdb->query( "DELETE FROM $wpdb->term_relationships" );
36
37
		// callables and constants
38
		$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'jetpack_%'" );
39
		$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key NOT LIKE '_%'" ); //TODO: delete by special prefix?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
40
	}
41
42
	function full_sync_start() {
43
		$this->reset();
44
	}
45
46
	function full_sync_end( $checksum ) {
47
		// noop right now
48
	}
49
50
	public function post_count( $status = null ) {
51
		return count( $this->get_posts( $status ) );
52
	}
53
54
	public function get_posts( $status = null ) {
55
		$args = array( 'orderby' => 'ID' );
56
57
		if ( $status ) {
58
			$args['post_status'] = $status;
59
		} else {
60
			$args['post_status'] = 'any';
61
		}
62
63
		return get_posts( $args );
64
	}
65
66
	public function get_post( $id ) {
67
		return get_post( $id );
68
	}
69
70
	public function upsert_post( $post ) {
71
		global $wpdb;
72
73
		// reject the post if it's not a WP_Post
74
		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...
75
			return;
76
		}
77
78
		$post = $post->to_array();
79
80
		// reject posts without an ID
81
		if ( ! isset( $post['ID'] ) ) {
82
			return;
83
		}
84
85
		$now     = current_time( 'mysql' );
86
		$now_gmt = get_gmt_from_date( $now );
87
88
		$defaults = array(
89
			'ID'                    => 0,
90
			'post_author'           => '0',
91
			'post_content'          => '',
92
			'post_content_filtered' => '',
93
			'post_title'            => '',
94
			'post_name'             => '',
95
			'post_excerpt'          => '',
96
			'post_status'           => 'draft',
97
			'post_type'             => 'post',
98
			'comment_status'        => 'closed',
99
			'comment_count'         => '0',
100
			'ping_status'           => '',
101
			'post_password'         => '',
102
			'to_ping'               => '',
103
			'pinged'                => '',
104
			'post_parent'           => 0,
105
			'menu_order'            => 0,
106
			'guid'                  => '',
107
			'post_date'             => $now,
108
			'post_date_gmt'         => $now_gmt,
109
			'post_modified'         => $now,
110
			'post_modified_gmt'     => $now_gmt,
111
		);
112
113
		$post = array_intersect_key( $post, $defaults );
114
115
		$post = sanitize_post( $post, 'db' );
116
117
		unset( $post['filter'] );
118
119
		$exists = $wpdb->get_var( $wpdb->prepare( "SELECT EXISTS( SELECT 1 FROM $wpdb->posts WHERE ID = %d )", $post['ID'] ) );
120
121
		if ( $exists ) {
122
			$wpdb->update( $wpdb->posts, $post, array( 'ID' => $post['ID'] ) );
123
		} else {
124
			$wpdb->insert( $wpdb->posts, $post );
125
		}
126
127
		clean_post_cache( $post['ID'] );
128
	}
129
130
	public function delete_post( $post_id ) {
131
		wp_delete_post( $post_id, true );
132
	}
133
134
	public function posts_checksum() {
135
		global $wpdb;
136
137
		$post_type_sql = Jetpack_Sync_Defaults::get_blacklisted_post_types_sql();
138
139
		$query = <<<ENDSQL
140
			SELECT CONV(BIT_XOR(CRC32(CONCAT(ID,post_modified))), 10, 16) 
141
				FROM $wpdb->posts
142
				WHERE $post_type_sql
143
ENDSQL;
144
145
		return $wpdb->get_var( $query );
146
	}
147
148
	public function comment_count( $status = null ) {
149
		global $wpdb;
150
151
		$comment_approved = $this->comment_status_to_approval_value( $status );
152
153
		if ( $comment_approved !== false ) {
154
			return $wpdb->get_var( $wpdb->prepare(
155
				"SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = %s",
156
				$comment_approved
157
			) );
158
		} else {
159
			return $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments" );
160
		}
161
	}
162
163
	private function comment_status_to_approval_value( $status ) {
164
		switch ( $status ) {
165
			case 'approve':
166
				return "1";
167
			case 'hold':
168
				return "0";
169
			case 'spam':
170
				return 'spam';
171
			case 'trash':
172
				return 'trash';
173
			case 'any':
174
				return false;
175
			case 'all':
176
				return false;
177
			default:
178
				return false;
179
		}
180
	}
181
182
	public function get_comments( $status = null ) {
183
		$args = array( 'orderby' => 'ID', 'status' => 'all' );
184
185
		if ( $status ) {
186
			$args['status'] = $status;
187
		}
188
189
		return get_comments( $args );
190
	}
191
192
	public function get_comment( $id ) {
193
		return WP_Comment::get_instance( $id );
194
	}
195
196
	public function upsert_comment( $comment ) {
197
		global $wpdb, $wp_version;
198
199
		if ( version_compare( $wp_version, '4.4', '<' ) ) {
200
			$comment = (array) $comment;
201
		} else {
202
			// WP 4.4 introduced the WP_Comment Class
203
			$comment = $comment->to_array();
204
		}
205
206
		// filter by fields on comment table
207
		$comment_fields_whitelist = array(
208
			'comment_ID',
209
			'comment_post_ID',
210
			'comment_author',
211
			'comment_author_email',
212
			'comment_author_url',
213
			'comment_author_IP',
214
			'comment_date',
215
			'comment_date_gmt',
216
			'comment_content',
217
			'comment_karma',
218
			'comment_approved',
219
			'comment_agent',
220
			'comment_type',
221
			'comment_parent',
222
			'user_id'
223
		);
224
225
		foreach ( $comment as $key => $value ) {
226
			if ( ! in_array( $key, $comment_fields_whitelist ) ) {
227
				unset( $comment[ $key ] );
228
			}
229
		}
230
231
		$exists = $wpdb->get_var(
232
			$wpdb->prepare(
233
				"SELECT EXISTS( SELECT 1 FROM $wpdb->comments WHERE comment_ID = %d )",
234
				$comment['comment_ID']
235
			)
236
		);
237
238
		if ( $exists ) {
239
			$wpdb->update( $wpdb->comments, $comment, array( 'comment_ID' => $comment['comment_ID'] ) );
240
		} else {
241
			$wpdb->insert( $wpdb->comments, $comment );
242
		}
243
244
		wp_update_comment_count( $comment['comment_post_ID'] );
245
	}
246
247
	public function trash_comment( $comment_id ) {
248
		wp_delete_comment( $comment_id );
249
	}
250
251
	public function delete_comment( $comment_id ) {
252
		wp_delete_comment( $comment_id, true );
253
	}
254
255
	public function spam_comment( $comment_id ) {
256
		wp_spam_comment( $comment_id );
257
	}
258
259
	public function comments_checksum() {
260
		global $wpdb;
261
262
		$query = <<<ENDSQL
263
			SELECT CONV(BIT_XOR(CRC32(CONCAT(comment_ID,comment_content))), 10, 16) FROM $wpdb->comments
264
ENDSQL;
265
266
		return $wpdb->get_var( $query );
267
	}
268
269
	public function update_option( $option, $value ) {
270
		return update_option( $option, $value );
271
	}
272
273
	public function get_option( $option ) {
274
		return get_option( $option );
275
	}
276
277
	public function delete_option( $option ) {
278
		return delete_option( $option );
279
	}
280
281
	public function set_theme_support( $theme_support ) {
282
		// noop
283
	}
284
285
	public function current_theme_supports( $feature ) {
286
		return current_theme_supports( $feature );
287
	}
288
289
	// meta
290
	public function get_metadata( $type, $object_id, $meta_key = '', $single = false ) {
291
		return get_metadata( $type, $object_id, $meta_key, $single );
292
	}
293
294
	public function upsert_metadata( $type, $object_id, $meta_key, $meta_value, $meta_id ) {
295
		// add_metadata( $type, $object_id, $meta_key, $value, $unique );
296
	}
297
298
	public function delete_metadata( $type, $object_id, $meta_ids ) {
299
		// TODO: SQL delete
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
300
		// delete_metadata( $meta_type, $object_id, $meta_key, $meta_value, $delete_all );
301
	}
302
303
	// constants
304
	public function get_constant( $constant ) {
305
		$value = get_option( 'jetpack_constant_' . $constant );
306
307
		if ( $value ) {
308
			return $value;
309
		}
310
311
		return null;
312
	}
313
314
	public function set_constants( $constants ) {
315
		global $wpdb;
316
317
		$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'jetpack_constant_%'" );
318
319
		foreach ( $constants as $key => $value ) {
320
			update_option( 'jetpack_constant_' . $key, $value );
321
		}
322
	}
323
324
	public function get_updates( $type ) {
325
		$all_updates = get_option( 'jetpack_updates', array() );
326
327
		if ( isset( $all_updates[ $type ] ) ) {
328
			return $all_updates[ $type ];
329
		} else {
330
			return null;
331
		}
332
	}
333
334
	public function set_updates( $type, $updates ) {
335
		$all_updates          = get_option( 'jetpack_updates', array() );
336
		$all_updates[ $type ] = $updates;
337
		update_option( 'jetpack_updates', $all_updates );
338
	}
339
340
	// functions
341
	public function get_callable( $name ) {
342
		$value = get_option( 'jetpack_' . $name );
343
344
		if ( $value ) {
345
			return $value;
346
		}
347
348
		return null;
349
	}
350
351
	public function set_callable( $name, $value ) {
352
		update_option( 'jetpack_' . $name, $value );
353
	}
354
355
	// network options
356
	public function get_site_option( $option ) {
357
		return get_option( 'jetpack_network_' . $option );
358
	}
359
360
	public function update_site_option( $option, $value ) {
361
		return update_option( 'jetpack_network_' . $option, $value );
362
	}
363
364
	public function delete_site_option( $option ) {
365
		return delete_option( 'jetpack_network_' . $option );
366
	}
367
368
	// terms
369
	// terms
370
	public function get_terms( $taxonomy ) {
371
		return get_terms( $taxonomy );
372
	}
373
374
	public function get_term( $taxonomy, $term_id, $is_term_id = true ) {
375
		$t = $this->ensure_taxonomy( $taxonomy );
376
		if ( ! $t || is_wp_error( $t ) ) {
377
			return $t;
378
		}
379
380
		return get_term( $term_id, $taxonomy );
381
	}
382
383
	private function ensure_taxonomy( $taxonomy ) {
384
		if ( ! taxonomy_exists( $taxonomy ) ) {
385
			// try re-registering synced taxonomies
386
			$taxonomies = $this->get_callable( 'taxonomies' );
387
			if ( ! isset( $taxonomies[ $taxonomy ] ) ) {
388
				// doesn't exist, or somehow hasn't been synced
389
				return new WP_Error( 'invalid_taxonomy', "The taxonomy '$taxonomy' doesn't exist" );
390
			}
391
			$t = $taxonomies[ $taxonomy ];
392
393
			return register_taxonomy(
394
				$taxonomy,
395
				$t->object_type,
396
				(array) $t
397
			);
398
		}
399
400
		return true;
401
	}
402
403
	public function get_the_terms( $object_id, $taxonomy ) {
404
		return get_the_terms( $object_id, $taxonomy );
405
	}
406
407
	public function update_term( $term_object ) {
408
		$taxonomy = $term_object->taxonomy;
409
		global $wpdb;
410
		$exists = $wpdb->get_var( $wpdb->prepare(
411
			"SELECT EXISTS( SELECT 1 FROM $wpdb->terms WHERE term_id = %d )",
412
			$term_object->term_id
413
		) );
414
		if ( ! $exists ) {
415
			$term_object   = sanitize_term( clone( $term_object ), $taxonomy, 'db' );
416
			$term          = array(
417
				'term_id'    => $term_object->term_id,
418
				'name'       => $term_object->name,
419
				'slug'       => $term_object->slug,
420
				'term_group' => $term_object->term_group,
421
			);
422
			$term_taxonomy = array(
423
				'term_taxonomy_id' => $term_object->term_taxonomy_id,
424
				'term_id'          => $term_object->term_id,
425
				'taxonomy'         => $term_object->taxonomy,
426
				'description'      => $term_object->description,
427
				'parent'           => (int) $term_object->parent,
428
				'count'            => (int) $term_object->count,
429
			);
430
			$wpdb->insert( $wpdb->terms, $term );
431
			$wpdb->insert( $wpdb->term_taxonomy, $term_taxonomy );
432
433
//			clean_term_cache( $term_object->term_id, $taxonomy );
434
435
			return true;
436
		}
437
438
		return wp_update_term( $term_object->term_id, $taxonomy, (array) $term_object );
439
	}
440
441
	public function delete_term( $term_id, $taxonomy ) {
442
		return wp_delete_term( $term_id, $taxonomy );
443
	}
444
445
	public function update_object_terms( $object_id, $taxonomy, $terms, $append ) {
446
		wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
447
	}
448
449
	public function delete_object_terms( $object_id, $tt_ids ) {
450
		global $wpdb;
451
452
		if ( is_array( $tt_ids ) && ! empty( $tt_ids ) ) {
453
			$taxonomies = array();
454
			foreach ( $tt_ids as $tt_id ) {
455
				$term                            = get_term_by( 'term_taxonomy_id', $tt_id );
456
				$taxonomies[ $term->taxonomy ][] = $tt_id;
457
			}
458
			$in_tt_ids = "'" . implode( "', '", $tt_ids ) . "'";
459
460
			/**
461
			 * Fires immediately before an object-term relationship is deleted.
462
			 *
463
			 * @since 2.9.0
464
			 *
465
			 * @param int $object_id Object ID.
466
			 * @param array $tt_ids An array of term taxonomy IDs.
467
			 */
468
			do_action( 'delete_term_relationships', $object_id, $tt_ids );
469
			$deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) );
470
			foreach ( $taxonomies as $taxonomy => $taxonomy_tt_ids ) {
471
				wp_cache_delete( $object_id, $taxonomy . '_relationships' );
472
				/**
473
				 * Fires immediately after an object-term relationship is deleted.
474
				 *
475
				 * @since 2.9.0
476
				 *
477
				 * @param int $object_id Object ID.
478
				 * @param array $tt_ids An array of term taxonomy IDs.
479
				 */
480
				do_action( 'deleted_term_relationships', $object_id, $taxonomy_tt_ids );
481
				wp_update_term_count( $taxonomy_tt_ids, $taxonomy );
482
			}
483
484
			return (bool) $deleted;
485
		}
486
487
		return false;
488
	}
489
490
	// users
491
	public function user_count() {
492
493
	}
494
495
	public function get_user( $user_id ) {
496
		return WP_User::get_instance( $user_id );
497
	}
498
499
	public function upsert_user( $user ) {
500
		$this->invalid_call();
501
	}
502
503
	public function delete_user( $user_id ) {
504
		$this->invalid_call();
505
	}
506
507
	public function checksum_all() {
508
		return array(
509
			'posts'    => $this->posts_checksum(),
510
			'comments' => $this->comments_checksum()
511
		);
512
	}
513
514
	private function invalid_call() {
515
		$backtrace = debug_backtrace();
516
		$caller    = $backtrace[1]['function'];
517
		throw new Exception( "This function $caller is not supported on the WP Replicastore" );
518
	}
519
}
520