Completed
Push — update/whitelist-post-meta ( 017820 )
by
unknown
10:07
created

Jetpack_Sync_Module_Meta::set_defaults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
class Jetpack_Sync_Module_Meta extends Jetpack_Sync_Module {
4
	private $meta_types = array( 'post', 'comment' );
5
	private $post_meta_whitelist = array();
6
7
	public function name() {
8
		return 'meta';
9
	}
10
11
	public function set_defaults() {
12
		$this->update_post_meta_whitelist();
13
		$this->update_comment_meta_whitelist();
14
	}
15
16
	/**
17
	 * This implementation of get_objects_by_id() is a bit hacky since we're not passing in an array of meta IDs,
18
	 * but instead an array of post or comment IDs for which to retrieve meta for. On top of that,
19
	 * we also pass in an associative array where we expect there to be 'meta_key' and 'ids' keys present.
20
	 *
21
	 * This seemed to be required since if we have missing meta on WP.com and need to fetch it, we don't know what
22
	 * the meta key is, but we do know that we have missing meta for a given post or comment.
23
	 *
24
	 * @param string $object_type The type of object for which we retrieve meta. Either 'post' or 'comment'
25
	 * @param array $config Must include 'meta_key' and 'ids' keys
26
	 *
27
	 * @return array
28
	 */
29
	public function get_objects_by_id( $object_type, $config ) {
30
		global $wpdb;
31
		if ( ! in_array( $object_type, $this->meta_types ) ) {
32
			return array();
33
		}
34
35
		if ( ! isset( $config['meta_key'] ) || ! isset( $config['ids'] ) || ! is_array( $config['ids'] ) ) {
36
			return array();
37
		}
38
39
		$meta_key = $config['meta_key'];
40
		$ids = $config['ids'];
41
42
		if ( ! $this->is_meta_key_allowed( $meta_key ) ) {
43
			return array();
44
		}
45
46
		if ( 'post' == $object_type ) {
47
			$table = $wpdb->postmeta;
48
			$object_id_column = 'post_id';
49
		} else {
50
			$table = $wpdb->commentmeta;
51
			$object_id_column = 'comment_id';
52
		}
53
54
		// Sanitize so that the array only has integer values
55
		$ids_string = implode( ', ', array_map( 'intval', $ids ) );
56
		$metas = $wpdb->get_results(
57
			$wpdb->prepare(
58
				"SELECT * FROM {$table} WHERE {$object_id_column} IN ( {$ids_string} ) AND meta_key = %s",
59
				$meta_key
60
			)
61
		);
62
63
		$meta_objects = array();
64
		foreach( (array) $metas as $meta_object ) {
65
			$meta_object = (array) $meta_object;
66
			$meta_objects[ $meta_object[ $object_id_column ] ] = array(
67
				'meta_type' => $object_type,
68
				'meta_id' => $meta_object['meta_id'],
69
				'meta_key' => $meta_key,
70
				'meta_value' => $meta_object['meta_value'],
71
				'object_id' => $meta_object[ $object_id_column ],
72
			);
73
		}
74
75
		return $meta_objects;
76
	}
77
78
	public function init_listeners( $callable ) {
79
		foreach ( $this->meta_types as $meta_type ) {
80
			add_action( "added_{$meta_type}_meta", $callable, 10, 4 );
81
			add_action( "updated_{$meta_type}_meta", $callable, 10, 4 );
82
			add_action( "deleted_{$meta_type}_meta", $callable, 10, 4 );
83
84
			$whitelist_handler = array( $this, 'filter_meta_' . $meta_type );
85
			add_filter( "jetpack_sync_before_enqueue_added_{$meta_type}_meta", $whitelist_handler );
86
			add_filter( "jetpack_sync_before_enqueue_updated_{$meta_type}_meta", $whitelist_handler );
87
			add_filter( "jetpack_sync_before_enqueue_deleted_{$meta_type}_meta", $whitelist_handler );
88
		}
89
	}
90
	// POST Meta
91
	function update_post_meta_whitelist() {
92
		$this->post_meta_whitelist = Jetpack_Sync_Defaults::$default_whitelist_post_meta_keys;
0 ignored issues
show
Bug introduced by
The property default_whitelist_post_meta_keys cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
93
	}
94
95
	function set_post_meta_whitelist( $post_meta ) {
96
		$this->post_meta_whitelist = $post_meta;
97
	}
98
99
	function get_post_meta_whitelist() {
100
		return $this->post_meta_whitelist;
101
	}
102
103
	function is_whitelisted_post_meta( $option ) {
104
		return in_array( $option, $this->post_meta_whitelist );
105
	}
106
107
	// Comment Meta
108
	function update_comment_meta_whitelist() {
109
		$this->comment_meta_whitelist = Jetpack_Sync_Defaults::$default_whitelist_comment_meta_keys;
0 ignored issues
show
Bug introduced by
The property default_whitelist_comment_meta_keys cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property comment_meta_whitelist 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...
110
	}
111
112
	function set_comment_meta_whitelist( $comment_meta ) {
113
		$this->comment_meta_whitelist = $comment_meta;
114
	}
115
116
	function get_comment_meta_whitelist() {
117
		return $this->comment_meta_whitelist;
118
	}
119
120
	function is_whitelisted_comment_meta( $option ) {
121
		return in_array( $option, $this->comment_meta_whitelist );
122
	}
123
124
125
	/**
126
	 * Should we allow the meta key to be synced?
127
	 *
128
	 * @param string $meta_key The meta key.
129
	 *
130
	 * @return bool
131
	 */
132
	function is_meta_key_allowed( $meta_key ) {
133
		if ( '_' === $meta_key[0] &&
134
		     ! in_array( $meta_key, Jetpack_Sync_Defaults::$default_whitelist_meta_keys ) &&
0 ignored issues
show
Bug introduced by
The property default_whitelist_meta_keys cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
135
		     ! wp_startswith( $meta_key, '_wpas_skip_' )
136
		) {
137
			return false;
138
		}
139
140
		if ( in_array( $meta_key, Jetpack_Sync_Settings::get_setting( 'meta_blacklist' ) ) ) {
141
			return false;
142
		}
143
144
		return true;
145
	}
146
147 View Code Duplication
	function is_post_type_allowed( $post_id ) {
148
		$post = get_post( $post_id );
149
		if ( in_array( $post->post_type, Jetpack_Sync_Settings::get_setting( 'post_types_blacklist' ) ) ) {
150
			return false;
151
		}
152
		return true;
153
	}
154
155
	function filter_meta_post( $args ) {
156
		if ( ! $this->is_post_type_allowed( $args[1] ) ) {
157
			return false;
158
		}
159
		return ( $this->is_whitelisted_comment_meta( $args[2] ) ? $args : false );
160
	}
161
162
	function filter_meta_comment( $args ) {
163
		return ( $this->is_whitelisted_comment_meta( $args[2] ) ? $args : false );
164
	}
165
	
166
}
167