15 * |
15 * |
16 * @since 2.9.0 |
16 * @since 2.9.0 |
17 * |
17 * |
18 * @global wpdb $wpdb WordPress database abstraction object. |
18 * @global wpdb $wpdb WordPress database abstraction object. |
19 * |
19 * |
20 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
20 * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
21 * @param int $object_id ID of the object metadata is for |
21 * @param int $object_id ID of the object metadata is for |
22 * @param string $meta_key Metadata key |
22 * @param string $meta_key Metadata key |
23 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
23 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
24 * @param bool $unique Optional, default is false. |
24 * @param bool $unique Optional, default is false. |
25 * Whether the specified metadata key should be unique for the object. |
25 * Whether the specified metadata key should be unique for the object. |
26 * If true, and the object already has a value for the specified metadata key, |
26 * If true, and the object already has a value for the specified metadata key, |
27 * no change will be made. |
27 * no change will be made. |
28 * @return int|false The meta ID on success, false on failure. |
28 * @return int|false The meta ID on success, false on failure. |
29 */ |
29 */ |
30 function add_metadata($meta_type, $object_id, $meta_key, $meta_value, $unique = false) { |
30 function add_metadata( $meta_type, $object_id, $meta_key, $meta_value, $unique = false ) { |
31 global $wpdb; |
31 global $wpdb; |
32 |
32 |
33 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { |
33 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { |
34 return false; |
34 return false; |
35 } |
35 } |
44 return false; |
44 return false; |
45 } |
45 } |
46 |
46 |
47 $meta_subtype = get_object_subtype( $meta_type, $object_id ); |
47 $meta_subtype = get_object_subtype( $meta_type, $object_id ); |
48 |
48 |
49 $column = sanitize_key($meta_type . '_id'); |
49 $column = sanitize_key( $meta_type . '_id' ); |
50 |
50 |
51 // expected_slashed ($meta_key) |
51 // expected_slashed ($meta_key) |
52 $meta_key = wp_unslash($meta_key); |
52 $meta_key = wp_unslash( $meta_key ); |
53 $meta_value = wp_unslash($meta_value); |
53 $meta_value = wp_unslash( $meta_value ); |
54 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); |
54 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); |
55 |
55 |
56 /** |
56 /** |
57 * Filters whether to add metadata of a specific type. |
57 * Filters whether to add metadata of a specific type. |
58 * |
58 * |
59 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
59 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
60 * object type (comment, post, or user). Returning a non-null value |
60 * object type (comment, post, term, or user). Returning a non-null value |
61 * will effectively short-circuit the function. |
61 * will effectively short-circuit the function. |
62 * |
62 * |
63 * @since 3.1.0 |
63 * @since 3.1.0 |
64 * |
64 * |
65 * @param null|bool $check Whether to allow adding metadata for the given type. |
65 * @param null|bool $check Whether to allow adding metadata for the given type. |
68 * @param mixed $meta_value Meta value. Must be serializable if non-scalar. |
68 * @param mixed $meta_value Meta value. Must be serializable if non-scalar. |
69 * @param bool $unique Whether the specified meta key should be unique |
69 * @param bool $unique Whether the specified meta key should be unique |
70 * for the object. Optional. Default false. |
70 * for the object. Optional. Default false. |
71 */ |
71 */ |
72 $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique ); |
72 $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique ); |
73 if ( null !== $check ) |
73 if ( null !== $check ) { |
74 return $check; |
74 return $check; |
75 |
75 } |
76 if ( $unique && $wpdb->get_var( $wpdb->prepare( |
76 |
77 "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d", |
77 if ( $unique && $wpdb->get_var( |
78 $meta_key, $object_id ) ) ) |
78 $wpdb->prepare( |
79 return false; |
79 "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d", |
|
80 $meta_key, |
|
81 $object_id |
|
82 ) |
|
83 ) ) { |
|
84 return false; |
|
85 } |
80 |
86 |
81 $_meta_value = $meta_value; |
87 $_meta_value = $meta_value; |
82 $meta_value = maybe_serialize( $meta_value ); |
88 $meta_value = maybe_serialize( $meta_value ); |
83 |
89 |
84 /** |
90 /** |
85 * Fires immediately before meta of a specific type is added. |
91 * Fires immediately before meta of a specific type is added. |
86 * |
92 * |
87 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
93 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
88 * object type (comment, post, or user). |
94 * object type (comment, post, term, or user). |
89 * |
95 * |
90 * @since 3.1.0 |
96 * @since 3.1.0 |
91 * |
97 * |
92 * @param int $object_id Object ID. |
98 * @param int $object_id Object ID. |
93 * @param string $meta_key Meta key. |
99 * @param string $meta_key Meta key. |
94 * @param mixed $meta_value Meta value. |
100 * @param mixed $_meta_value Meta value. |
95 */ |
101 */ |
96 do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value ); |
102 do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value ); |
97 |
103 |
98 $result = $wpdb->insert( $table, array( |
104 $result = $wpdb->insert( |
99 $column => $object_id, |
105 $table, |
100 'meta_key' => $meta_key, |
106 array( |
101 'meta_value' => $meta_value |
107 $column => $object_id, |
102 ) ); |
108 'meta_key' => $meta_key, |
103 |
109 'meta_value' => $meta_value, |
104 if ( ! $result ) |
110 ) |
105 return false; |
111 ); |
|
112 |
|
113 if ( ! $result ) { |
|
114 return false; |
|
115 } |
106 |
116 |
107 $mid = (int) $wpdb->insert_id; |
117 $mid = (int) $wpdb->insert_id; |
108 |
118 |
109 wp_cache_delete($object_id, $meta_type . '_meta'); |
119 wp_cache_delete( $object_id, $meta_type . '_meta' ); |
110 |
120 |
111 /** |
121 /** |
112 * Fires immediately after meta of a specific type is added. |
122 * Fires immediately after meta of a specific type is added. |
113 * |
123 * |
114 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
124 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
115 * object type (comment, post, or user). |
125 * object type (comment, post, term, or user). |
116 * |
126 * |
117 * @since 2.9.0 |
127 * @since 2.9.0 |
118 * |
128 * |
119 * @param int $mid The meta ID after successful update. |
129 * @param int $mid The meta ID after successful update. |
120 * @param int $object_id Object ID. |
130 * @param int $object_id Object ID. |
121 * @param string $meta_key Meta key. |
131 * @param string $meta_key Meta key. |
122 * @param mixed $meta_value Meta value. |
132 * @param mixed $_meta_value Meta value. |
123 */ |
133 */ |
124 do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value ); |
134 do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value ); |
125 |
135 |
126 return $mid; |
136 return $mid; |
127 } |
137 } |
132 * |
142 * |
133 * @since 2.9.0 |
143 * @since 2.9.0 |
134 * |
144 * |
135 * @global wpdb $wpdb WordPress database abstraction object. |
145 * @global wpdb $wpdb WordPress database abstraction object. |
136 * |
146 * |
137 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
147 * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
138 * @param int $object_id ID of the object metadata is for |
148 * @param int $object_id ID of the object metadata is for |
139 * @param string $meta_key Metadata key |
149 * @param string $meta_key Metadata key |
140 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
150 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
141 * @param mixed $prev_value Optional. If specified, only update existing metadata entries with |
151 * @param mixed $prev_value Optional. If specified, only update existing metadata entries with |
142 * the specified value. Otherwise, update all entries. |
152 * the specified value. Otherwise, update all entries. |
143 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure. |
153 * @return int|bool The new meta field ID if a field with the given key didn't exist and was |
144 */ |
154 * therefore added, true on successful update, false on failure. |
145 function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '') { |
155 */ |
|
156 function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) { |
146 global $wpdb; |
157 global $wpdb; |
147 |
158 |
148 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { |
159 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { |
149 return false; |
160 return false; |
150 } |
161 } |
159 return false; |
170 return false; |
160 } |
171 } |
161 |
172 |
162 $meta_subtype = get_object_subtype( $meta_type, $object_id ); |
173 $meta_subtype = get_object_subtype( $meta_type, $object_id ); |
163 |
174 |
164 $column = sanitize_key($meta_type . '_id'); |
175 $column = sanitize_key( $meta_type . '_id' ); |
165 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
176 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
166 |
177 |
167 // expected_slashed ($meta_key) |
178 // expected_slashed ($meta_key) |
168 $raw_meta_key = $meta_key; |
179 $raw_meta_key = $meta_key; |
169 $meta_key = wp_unslash($meta_key); |
180 $meta_key = wp_unslash( $meta_key ); |
170 $passed_value = $meta_value; |
181 $passed_value = $meta_value; |
171 $meta_value = wp_unslash($meta_value); |
182 $meta_value = wp_unslash( $meta_value ); |
172 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); |
183 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); |
173 |
184 |
174 /** |
185 /** |
175 * Filters whether to update metadata of a specific type. |
186 * Filters whether to update metadata of a specific type. |
176 * |
187 * |
177 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
188 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
178 * object type (comment, post, or user). Returning a non-null value |
189 * object type (comment, post, term, or user). Returning a non-null value |
179 * will effectively short-circuit the function. |
190 * will effectively short-circuit the function. |
180 * |
191 * |
181 * @since 3.1.0 |
192 * @since 3.1.0 |
182 * |
193 * |
183 * @param null|bool $check Whether to allow updating metadata for the given type. |
194 * @param null|bool $check Whether to allow updating metadata for the given type. |
187 * @param mixed $prev_value Optional. If specified, only update existing |
198 * @param mixed $prev_value Optional. If specified, only update existing |
188 * metadata entries with the specified value. |
199 * metadata entries with the specified value. |
189 * Otherwise, update all entries. |
200 * Otherwise, update all entries. |
190 */ |
201 */ |
191 $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value ); |
202 $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value ); |
192 if ( null !== $check ) |
203 if ( null !== $check ) { |
193 return (bool) $check; |
204 return (bool) $check; |
|
205 } |
194 |
206 |
195 // Compare existing value to new value if no prev value given and the key exists only once. |
207 // Compare existing value to new value if no prev value given and the key exists only once. |
196 if ( empty($prev_value) ) { |
208 if ( empty( $prev_value ) ) { |
197 $old_value = get_metadata($meta_type, $object_id, $meta_key); |
209 $old_value = get_metadata( $meta_type, $object_id, $meta_key ); |
198 if ( count($old_value) == 1 ) { |
210 if ( count( $old_value ) == 1 ) { |
199 if ( $old_value[0] === $meta_value ) |
211 if ( $old_value[0] === $meta_value ) { |
200 return false; |
212 return false; |
|
213 } |
201 } |
214 } |
202 } |
215 } |
203 |
216 |
204 $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ); |
217 $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ); |
205 if ( empty( $meta_ids ) ) { |
218 if ( empty( $meta_ids ) ) { |
206 return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value ); |
219 return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value ); |
207 } |
220 } |
208 |
221 |
209 $_meta_value = $meta_value; |
222 $_meta_value = $meta_value; |
210 $meta_value = maybe_serialize( $meta_value ); |
223 $meta_value = maybe_serialize( $meta_value ); |
211 |
224 |
212 $data = compact( 'meta_value' ); |
225 $data = compact( 'meta_value' ); |
213 $where = array( $column => $object_id, 'meta_key' => $meta_key ); |
226 $where = array( |
214 |
227 $column => $object_id, |
215 if ( !empty( $prev_value ) ) { |
228 'meta_key' => $meta_key, |
216 $prev_value = maybe_serialize($prev_value); |
229 ); |
|
230 |
|
231 if ( ! empty( $prev_value ) ) { |
|
232 $prev_value = maybe_serialize( $prev_value ); |
217 $where['meta_value'] = $prev_value; |
233 $where['meta_value'] = $prev_value; |
218 } |
234 } |
219 |
235 |
220 foreach ( $meta_ids as $meta_id ) { |
236 foreach ( $meta_ids as $meta_id ) { |
221 /** |
237 /** |
222 * Fires immediately before updating metadata of a specific type. |
238 * Fires immediately before updating metadata of a specific type. |
223 * |
239 * |
224 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
240 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
225 * object type (comment, post, or user). |
241 * object type (comment, post, term, or user). |
226 * |
242 * |
227 * @since 2.9.0 |
243 * @since 2.9.0 |
228 * |
244 * |
229 * @param int $meta_id ID of the metadata entry to update. |
245 * @param int $meta_id ID of the metadata entry to update. |
230 * @param int $object_id Object ID. |
246 * @param int $object_id Object ID. |
231 * @param string $meta_key Meta key. |
247 * @param string $meta_key Meta key. |
232 * @param mixed $meta_value Meta value. |
248 * @param mixed $_meta_value Meta value. |
233 */ |
249 */ |
234 do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); |
250 do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); |
235 |
251 |
236 if ( 'post' == $meta_type ) { |
252 if ( 'post' == $meta_type ) { |
237 /** |
253 /** |
238 * Fires immediately before updating a post's metadata. |
254 * Fires immediately before updating a post's metadata. |
239 * |
255 * |
240 * @since 2.9.0 |
256 * @since 2.9.0 |
241 * |
257 * |
242 * @param int $meta_id ID of metadata entry to update. |
258 * @param int $meta_id ID of metadata entry to update. |
243 * @param int $object_id Object ID. |
259 * @param int $object_id Post ID. |
244 * @param string $meta_key Meta key. |
260 * @param string $meta_key Meta key. |
245 * @param mixed $meta_value Meta value. |
261 * @param mixed $meta_value Meta value. This will be a PHP-serialized string representation of the value if |
|
262 * the value is an array, an object, or itself a PHP-serialized string. |
246 */ |
263 */ |
247 do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); |
264 do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); |
248 } |
265 } |
249 } |
266 } |
250 |
267 |
251 $result = $wpdb->update( $table, $data, $where ); |
268 $result = $wpdb->update( $table, $data, $where ); |
252 if ( ! $result ) |
269 if ( ! $result ) { |
253 return false; |
270 return false; |
254 |
271 } |
255 wp_cache_delete($object_id, $meta_type . '_meta'); |
272 |
|
273 wp_cache_delete( $object_id, $meta_type . '_meta' ); |
256 |
274 |
257 foreach ( $meta_ids as $meta_id ) { |
275 foreach ( $meta_ids as $meta_id ) { |
258 /** |
276 /** |
259 * Fires immediately after updating metadata of a specific type. |
277 * Fires immediately after updating metadata of a specific type. |
260 * |
278 * |
261 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
279 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
262 * object type (comment, post, or user). |
280 * object type (comment, post, term, or user). |
263 * |
281 * |
264 * @since 2.9.0 |
282 * @since 2.9.0 |
265 * |
283 * |
266 * @param int $meta_id ID of updated metadata entry. |
284 * @param int $meta_id ID of updated metadata entry. |
267 * @param int $object_id Object ID. |
285 * @param int $object_id Object ID. |
268 * @param string $meta_key Meta key. |
286 * @param string $meta_key Meta key. |
269 * @param mixed $meta_value Meta value. |
287 * @param mixed $_meta_value Meta value. |
270 */ |
288 */ |
271 do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); |
289 do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); |
272 |
290 |
273 if ( 'post' == $meta_type ) { |
291 if ( 'post' == $meta_type ) { |
274 /** |
292 /** |
275 * Fires immediately after updating a post's metadata. |
293 * Fires immediately after updating a post's metadata. |
276 * |
294 * |
277 * @since 2.9.0 |
295 * @since 2.9.0 |
278 * |
296 * |
279 * @param int $meta_id ID of updated metadata entry. |
297 * @param int $meta_id ID of updated metadata entry. |
280 * @param int $object_id Object ID. |
298 * @param int $object_id Post ID. |
281 * @param string $meta_key Meta key. |
299 * @param string $meta_key Meta key. |
282 * @param mixed $meta_value Meta value. |
300 * @param mixed $meta_value Meta value. This will be a PHP-serialized string representation of the value if |
|
301 * the value is an array, an object, or itself a PHP-serialized string. |
283 */ |
302 */ |
284 do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); |
303 do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); |
285 } |
304 } |
286 } |
305 } |
287 |
306 |
293 * |
312 * |
294 * @since 2.9.0 |
313 * @since 2.9.0 |
295 * |
314 * |
296 * @global wpdb $wpdb WordPress database abstraction object. |
315 * @global wpdb $wpdb WordPress database abstraction object. |
297 * |
316 * |
298 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
317 * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
299 * @param int $object_id ID of the object metadata is for |
318 * @param int $object_id ID of the object metadata is for |
300 * @param string $meta_key Metadata key |
319 * @param string $meta_key Metadata key |
301 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete |
320 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete |
302 * metadata entries with this value. Otherwise, delete all entries with the specified meta_key. |
321 * metadata entries with this value. Otherwise, delete all entries with the specified meta_key. |
303 * Pass `null, `false`, or an empty string to skip this check. (For backward compatibility, |
322 * Pass `null`, `false`, or an empty string to skip this check. (For backward compatibility, |
304 * it is not possible to pass an empty string to delete those entries with an empty string |
323 * it is not possible to pass an empty string to delete those entries with an empty string |
305 * for a value.) |
324 * for a value.) |
306 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries for all objects, |
325 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries for all objects, |
307 * ignoring the specified object_id. Otherwise, only delete matching metadata entries for |
326 * ignoring the specified object_id. Otherwise, only delete matching metadata entries for |
308 * the specified object_id. |
327 * the specified object_id. |
309 * @return bool True on successful delete, false on failure. |
328 * @return bool True on successful delete, false on failure. |
310 */ |
329 */ |
311 function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false) { |
330 function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) { |
312 global $wpdb; |
331 global $wpdb; |
313 |
332 |
314 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) { |
333 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) { |
315 return false; |
334 return false; |
316 } |
335 } |
347 * @param bool $delete_all Whether to delete the matching metadata entries |
366 * @param bool $delete_all Whether to delete the matching metadata entries |
348 * for all objects, ignoring the specified $object_id. |
367 * for all objects, ignoring the specified $object_id. |
349 * Default false. |
368 * Default false. |
350 */ |
369 */ |
351 $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all ); |
370 $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all ); |
352 if ( null !== $check ) |
371 if ( null !== $check ) { |
353 return (bool) $check; |
372 return (bool) $check; |
|
373 } |
354 |
374 |
355 $_meta_value = $meta_value; |
375 $_meta_value = $meta_value; |
356 $meta_value = maybe_serialize( $meta_value ); |
376 $meta_value = maybe_serialize( $meta_value ); |
357 |
377 |
358 $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key ); |
378 $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key ); |
359 |
379 |
360 if ( !$delete_all ) |
380 if ( ! $delete_all ) { |
361 $query .= $wpdb->prepare(" AND $type_column = %d", $object_id ); |
381 $query .= $wpdb->prepare( " AND $type_column = %d", $object_id ); |
362 |
382 } |
363 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) |
383 |
364 $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value ); |
384 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { |
|
385 $query .= $wpdb->prepare( ' AND meta_value = %s', $meta_value ); |
|
386 } |
365 |
387 |
366 $meta_ids = $wpdb->get_col( $query ); |
388 $meta_ids = $wpdb->get_col( $query ); |
367 if ( !count( $meta_ids ) ) |
389 if ( ! count( $meta_ids ) ) { |
368 return false; |
390 return false; |
|
391 } |
369 |
392 |
370 if ( $delete_all ) { |
393 if ( $delete_all ) { |
371 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { |
394 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { |
372 $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) ); |
395 $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) ); |
373 } else { |
396 } else { |
400 * @param array $meta_ids An array of post metadata entry IDs to delete. |
423 * @param array $meta_ids An array of post metadata entry IDs to delete. |
401 */ |
424 */ |
402 do_action( 'delete_postmeta', $meta_ids ); |
425 do_action( 'delete_postmeta', $meta_ids ); |
403 } |
426 } |
404 |
427 |
405 $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . " )"; |
428 $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . ' )'; |
406 |
429 |
407 $count = $wpdb->query($query); |
430 $count = $wpdb->query( $query ); |
408 |
431 |
409 if ( !$count ) |
432 if ( ! $count ) { |
410 return false; |
433 return false; |
|
434 } |
411 |
435 |
412 if ( $delete_all ) { |
436 if ( $delete_all ) { |
413 foreach ( (array) $object_ids as $o_id ) { |
437 foreach ( (array) $object_ids as $o_id ) { |
414 wp_cache_delete($o_id, $meta_type . '_meta'); |
438 wp_cache_delete( $o_id, $meta_type . '_meta' ); |
415 } |
439 } |
416 } else { |
440 } else { |
417 wp_cache_delete($object_id, $meta_type . '_meta'); |
441 wp_cache_delete( $object_id, $meta_type . '_meta' ); |
418 } |
442 } |
419 |
443 |
420 /** |
444 /** |
421 * Fires immediately after deleting metadata of a specific type. |
445 * Fires immediately after deleting metadata of a specific type. |
422 * |
446 * |
423 * The dynamic portion of the hook name, `$meta_type`, refers to the meta |
447 * The dynamic portion of the hook name, `$meta_type`, refers to the meta |
424 * object type (comment, post, or user). |
448 * object type (comment, post, term, or user). |
425 * |
449 * |
426 * @since 2.9.0 |
450 * @since 2.9.0 |
427 * |
451 * |
428 * @param array $meta_ids An array of deleted metadata entry IDs. |
452 * @param array $meta_ids An array of deleted metadata entry IDs. |
429 * @param int $object_id Object ID. |
453 * @param int $object_id Object ID. |
430 * @param string $meta_key Meta key. |
454 * @param string $meta_key Meta key. |
431 * @param mixed $meta_value Meta value. |
455 * @param mixed $_meta_value Meta value. |
432 */ |
456 */ |
433 do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); |
457 do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); |
434 |
458 |
435 // Old-style action. |
459 // Old-style action. |
436 if ( 'post' == $meta_type ) { |
460 if ( 'post' == $meta_type ) { |
450 /** |
474 /** |
451 * Retrieve metadata for the specified object. |
475 * Retrieve metadata for the specified object. |
452 * |
476 * |
453 * @since 2.9.0 |
477 * @since 2.9.0 |
454 * |
478 * |
455 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
479 * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
456 * @param int $object_id ID of the object metadata is for |
480 * @param int $object_id ID of the object metadata is for |
457 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for |
481 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for |
458 * the specified object. |
482 * the specified object. |
459 * @param bool $single Optional, default is false. |
483 * @param bool $single Optional, default is false. |
460 * If true, return only the first value of the specified meta_key. |
484 * If true, return only the first value of the specified meta_key. |
461 * This parameter has no effect if meta_key is not specified. |
485 * This parameter has no effect if meta_key is not specified. |
462 * @return mixed Single metadata value, or array of values |
486 * @return mixed Single metadata value, or array of values |
463 */ |
487 */ |
464 function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) { |
488 function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) { |
465 if ( ! $meta_type || ! is_numeric( $object_id ) ) { |
489 if ( ! $meta_type || ! is_numeric( $object_id ) ) { |
466 return false; |
490 return false; |
467 } |
491 } |
468 |
492 |
469 $object_id = absint( $object_id ); |
493 $object_id = absint( $object_id ); |
486 * @param string $meta_key Meta key. |
510 * @param string $meta_key Meta key. |
487 * @param bool $single Whether to return only the first value of the specified $meta_key. |
511 * @param bool $single Whether to return only the first value of the specified $meta_key. |
488 */ |
512 */ |
489 $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single ); |
513 $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single ); |
490 if ( null !== $check ) { |
514 if ( null !== $check ) { |
491 if ( $single && is_array( $check ) ) |
515 if ( $single && is_array( $check ) ) { |
492 return $check[0]; |
516 return $check[0]; |
493 else |
517 } else { |
494 return $check; |
518 return $check; |
495 } |
519 } |
496 |
520 } |
497 $meta_cache = wp_cache_get($object_id, $meta_type . '_meta'); |
521 |
498 |
522 $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); |
499 if ( !$meta_cache ) { |
523 |
|
524 if ( ! $meta_cache ) { |
500 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); |
525 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); |
501 $meta_cache = $meta_cache[$object_id]; |
526 $meta_cache = $meta_cache[ $object_id ]; |
502 } |
527 } |
503 |
528 |
504 if ( ! $meta_key ) { |
529 if ( ! $meta_key ) { |
505 return $meta_cache; |
530 return $meta_cache; |
506 } |
531 } |
507 |
532 |
508 if ( isset($meta_cache[$meta_key]) ) { |
533 if ( isset( $meta_cache[ $meta_key ] ) ) { |
509 if ( $single ) |
534 if ( $single ) { |
510 return maybe_unserialize( $meta_cache[$meta_key][0] ); |
535 return maybe_unserialize( $meta_cache[ $meta_key ][0] ); |
511 else |
536 } else { |
512 return array_map('maybe_unserialize', $meta_cache[$meta_key]); |
537 return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] ); |
513 } |
538 } |
514 |
539 } |
515 if ($single) |
540 |
|
541 if ( $single ) { |
516 return ''; |
542 return ''; |
517 else |
543 } else { |
518 return array(); |
544 return array(); |
|
545 } |
519 } |
546 } |
520 |
547 |
521 /** |
548 /** |
522 * Determine if a meta key is set for a given object |
549 * Determine if a meta key is set for a given object |
523 * |
550 * |
524 * @since 3.3.0 |
551 * @since 3.3.0 |
525 * |
552 * |
526 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
553 * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
527 * @param int $object_id ID of the object metadata is for |
554 * @param int $object_id ID of the object metadata is for |
528 * @param string $meta_key Metadata key. |
555 * @param string $meta_key Metadata key. |
529 * @return bool True of the key is set, false if not. |
556 * @return bool True of the key is set, false if not. |
530 */ |
557 */ |
531 function metadata_exists( $meta_type, $object_id, $meta_key ) { |
558 function metadata_exists( $meta_type, $object_id, $meta_key ) { |
626 $table = _get_meta_table( $meta_type ); |
674 $table = _get_meta_table( $meta_type ); |
627 if ( ! $table ) { |
675 if ( ! $table ) { |
628 return false; |
676 return false; |
629 } |
677 } |
630 |
678 |
631 $column = sanitize_key($meta_type . '_id'); |
679 $column = sanitize_key( $meta_type . '_id' ); |
632 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
680 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
|
681 |
|
682 /** |
|
683 * Filters whether to update metadata of a specific type by meta ID. |
|
684 * |
|
685 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
|
686 * object type (comment, post, term, or user). Returning a non-null value |
|
687 * will effectively short-circuit the function. |
|
688 * |
|
689 * @since 5.0.0 |
|
690 * |
|
691 * @param null|bool $check Whether to allow updating metadata for the given type. |
|
692 * @param int $meta_id Meta ID. |
|
693 * @param mixed $meta_value Meta value. Must be serializable if non-scalar. |
|
694 * @param string|bool $meta_key Meta key, if provided. |
|
695 */ |
|
696 $check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key ); |
|
697 if ( null !== $check ) { |
|
698 return (bool) $check; |
|
699 } |
633 |
700 |
634 // Fetch the meta and go on if it's found. |
701 // Fetch the meta and go on if it's found. |
635 if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) { |
702 if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) { |
636 $original_key = $meta->meta_key; |
703 $original_key = $meta->meta_key; |
637 $object_id = $meta->{$column}; |
704 $object_id = $meta->{$column}; |
638 |
705 |
639 // If a new meta_key (last parameter) was specified, change the meta key, |
706 // If a new meta_key (last parameter) was specified, change the meta key, |
640 // otherwise use the original key in the update statement. |
707 // otherwise use the original key in the update statement. |
641 if ( false === $meta_key ) { |
708 if ( false === $meta_key ) { |
642 $meta_key = $original_key; |
709 $meta_key = $original_key; |
720 if ( ! $table ) { |
788 if ( ! $table ) { |
721 return false; |
789 return false; |
722 } |
790 } |
723 |
791 |
724 // object and id columns |
792 // object and id columns |
725 $column = sanitize_key($meta_type . '_id'); |
793 $column = sanitize_key( $meta_type . '_id' ); |
726 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
794 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
|
795 |
|
796 /** |
|
797 * Filters whether to delete metadata of a specific type by meta ID. |
|
798 * |
|
799 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
|
800 * object type (comment, post, term, or user). Returning a non-null value |
|
801 * will effectively short-circuit the function. |
|
802 * |
|
803 * @since 5.0.0 |
|
804 * |
|
805 * @param null|bool $delete Whether to allow metadata deletion of the given type. |
|
806 * @param int $meta_id Meta ID. |
|
807 */ |
|
808 $check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id ); |
|
809 if ( null !== $check ) { |
|
810 return (bool) $check; |
|
811 } |
727 |
812 |
728 // Fetch the meta and go on if it's found. |
813 // Fetch the meta and go on if it's found. |
729 if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) { |
814 if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) { |
730 $object_id = $meta->{$column}; |
815 $object_id = (int) $meta->{$column}; |
731 |
816 |
732 /** This action is documented in wp-includes/meta.php */ |
817 /** This action is documented in wp-includes/meta.php */ |
733 do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value ); |
818 do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value ); |
734 |
819 |
735 // Old-style action. |
820 // Old-style action. |
800 $table = _get_meta_table( $meta_type ); |
885 $table = _get_meta_table( $meta_type ); |
801 if ( ! $table ) { |
886 if ( ! $table ) { |
802 return false; |
887 return false; |
803 } |
888 } |
804 |
889 |
805 $column = sanitize_key($meta_type . '_id'); |
890 $column = sanitize_key( $meta_type . '_id' ); |
806 |
891 |
807 if ( !is_array($object_ids) ) { |
892 if ( ! is_array( $object_ids ) ) { |
808 $object_ids = preg_replace('|[^0-9,]|', '', $object_ids); |
893 $object_ids = preg_replace( '|[^0-9,]|', '', $object_ids ); |
809 $object_ids = explode(',', $object_ids); |
894 $object_ids = explode( ',', $object_ids ); |
810 } |
895 } |
811 |
896 |
812 $object_ids = array_map('intval', $object_ids); |
897 $object_ids = array_map( 'intval', $object_ids ); |
|
898 |
|
899 /** |
|
900 * Filters whether to update the metadata cache of a specific type. |
|
901 * |
|
902 * The dynamic portion of the hook, `$meta_type`, refers to the meta |
|
903 * object type (comment, post, term, or user). Returning a non-null value |
|
904 * will effectively short-circuit the function. |
|
905 * |
|
906 * @since 5.0.0 |
|
907 * |
|
908 * @param mixed $check Whether to allow updating the meta cache of the given type. |
|
909 * @param array $object_ids Array of object IDs to update the meta cache for. |
|
910 */ |
|
911 $check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids ); |
|
912 if ( null !== $check ) { |
|
913 return (bool) $check; |
|
914 } |
813 |
915 |
814 $cache_key = $meta_type . '_meta'; |
916 $cache_key = $meta_type . '_meta'; |
815 $ids = array(); |
917 $ids = array(); |
816 $cache = array(); |
918 $cache = array(); |
817 foreach ( $object_ids as $id ) { |
919 foreach ( $object_ids as $id ) { |
818 $cached_object = wp_cache_get( $id, $cache_key ); |
920 $cached_object = wp_cache_get( $id, $cache_key ); |
819 if ( false === $cached_object ) |
921 if ( false === $cached_object ) { |
820 $ids[] = $id; |
922 $ids[] = $id; |
821 else |
923 } else { |
822 $cache[$id] = $cached_object; |
924 $cache[ $id ] = $cached_object; |
823 } |
925 } |
824 |
926 } |
825 if ( empty( $ids ) ) |
927 |
|
928 if ( empty( $ids ) ) { |
826 return $cache; |
929 return $cache; |
|
930 } |
827 |
931 |
828 // Get meta info |
932 // Get meta info |
829 $id_list = join( ',', $ids ); |
933 $id_list = join( ',', $ids ); |
830 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
934 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
831 $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A ); |
935 $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A ); |
832 |
936 |
833 if ( !empty($meta_list) ) { |
937 if ( ! empty( $meta_list ) ) { |
834 foreach ( $meta_list as $metarow) { |
938 foreach ( $meta_list as $metarow ) { |
835 $mpid = intval($metarow[$column]); |
939 $mpid = intval( $metarow[ $column ] ); |
836 $mkey = $metarow['meta_key']; |
940 $mkey = $metarow['meta_key']; |
837 $mval = $metarow['meta_value']; |
941 $mval = $metarow['meta_value']; |
838 |
942 |
839 // Force subkeys to be array type: |
943 // Force subkeys to be array type: |
840 if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) ) |
944 if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) { |
841 $cache[$mpid] = array(); |
945 $cache[ $mpid ] = array(); |
842 if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) ) |
946 } |
843 $cache[$mpid][$mkey] = array(); |
947 if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) { |
|
948 $cache[ $mpid ][ $mkey ] = array(); |
|
949 } |
844 |
950 |
845 // Add a value to the current pid/key: |
951 // Add a value to the current pid/key: |
846 $cache[$mpid][$mkey][] = $mval; |
952 $cache[ $mpid ][ $mkey ][] = $mval; |
847 } |
953 } |
848 } |
954 } |
849 |
955 |
850 foreach ( $ids as $id ) { |
956 foreach ( $ids as $id ) { |
851 if ( ! isset($cache[$id]) ) |
957 if ( ! isset( $cache[ $id ] ) ) { |
852 $cache[$id] = array(); |
958 $cache[ $id ] = array(); |
853 wp_cache_add( $id, $cache[$id], $cache_key ); |
959 } |
|
960 wp_cache_add( $id, $cache[ $id ], $cache_key ); |
854 } |
961 } |
855 |
962 |
856 return $cache; |
963 return $cache; |
857 } |
964 } |
858 |
965 |
897 * |
1004 * |
898 * @since 2.9.0 |
1005 * @since 2.9.0 |
899 * |
1006 * |
900 * @global wpdb $wpdb WordPress database abstraction object. |
1007 * @global wpdb $wpdb WordPress database abstraction object. |
901 * |
1008 * |
902 * @param string $type Type of object to get metadata table for (e.g., comment, post, or user) |
1009 * @param string $type Type of object to get metadata table for (e.g., comment, post, term, or user). |
903 * @return string|false Metadata table name, or false if no metadata table exists |
1010 * @return string|false Metadata table name, or false if no metadata table exists |
904 */ |
1011 */ |
905 function _get_meta_table($type) { |
1012 function _get_meta_table( $type ) { |
906 global $wpdb; |
1013 global $wpdb; |
907 |
1014 |
908 $table_name = $type . 'meta'; |
1015 $table_name = $type . 'meta'; |
909 |
1016 |
910 if ( empty($wpdb->$table_name) ) |
1017 if ( empty( $wpdb->$table_name ) ) { |
911 return false; |
1018 return false; |
|
1019 } |
912 |
1020 |
913 return $wpdb->$table_name; |
1021 return $wpdb->$table_name; |
914 } |
1022 } |
915 |
1023 |
916 /** |
1024 /** |
917 * Determine whether a meta key is protected. |
1025 * Determines whether a meta key is considered protected. |
918 * |
1026 * |
919 * @since 3.1.3 |
1027 * @since 3.1.3 |
920 * |
1028 * |
921 * @param string $meta_key Meta key |
1029 * @param string $meta_key Meta key. |
922 * @param string|null $meta_type |
1030 * @param string|null $meta_type Optional. Type of object metadata is for (e.g., comment, post, term, or user). |
923 * @return bool True if the key is protected, false otherwise. |
1031 * @return bool Whether the meta key is considered protected. |
924 */ |
1032 */ |
925 function is_protected_meta( $meta_key, $meta_type = null ) { |
1033 function is_protected_meta( $meta_key, $meta_type = null ) { |
926 $protected = ( '_' == $meta_key[0] ); |
1034 $protected = ( '_' == $meta_key[0] ); |
927 |
1035 |
928 /** |
1036 /** |
929 * Filters whether a meta key is protected. |
1037 * Filters whether a meta key is considered protected. |
930 * |
1038 * |
931 * @since 3.2.0 |
1039 * @since 3.2.0 |
932 * |
1040 * |
933 * @param bool $protected Whether the key is protected. Default false. |
1041 * @param bool $protected Whether the key is considered protected. |
934 * @param string $meta_key Meta key. |
1042 * @param string $meta_key Meta key. |
935 * @param string $meta_type Meta type. |
1043 * @param string|null $meta_type Type of object metadata is for (e.g., comment, post, term, or user). |
936 */ |
1044 */ |
937 return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); |
1045 return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); |
938 } |
1046 } |
939 |
1047 |
940 /** |
1048 /** |
944 * @since 4.9.8 The `$object_subtype` parameter was added. |
1052 * @since 4.9.8 The `$object_subtype` parameter was added. |
945 * |
1053 * |
946 * @param string $meta_key Meta key. |
1054 * @param string $meta_key Meta key. |
947 * @param mixed $meta_value Meta value to sanitize. |
1055 * @param mixed $meta_value Meta value to sanitize. |
948 * @param string $object_type Type of object the meta is registered to. |
1056 * @param string $object_type Type of object the meta is registered to. |
|
1057 * @param string $object_subtype Optional. The subtype of the object type. |
949 * |
1058 * |
950 * @return mixed Sanitized $meta_value. |
1059 * @return mixed Sanitized $meta_value. |
951 */ |
1060 */ |
952 function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) { |
1061 function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) { |
953 if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { |
1062 if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { |
954 |
1063 |
955 /** |
1064 /** |
956 * Filters the sanitization of a specific meta key of a specific meta type and subtype. |
1065 * Filters the sanitization of a specific meta key of a specific meta type and subtype. |
957 * |
1066 * |
958 * The dynamic portions of the hook name, `$object_type`, `$meta_key`, |
1067 * The dynamic portions of the hook name, `$object_type`, `$meta_key`, |
959 * and `$object_subtype`, refer to the metadata object type (comment, post, term or user), |
1068 * and `$object_subtype`, refer to the metadata object type (comment, post, term, or user), |
960 * the meta key value, and the object subtype respectively. |
1069 * the meta key value, and the object subtype respectively. |
961 * |
1070 * |
962 * @since 4.9.8 |
1071 * @since 4.9.8 |
963 * |
1072 * |
964 * @param mixed $meta_value Meta value to sanitize. |
1073 * @param mixed $meta_value Meta value to sanitize. |