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 +196 -0 16.2-beta → 16.3-beta View file →
@@ -1,0 +1,196 @@
1 +<?php
2 +/**
3 + * Meta sync module.
4 + *
5 + * @package automattic/jetpack-sync
6 + */
7 +
8 +namespace Automattic\Jetpack\Sync\Modules;
9 +
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
14 +/**
15 + * Class to handle sync for meta.
16 + */
17 +class Meta extends Module {
18 + /**
19 + * Sync module name.
20 + *
21 + * @access public
22 + *
23 + * @return string
24 + */
25 + public function name() {
26 + return 'meta';
27 + }
28 +
29 + /**
30 + * This implementation of get_objects_by_id() is a bit hacky since we're not passing in an array of meta IDs,
31 + * but instead an array of post or comment IDs for which to retrieve meta for. On top of that,
32 + * we also pass in an associative array where we expect there to be 'meta_key' and 'ids' keys present.
33 + *
34 + * This seemed to be required since if we have missing meta on WP.com and need to fetch it, we don't know what
35 + * the meta key is, but we do know that we have missing meta for a given post or comment.
36 + *
37 + * @todo Refactor the $wpdb->prepare call to use placeholders.
38 + *
39 + * @param string $object_type The type of object for which we retrieve meta. Either 'post' or 'comment'.
40 + * @param array $config Must include 'meta_key' and 'ids' keys.
41 + *
42 + * @return array
43 + */
44 + public function get_objects_by_id( $object_type, $config ) {
45 + global $wpdb;
46 +
47 + $table = _get_meta_table( $object_type );
48 +
49 + if ( ! $table ) {
50 + return array();
51 + }
52 +
53 + if ( ! is_array( $config ) ) {
54 + return array();
55 + }
56 +
57 + $object_id_column = $object_type . '_id';
58 + $object_key_pairs = array();
59 +
60 + foreach ( $config as $item ) {
61 + if ( isset( $item['id'] ) && isset( $item['meta_key'] ) ) {
62 + $object_key_pairs[ (int) $item['id'] ][] = (string) $item['meta_key'];
63 + }
64 + }
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 +
95 + return $meta_objects;
96 + }
97 +
98 + /**
99 + * Get a single Meta Result.
100 + *
101 + * @param string $object_type post, comment, term, user.
102 + * @param int|null $id Object ID.
103 + * @param string|null $meta_key Meta Key.
104 + *
105 + * @return mixed|null
106 + */
107 + public function get_object_by_id( $object_type, $id = null, $meta_key = null ) {
108 + global $wpdb;
109 +
110 + if ( ! is_int( $id ) || ! is_string( $meta_key ) ) {
111 + return null;
112 + }
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 +
148 + $table = _get_meta_table( $object_type );
149 + $object_id_column = $object_type . '_id';
150 +
151 + $meta = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
152 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
153 + "SELECT * FROM {$table} WHERE {$where}",
154 + ARRAY_A
155 + );
156 +
157 + if ( ! is_wp_error( $meta ) && ! empty( $meta ) ) {
158 + foreach ( $meta as $meta_entry ) {
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();
165 + }
166 +
167 + $meta_objects[ $key ][] = $this->get_prepared_meta_object( $object_type, $meta_entry );
168 + }
169 + }
170 +
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 + );
195 + }
196 +}