PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.3
WooCommerce v10.9.3
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / src / Internal / DataStores / CustomMetaDataStore.php
woocommerce / src / Internal / DataStores Last commit date
Orders 4 weeks ago StockNotifications 10 months ago CustomMetaDataStore.php 4 months ago
CustomMetaDataStore.php
305 lines
1 <?php
2 /**
3 * CustomMetaDataStore class file.
4 */
5
6 namespace Automattic\WooCommerce\Internal\DataStores;
7
8 /**
9 * Implements functions similar to WP's add_metadata(), get_metadata(), and friends using a custom table.
10 *
11 * @see WC_Data_Store_WP For an implementation using WP's metadata functions and tables.
12 */
13 abstract class CustomMetaDataStore {
14
15 /**
16 * Returns the name of the table used for storage.
17 *
18 * @return string
19 */
20 abstract protected function get_table_name();
21
22 /**
23 * Returns the name of the field/column used for identifiying metadata entries.
24 *
25 * @return string
26 */
27 protected function get_meta_id_field() {
28 return 'id';
29 }
30
31 /**
32 * Returns the name of the field/column used for associating meta with objects.
33 *
34 * @return string
35 */
36 protected function get_object_id_field() {
37 return 'object_id';
38 }
39
40 /**
41 * Describes the structure of the metadata table.
42 *
43 * @return array Array elements: table, object_id_field, meta_id_field.
44 */
45 protected function get_db_info() {
46 return array(
47 'table' => $this->get_table_name(),
48 'meta_id_field' => $this->get_meta_id_field(),
49 'object_id_field' => $this->get_object_id_field(),
50 );
51 }
52
53 /**
54 * Returns an array of meta for an object.
55 *
56 * @param \WC_Data $object WC_Data object.
57 * @return array
58 */
59 public function read_meta( &$object ) {
60 $object_id = $object->get_id();
61 $raw_meta_data = $this->get_meta_data_for_object_ids( array( $object_id ) );
62
63 return isset( $raw_meta_data[ $object_id ] ) ? (array) $raw_meta_data[ $object_id ] : array();
64 }
65
66 /**
67 * Deletes meta based on meta ID.
68 *
69 * @param \WC_Data $object WC_Data object.
70 * @param \stdClass $meta (containing at least ->id).
71 *
72 * @return bool
73 */
74 public function delete_meta( &$object, $meta ) : bool {
75 global $wpdb;
76
77 if ( ! isset( $meta->id ) ) {
78 return false;
79 }
80
81 $db_info = $this->get_db_info();
82 $meta_id = absint( $meta->id );
83
84 return (bool) $wpdb->delete(
85 $db_info['table'],
86 array(
87 $db_info['meta_id_field'] => $meta_id,
88 $db_info['object_id_field'] => $object->get_id(),
89 ),
90 '%d'
91 );
92 }
93
94 /**
95 * Add new piece of meta.
96 *
97 * @param WC_Data $object WC_Data object.
98 * @param stdClass $meta (containing ->key and ->value).
99 *
100 * @return int|false meta ID
101 */
102 public function add_meta( &$object, $meta ) {
103 global $wpdb;
104
105 $db_info = $this->get_db_info();
106
107 $object_id = $object->get_id();
108 if ( ! $object_id ) {
109 return false;
110 }
111
112 $meta_key = wp_unslash( wp_slash( $meta->key ) );
113 $meta_value = maybe_serialize( is_string( $meta->value ) ? wp_unslash( wp_slash( $meta->value ) ) : $meta->value );
114
115 // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_value,WordPress.DB.SlowDBQuery.slow_db_query_meta_key
116 $result = $wpdb->insert(
117 $db_info['table'],
118 array(
119 $db_info['object_id_field'] => $object_id,
120 'meta_key' => $meta_key,
121 'meta_value' => $meta_value,
122 )
123 );
124 // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_value,WordPress.DB.SlowDBQuery.slow_db_query_meta_key
125
126 return $result ? (int) $wpdb->insert_id : false;
127 }
128
129 /**
130 * Update meta.
131 *
132 * @param \WC_Data $object WC_Data object.
133 * @param \stdClass $meta (containing ->id, ->key and ->value).
134 *
135 * @return bool
136 */
137 public function update_meta( &$object, $meta ) : bool {
138 global $wpdb;
139
140 if ( ! isset( $meta->id ) || empty( $meta->key ) || ! $object->get_id() ) {
141 return false;
142 }
143
144 // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_value,WordPress.DB.SlowDBQuery.slow_db_query_meta_key
145 $data = array(
146 'meta_key' => $meta->key,
147 'meta_value' => maybe_serialize( $meta->value ),
148 );
149 // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_value,WordPress.DB.SlowDBQuery.slow_db_query_meta_key
150
151 $result = $wpdb->update(
152 $this->get_table_name(),
153 $data,
154 array(
155 $this->get_meta_id_field() => $meta->id,
156 $this->get_object_id_field() => $object->get_id(),
157 ),
158 '%s',
159 '%d'
160 );
161
162 return 1 === $result;
163 }
164
165 /**
166 * Retrieves metadata by meta ID.
167 *
168 * @param int $meta_id Meta ID.
169 * @return object|bool Metadata object or FALSE if not found.
170 */
171 public function get_metadata_by_id( $meta_id ) {
172 global $wpdb;
173
174 if ( ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
175 return false;
176 }
177
178 $db_info = $this->get_db_info();
179
180 $meta_id = absint( $meta_id );
181 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
182 $meta = $wpdb->get_row(
183 $wpdb->prepare(
184 "SELECT {$db_info['meta_id_field']}, meta_key, meta_value, {$db_info['object_id_field']} FROM {$db_info['table']} WHERE {$db_info['meta_id_field']} = %d",
185 $meta_id
186 )
187 );
188 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
189
190 if ( empty( $meta ) ) {
191 return false;
192 }
193
194 if ( isset( $meta->meta_value ) ) {
195 $meta->meta_value = maybe_unserialize( $meta->meta_value );
196 }
197
198 return $meta;
199 }
200
201 /**
202 * Retrieves metadata by meta key.
203 *
204 * @param \WC_Data $object Object ID.
205 * @param string $meta_key Meta key.
206 *
207 * @return \stdClass[]|false Metadata object or FALSE if not found.
208 */
209 public function get_metadata_by_key( &$object, string $meta_key ) {
210 global $wpdb;
211
212 if ( ! $object->get_id() ) {
213 return false;
214 }
215
216 $db_info = $this->get_db_info();
217
218 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
219 $meta = $wpdb->get_results(
220 $wpdb->prepare(
221 "SELECT {$db_info['meta_id_field']}, meta_key, meta_value, {$db_info['object_id_field']} FROM {$db_info['table']} WHERE meta_key = %s AND {$db_info['object_id_field']} = %d",
222 $meta_key,
223 $object->get_id(),
224 )
225 );
226 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
227
228 if ( empty( $meta ) ) {
229 return false;
230 }
231
232 foreach ( $meta as $row ) {
233 if ( isset( $row->meta_value ) ) {
234 $row->meta_value = maybe_unserialize( $row->meta_value );
235 }
236 }
237
238 return $meta;
239 }
240
241 /**
242 * Returns distinct meta keys in use.
243 *
244 * @since 8.8.0
245 *
246 * @param int $limit Maximum number of meta keys to return. Defaults to 100.
247 * @return string[]
248 */
249 public function get_meta_keys( int $limit = 100 ): array {
250 global $wpdb;
251
252 return $wpdb->get_col(
253 $wpdb->prepare(
254 "SELECT DISTINCT meta_key FROM %i WHERE meta_key != '' AND meta_key NOT BETWEEN '_' AND '_z' AND meta_key NOT LIKE %s ORDER BY meta_key ASC LIMIT %d",
255 $this->get_db_info()['table'],
256 $wpdb->esc_like( '_' ) . '%',
257 $limit
258 )
259 );
260 }
261
262 /**
263 * Return order meta data for multiple IDs.
264 *
265 * @param array $object_ids List of object IDs.
266 *
267 * @return \stdClass[][] An array, keyed by object_ids, containing array of raw meta data records for each object. Objects with no meta data will have an empty array.
268 */
269 public function get_meta_data_for_object_ids( array $object_ids ): array {
270 global $wpdb;
271
272 if ( empty( $object_ids ) ) {
273 return array();
274 }
275
276 $id_placeholder = implode( ', ', array_fill( 0, count( $object_ids ), '%d' ) );
277 $meta_table = $this->get_table_name();
278 $object_id_column = $this->get_object_id_field();
279
280 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $object_id_column and $meta_table is hardcoded. IDs are prepared above.
281 $meta_rows = $wpdb->get_results(
282 $wpdb->prepare(
283 "SELECT id, $object_id_column as object_id, meta_key, meta_value FROM $meta_table WHERE $object_id_column in ( $id_placeholder )",
284 $object_ids
285 )
286 );
287 // phpcs:enable
288
289 $meta_data = array_fill_keys( $object_ids, array() );
290 foreach ( $meta_rows as $meta_row ) {
291 if ( ! isset( $meta_data[ $meta_row->object_id ] ) ) {
292 $meta_data[ $meta_row->object_id ] = array();
293 }
294 $meta_data[ $meta_row->object_id ][] = (object) array(
295 'meta_id' => $meta_row->id,
296 'meta_key' => $meta_row->meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
297 'meta_value' => $meta_row->meta_value, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
298 );
299 }
300
301 return $meta_data;
302 }
303
304 }
305