PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-sync/src/modules/class-meta.php +109 -25 13.2.4 → 16.3-beta View file →
@@ -6,8 +6,12 @@
6 6 */
7 7
8 8 namespace Automattic\Jetpack\Sync\Modules;
9 9
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
10 14 /**
11 15 * Class to handle sync for meta.
12 16 */
13 17 class Meta extends Module {
@@ -37,8 +41,10 @@
37 41 *
38 42 * @return array
39 43 */
40 44 public function get_objects_by_id( $object_type, $config ) {
45 + global $wpdb;
46 +
41 47 $table = _get_meta_table( $object_type );
42 48
43 49 if ( ! $table ) {
44 50 return array();
@@ -47,17 +53,46 @@
47 53 if ( ! is_array( $config ) ) {
48 54 return array();
49 55 }
50 56
51 - $meta_objects = array();
57 + $object_id_column = $object_type . '_id';
58 + $object_key_pairs = array();
59 +
52 60 foreach ( $config as $item ) {
53 - $meta = null;
54 61 if ( isset( $item['id'] ) && isset( $item['meta_key'] ) ) {
55 - $meta = $this->get_object_by_id( $object_type, (int) $item['id'], (string) $item['meta_key'] );
62 + $object_key_pairs[ (int) $item['id'] ][] = (string) $item['meta_key'];
56 63 }
57 - $meta_objects[ $item['id'] . '-' . $item['meta_key'] ] = $meta;
58 64 }
59 65
66 + $meta_objects = array();
67 + $where_sql = '';
68 + $current_query_length = 0;
69 +
70 + foreach ( $object_key_pairs as $object_id => $keys ) {
71 + $keys_placeholders = implode( ',', array_fill( 0, count( $keys ), '%s' ) );
72 + $where_condition = trim(
73 + $wpdb->prepare(
74 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
75 + "( `$object_id_column` = %d AND meta_key IN ( $keys_placeholders ) )",
76 + array_merge( array( $object_id ), $keys )
77 + )
78 + );
79 +
80 + $where_sql = empty( $where_sql ) ? $where_condition : $where_sql . ' OR ' . $where_condition;
81 +
82 + $current_query_length += strlen( $where_sql );
83 +
84 + if ( $current_query_length > self::MAX_DB_QUERY_LENGTH ) {
85 + $meta_objects = $this->fetch_prepared_meta_from_db( $object_type, $where_sql, $meta_objects );
86 + $where_sql = '';
87 + $current_query_length = 0;
88 + }
89 + }
90 +
91 + if ( ! empty( $where_sql ) ) {
92 + $meta_objects = $this->fetch_prepared_meta_from_db( $object_type, $where_sql, $meta_objects );
93 + }
94 +
60 95 return $meta_objects;
61 96 }
62 97
63 98 /**
@@ -62,11 +97,11 @@
62 97
63 98 /**
64 99 * Get a single Meta Result.
65 100 *
66 - * @param string $object_type post, comment, term, user.
67 - * @param null $id Object ID.
68 - * @param null $meta_key Meta Key.
101 + * @param string $object_type post, comment, term, user.
102 + * @param int|null $id Object ID.
103 + * @param string|null $meta_key Meta Key.
69 104 *
70 105 * @return mixed|null
71 106 */
72 107 public function get_object_by_id( $object_type, $id = null, $meta_key = null ) {
@@ -75,38 +110,87 @@
75 110 if ( ! is_int( $id ) || ! is_string( $meta_key ) ) {
76 111 return null;
77 112 }
78 113
114 + $table = _get_meta_table( $object_type );
115 +
116 + if ( ! $table ) {
117 + return null;
118 + }
119 +
120 + $object_id_column = $object_type . '_id';
121 +
122 + // Sanitize so that the array only has integer values.
123 + $where_condition = $wpdb->prepare(
124 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
125 + "{$object_id_column} = %d AND meta_key = %s",
126 + $id,
127 + $meta_key
128 + );
129 +
130 + $meta_objects = $this->fetch_prepared_meta_from_db( $object_type, $where_condition );
131 +
132 + $key = $id . '-' . $meta_key;
133 +
134 + return $meta_objects[ $key ] ?? null;
135 + }
136 +
137 + /**
138 + * Fetch meta from DB and return them in a standard format.
139 + *
140 + * @param string $object_type The meta object type, eg 'post', 'user' etc.
141 + * @param string $where Prepared SQL 'where' statement.
142 + * @param array $meta_objects An existing array of meta to populate. Defaults to an empty array.
143 + * @return array
144 + */
145 + private function fetch_prepared_meta_from_db( $object_type, $where, $meta_objects = array() ) {
146 + global $wpdb;
147 +
79 148 $table = _get_meta_table( $object_type );
80 149 $object_id_column = $object_type . '_id';
81 150
82 - // Sanitize so that the array only has integer values.
83 - $meta = $wpdb->get_results(
84 - $wpdb->prepare(
151 + $meta = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
85 152 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
86 - "SELECT * FROM {$table} WHERE {$object_id_column} = %d AND meta_key = %s",
87 - $id,
88 - $meta_key
89 - ),
153 + "SELECT * FROM {$table} WHERE {$where}",
90 154 ARRAY_A
91 155 );
92 156
93 - $meta_objects = null;
94 -
95 157 if ( ! is_wp_error( $meta ) && ! empty( $meta ) ) {
96 158 foreach ( $meta as $meta_entry ) {
97 - if ( 'post' === $object_type && strlen( $meta_entry['meta_value'] ) >= Posts::MAX_POST_META_LENGTH ) {
98 - $meta_entry['meta_value'] = '';
159 + $object_id = $meta_entry[ $object_id_column ];
160 + $meta_key = $meta_entry['meta_key'];
161 + $key = $object_id . '-' . $meta_key;
162 +
163 + if ( ! isset( $meta_objects[ $key ] ) ) {
164 + $meta_objects[ $key ] = array();
99 165 }
100 - $meta_objects[] = array(
101 - 'meta_type' => $object_type,
102 - 'meta_id' => $meta_entry['meta_id'],
103 - 'meta_key' => $meta_key,
104 - 'meta_value' => $meta_entry['meta_value'],
105 - 'object_id' => $meta_entry[ $object_id_column ],
106 - );
166 +
167 + $meta_objects[ $key ][] = $this->get_prepared_meta_object( $object_type, $meta_entry );
107 168 }
108 169 }
109 170
110 171 return $meta_objects;
172 + }
173 +
174 + /**
175 + * Accepts a DB meta entry and returns it in a standard format.
176 + *
177 + * @param string $object_type The meta object type, eg 'post', 'user' etc.
178 + * @param array $meta_entry A meta array.
179 + * @return array
180 + */
181 + private function get_prepared_meta_object( $object_type, $meta_entry ) {
182 + $object_id_column = $object_type . '_id';
183 +
184 + if ( 'post' === $object_type && isset( $meta_entry['meta_value'] ) && is_string( $meta_entry['meta_value'] ) && strlen( $meta_entry['meta_value'] ) >= Posts::MAX_META_LENGTH ) {
185 + $meta_entry['meta_value'] = '';
186 + }
187 +
188 + return array(
189 + 'meta_type' => $object_type,
190 + 'meta_id' => $meta_entry['meta_id'],
191 + 'meta_key' => $meta_entry['meta_key'],
192 + 'meta_value' => $meta_entry['meta_value'],
193 + 'object_id' => $meta_entry[ $object_id_column ],
194 + );
111 195 }
112 196 }