PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
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 13.8.3 13.9.2 14.0.1 All 504 releases
jetpack / jetpack_vendor / automattic / jetpack-sync / src / modules / class-meta.php

class-meta.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.1, at jetpack_vendor/automattic/jetpack-sync/src/modules/class-meta.php

197 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 }
197