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
|
|
|
|
12
|
|
|
public function reset() { |
13
|
|
|
global $wpdb; |
14
|
|
|
|
15
|
|
|
$wpdb->query( "DELETE FROM $wpdb->posts" ); |
16
|
|
|
$wpdb->query( "DELETE FROM $wpdb->comments" ); |
17
|
|
|
|
18
|
|
|
// also need to delete terms from cache |
19
|
|
|
$term_ids = $wpdb->get_col( "SELECT term_id FROM $wpdb->terms" ); |
20
|
|
|
foreach ( $term_ids as $term_id ) { |
21
|
|
|
wp_cache_delete( $term_id, 'terms' ); |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
$wpdb->query( "DELETE FROM $wpdb->terms" ); |
25
|
|
|
|
26
|
|
|
$wpdb->query( "DELETE FROM $wpdb->term_taxonomy" ); |
27
|
|
|
$wpdb->query( "DELETE FROM $wpdb->term_relationships" ); |
28
|
|
|
|
29
|
|
|
// callables and constants |
30
|
|
|
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'jetpack_%'" ); |
31
|
|
|
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key NOT LIKE '\_%'" ); |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
function full_sync_start() { |
35
|
|
|
$this->reset(); |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
function full_sync_end( $checksum ) { |
39
|
|
|
// noop right now |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function post_count( $status = null ) { |
43
|
|
|
return count( $this->get_posts( $status ) ); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
public function get_posts( $status = null ) { |
47
|
|
|
$args = array( 'orderby' => 'ID', 'posts_per_page' => -1 ); |
48
|
|
|
|
49
|
|
|
if ( $status ) { |
50
|
|
|
$args['post_status'] = $status; |
51
|
|
|
} else { |
52
|
|
|
$args['post_status'] = 'any'; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
return get_posts( $args ); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function get_post( $id ) { |
59
|
|
|
return get_post( $id ); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
public function upsert_post( $post, $silent = false ) { |
63
|
|
|
global $wpdb; |
64
|
|
|
|
65
|
|
|
// reject the post if it's not a WP_Post |
66
|
|
|
if ( ! $post instanceof WP_Post ) { |
|
|
|
|
67
|
|
|
return; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$post = $post->to_array(); |
71
|
|
|
|
72
|
|
|
// reject posts without an ID |
73
|
|
|
if ( ! isset( $post['ID'] ) ) { |
74
|
|
|
return; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$now = current_time( 'mysql' ); |
78
|
|
|
$now_gmt = get_gmt_from_date( $now ); |
79
|
|
|
|
80
|
|
|
$defaults = array( |
81
|
|
|
'ID' => 0, |
82
|
|
|
'post_author' => '0', |
83
|
|
|
'post_content' => '', |
84
|
|
|
'post_content_filtered' => '', |
85
|
|
|
'post_title' => '', |
86
|
|
|
'post_name' => '', |
87
|
|
|
'post_excerpt' => '', |
88
|
|
|
'post_status' => 'draft', |
89
|
|
|
'post_type' => 'post', |
90
|
|
|
'comment_status' => 'closed', |
91
|
|
|
'comment_count' => '0', |
92
|
|
|
'ping_status' => '', |
93
|
|
|
'post_password' => '', |
94
|
|
|
'to_ping' => '', |
95
|
|
|
'pinged' => '', |
96
|
|
|
'post_parent' => 0, |
97
|
|
|
'menu_order' => 0, |
98
|
|
|
'guid' => '', |
99
|
|
|
'post_date' => $now, |
100
|
|
|
'post_date_gmt' => $now_gmt, |
101
|
|
|
'post_modified' => $now, |
102
|
|
|
'post_modified_gmt' => $now_gmt, |
103
|
|
|
); |
104
|
|
|
|
105
|
|
|
$post = array_intersect_key( $post, $defaults ); |
106
|
|
|
|
107
|
|
|
$post = sanitize_post( $post, 'db' ); |
108
|
|
|
|
109
|
|
|
unset( $post['filter'] ); |
110
|
|
|
|
111
|
|
|
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT EXISTS( SELECT 1 FROM $wpdb->posts WHERE ID = %d )", $post['ID'] ) ); |
112
|
|
|
|
113
|
|
|
if ( $exists ) { |
114
|
|
|
$wpdb->update( $wpdb->posts, $post, array( 'ID' => $post['ID'] ) ); |
115
|
|
|
} else { |
116
|
|
|
$wpdb->insert( $wpdb->posts, $post ); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
clean_post_cache( $post['ID'] ); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
public function delete_post( $post_id ) { |
123
|
|
|
wp_delete_post( $post_id, true ); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
public function posts_checksum( $min_id = null, $max_id = null ) { |
127
|
|
|
global $wpdb; |
128
|
|
|
|
129
|
|
|
$where_sql = Jetpack_Sync_Defaults::get_blacklisted_post_types_sql(); |
130
|
|
|
|
131
|
|
|
if ( $min_id !== null ) { |
132
|
|
|
$min_id = intval( $min_id ); |
133
|
|
|
$where_sql .= " AND ID >= $min_id"; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
if ( $max_id !== null ) { |
137
|
|
|
$max_id = intval( $max_id ); |
138
|
|
|
$where_sql .= " AND ID <= $max_id"; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
$query = <<<ENDSQL |
142
|
|
|
SELECT CONV(BIT_XOR(CRC32(CONCAT(ID,post_modified))), 10, 16) |
143
|
|
|
FROM $wpdb->posts |
144
|
|
|
WHERE $where_sql |
145
|
|
|
ENDSQL; |
146
|
|
|
|
147
|
|
|
return $wpdb->get_var( $query ); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function comment_count( $status = null ) { |
151
|
|
|
global $wpdb; |
152
|
|
|
|
153
|
|
|
$comment_approved = $this->comment_status_to_approval_value( $status ); |
154
|
|
|
|
155
|
|
|
if ( $comment_approved !== false ) { |
156
|
|
|
return $wpdb->get_var( $wpdb->prepare( |
157
|
|
|
"SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = %s", |
158
|
|
|
$comment_approved |
159
|
|
|
) ); |
160
|
|
|
} else { |
161
|
|
|
return $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments" ); |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
private function comment_status_to_approval_value( $status ) { |
166
|
|
|
switch ( $status ) { |
167
|
|
|
case 'approve': |
168
|
|
|
return "1"; |
169
|
|
|
case 'hold': |
170
|
|
|
return "0"; |
171
|
|
|
case 'spam': |
172
|
|
|
return 'spam'; |
173
|
|
|
case 'trash': |
174
|
|
|
return 'trash'; |
175
|
|
|
case 'any': |
176
|
|
|
return false; |
177
|
|
|
case 'all': |
178
|
|
|
return false; |
179
|
|
|
default: |
180
|
|
|
return false; |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
public function get_comments( $status = null ) { |
185
|
|
|
$args = array( 'orderby' => 'ID', 'status' => 'all' ); |
186
|
|
|
|
187
|
|
|
if ( $status ) { |
188
|
|
|
$args['status'] = $status; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return get_comments( $args ); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
public function get_comment( $id ) { |
195
|
|
|
return WP_Comment::get_instance( $id ); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
public function upsert_comment( $comment ) { |
199
|
|
|
global $wpdb, $wp_version; |
200
|
|
|
|
201
|
|
|
if ( version_compare( $wp_version, '4.4', '<' ) ) { |
202
|
|
|
$comment = (array) $comment; |
203
|
|
|
} else { |
204
|
|
|
// WP 4.4 introduced the WP_Comment Class |
205
|
|
|
$comment = $comment->to_array(); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
// filter by fields on comment table |
209
|
|
|
$comment_fields_whitelist = array( |
210
|
|
|
'comment_ID', |
211
|
|
|
'comment_post_ID', |
212
|
|
|
'comment_author', |
213
|
|
|
'comment_author_email', |
214
|
|
|
'comment_author_url', |
215
|
|
|
'comment_author_IP', |
216
|
|
|
'comment_date', |
217
|
|
|
'comment_date_gmt', |
218
|
|
|
'comment_content', |
219
|
|
|
'comment_karma', |
220
|
|
|
'comment_approved', |
221
|
|
|
'comment_agent', |
222
|
|
|
'comment_type', |
223
|
|
|
'comment_parent', |
224
|
|
|
'user_id' |
225
|
|
|
); |
226
|
|
|
|
227
|
|
|
foreach ( $comment as $key => $value ) { |
228
|
|
|
if ( ! in_array( $key, $comment_fields_whitelist ) ) { |
229
|
|
|
unset( $comment[ $key ] ); |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
$exists = $wpdb->get_var( |
234
|
|
|
$wpdb->prepare( |
235
|
|
|
"SELECT EXISTS( SELECT 1 FROM $wpdb->comments WHERE comment_ID = %d )", |
236
|
|
|
$comment['comment_ID'] |
237
|
|
|
) |
238
|
|
|
); |
239
|
|
|
|
240
|
|
|
if ( $exists ) { |
241
|
|
|
$wpdb->update( $wpdb->comments, $comment, array( 'comment_ID' => $comment['comment_ID'] ) ); |
242
|
|
|
} else { |
243
|
|
|
$wpdb->insert( $wpdb->comments, $comment ); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
wp_update_comment_count( $comment['comment_post_ID'] ); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
public function trash_comment( $comment_id ) { |
250
|
|
|
wp_delete_comment( $comment_id ); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
public function delete_comment( $comment_id ) { |
254
|
|
|
wp_delete_comment( $comment_id, true ); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
public function spam_comment( $comment_id ) { |
258
|
|
|
wp_spam_comment( $comment_id ); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
public function comments_checksum() { |
262
|
|
|
global $wpdb; |
263
|
|
|
|
264
|
|
|
$query = <<<ENDSQL |
265
|
|
|
SELECT CONV(BIT_XOR(CRC32(CONCAT(comment_ID,comment_content))), 10, 16) FROM $wpdb->comments |
266
|
|
|
ENDSQL; |
267
|
|
|
|
268
|
|
|
return $wpdb->get_var( $query ); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
public function options_checksum() { |
272
|
|
|
global $wpdb; |
273
|
|
|
|
274
|
|
|
$options_whitelist = "'" . implode( "', '", Jetpack_Sync_Defaults::$default_options_whitelist ) . "'"; |
|
|
|
|
275
|
|
|
$query = <<<ENDSQL |
276
|
|
|
SELECT CONV(BIT_XOR(CRC32(CONCAT(option_name,option_value))), 10, 16) FROM $wpdb->options WHERE option_name IN ( $options_whitelist ) |
277
|
|
|
ENDSQL; |
278
|
|
|
|
279
|
|
|
return $wpdb->get_var( $query ); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
|
283
|
|
|
public function update_option( $option, $value ) { |
284
|
|
|
return update_option( $option, $value ); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
public function get_option( $option, $default = false ) { |
288
|
|
|
return get_option( $option, $default ); |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
public function delete_option( $option ) { |
292
|
|
|
return delete_option( $option ); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
public function set_theme_support( $theme_support ) { |
296
|
|
|
// noop |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
public function current_theme_supports( $feature ) { |
300
|
|
|
return current_theme_supports( $feature ); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
public function get_metadata( $type, $object_id, $meta_key = '', $single = false ) { |
304
|
|
|
return get_metadata( $type, $object_id, $meta_key, $single ); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* |
309
|
|
|
* Stores remote meta key/values alongside an ID mapping key |
310
|
|
|
* |
311
|
|
|
* @param $type |
312
|
|
|
* @param $object_id |
313
|
|
|
* @param $meta_key |
314
|
|
|
* @param $meta_value |
315
|
|
|
* @param $meta_id |
316
|
|
|
* |
317
|
|
|
* @return bool |
318
|
|
|
*/ |
319
|
|
|
public function upsert_metadata( $type, $object_id, $meta_key, $meta_value, $meta_id ) { |
320
|
|
|
|
321
|
|
|
$table = _get_meta_table( $type ); |
322
|
|
|
if ( ! $table ) { |
323
|
|
|
return false; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
global $wpdb; |
327
|
|
|
|
328
|
|
|
$exists = $wpdb->get_var( $wpdb->prepare( |
329
|
|
|
"SELECT EXISTS( SELECT 1 FROM $table WHERE meta_id = %d )", |
330
|
|
|
$meta_id |
331
|
|
|
) ); |
332
|
|
|
|
333
|
|
|
if ( $exists ) { |
334
|
|
|
$wpdb->update( $table, array( 'meta_key' => $meta_key, |
335
|
|
|
'meta_value' => serialize( $meta_value ) |
336
|
|
|
), array( 'meta_id' => $meta_id ) ); |
337
|
|
|
} else { |
338
|
|
|
$object_id_field = $type . '_id'; |
339
|
|
|
$wpdb->insert( $table, array( 'meta_id' => $meta_id, |
340
|
|
|
$object_id_field => $object_id, |
341
|
|
|
'meta_key' => $meta_key, |
342
|
|
|
'meta_value' => serialize( $meta_value ) |
343
|
|
|
) ); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
wp_cache_delete( $object_id, $type . '_meta' ); |
347
|
|
|
|
348
|
|
|
return true; |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
public function delete_metadata( $type, $object_id, $meta_ids ) { |
352
|
|
|
global $wpdb; |
353
|
|
|
|
354
|
|
|
$table = _get_meta_table( $type ); |
355
|
|
|
if ( ! $table ) { |
356
|
|
|
return false; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
foreach ( $meta_ids as $meta_id ) { |
360
|
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM $table WHERE meta_id = %d", $meta_id ) ); |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
// if we don't have an object ID what do we do - invalidate ALL meta? |
364
|
|
|
if ( $object_id ) { |
365
|
|
|
wp_cache_delete( $object_id, $type . '_meta' ); |
366
|
|
|
} |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
// constants |
370
|
|
|
public function get_constant( $constant ) { |
371
|
|
|
$value = get_option( 'jetpack_constant_' . $constant ); |
372
|
|
|
|
373
|
|
|
if ( $value ) { |
374
|
|
|
return $value; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
return null; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
public function set_constant( $constant, $value ) { |
381
|
|
|
update_option( 'jetpack_constant_' . $constant, $value ); |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
public function get_updates( $type ) { |
385
|
|
|
$all_updates = get_option( 'jetpack_updates', array() ); |
386
|
|
|
|
387
|
|
|
if ( isset( $all_updates[ $type ] ) ) { |
388
|
|
|
return $all_updates[ $type ]; |
389
|
|
|
} else { |
390
|
|
|
return null; |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
public function set_updates( $type, $updates ) { |
395
|
|
|
$all_updates = get_option( 'jetpack_updates', array() ); |
396
|
|
|
$all_updates[ $type ] = $updates; |
397
|
|
|
update_option( 'jetpack_updates', $all_updates ); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
// functions |
401
|
|
|
public function get_callable( $name ) { |
402
|
|
|
$value = get_option( 'jetpack_' . $name ); |
403
|
|
|
|
404
|
|
|
if ( $value ) { |
405
|
|
|
return $value; |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
return null; |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
public function set_callable( $name, $value ) { |
412
|
|
|
update_option( 'jetpack_' . $name, $value ); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
// network options |
416
|
|
|
public function get_site_option( $option ) { |
417
|
|
|
return get_option( 'jetpack_network_' . $option ); |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
public function update_site_option( $option, $value ) { |
421
|
|
|
return update_option( 'jetpack_network_' . $option, $value ); |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
public function delete_site_option( $option ) { |
425
|
|
|
return delete_option( 'jetpack_network_' . $option ); |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
// terms |
429
|
|
|
// terms |
430
|
|
|
public function get_terms( $taxonomy ) { |
431
|
|
|
return get_terms( $taxonomy ); |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
public function get_term( $taxonomy, $term_id, $is_term_id = true ) { |
435
|
|
|
$t = $this->ensure_taxonomy( $taxonomy ); |
436
|
|
|
if ( ! $t || is_wp_error( $t ) ) { |
437
|
|
|
return $t; |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
return get_term( $term_id, $taxonomy ); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
private function ensure_taxonomy( $taxonomy ) { |
444
|
|
|
if ( ! taxonomy_exists( $taxonomy ) ) { |
445
|
|
|
// try re-registering synced taxonomies |
446
|
|
|
$taxonomies = $this->get_callable( 'taxonomies' ); |
447
|
|
|
if ( ! isset( $taxonomies[ $taxonomy ] ) ) { |
448
|
|
|
// doesn't exist, or somehow hasn't been synced |
449
|
|
|
return new WP_Error( 'invalid_taxonomy', "The taxonomy '$taxonomy' doesn't exist" ); |
450
|
|
|
} |
451
|
|
|
$t = $taxonomies[ $taxonomy ]; |
452
|
|
|
|
453
|
|
|
return register_taxonomy( |
454
|
|
|
$taxonomy, |
455
|
|
|
$t->object_type, |
456
|
|
|
(array) $t |
457
|
|
|
); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return true; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
public function get_the_terms( $object_id, $taxonomy ) { |
464
|
|
|
return get_the_terms( $object_id, $taxonomy ); |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
public function update_term( $term_object ) { |
468
|
|
|
$taxonomy = $term_object->taxonomy; |
469
|
|
|
global $wpdb; |
470
|
|
|
$exists = $wpdb->get_var( $wpdb->prepare( |
471
|
|
|
"SELECT EXISTS( SELECT 1 FROM $wpdb->terms WHERE term_id = %d )", |
472
|
|
|
$term_object->term_id |
473
|
|
|
) ); |
474
|
|
|
if ( ! $exists ) { |
475
|
|
|
$term_object = sanitize_term( clone( $term_object ), $taxonomy, 'db' ); |
476
|
|
|
$term = array( |
477
|
|
|
'term_id' => $term_object->term_id, |
478
|
|
|
'name' => $term_object->name, |
479
|
|
|
'slug' => $term_object->slug, |
480
|
|
|
'term_group' => $term_object->term_group, |
481
|
|
|
); |
482
|
|
|
$term_taxonomy = array( |
483
|
|
|
'term_taxonomy_id' => $term_object->term_taxonomy_id, |
484
|
|
|
'term_id' => $term_object->term_id, |
485
|
|
|
'taxonomy' => $term_object->taxonomy, |
486
|
|
|
'description' => $term_object->description, |
487
|
|
|
'parent' => (int) $term_object->parent, |
488
|
|
|
'count' => (int) $term_object->count, |
489
|
|
|
); |
490
|
|
|
$wpdb->insert( $wpdb->terms, $term ); |
491
|
|
|
$wpdb->insert( $wpdb->term_taxonomy, $term_taxonomy ); |
492
|
|
|
|
493
|
|
|
// clean_term_cache( $term_object->term_id, $taxonomy ); |
494
|
|
|
|
495
|
|
|
return true; |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
return wp_update_term( $term_object->term_id, $taxonomy, (array) $term_object ); |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
public function delete_term( $term_id, $taxonomy ) { |
502
|
|
|
return wp_delete_term( $term_id, $taxonomy ); |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
public function update_object_terms( $object_id, $taxonomy, $terms, $append ) { |
506
|
|
|
wp_set_object_terms( $object_id, $terms, $taxonomy, $append ); |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
public function delete_object_terms( $object_id, $tt_ids ) { |
510
|
|
|
global $wpdb; |
511
|
|
|
|
512
|
|
|
if ( is_array( $tt_ids ) && ! empty( $tt_ids ) ) { |
513
|
|
|
$taxonomies = array(); |
514
|
|
|
foreach ( $tt_ids as $tt_id ) { |
515
|
|
|
$term = get_term_by( 'term_taxonomy_id', $tt_id ); |
516
|
|
|
$taxonomies[ $term->taxonomy ][] = $tt_id; |
517
|
|
|
} |
518
|
|
|
$in_tt_ids = "'" . implode( "', '", $tt_ids ) . "'"; |
519
|
|
|
|
520
|
|
|
/** |
521
|
|
|
* Fires immediately before an object-term relationship is deleted. |
522
|
|
|
* |
523
|
|
|
* @since 2.9.0 |
524
|
|
|
* |
525
|
|
|
* @param int $object_id Object ID. |
526
|
|
|
* @param array $tt_ids An array of term taxonomy IDs. |
527
|
|
|
*/ |
528
|
|
|
do_action( 'delete_term_relationships', $object_id, $tt_ids ); |
529
|
|
|
$deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) ); |
530
|
|
|
foreach ( $taxonomies as $taxonomy => $taxonomy_tt_ids ) { |
531
|
|
|
wp_cache_delete( $object_id, $taxonomy . '_relationships' ); |
532
|
|
|
/** |
533
|
|
|
* Fires immediately after an object-term relationship is deleted. |
534
|
|
|
* |
535
|
|
|
* @since 2.9.0 |
536
|
|
|
* |
537
|
|
|
* @param int $object_id Object ID. |
538
|
|
|
* @param array $tt_ids An array of term taxonomy IDs. |
539
|
|
|
*/ |
540
|
|
|
do_action( 'deleted_term_relationships', $object_id, $taxonomy_tt_ids ); |
541
|
|
|
wp_update_term_count( $taxonomy_tt_ids, $taxonomy ); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
return (bool) $deleted; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
return false; |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
// users |
551
|
|
|
public function user_count() { |
552
|
|
|
|
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
public function get_user( $user_id ) { |
556
|
|
|
return WP_User::get_instance( $user_id ); |
557
|
|
|
} |
558
|
|
|
|
559
|
|
|
public function upsert_user( $user ) { |
560
|
|
|
$this->invalid_call(); |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
public function delete_user( $user_id ) { |
564
|
|
|
$this->invalid_call(); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
public function get_allowed_mime_types( $user_id ) { |
568
|
|
|
|
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
public function checksum_all() { |
572
|
|
|
return array( |
573
|
|
|
'posts' => $this->posts_checksum(), |
574
|
|
|
'comments' => $this->comments_checksum(), |
575
|
|
|
'options' => $this->options_checksum(), |
576
|
|
|
); |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
function checksum_histogram( $object_type, $buckets, $start_id, $end_id ) { |
580
|
|
|
global $wpdb; |
581
|
|
|
|
582
|
|
|
switch( $object_type ) { |
583
|
|
|
case "posts": |
584
|
|
|
$object_count = $this->post_count(); |
585
|
|
|
$object_table = $wpdb->posts; |
586
|
|
|
$id_field = 'ID'; |
587
|
|
|
$checksum_method = array( $this, 'posts_checksum' ); |
588
|
|
|
break; |
589
|
|
|
case "comments": |
590
|
|
|
$object_count = $this->comment_count(); |
591
|
|
|
$object_table = $wpdb->comments; |
592
|
|
|
$id_field = 'comment_ID'; |
593
|
|
|
$checksum_method = array( $this, 'comments_checksum' ); |
594
|
|
|
break; |
595
|
|
|
default: |
596
|
|
|
return false; |
597
|
|
|
} |
598
|
|
|
|
599
|
|
|
$bucket_size = intval( ceil( $object_count / $buckets ) ); |
600
|
|
|
$query_offset = 0; |
601
|
|
|
$histogram = array(); |
602
|
|
|
|
603
|
|
|
do { |
604
|
|
|
list( $first_id, $last_id ) = $wpdb->get_row( |
605
|
|
|
"SELECT MIN($id_field) as min_id, MAX($id_field) as max_id FROM ( SELECT $id_field FROM $object_table ORDER BY $id_field ASC LIMIT $query_offset, $bucket_size ) as ids", |
606
|
|
|
ARRAY_N |
607
|
|
|
); |
608
|
|
|
|
609
|
|
|
// get the checksum value |
610
|
|
|
$value = call_user_func( $checksum_method, $first_id, $last_id ); |
611
|
|
|
|
612
|
|
|
if ( $first_id === null || $last_id === null ) { |
613
|
|
|
break; |
614
|
|
|
} elseif ( $first_id === $last_id ) { |
615
|
|
|
$histogram[$first_id] = $value; |
616
|
|
|
} else { |
617
|
|
|
$histogram["{$first_id}-{$last_id}"] = $value; |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
$query_offset += $bucket_size; |
621
|
|
|
} while ( true ); |
622
|
|
|
|
623
|
|
|
return $histogram; |
624
|
|
|
} |
625
|
|
|
|
626
|
|
|
private function invalid_call() { |
627
|
|
|
$backtrace = debug_backtrace(); |
628
|
|
|
$caller = $backtrace[1]['function']; |
629
|
|
|
throw new Exception( "This function $caller is not supported on the WP Replicastore" ); |
630
|
|
|
} |
631
|
|
|
} |
632
|
|
|
|
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 thecomposer.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
orrequire-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 you have not tested against this specific condition, such errors might go unnoticed.