at path:ROOT / wp-includes / meta.php
run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄meta.php
1<?php
2/**
3 * Core Metadata API
4 *
5 * Functions for retrieving and manipulating metadata of various WordPress object types. Metadata
6 * for an object is a represented by a simple key-value pair. Objects may contain multiple
7 * metadata entries that share the same key and differ only in their value.
8 *
9 * @package WordPress
10 * @subpackage Meta
11 */
12
13require ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php';
14
15/**
16 * Adds metadata for the specified object.
17 *
18 * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
19 *
20 * @since 2.9.0
21 *
22 * @global wpdb $wpdb WordPress database abstraction object.
23 *
24 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
25 * 'user', or any other object type with an associated meta table.
26 * @param int $object_id ID of the object metadata is for.
27 * @param string $meta_key Metadata key.
28 * @param mixed $meta_value Metadata value. Arrays and objects are stored as serialized data and
29 * will be returned as the same type when retrieved. Other data types will
30 * be stored as strings in the database:
31 * - false is stored and retrieved as an empty string ('')
32 * - true is stored and retrieved as '1'
33 * - numbers (both integer and float) are stored and retrieved as strings
34 * Must be serializable if non-scalar.
35 * @param bool $unique Optional. Whether the specified metadata key should be unique for the object.
36 * If true, and the object already has a value for the specified metadata key,
37 * no change will be made. Default false.
38 * @return int|false The meta ID on success, false on failure.
39 */
40function add_metadata( $meta_type, $object_id, $meta_key, $meta_value, $unique = false ) {
41 global $wpdb;
42
43 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
44 return false;
45 }
46
47 $object_id = absint( $object_id );
48 if ( ! $object_id ) {
49 return false;
50 }
51
52 $table = _get_meta_table( $meta_type );
53 if ( ! $table ) {
54 return false;
55 }
56
57 $meta_subtype = get_object_subtype( $meta_type, $object_id );
58
59 $column = sanitize_key( $meta_type . '_id' );
60
61 // expected_slashed ($meta_key)
62 $meta_key = wp_unslash( $meta_key );
63 $meta_value = wp_unslash( $meta_value );
64 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
65
66 /**
67 * Short-circuits adding metadata of a specific type.
68 *
69 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
70 * (blog, post, comment, term, user, or any other type with an associated meta table).
71 * Returning a non-null value will effectively short-circuit the function.
72 *
73 * Possible hook names include:
74 *
75 * - `add_blog_metadata`
76 * - `add_post_metadata`
77 * - `add_comment_metadata`
78 * - `add_term_metadata`
79 * - `add_user_metadata`
80 *
81 * @since 3.1.0
82 *
83 * @param null|int|false $check Whether to allow adding metadata for the given type. Return false or a meta ID
84 * to short-circuit the function. Return null to continue with the default behavior.
85 * @param int $object_id ID of the object metadata is for.
86 * @param string $meta_key Metadata key.
87 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
88 * @param bool $unique Whether the specified meta key should be unique for the object.
89 */
90 $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
91 if ( null !== $check ) {
92 return $check;
93 }
94
95 if ( $unique && $wpdb->get_var(
96 $wpdb->prepare(
97 "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
98 $meta_key,
99 $object_id
100 )
101 ) ) {
102 return false;
103 }
104
105 $_meta_value = $meta_value;
106 $meta_value = maybe_serialize( $meta_value );
107
108 /**
109 * Fires immediately before meta of a specific type is added.
110 *
111 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
112 * (blog, post, comment, term, user, or any other type with an associated meta table).
113 *
114 * Possible hook names include:
115 *
116 * - `add_blog_meta`
117 * - `add_post_meta`
118 * - `add_comment_meta`
119 * - `add_term_meta`
120 * - `add_user_meta`
121 *
122 * @since 3.1.0
123 *
124 * @param int $object_id ID of the object metadata is for.
125 * @param string $meta_key Metadata key.
126 * @param mixed $_meta_value Metadata value.
127 */
128 do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
129
130 $result = $wpdb->insert(
131 $table,
132 array(
133 $column => $object_id,
134 'meta_key' => $meta_key,
135 'meta_value' => $meta_value,
136 )
137 );
138
139 if ( ! $result ) {
140 return false;
141 }
142
143 $mid = (int) $wpdb->insert_id;
144
145 wp_cache_delete( $object_id, $meta_type . '_meta' );
146
147 /**
148 * Fires immediately after meta of a specific type is added.
149 *
150 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
151 * (blog, post, comment, term, user, or any other type with an associated meta table).
152 *
153 * Possible hook names include:
154 *
155 * - `added_blog_meta`
156 * - `added_post_meta`
157 * - `added_comment_meta`
158 * - `added_term_meta`
159 * - `added_user_meta`
160 *
161 * @since 2.9.0
162 *
163 * @param int $mid The meta ID after successful update.
164 * @param int $object_id ID of the object metadata is for.
165 * @param string $meta_key Metadata key.
166 * @param mixed $_meta_value Metadata value.
167 */
168 do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
169
170 return $mid;
171}
172
173/**
174 * Updates metadata for the specified object. If no value already exists for the specified object
175 * ID and metadata key, the metadata will be added.
176 *
177 * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
178 *
179 * @since 2.9.0
180 *
181 * @global wpdb $wpdb WordPress database abstraction object.
182 *
183 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
184 * 'user', or any other object type with an associated meta table.
185 * @param int $object_id ID of the object metadata is for.
186 * @param string $meta_key Metadata key.
187 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
188 * @param mixed $prev_value Optional. Previous value to check before updating.
189 * If specified, only update existing metadata entries with
190 * this value. Otherwise, update all entries. Default empty string.
191 * @return int|bool The new meta field ID if a field with the given key didn't exist
192 * and was therefore added, true on successful update,
193 * false on failure or if the value passed to the function
194 * is the same as the one that is already in the database.
195 */
196function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) {
197 global $wpdb;
198
199 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
200 return false;
201 }
202
203 $object_id = absint( $object_id );
204 if ( ! $object_id ) {
205 return false;
206 }
207
208 $table = _get_meta_table( $meta_type );
209 if ( ! $table ) {
210 return false;
211 }
212
213 $meta_subtype = get_object_subtype( $meta_type, $object_id );
214
215 $column = sanitize_key( $meta_type . '_id' );
216 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
217
218 // expected_slashed ($meta_key)
219 $raw_meta_key = $meta_key;
220 $meta_key = wp_unslash( $meta_key );
221 $passed_value = $meta_value;
222 $meta_value = wp_unslash( $meta_value );
223 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
224
225 /**
226 * Short-circuits updating metadata of a specific type.
227 *
228 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
229 * (blog, post, comment, term, user, or any other type with an associated meta table).
230 * Returning a non-null value will effectively short-circuit the function.
231 *
232 * Possible hook names include:
233 *
234 * - `update_blog_metadata`
235 * - `update_post_metadata`
236 * - `update_comment_metadata`
237 * - `update_term_metadata`
238 * - `update_user_metadata`
239 *
240 * @since 3.1.0
241 *
242 * @param null|bool $check Whether to allow updating metadata for the given type.
243 * @param int $object_id ID of the object metadata is for.
244 * @param string $meta_key Metadata key.
245 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
246 * @param mixed $prev_value Optional. Previous value to check before updating.
247 * If specified, only update existing metadata entries with
248 * this value. Otherwise, update all entries.
249 */
250 $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
251 if ( null !== $check ) {
252 return (bool) $check;
253 }
254
255 // Compare existing value to new value if no prev value given and the key exists only once.
256 if ( empty( $prev_value ) ) {
257 $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key );
258 if ( is_countable( $old_value ) && count( $old_value ) === 1 ) {
259 if ( $old_value[0] === $meta_value ) {
260 return false;
261 }
262 }
263 }
264
265 $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) );
266 if ( empty( $meta_ids ) ) {
267 return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
268 }
269
270 $_meta_value = $meta_value;
271 $meta_value = maybe_serialize( $meta_value );
272
273 $data = compact( 'meta_value' );
274 $where = array(
275 $column => $object_id,
276 'meta_key' => $meta_key,
277 );
278
279 if ( ! empty( $prev_value ) ) {
280 $prev_value = maybe_serialize( $prev_value );
281 $where['meta_value'] = $prev_value;
282 }
283
284 foreach ( $meta_ids as $meta_id ) {
285 /**
286 * Fires immediately before updating metadata of a specific type.
287 *
288 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
289 * (blog, post, comment, term, user, or any other type with an associated meta table).
290 *
291 * Possible hook names include:
292 *
293 * - `update_blog_meta`
294 * - `update_post_meta`
295 * - `update_comment_meta`
296 * - `update_term_meta`
297 * - `update_user_meta`
298 *
299 * @since 2.9.0
300 *
301 * @param int $meta_id ID of the metadata entry to update.
302 * @param int $object_id ID of the object metadata is for.
303 * @param string $meta_key Metadata key.
304 * @param mixed $_meta_value Metadata value.
305 */
306 do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
307
308 if ( 'post' === $meta_type ) {
309 /**
310 * Fires immediately before updating a post's metadata.
311 *
312 * @since 2.9.0
313 *
314 * @param int $meta_id ID of metadata entry to update.
315 * @param int $object_id Post ID.
316 * @param string $meta_key Metadata key.
317 * @param mixed $meta_value Metadata value. This will be a PHP-serialized string representation of the value
318 * if the value is an array, an object, or itself a PHP-serialized string.
319 */
320 do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
321 }
322 }
323
324 $result = $wpdb->update( $table, $data, $where );
325 if ( ! $result ) {
326 return false;
327 }
328
329 wp_cache_delete( $object_id, $meta_type . '_meta' );
330
331 foreach ( $meta_ids as $meta_id ) {
332 /**
333 * Fires immediately after updating metadata of a specific type.
334 *
335 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
336 * (blog, post, comment, term, user, or any other type with an associated meta table).
337 *
338 * Possible hook names include:
339 *
340 * - `updated_blog_meta`
341 * - `updated_post_meta`
342 * - `updated_comment_meta`
343 * - `updated_term_meta`
344 * - `updated_user_meta`
345 *
346 * @since 2.9.0
347 *
348 * @param int $meta_id ID of updated metadata entry.
349 * @param int $object_id ID of the object metadata is for.
350 * @param string $meta_key Metadata key.
351 * @param mixed $_meta_value Metadata value.
352 */
353 do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
354
355 if ( 'post' === $meta_type ) {
356 /**
357 * Fires immediately after updating a post's metadata.
358 *
359 * @since 2.9.0
360 *
361 * @param int $meta_id ID of updated metadata entry.
362 * @param int $object_id Post ID.
363 * @param string $meta_key Metadata key.
364 * @param mixed $meta_value Metadata value. This will be a PHP-serialized string representation of the value
365 * if the value is an array, an object, or itself a PHP-serialized string.
366 */
367 do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
368 }
369 }
370
371 return true;
372}
373
374/**
375 * Deletes metadata for the specified object.
376 *
377 * For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
378 *
379 * @since 2.9.0
380 *
381 * @global wpdb $wpdb WordPress database abstraction object.
382 *
383 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
384 * 'user', or any other object type with an associated meta table.
385 * @param int $object_id ID of the object metadata is for.
386 * @param string $meta_key Metadata key.
387 * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar.
388 * If specified, only delete metadata entries with this value.
389 * Otherwise, delete all entries with the specified meta_key.
390 * Pass `null`, `false`, or an empty string to skip this check.
391 * (For backward compatibility, it is not possible to pass an empty string
392 * to delete those entries with an empty string for a value.)
393 * Default empty string.
394 * @param bool $delete_all Optional. If true, delete matching metadata entries for all objects,
395 * ignoring the specified object_id. Otherwise, only delete
396 * matching metadata entries for the specified object_id. Default false.
397 * @return bool True on successful delete, false on failure.
398 */
399function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
400 global $wpdb;
401
402 if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
403 return false;
404 }
405
406 $object_id = absint( $object_id );
407 if ( ! $object_id && ! $delete_all ) {
408 return false;
409 }
410
411 $table = _get_meta_table( $meta_type );
412 if ( ! $table ) {
413 return false;
414 }
415
416 $type_column = sanitize_key( $meta_type . '_id' );
417 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
418
419 // expected_slashed ($meta_key)
420 $meta_key = wp_unslash( $meta_key );
421 $meta_value = wp_unslash( $meta_value );
422
423 /**
424 * Short-circuits deleting metadata of a specific type.
425 *
426 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
427 * (blog, post, comment, term, user, or any other type with an associated meta table).
428 * Returning a non-null value will effectively short-circuit the function.
429 *
430 * Possible hook names include:
431 *
432 * - `delete_blog_metadata`
433 * - `delete_post_metadata`
434 * - `delete_comment_metadata`
435 * - `delete_term_metadata`
436 * - `delete_user_metadata`
437 *
438 * @since 3.1.0
439 *
440 * @param null|bool $delete Whether to allow metadata deletion of the given type.
441 * @param int $object_id ID of the object metadata is for.
442 * @param string $meta_key Metadata key.
443 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
444 * @param bool $delete_all Whether to delete the matching metadata entries
445 * for all objects, ignoring the specified $object_id.
446 * Default false.
447 */
448 $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
449 if ( null !== $check ) {
450 return (bool) $check;
451 }
452
453 $_meta_value = $meta_value;
454 $meta_value = maybe_serialize( $meta_value );
455
456 $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
457
458 if ( ! $delete_all ) {
459 $query .= $wpdb->prepare( " AND $type_column = %d", $object_id );
460 }
461
462 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
463 $query .= $wpdb->prepare( ' AND meta_value = %s', $meta_value );
464 }
465
466 $meta_ids = $wpdb->get_col( $query );
467 if ( ! count( $meta_ids ) ) {
468 return false;
469 }
470
471 if ( $delete_all ) {
472 if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
473 $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) );
474 } else {
475 $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) );
476 }
477 }
478
479 /**
480 * Fires immediately before deleting metadata of a specific type.
481 *
482 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
483 * (blog, post, comment, term, user, or any other type with an associated meta table).
484 *
485 * Possible hook names include:
486 *
487 * - `delete_blog_meta`
488 * - `delete_post_meta`
489 * - `delete_comment_meta`
490 * - `delete_term_meta`
491 * - `delete_user_meta`
492 *
493 * @since 3.1.0
494 *
495 * @param string[] $meta_ids An array of metadata entry IDs to delete.
496 * @param int $object_id ID of the object metadata is for.
497 * @param string $meta_key Metadata key.
498 * @param mixed $_meta_value Metadata value.
499 */
500 do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
501
502 // Old-style action.
503 if ( 'post' === $meta_type ) {
504 /**
505 * Fires immediately before deleting metadata for a post.
506 *
507 * @since 2.9.0
508 *
509 * @param string[] $meta_ids An array of metadata entry IDs to delete.
510 */
511 do_action( 'delete_postmeta', $meta_ids );
512 }
513
514 $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . ' )';
515
516 $count = $wpdb->query( $query );
517
518 if ( ! $count ) {
519 return false;
520 }
521
522 if ( $delete_all ) {
523 $data = (array) $object_ids;
524 } else {
525 $data = array( $object_id );
526 }
527 wp_cache_delete_multiple( $data, $meta_type . '_meta' );
528
529 /**
530 * Fires immediately after deleting metadata of a specific type.
531 *
532 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
533 * (blog, post, comment, term, user, or any other type with an associated meta table).
534 *
535 * Possible hook names include:
536 *
537 * - `deleted_blog_meta`
538 * - `deleted_post_meta`
539 * - `deleted_comment_meta`
540 * - `deleted_term_meta`
541 * - `deleted_user_meta`
542 *
543 * @since 2.9.0
544 *
545 * @param string[] $meta_ids An array of metadata entry IDs to delete.
546 * @param int $object_id ID of the object metadata is for.
547 * @param string $meta_key Metadata key.
548 * @param mixed $_meta_value Metadata value.
549 */
550 do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
551
552 // Old-style action.
553 if ( 'post' === $meta_type ) {
554 /**
555 * Fires immediately after deleting metadata for a post.
556 *
557 * @since 2.9.0
558 *
559 * @param string[] $meta_ids An array of metadata entry IDs to delete.
560 */
561 do_action( 'deleted_postmeta', $meta_ids );
562 }
563
564 return true;
565}
566
567/**
568 * Retrieves the value of a metadata field for the specified object type and ID.
569 *
570 * If the meta field exists, a single value is returned if `$single` is true,
571 * or an array of values if it's false.
572 *
573 * If the meta field does not exist, the result depends on get_metadata_default().
574 * By default, an empty string is returned if `$single` is true, or an empty array
575 * if it's false.
576 *
577 * @since 2.9.0
578 *
579 * @see get_metadata_raw()
580 * @see get_metadata_default()
581 *
582 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
583 * 'user', or any other object type with an associated meta table.
584 * @param int $object_id ID of the object metadata is for.
585 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for
586 * the specified object. Default empty string.
587 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`.
588 * This parameter has no effect if `$meta_key` is not specified. Default false.
589 * @return mixed An array of values if `$single` is false.
590 * The value of the meta field if `$single` is true.
591 * False for an invalid `$object_id` (non-numeric, zero, or negative value),
592 * or if `$meta_type` is not specified.
593 * An empty array if a valid but non-existing object ID is passed and `$single` is false.
594 * An empty string if a valid but non-existing object ID is passed and `$single` is true.
595 * Note: Non-serialized values are returned as strings:
596 * - false values are returned as empty strings ('')
597 * - true values are returned as '1'
598 * - numbers (both integer and float) are returned as strings
599 * Arrays and objects retain their original type.
600 */
601function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) {
602 $value = get_metadata_raw( $meta_type, $object_id, $meta_key, $single );
603 if ( ! is_null( $value ) ) {
604 return $value;
605 }
606
607 return get_metadata_default( $meta_type, $object_id, $meta_key, $single );
608}
609
610/**
611 * Retrieves raw metadata value for the specified object.
612 *
613 * @since 5.5.0
614 *
615 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
616 * 'user', or any other object type with an associated meta table.
617 * @param int $object_id ID of the object metadata is for.
618 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for
619 * the specified object. Default empty string.
620 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`.
621 * This parameter has no effect if `$meta_key` is not specified. Default false.
622 * @return mixed An array of values if `$single` is false.
623 * The value of the meta field if `$single` is true.
624 * False for an invalid `$object_id` (non-numeric, zero, or negative value),
625 * or if `$meta_type` is not specified.
626 * Null if the value does not exist.
627 */
628function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false ) {
629 if ( ! $meta_type || ! is_numeric( $object_id ) ) {
630 return false;
631 }
632
633 $object_id = absint( $object_id );
634 if ( ! $object_id ) {
635 return false;
636 }
637
638 /**
639 * Short-circuits the return value of a meta field.
640 *
641 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
642 * (blog, post, comment, term, user, or any other type with an associated meta table).
643 * Returning a non-null value will effectively short-circuit the function.
644 *
645 * Possible filter names include:
646 *
647 * - `get_blog_metadata`
648 * - `get_post_metadata`
649 * - `get_comment_metadata`
650 * - `get_term_metadata`
651 * - `get_user_metadata`
652 *
653 * @since 3.1.0
654 * @since 5.5.0 Added the `$meta_type` parameter.
655 *
656 * @param mixed $value The value to return, either a single metadata value or an array
657 * of values depending on the value of `$single`. Default null.
658 * @param int $object_id ID of the object metadata is for.
659 * @param string $meta_key Metadata key.
660 * @param bool $single Whether to return only the first value of the specified `$meta_key`.
661 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
662 * 'user', or any other object type with an associated meta table.
663 */
664 $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $meta_type );
665 if ( null !== $check ) {
666 if ( $single && is_array( $check ) ) {
667 return $check[0];
668 } else {
669 return $check;
670 }
671 }
672
673 $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
674
675 if ( ! $meta_cache ) {
676 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
677 if ( isset( $meta_cache[ $object_id ] ) ) {
678 $meta_cache = $meta_cache[ $object_id ];
679 } else {
680 $meta_cache = null;
681 }
682 }
683
684 if ( ! $meta_key ) {
685 return $meta_cache;
686 }
687
688 if ( isset( $meta_cache[ $meta_key ] ) ) {
689 if ( $single ) {
690 return maybe_unserialize( $meta_cache[ $meta_key ][0] );
691 } else {
692 return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] );
693 }
694 }
695
696 return null;
697}
698
699/**
700 * Retrieves default metadata value for the specified meta key and object.
701 *
702 * By default, an empty string is returned if `$single` is true, or an empty array
703 * if it's false.
704 *
705 * @since 5.5.0
706 *
707 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
708 * 'user', or any other object type with an associated meta table.
709 * @param int $object_id ID of the object metadata is for.
710 * @param string $meta_key Metadata key.
711 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`.
712 * This parameter has no effect if `$meta_key` is not specified. Default false.
713 * @return mixed An array of default values if `$single` is false.
714 * The default value of the meta field if `$single` is true.
715 */
716function get_metadata_default( $meta_type, $object_id, $meta_key, $single = false ) {
717 if ( $single ) {
718 $value = '';
719 } else {
720 $value = array();
721 }
722
723 /**
724 * Filters the default metadata value for a specified meta key and object.
725 *
726 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
727 * (blog, post, comment, term, user, or any other type with an associated meta table).
728 *
729 * Possible filter names include:
730 *
731 * - `default_blog_metadata`
732 * - `default_post_metadata`
733 * - `default_comment_metadata`
734 * - `default_term_metadata`
735 * - `default_user_metadata`
736 *
737 * @since 5.5.0
738 *
739 * @param mixed $value The value to return, either a single metadata value or an array
740 * of values depending on the value of `$single`.
741 * @param int $object_id ID of the object metadata is for.
742 * @param string $meta_key Metadata key.
743 * @param bool $single Whether to return only the first value of the specified `$meta_key`.
744 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
745 * 'user', or any other object type with an associated meta table.
746 */
747 $value = apply_filters( "default_{$meta_type}_metadata", $value, $object_id, $meta_key, $single, $meta_type );
748
749 if ( ! $single && ! wp_is_numeric_array( $value ) ) {
750 $value = array( $value );
751 }
752
753 return $value;
754}
755
756/**
757 * Determines if a meta field with the given key exists for the given object ID.
758 *
759 * @since 3.3.0
760 *
761 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
762 * 'user', or any other object type with an associated meta table.
763 * @param int $object_id ID of the object metadata is for.
764 * @param string $meta_key Metadata key.
765 * @return bool Whether a meta field with the given key exists.
766 */
767function metadata_exists( $meta_type, $object_id, $meta_key ) {
768 if ( ! $meta_type || ! is_numeric( $object_id ) ) {
769 return false;
770 }
771
772 $object_id = absint( $object_id );
773 if ( ! $object_id ) {
774 return false;
775 }
776
777 /** This filter is documented in wp-includes/meta.php */
778 $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true, $meta_type );
779 if ( null !== $check ) {
780 return (bool) $check;
781 }
782
783 $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
784
785 if ( ! $meta_cache ) {
786 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
787 $meta_cache = $meta_cache[ $object_id ];
788 }
789
790 if ( isset( $meta_cache[ $meta_key ] ) ) {
791 return true;
792 }
793
794 return false;
795}
796
797/**
798 * Retrieves metadata by meta ID.
799 *
800 * @since 3.3.0
801 *
802 * @global wpdb $wpdb WordPress database abstraction object.
803 *
804 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
805 * 'user', or any other object type with an associated meta table.
806 * @param int $meta_id ID for a specific meta row.
807 * @return stdClass|false {
808 * Metadata object, or boolean `false` if the metadata doesn't exist.
809 *
810 * @type string $meta_key The meta key.
811 * @type mixed $meta_value The unserialized meta value.
812 * @type string $meta_id Optional. The meta ID when the meta type is any value except 'user'.
813 * @type string $umeta_id Optional. The meta ID when the meta type is 'user'.
814 * @type string $blog_id Optional. The object ID when the meta type is 'blog'.
815 * @type string $post_id Optional. The object ID when the meta type is 'post'.
816 * @type string $comment_id Optional. The object ID when the meta type is 'comment'.
817 * @type string $term_id Optional. The object ID when the meta type is 'term'.
818 * @type string $user_id Optional. The object ID when the meta type is 'user'.
819 * }
820 */
821function get_metadata_by_mid( $meta_type, $meta_id ) {
822 global $wpdb;
823
824 if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
825 return false;
826 }
827
828 $meta_id = (int) $meta_id;
829 if ( $meta_id <= 0 ) {
830 return false;
831 }
832
833 $table = _get_meta_table( $meta_type );
834 if ( ! $table ) {
835 return false;
836 }
837
838 /**
839 * Short-circuits the return value when fetching a meta field by meta ID.
840 *
841 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
842 * (blog, post, comment, term, user, or any other type with an associated meta table).
843 * Returning a non-null value will effectively short-circuit the function.
844 *
845 * Possible hook names include:
846 *
847 * - `get_blog_metadata_by_mid`
848 * - `get_post_metadata_by_mid`
849 * - `get_comment_metadata_by_mid`
850 * - `get_term_metadata_by_mid`
851 * - `get_user_metadata_by_mid`
852 *
853 * @since 5.0.0
854 *
855 * @param stdClass|null $value The value to return.
856 * @param int $meta_id Meta ID.
857 */
858 $check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id );
859 if ( null !== $check ) {
860 return $check;
861 }
862
863 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
864
865 $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
866
867 if ( empty( $meta ) ) {
868 return false;
869 }
870
871 if ( isset( $meta->meta_value ) ) {
872 $meta->meta_value = maybe_unserialize( $meta->meta_value );
873 }
874
875 return $meta;
876}
877
878/**
879 * Updates metadata by meta ID.
880 *
881 * @since 3.3.0
882 *
883 * @global wpdb $wpdb WordPress database abstraction object.
884 *
885 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
886 * 'user', or any other object type with an associated meta table.
887 * @param int $meta_id ID for a specific meta row.
888 * @param string $meta_value Metadata value. Must be serializable if non-scalar.
889 * @param string|false $meta_key Optional. You can provide a meta key to update it. Default false.
890 * @return bool True on successful update, false on failure.
891 */
892function update_metadata_by_mid( $meta_type, $meta_id, $meta_value, $meta_key = false ) {
893 global $wpdb;
894
895 // Make sure everything is valid.
896 if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
897 return false;
898 }
899
900 $meta_id = (int) $meta_id;
901 if ( $meta_id <= 0 ) {
902 return false;
903 }
904
905 $table = _get_meta_table( $meta_type );
906 if ( ! $table ) {
907 return false;
908 }
909
910 $column = sanitize_key( $meta_type . '_id' );
911 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
912
913 /**
914 * Short-circuits updating metadata of a specific type by meta ID.
915 *
916 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
917 * (blog, post, comment, term, user, or any other type with an associated meta table).
918 * Returning a non-null value will effectively short-circuit the function.
919 *
920 * Possible hook names include:
921 *
922 * - `update_blog_metadata_by_mid`
923 * - `update_post_metadata_by_mid`
924 * - `update_comment_metadata_by_mid`
925 * - `update_term_metadata_by_mid`
926 * - `update_user_metadata_by_mid`
927 *
928 * @since 5.0.0
929 *
930 * @param null|bool $check Whether to allow updating metadata for the given type.
931 * @param int $meta_id Meta ID.
932 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
933 * @param string|false $meta_key Meta key, if provided.
934 */
935 $check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key );
936 if ( null !== $check ) {
937 return (bool) $check;
938 }
939
940 // Fetch the meta and go on if it's found.
941 $meta = get_metadata_by_mid( $meta_type, $meta_id );
942 if ( $meta ) {
943 $original_key = $meta->meta_key;
944 $object_id = $meta->{$column};
945
946 /*
947 * If a new meta_key (last parameter) was specified, change the meta key,
948 * otherwise use the original key in the update statement.
949 */
950 if ( false === $meta_key ) {
951 $meta_key = $original_key;
952 } elseif ( ! is_string( $meta_key ) ) {
953 return false;
954 }
955
956 $meta_subtype = get_object_subtype( $meta_type, $object_id );
957
958 // Sanitize the meta.
959 $_meta_value = $meta_value;
960 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
961 $meta_value = maybe_serialize( $meta_value );
962
963 // Format the data query arguments.
964 $data = array(
965 'meta_key' => $meta_key,
966 'meta_value' => $meta_value,
967 );
968
969 // Format the where query arguments.
970 $where = array();
971 $where[ $id_column ] = $meta_id;
972
973 /** This action is documented in wp-includes/meta.php */
974 do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
975
976 if ( 'post' === $meta_type ) {
977 /** This action is documented in wp-includes/meta.php */
978 do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
979 }
980
981 // Run the update query, all fields in $data are %s, $where is a %d.
982 $result = $wpdb->update( $table, $data, $where, '%s', '%d' );
983 if ( ! $result ) {
984 return false;
985 }
986
987 // Clear the caches.
988 wp_cache_delete( $object_id, $meta_type . '_meta' );
989
990 /** This action is documented in wp-includes/meta.php */
991 do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
992
993 if ( 'post' === $meta_type ) {
994 /** This action is documented in wp-includes/meta.php */
995 do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
996 }
997
998 return true;
999 }
1000
1001 // And if the meta was not found.
1002 return false;
1003}
1004
1005/**
1006 * Deletes metadata by meta ID.
1007 *
1008 * @since 3.3.0
1009 *
1010 * @global wpdb $wpdb WordPress database abstraction object.
1011 *
1012 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1013 * 'user', or any other object type with an associated meta table.
1014 * @param int $meta_id ID for a specific meta row.
1015 * @return bool True on successful delete, false on failure.
1016 */
1017function delete_metadata_by_mid( $meta_type, $meta_id ) {
1018 global $wpdb;
1019
1020 // Make sure everything is valid.
1021 if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) {
1022 return false;
1023 }
1024
1025 $meta_id = (int) $meta_id;
1026 if ( $meta_id <= 0 ) {
1027 return false;
1028 }
1029
1030 $table = _get_meta_table( $meta_type );
1031 if ( ! $table ) {
1032 return false;
1033 }
1034
1035 // Object and ID columns.
1036 $column = sanitize_key( $meta_type . '_id' );
1037 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
1038
1039 /**
1040 * Short-circuits deleting metadata of a specific type by meta ID.
1041 *
1042 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
1043 * (blog, post, comment, term, user, or any other type with an associated meta table).
1044 * Returning a non-null value will effectively short-circuit the function.
1045 *
1046 * Possible hook names include:
1047 *
1048 * - `delete_blog_metadata_by_mid`
1049 * - `delete_post_metadata_by_mid`
1050 * - `delete_comment_metadata_by_mid`
1051 * - `delete_term_metadata_by_mid`
1052 * - `delete_user_metadata_by_mid`
1053 *
1054 * @since 5.0.0
1055 *
1056 * @param null|bool $delete Whether to allow metadata deletion of the given type.
1057 * @param int $meta_id Meta ID.
1058 */
1059 $check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id );
1060 if ( null !== $check ) {
1061 return (bool) $check;
1062 }
1063
1064 // Fetch the meta and go on if it's found.
1065 $meta = get_metadata_by_mid( $meta_type, $meta_id );
1066 if ( $meta ) {
1067 $object_id = (int) $meta->{$column};
1068
1069 /** This action is documented in wp-includes/meta.php */
1070 do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
1071
1072 // Old-style action.
1073 if ( 'post' === $meta_type || 'comment' === $meta_type ) {
1074 /**
1075 * Fires immediately before deleting post or comment metadata of a specific type.
1076 *
1077 * The dynamic portion of the hook name, `$meta_type`, refers to the meta
1078 * object type (post or comment).
1079 *
1080 * Possible hook names include:
1081 *
1082 * - `delete_postmeta`
1083 * - `delete_commentmeta`
1084 *
1085 * @since 3.4.0
1086 *
1087 * @param int $meta_id ID of the metadata entry to delete.
1088 */
1089 do_action( "delete_{$meta_type}meta", $meta_id );
1090 }
1091
1092 // Run the query, will return true if deleted, false otherwise.
1093 $result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) );
1094
1095 // Clear the caches.
1096 wp_cache_delete( $object_id, $meta_type . '_meta' );
1097
1098 /** This action is documented in wp-includes/meta.php */
1099 do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
1100
1101 // Old-style action.
1102 if ( 'post' === $meta_type || 'comment' === $meta_type ) {
1103 /**
1104 * Fires immediately after deleting post or comment metadata of a specific type.
1105 *
1106 * The dynamic portion of the hook name, `$meta_type`, refers to the meta
1107 * object type (post or comment).
1108 *
1109 * Possible hook names include:
1110 *
1111 * - `deleted_postmeta`
1112 * - `deleted_commentmeta`
1113 *
1114 * @since 3.4.0
1115 *
1116 * @param int $meta_id Deleted metadata entry ID.
1117 */
1118 do_action( "deleted_{$meta_type}meta", $meta_id );
1119 }
1120
1121 return $result;
1122
1123 }
1124
1125 // Meta ID was not found.
1126 return false;
1127}
1128
1129/**
1130 * Updates the metadata cache for the specified objects.
1131 *
1132 * @since 2.9.0
1133 *
1134 * @global wpdb $wpdb WordPress database abstraction object.
1135 *
1136 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1137 * 'user', or any other object type with an associated meta table.
1138 * @param string|int[] $object_ids Array or comma delimited list of object IDs to update cache for.
1139 * @return array|false Metadata cache for the specified objects, or false on failure.
1140 */
1141function update_meta_cache( $meta_type, $object_ids ) {
1142 global $wpdb;
1143
1144 if ( ! $meta_type || ! $object_ids ) {
1145 return false;
1146 }
1147
1148 $table = _get_meta_table( $meta_type );
1149 if ( ! $table ) {
1150 return false;
1151 }
1152
1153 $column = sanitize_key( $meta_type . '_id' );
1154
1155 if ( ! is_array( $object_ids ) ) {
1156 $object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
1157 $object_ids = explode( ',', $object_ids );
1158 }
1159
1160 $object_ids = array_map( 'intval', $object_ids );
1161
1162 /**
1163 * Short-circuits updating the metadata cache of a specific type.
1164 *
1165 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
1166 * (blog, post, comment, term, user, or any other type with an associated meta table).
1167 * Returning a non-null value will effectively short-circuit the function.
1168 *
1169 * Possible hook names include:
1170 *
1171 * - `update_blog_metadata_cache`
1172 * - `update_post_metadata_cache`
1173 * - `update_comment_metadata_cache`
1174 * - `update_term_metadata_cache`
1175 * - `update_user_metadata_cache`
1176 *
1177 * @since 5.0.0
1178 *
1179 * @param mixed $check Whether to allow updating the meta cache of the given type.
1180 * @param int[] $object_ids Array of object IDs to update the meta cache for.
1181 */
1182 $check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids );
1183 if ( null !== $check ) {
1184 return (bool) $check;
1185 }
1186
1187 $cache_group = $meta_type . '_meta';
1188 $non_cached_ids = array();
1189 $cache = array();
1190 $cache_values = wp_cache_get_multiple( $object_ids, $cache_group );
1191
1192 foreach ( $cache_values as $id => $cached_object ) {
1193 if ( false === $cached_object ) {
1194 $non_cached_ids[] = $id;
1195 } else {
1196 $cache[ $id ] = $cached_object;
1197 }
1198 }
1199
1200 if ( empty( $non_cached_ids ) ) {
1201 return $cache;
1202 }
1203
1204 // Get meta info.
1205 $id_list = implode( ',', $non_cached_ids );
1206 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';
1207
1208 $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 );
1209
1210 if ( ! empty( $meta_list ) ) {
1211 foreach ( $meta_list as $metarow ) {
1212 $mpid = (int) $metarow[ $column ];
1213 $mkey = $metarow['meta_key'];
1214 $mval = $metarow['meta_value'];
1215
1216 // Force subkeys to be array type.
1217 if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) {
1218 $cache[ $mpid ] = array();
1219 }
1220 if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) {
1221 $cache[ $mpid ][ $mkey ] = array();
1222 }
1223
1224 // Add a value to the current pid/key.
1225 $cache[ $mpid ][ $mkey ][] = $mval;
1226 }
1227 }
1228
1229 $cache = apply_filters('godaddy/update_meta_cache', $cache, $non_cached_ids, $meta_type);
1230
1231 $data = array();
1232 foreach ( $non_cached_ids as $id ) {
1233 if ( ! isset( $cache[ $id ] ) ) {
1234 $cache[ $id ] = array();
1235 }
1236 $data[ $id ] = $cache[ $id ];
1237 }
1238 wp_cache_add_multiple( $data, $cache_group );
1239
1240 return $cache;
1241}
1242
1243/**
1244 * Retrieves the queue for lazy-loading metadata.
1245 *
1246 * @since 4.5.0
1247 *
1248 * @return WP_Metadata_Lazyloader Metadata lazyloader queue.
1249 */
1250function wp_metadata_lazyloader() {
1251 static $wp_metadata_lazyloader;
1252
1253 if ( null === $wp_metadata_lazyloader ) {
1254 $wp_metadata_lazyloader = new WP_Metadata_Lazyloader();
1255 }
1256
1257 return $wp_metadata_lazyloader;
1258}
1259
1260/**
1261 * Given a meta query, generates SQL clauses to be appended to a main query.
1262 *
1263 * @since 3.2.0
1264 *
1265 * @see WP_Meta_Query
1266 *
1267 * @param array $meta_query A meta query.
1268 * @param string $type Type of meta.
1269 * @param string $primary_table Primary database table name.
1270 * @param string $primary_id_column Primary ID column name.
1271 * @param object $context Optional. The main query object. Default null.
1272 * @return string[]|false {
1273 * Array containing JOIN and WHERE SQL clauses to append to the main query,
1274 * or false if no table exists for the requested meta type.
1275 *
1276 * @type string $join SQL fragment to append to the main JOIN clause.
1277 * @type string $where SQL fragment to append to the main WHERE clause.
1278 * }
1279 */
1280function get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) {
1281 $meta_query_obj = new WP_Meta_Query( $meta_query );
1282 return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context );
1283}
1284
1285/**
1286 * Retrieves the name of the metadata table for the specified object type.
1287 *
1288 * @since 2.9.0
1289 *
1290 * @global wpdb $wpdb WordPress database abstraction object.
1291 *
1292 * @param string $type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1293 * 'user', or any other object type with an associated meta table.
1294 * @return string|false Metadata table name, or false if no metadata table exists
1295 */
1296function _get_meta_table( $type ) {
1297 global $wpdb;
1298
1299 $table_name = $type . 'meta';
1300
1301 if ( empty( $wpdb->$table_name ) ) {
1302 return false;
1303 }
1304
1305 return $wpdb->$table_name;
1306}
1307
1308/**
1309 * Determines whether a meta key is considered protected.
1310 *
1311 * @since 3.1.3
1312 *
1313 * @param string $meta_key Metadata key.
1314 * @param string $meta_type Optional. Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1315 * 'user', or any other object type with an associated meta table. Default empty string.
1316 * @return bool Whether the meta key is considered protected.
1317 */
1318function is_protected_meta( $meta_key, $meta_type = '' ) {
1319 $sanitized_key = preg_replace( "/[^\x20-\x7E\p{L}]/", '', $meta_key );
1320 $protected = strlen( $sanitized_key ) > 0 && ( '_' === $sanitized_key[0] );
1321
1322 /**
1323 * Filters whether a meta key is considered protected.
1324 *
1325 * @since 3.2.0
1326 *
1327 * @param bool $protected Whether the key is considered protected.
1328 * @param string $meta_key Metadata key.
1329 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1330 * 'user', or any other object type with an associated meta table.
1331 */
1332 return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
1333}
1334
1335/**
1336 * Sanitizes meta value.
1337 *
1338 * @since 3.1.3
1339 * @since 4.9.8 The `$object_subtype` parameter was added.
1340 *
1341 * @param string $meta_key Metadata key.
1342 * @param mixed $meta_value Metadata value to sanitize.
1343 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1344 * 'user', or any other object type with an associated meta table.
1345 * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1346 * @return mixed Sanitized $meta_value.
1347 */
1348function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) {
1349 if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
1350
1351 /**
1352 * Filters the sanitization of a specific meta key of a specific meta type and subtype.
1353 *
1354 * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
1355 * and `$object_subtype`, refer to the metadata object type (blog, comment, post, term, or user),
1356 * the meta key value, and the object subtype respectively.
1357 *
1358 * @since 4.9.8
1359 *
1360 * @param mixed $meta_value Metadata value to sanitize.
1361 * @param string $meta_key Metadata key.
1362 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1363 * 'user', or any other object type with an associated meta table.
1364 * @param string $object_subtype Object subtype.
1365 */
1366 return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $meta_value, $meta_key, $object_type, $object_subtype );
1367 }
1368
1369 /**
1370 * Filters the sanitization of a specific meta key of a specific meta type.
1371 *
1372 * The dynamic portions of the hook name, `$meta_type`, and `$meta_key`,
1373 * refer to the metadata object type (blog, comment, post, term, or user) and the meta
1374 * key value, respectively.
1375 *
1376 * @since 3.3.0
1377 *
1378 * @param mixed $meta_value Metadata value to sanitize.
1379 * @param string $meta_key Metadata key.
1380 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1381 * 'user', or any other object type with an associated meta table.
1382 */
1383 return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type );
1384}
1385
1386/**
1387 * Registers a meta key.
1388 *
1389 * It is recommended to register meta keys for a specific combination of object type and object subtype. If passing
1390 * an object subtype is omitted, the meta key will be registered for the entire object type, however it can be partly
1391 * overridden in case a more specific meta key of the same name exists for the same object type and a subtype.
1392 *
1393 * If an object type does not support any subtypes, such as blogs, users, or comments, you should commonly call this function
1394 * without passing a subtype.
1395 *
1396 * @since 3.3.0
1397 * @since 4.6.0 {@link https://core.trac.wordpress.org/ticket/35658 Modified
1398 * to support an array of data to attach to registered meta keys}. Previous arguments for
1399 * `$sanitize_callback` and `$auth_callback` have been folded into this array.
1400 * @since 4.9.8 The `$object_subtype` argument was added to the arguments array.
1401 * @since 5.3.0 Valid meta types expanded to include "array" and "object".
1402 * @since 5.5.0 The `$default` argument was added to the arguments array.
1403 * @since 6.4.0 The `$revisions_enabled` argument was added to the arguments array.
1404 * @since 6.7.0 The `label` argument was added to the arguments array.
1405 *
1406 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1407 * 'user', or any other object type with an associated meta table.
1408 * @param string $meta_key Meta key to register.
1409 * @param array $args {
1410 * Data used to describe the meta key when registered.
1411 *
1412 * @type string $object_subtype A subtype; e.g. if the object type is "post", the post type. If left empty,
1413 * the meta key will be registered on the entire object type. Default empty.
1414 * @type string $type The type of data associated with this meta key.
1415 * Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
1416 * @type string $label A human-readable label of the data attached to this meta key.
1417 * @type string $description A description of the data attached to this meta key.
1418 * @type bool $single Whether the meta key has one value per object, or an array of values per object.
1419 * @type mixed $default The default value returned from get_metadata() if no value has been set yet.
1420 * When using a non-single meta key, the default value is for the first entry.
1421 * In other words, when calling get_metadata() with `$single` set to `false`,
1422 * the default value given here will be wrapped in an array.
1423 * @type callable $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
1424 * @type callable $auth_callback Optional. A function or method to call when performing edit_post_meta,
1425 * add_post_meta, and delete_post_meta capability checks.
1426 * @type bool|array $show_in_rest Whether data associated with this meta key can be considered public and
1427 * should be accessible via the REST API. A custom post type must also declare
1428 * support for custom fields for registered meta to be accessible via REST.
1429 * When registering complex meta values this argument may optionally be an
1430 * array with 'schema' or 'prepare_callback' keys instead of a boolean.
1431 * @type bool $revisions_enabled Whether to enable revisions support for this meta_key. Can only be used when the
1432 * object type is 'post'.
1433 * }
1434 * @param string|array $deprecated Deprecated. Use `$args` instead.
1435 * @return bool True if the meta key was successfully registered in the global array, false if not.
1436 * Registering a meta key with distinct sanitize and auth callbacks will fire those callbacks,
1437 * but will not add to the global registry.
1438 */
1439function register_meta( $object_type, $meta_key, $args, $deprecated = null ) {
1440 global $wp_meta_keys;
1441
1442 if ( ! is_array( $wp_meta_keys ) ) {
1443 $wp_meta_keys = array();
1444 }
1445
1446 $defaults = array(
1447 'object_subtype' => '',
1448 'type' => 'string',
1449 'label' => '',
1450 'description' => '',
1451 'default' => '',
1452 'single' => false,
1453 'sanitize_callback' => null,
1454 'auth_callback' => null,
1455 'show_in_rest' => false,
1456 'revisions_enabled' => false,
1457 );
1458
1459 // There used to be individual args for sanitize and auth callbacks.
1460 $has_old_sanitize_cb = false;
1461 $has_old_auth_cb = false;
1462
1463 if ( is_callable( $args ) ) {
1464 $args = array(
1465 'sanitize_callback' => $args,
1466 );
1467
1468 $has_old_sanitize_cb = true;
1469 } else {
1470 $args = (array) $args;
1471 }
1472
1473 if ( is_callable( $deprecated ) ) {
1474 $args['auth_callback'] = $deprecated;
1475 $has_old_auth_cb = true;
1476 }
1477
1478 /**
1479 * Filters the registration arguments when registering meta.
1480 *
1481 * @since 4.6.0
1482 *
1483 * @param array $args Array of meta registration arguments.
1484 * @param array $defaults Array of default arguments.
1485 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1486 * 'user', or any other object type with an associated meta table.
1487 * @param string $meta_key Meta key.
1488 */
1489 $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key );
1490 unset( $defaults['default'] );
1491 $args = wp_parse_args( $args, $defaults );
1492
1493 // Require an item schema when registering array meta.
1494 if ( false !== $args['show_in_rest'] && 'array' === $args['type'] ) {
1495 if ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) {
1496 _doing_it_wrong( __FUNCTION__, __( 'When registering an "array" meta type to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.3.0' );
1497
1498 return false;
1499 }
1500 }
1501
1502 $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : '';
1503 if ( $args['revisions_enabled'] ) {
1504 if ( 'post' !== $object_type ) {
1505 _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object type supports revisions.' ), '6.4.0' );
1506
1507 return false;
1508 } elseif ( ! empty( $object_subtype ) && ! post_type_supports( $object_subtype, 'revisions' ) ) {
1509 _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object subtype supports revisions.' ), '6.4.0' );
1510
1511 return false;
1512 }
1513 }
1514
1515 // If `auth_callback` is not provided, fall back to `is_protected_meta()`.
1516 if ( empty( $args['auth_callback'] ) ) {
1517 if ( is_protected_meta( $meta_key, $object_type ) ) {
1518 $args['auth_callback'] = '__return_false';
1519 } else {
1520 $args['auth_callback'] = '__return_true';
1521 }
1522 }
1523
1524 // Back-compat: old sanitize and auth callbacks are applied to all of an object type.
1525 if ( is_callable( $args['sanitize_callback'] ) ) {
1526 if ( ! empty( $object_subtype ) ) {
1527 add_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'], 10, 4 );
1528 } else {
1529 add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 );
1530 }
1531 }
1532
1533 if ( is_callable( $args['auth_callback'] ) ) {
1534 if ( ! empty( $object_subtype ) ) {
1535 add_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'], 10, 6 );
1536 } else {
1537 add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
1538 }
1539 }
1540
1541 if ( array_key_exists( 'default', $args ) ) {
1542 $schema = $args;
1543 if ( is_array( $args['show_in_rest'] ) && isset( $args['show_in_rest']['schema'] ) ) {
1544 $schema = array_merge( $schema, $args['show_in_rest']['schema'] );
1545 }
1546
1547 $check = rest_validate_value_from_schema( $args['default'], $schema );
1548 if ( is_wp_error( $check ) ) {
1549 _doing_it_wrong( __FUNCTION__, __( 'When registering a default meta value the data must match the type provided.' ), '5.5.0' );
1550
1551 return false;
1552 }
1553
1554 if ( ! has_filter( "default_{$object_type}_metadata", 'filter_default_metadata' ) ) {
1555 add_filter( "default_{$object_type}_metadata", 'filter_default_metadata', 10, 5 );
1556 }
1557 }
1558
1559 // Global registry only contains meta keys registered with the array of arguments added in 4.6.0.
1560 if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) {
1561 unset( $args['object_subtype'] );
1562
1563 $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args;
1564
1565 return true;
1566 }
1567
1568 return false;
1569}
1570
1571/**
1572 * Filters into default_{$object_type}_metadata and adds in default value.
1573 *
1574 * @since 5.5.0
1575 *
1576 * @param mixed $value Current value passed to filter.
1577 * @param int $object_id ID of the object metadata is for.
1578 * @param string $meta_key Metadata key.
1579 * @param bool $single If true, return only the first value of the specified `$meta_key`.
1580 * This parameter has no effect if `$meta_key` is not specified.
1581 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1582 * 'user', or any other object type with an associated meta table.
1583 * @return mixed An array of default values if `$single` is false.
1584 * The default value of the meta field if `$single` is true.
1585 */
1586function filter_default_metadata( $value, $object_id, $meta_key, $single, $meta_type ) {
1587 global $wp_meta_keys;
1588
1589 if ( wp_installing() ) {
1590 return $value;
1591 }
1592
1593 if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $meta_type ] ) ) {
1594 return $value;
1595 }
1596
1597 $defaults = array();
1598 foreach ( $wp_meta_keys[ $meta_type ] as $sub_type => $meta_data ) {
1599 foreach ( $meta_data as $_meta_key => $args ) {
1600 if ( $_meta_key === $meta_key && array_key_exists( 'default', $args ) ) {
1601 $defaults[ $sub_type ] = $args;
1602 }
1603 }
1604 }
1605
1606 if ( ! $defaults ) {
1607 return $value;
1608 }
1609
1610 // If this meta type does not have subtypes, then the default is keyed as an empty string.
1611 if ( isset( $defaults[''] ) ) {
1612 $metadata = $defaults[''];
1613 } else {
1614 $sub_type = get_object_subtype( $meta_type, $object_id );
1615 if ( ! isset( $defaults[ $sub_type ] ) ) {
1616 return $value;
1617 }
1618 $metadata = $defaults[ $sub_type ];
1619 }
1620
1621 if ( $single ) {
1622 $value = $metadata['default'];
1623 } else {
1624 $value = array( $metadata['default'] );
1625 }
1626
1627 return $value;
1628}
1629
1630/**
1631 * Checks if a meta key is registered.
1632 *
1633 * @since 4.6.0
1634 * @since 4.9.8 The `$object_subtype` parameter was added.
1635 *
1636 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1637 * 'user', or any other object type with an associated meta table.
1638 * @param string $meta_key Metadata key.
1639 * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1640 * @return bool True if the meta key is registered to the object type and, if provided,
1641 * the object subtype. False if not.
1642 */
1643function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) {
1644 $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
1645
1646 return isset( $meta_keys[ $meta_key ] );
1647}
1648
1649/**
1650 * Unregisters a meta key from the list of registered keys.
1651 *
1652 * @since 4.6.0
1653 * @since 4.9.8 The `$object_subtype` parameter was added.
1654 *
1655 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1656 * 'user', or any other object type with an associated meta table.
1657 * @param string $meta_key Metadata key.
1658 * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1659 * @return bool True if successful. False if the meta key was not registered.
1660 */
1661function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) {
1662 global $wp_meta_keys;
1663
1664 if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1665 return false;
1666 }
1667
1668 $args = $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ];
1669
1670 if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) {
1671 if ( ! empty( $object_subtype ) ) {
1672 remove_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'] );
1673 } else {
1674 remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] );
1675 }
1676 }
1677
1678 if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) {
1679 if ( ! empty( $object_subtype ) ) {
1680 remove_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'] );
1681 } else {
1682 remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] );
1683 }
1684 }
1685
1686 unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] );
1687
1688 // Do some clean up.
1689 if ( empty( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) {
1690 unset( $wp_meta_keys[ $object_type ][ $object_subtype ] );
1691 }
1692 if ( empty( $wp_meta_keys[ $object_type ] ) ) {
1693 unset( $wp_meta_keys[ $object_type ] );
1694 }
1695
1696 return true;
1697}
1698
1699/**
1700 * Retrieves a list of registered metadata args for an object type, keyed by their meta keys.
1701 *
1702 * @since 4.6.0
1703 * @since 4.9.8 The `$object_subtype` parameter was added.
1704 *
1705 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1706 * 'user', or any other object type with an associated meta table.
1707 * @param string $object_subtype Optional. The subtype of the object type. Default empty string.
1708 * @return array[] List of registered metadata args, keyed by their meta keys.
1709 */
1710function get_registered_meta_keys( $object_type, $object_subtype = '' ) {
1711 global $wp_meta_keys;
1712
1713 if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) || ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) {
1714 return array();
1715 }
1716
1717 return $wp_meta_keys[ $object_type ][ $object_subtype ];
1718}
1719
1720/**
1721 * Retrieves registered metadata for a specified object.
1722 *
1723 * The results include both meta that is registered specifically for the
1724 * object's subtype and meta that is registered for the entire object type.
1725 *
1726 * @since 4.6.0
1727 *
1728 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1729 * 'user', or any other object type with an associated meta table.
1730 * @param int $object_id ID of the object the metadata is for.
1731 * @param string $meta_key Optional. Registered metadata key. If not specified, retrieve all registered
1732 * metadata for the specified object.
1733 * @return mixed A single value or array of values for a key if specified. An array of all registered keys
1734 * and values for an object ID if not. False if a given $meta_key is not registered.
1735 */
1736function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) {
1737 $object_subtype = get_object_subtype( $object_type, $object_id );
1738
1739 if ( ! empty( $meta_key ) ) {
1740 if ( ! empty( $object_subtype ) && ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1741 $object_subtype = '';
1742 }
1743
1744 if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
1745 return false;
1746 }
1747
1748 $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
1749 $meta_key_data = $meta_keys[ $meta_key ];
1750
1751 $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] );
1752
1753 return $data;
1754 }
1755
1756 $data = get_metadata( $object_type, $object_id );
1757 if ( ! $data ) {
1758 return array();
1759 }
1760
1761 $meta_keys = get_registered_meta_keys( $object_type );
1762 if ( ! empty( $object_subtype ) ) {
1763 $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $object_type, $object_subtype ) );
1764 }
1765
1766 return array_intersect_key( $data, $meta_keys );
1767}
1768
1769/**
1770 * Filters out `register_meta()` args based on an allowed list.
1771 *
1772 * `register_meta()` args may change over time, so requiring the allowed list
1773 * to be explicitly turned off is a warranty seal of sorts.
1774 *
1775 * @access private
1776 * @since 5.5.0
1777 *
1778 * @param array $args Arguments from `register_meta()`.
1779 * @param array $default_args Default arguments for `register_meta()`.
1780 * @return array Filtered arguments.
1781 */
1782function _wp_register_meta_args_allowed_list( $args, $default_args ) {
1783 return array_intersect_key( $args, $default_args );
1784}
1785
1786/**
1787 * Returns the object subtype for a given object ID of a specific type.
1788 *
1789 * @since 4.9.8
1790 *
1791 * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
1792 * 'user', or any other object type with an associated meta table.
1793 * @param int $object_id ID of the object to retrieve its subtype.
1794 * @return string The object subtype or an empty string if unspecified subtype.
1795 */
1796function get_object_subtype( $object_type, $object_id ) {
1797 $object_id = (int) $object_id;
1798 $object_subtype = '';
1799
1800 switch ( $object_type ) {
1801 case 'post':
1802 $post_type = get_post_type( $object_id );
1803
1804 if ( ! empty( $post_type ) ) {
1805 $object_subtype = $post_type;
1806 }
1807 break;
1808
1809 case 'term':
1810 $term = get_term( $object_id );
1811 if ( ! $term instanceof WP_Term ) {
1812 break;
1813 }
1814
1815 $object_subtype = $term->taxonomy;
1816 break;
1817
1818 case 'comment':
1819 $comment = get_comment( $object_id );
1820 if ( ! $comment ) {
1821 break;
1822 }
1823
1824 $object_subtype = 'comment';
1825 break;
1826
1827 case 'user':
1828 $user = get_user_by( 'id', $object_id );
1829 if ( ! $user ) {
1830 break;
1831 }
1832
1833 $object_subtype = 'user';
1834 break;
1835 }
1836
1837 /**
1838 * Filters the object subtype identifier.
1839 *
1840 * The dynamic portion of the hook name, `$object_type`, refers to the meta object type
1841 * (blog, post, comment, term, user, or any other type with an associated meta table).
1842 *
1843 * Possible hook names include:
1844 *
1845 * - `get_object_subtype_blog`
1846 * - `get_object_subtype_post`
1847 * - `get_object_subtype_comment`
1848 * - `get_object_subtype_term`
1849 * - `get_object_subtype_user`
1850 *
1851 * @since 4.9.8
1852 *
1853 * @param string $object_subtype Object subtype or empty string to override.
1854 * @param int $object_id ID of the object to get the subtype for.
1855 */
1856 return apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id );
1857}
1858
Ui Ux Design – Teachers Night Out

Get in Touch

© 2024 Teachers Night Out. All Rights Reserved.