Completed
Push — add/sync-rest-2 ( 96002c...f41908 )
by
unknown
78:57 queued 69:47
created

Jetpack_Sync_Full::enqueue_all_posts()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
c 5
b 1
f 1
dl 0
loc 27
rs 8.8571
cc 3
eloc 14
nc 3
nop 0
1
<?php
2
3
/**
4
 * This class does a full resync of the database by 
5
 * enqueuing an outbound action for every single object
6
 * that we care about.
7
 * 
8
 * This class contains a few non-obvious optimisations that should be explained:
9
 * - we fire an action called jp_full_sync_start so that WPCOM can erase the contents of the cached database
10
 * - for each object type, we obtain a full list of object IDs to sync via a single API call (hoping that since they're ints, they can all fit in RAM)
11
 * - we load the full objects for those IDs in chunks of Jetpack_Sync_Full::$array_chunk_size (to reduce the number of MySQL calls)
12
 * - we fire a trigger for the entire array which the Jetpack_Sync_Client then serializes and queues.
13
 */
14
15
class Jetpack_Sync_Full {
16
	static $array_chunk_size = 5;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $array_chunk_size.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
17
18
	function start() {
19
		$this->client = Jetpack_Sync_Client::getInstance();
0 ignored issues
show
Bug introduced by
The property client does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
20
		do_action( 'jp_full_sync_start' );
21
		$this->enqueue_all_constants();
22
		$this->enqueue_all_functions();
23
		$this->enqueue_all_options();
24
		$this->enqueue_all_posts();
25
		$this->enqueue_all_comments();
26
	}
27
28
	private function enqueue_all_constants() {
29
		$this->client->force_sync_constants();
30
	}
31
32
	private function enqueue_all_functions() {
33
		$this->client->force_sync_callables();
34
	}
35
36
	private function enqueue_all_options() {
37
		global $wpdb;
38
39
		// Unfortunately, since our options whitelist includes regexes,
40
		// we need to load all option names and match them against the whitelist.
41
		// This could be pretty awful if we have huge queues, but it's the only way to 
42
		// be sure we're syncing everything that's whitelisted.
43
44
		// As per posts and comments, we do this in ID batches and hope the IDs *AND* names don't exceed RAM
45
46
		// In theory, MySQL has regex support. In practice, I wouldn't want to rely on it being compatible
47
		// with PHP's regexes.
48
49
		$option_names = $wpdb->get_col( "SELECT option_name FROM $wpdb->options" );
50
51
		// filter by client option whitelist
52
		$option_names = array_filter( $option_names, array( $this->client, 'is_whitelisted_option' ) );
53
54
		foreach ( $option_names as $option_name ) {
55
			do_action( 'jp_full_sync_option', $option_name, get_option( $option_name ) );
56
		}
57
	}
58
59
	private function enqueue_all_posts() {
60
		global $wpdb;
61
62
		// I hope this is never bigger than RAM...
63
		$post_ids = $wpdb->get_col( "SELECT id FROM $wpdb->posts");
64
65
		// Request posts in groups of N for efficiency
66
		$chunked_post_ids = array_chunk( $post_ids, self::$array_chunk_size );
67
68
		// Send each chunk as an array of objects
69
		foreach ( $chunked_post_ids as $chunk ) {
70
			$posts = get_posts( array( 'post__in' => $chunk, 'post_status' => 'any' ) );
71
			do_action( 'jp_full_sync_posts', $posts );
72
73
			// while we're here, sync post meta
74
			foreach( $posts as $post ) {
75
				$postmeta = $wpdb->get_results( 
76
					$wpdb->prepare( 
77
						"SELECT meta_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %s", 
78
						$post->ID 
79
					),
80
					OBJECT
81
				);
82
				do_action( 'jp_full_sync_postmeta', $post->ID, $postmeta );
83
			}
84
		}
85
	}
86
87
	private function enqueue_all_comments() {
88
		global $wpdb;
89
90
		$comment_ids = $wpdb->get_col( "SELECT comment_id FROM $wpdb->comments");
91
		$chunked_comment_ids = array_chunk( $comment_ids, self::$array_chunk_size );
92
93
		foreach ( $chunked_comment_ids as $chunk ) {
94
			$comments = get_comments( array( 'comment__in' => $chunk ) );
95
			do_action( 'jp_full_sync_comments', $comments );
96
		}
97
	}
98
	
99
}