summaryrefslogtreecommitdiff
blob: 504d878134f049751fe4388db1c5f8104b7f8406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php

/**
 * Basic methods implemented by Jetpack Sync extensions
 */
abstract class Jetpack_Sync_Module {
	const ARRAY_CHUNK_SIZE = 10;

	abstract public function name();

	public function get_object_by_id( $object_type, $id ) {
		return false;
	}

	// override these to set up listeners and set/reset data/defaults
	public function init_listeners( $callable ) {
	}

	public function init_full_sync_listeners( $callable ) {
	}

	public function init_before_send() {
	}

	public function set_defaults() {
	}

	public function reset_data() {
	}

	public function enqueue_full_sync_actions( $config ) {
		// in subclasses, return the number of items enqueued
		return 0;
	}

	public function estimate_full_sync_actions( $config ) {
		// in subclasses, return the number of items yet to be enqueued
		return 0;
	}

	public function get_full_sync_actions() {
		return array();
	}

	protected function count_actions( $action_names, $actions_to_count ) {
		return count( array_intersect( $action_names, $actions_to_count ) );
	}

	protected function get_check_sum( $values ) {
		return crc32( json_encode( $values ) );
	}

	protected function still_valid_checksum( $sums_to_check, $name, $new_sum ) {
		if ( isset( $sums_to_check[ $name ] ) && $sums_to_check[ $name ] === $new_sum ) {
			return true;
		}

		return false;
	}

	protected function enqueue_all_ids_as_action( $action_name, $table_name, $id_field, $where_sql ) {
		global $wpdb;

		if ( ! $where_sql ) {
			$where_sql = '1 = 1';
		}

		$items_per_page = 1000;
		$page           = 1;
		$chunk_count    = 0;
		$previous_id    = 0;
		$listener       = Jetpack_Sync_Listener::get_instance();
		while ( $ids = $wpdb->get_col( "SELECT {$id_field} FROM {$table_name} WHERE {$where_sql} AND {$id_field} > {$previous_id} ORDER BY {$id_field} ASC LIMIT {$items_per_page}" ) ) {
			// Request posts in groups of N for efficiency
			$chunked_ids = array_chunk( $ids, self::ARRAY_CHUNK_SIZE );

			$listener->bulk_enqueue_full_sync_actions( $action_name, $chunked_ids );

			$chunk_count += count( $chunked_ids );
			$page += 1;
			$previous_id = end( $ids );
		}

		return $chunk_count;
	}

	protected function get_metadata( $ids, $meta_type ) {
		global $wpdb;
		$table = _get_meta_table( $meta_type );
		$id    = $meta_type . '_id';
		if ( ! $table ) {
			return array();
		}

		$private_meta_whitelist_sql = "'" . implode( "','", array_map( 'esc_sql', Jetpack_Sync_Defaults::$default_whitelist_meta_keys ) ) . "'";
		$public_meta_blacklist_sql = "'" . implode( "','", array_map( 'esc_sql', Jetpack_Sync_Defaults::$default_blacklist_meta_keys ) ) . "'";

		return array_map( 
			array( $this, 'unserialize_meta' ), 
			$wpdb->get_results( 
				"SELECT $id, meta_key, meta_value, meta_id FROM $table WHERE $id IN ( " . implode( ',', wp_parse_id_list( $ids ) ) . ' )'.
				" AND ( ( meta_key LIKE '\_%' AND meta_key IN ( $private_meta_whitelist_sql ) )".
				" OR ( meta_key NOT LIKE '\_%' AND meta_key NOT IN ( $public_meta_blacklist_sql ) ) )",
				OBJECT ) 
		);
	}

	protected function get_term_relationships( $ids ) {
		global $wpdb;

		return $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id IN ( " . implode( ',', wp_parse_id_list( $ids ) ) . ' )', OBJECT );
	}

	public function unserialize_meta( $meta ) {
		$meta->meta_value = maybe_unserialize( $meta->meta_value );
		return $meta;
	}

	public function get_objects_by_id( $object_type, $ids ) {
		if ( empty( $ids ) || empty( $object_type ) ) {
			return array();
		}

		$objects = array();
		foreach( (array) $ids as $id ) {
			$object = $this->get_object_by_id( $object_type, $id );

			// Only add object if we have the object.
			if ( $object ) {
				$objects[ $id ] = $object;
			}
		}

		return $objects;
	}
}