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
📄option.php
1<?php
2/**
3 * Option API
4 *
5 * @package WordPress
6 * @subpackage Option
7 */
8
9/**
10 * Retrieves an option value based on an option name.
11 *
12 * If the option does not exist, and a default value is not provided,
13 * boolean false is returned. This could be used to check whether you need
14 * to initialize an option during installation of a plugin, however that
15 * can be done better by using add_option() which will not overwrite
16 * existing options.
17 *
18 * Not initializing an option and using boolean `false` as a return value
19 * is a bad practice as it triggers an additional database query.
20 *
21 * The type of the returned value can be different from the type that was passed
22 * when saving or updating the option. If the option value was serialized,
23 * then it will be unserialized when it is returned. In this case the type will
24 * be the same. For example, storing a non-scalar value like an array will
25 * return the same array.
26 *
27 * In most cases non-string scalar and null values will be converted and returned
28 * as string equivalents.
29 *
30 * Exceptions:
31 *
32 * 1. When the option has not been saved in the database, the `$default_value` value
33 * is returned if provided. If not, boolean `false` is returned.
34 * 2. When one of the Options API filters is used: {@see 'pre_option_$option'},
35 * {@see 'default_option_$option'}, or {@see 'option_$option'}, the returned
36 * value may not match the expected type.
37 * 3. When the option has just been saved in the database, and get_option()
38 * is used right after, non-string scalar and null values are not converted to
39 * string equivalents and the original type is returned.
40 *
41 * Examples:
42 *
43 * When adding options like this: `add_option( 'my_option_name', 'value' )`
44 * and then retrieving them with `get_option( 'my_option_name' )`, the returned
45 * values will be:
46 *
47 * - `false` returns `string(0) ""`
48 * - `true` returns `string(1) "1"`
49 * - `0` returns `string(1) "0"`
50 * - `1` returns `string(1) "1"`
51 * - `'0'` returns `string(1) "0"`
52 * - `'1'` returns `string(1) "1"`
53 * - `null` returns `string(0) ""`
54 *
55 * When adding options with non-scalar values like
56 * `add_option( 'my_array', array( false, 'str', null ) )`, the returned value
57 * will be identical to the original as it is serialized before saving
58 * it in the database:
59 *
60 * array(3) {
61 * [0] => bool(false)
62 * [1] => string(3) "str"
63 * [2] => NULL
64 * }
65 *
66 * @since 1.5.0
67 *
68 * @global wpdb $wpdb WordPress database abstraction object.
69 *
70 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped.
71 * @param mixed $default_value Optional. Default value to return if the option does not exist.
72 * @return mixed Value of the option. A value of any type may be returned, including
73 * scalar (string, boolean, float, integer), null, array, object.
74 * Scalar and null values will be returned as strings as long as they originate
75 * from a database stored option value. If there is no option in the database,
76 * boolean `false` is returned.
77 */
78function get_option( $option, $default_value = false ) {
79 global $wpdb;
80
81 if ( is_scalar( $option ) ) {
82 $option = trim( $option );
83 }
84
85 if ( empty( $option ) ) {
86 return false;
87 }
88
89 /*
90 * Until a proper _deprecated_option() function can be introduced,
91 * redirect requests to deprecated keys to the new, correct ones.
92 */
93 $deprecated_keys = array(
94 'blacklist_keys' => 'disallowed_keys',
95 'comment_whitelist' => 'comment_previously_approved',
96 );
97
98 if ( isset( $deprecated_keys[ $option ] ) && ! wp_installing() ) {
99 _deprecated_argument(
100 __FUNCTION__,
101 '5.5.0',
102 sprintf(
103 /* translators: 1: Deprecated option key, 2: New option key. */
104 __( 'The "%1$s" option key has been renamed to "%2$s".' ),
105 $option,
106 $deprecated_keys[ $option ]
107 )
108 );
109 return get_option( $deprecated_keys[ $option ], $default_value );
110 }
111
112 /**
113 * Filters the value of an existing option before it is retrieved.
114 *
115 * The dynamic portion of the hook name, `$option`, refers to the option name.
116 *
117 * Returning a value other than false from the filter will short-circuit retrieval
118 * and return that value instead.
119 *
120 * @since 1.5.0
121 * @since 4.4.0 The `$option` parameter was added.
122 * @since 4.9.0 The `$default_value` parameter was added.
123 *
124 * @param mixed $pre_option The value to return instead of the option value. This differs from
125 * `$default_value`, which is used as the fallback value in the event
126 * the option doesn't exist elsewhere in get_option().
127 * Default false (to skip past the short-circuit).
128 * @param string $option Option name.
129 * @param mixed $default_value The fallback value to return if the option does not exist.
130 * Default false.
131 */
132 $pre = apply_filters( "pre_option_{$option}", false, $option, $default_value );
133
134 /**
135 * Filters the value of any existing option before it is retrieved.
136 *
137 * Returning a value other than false from the filter will short-circuit retrieval
138 * and return that value instead.
139 *
140 * @since 6.1.0
141 *
142 * @param mixed $pre_option The value to return instead of the option value. This differs from
143 * `$default_value`, which is used as the fallback value in the event
144 * the option doesn't exist elsewhere in get_option().
145 * Default false (to skip past the short-circuit).
146 * @param string $option Name of the option.
147 * @param mixed $default_value The fallback value to return if the option does not exist.
148 * Default false.
149 */
150 $pre = apply_filters( 'pre_option', $pre, $option, $default_value );
151
152 if ( false !== $pre ) {
153 return $pre;
154 }
155
156 if ( defined( 'WP_SETUP_CONFIG' ) ) {
157 return false;
158 }
159
160 // Distinguish between `false` as a default, and not passing one.
161 $passed_default = func_num_args() > 1;
162
163 if ( ! wp_installing() ) {
164 $alloptions = wp_load_alloptions();
165 /*
166 * When getting an option value, we check in the following order for performance:
167 *
168 * 1. Check the 'alloptions' cache first to prioritize existing loaded options.
169 * 2. Check the 'notoptions' cache before a cache lookup or DB hit.
170 * 3. Check the 'options' cache prior to a DB hit.
171 * 4. Check the DB for the option and cache it in either the 'options' or 'notoptions' cache.
172 */
173 if ( isset( $alloptions[ $option ] ) ) {
174 $value = $alloptions[ $option ];
175 } else {
176 // Check for non-existent options first to avoid unnecessary object cache lookups and DB hits.
177 $notoptions = wp_cache_get( 'notoptions', 'options' );
178
179 if ( ! is_array( $notoptions ) ) {
180 $notoptions = array();
181 wp_cache_set( 'notoptions', $notoptions, 'options' );
182 }
183
184 if ( isset( $notoptions[ $option ] ) ) {
185 /**
186 * Filters the default value for an option.
187 *
188 * The dynamic portion of the hook name, `$option`, refers to the option name.
189 *
190 * @since 3.4.0
191 * @since 4.4.0 The `$option` parameter was added.
192 * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value.
193 *
194 * @param mixed $default_value The default value to return if the option does not exist
195 * in the database.
196 * @param string $option Option name.
197 * @param bool $passed_default Was `get_option()` passed a default value?
198 */
199 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );
200 }
201
202 $value = wp_cache_get( $option, 'options' );
203
204 if ( false === $value ) {
205
206 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
207
208 // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values.
209 if ( is_object( $row ) ) {
210 $value = $row->option_value;
211 wp_cache_add( $option, $value, 'options' );
212 } else { // Option does not exist, so we must cache its non-existence.
213 $notoptions[ $option ] = true;
214 wp_cache_set( 'notoptions', $notoptions, 'options' );
215
216 /** This filter is documented in wp-includes/option.php */
217 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );
218 }
219 }
220 }
221 } else {
222 $suppress = $wpdb->suppress_errors();
223 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
224 $wpdb->suppress_errors( $suppress );
225
226 if ( is_object( $row ) ) {
227 $value = $row->option_value;
228 } else {
229 /** This filter is documented in wp-includes/option.php */
230 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );
231 }
232 }
233
234 // If home is not set, use siteurl.
235 if ( 'home' === $option && '' === $value ) {
236 return get_option( 'siteurl' );
237 }
238
239 if ( in_array( $option, array( 'siteurl', 'home', 'category_base', 'tag_base' ), true ) ) {
240 $value = untrailingslashit( $value );
241 }
242
243 /**
244 * Filters the value of an existing option.
245 *
246 * The dynamic portion of the hook name, `$option`, refers to the option name.
247 *
248 * @since 1.5.0 As 'option_' . $setting
249 * @since 3.0.0
250 * @since 4.4.0 The `$option` parameter was added.
251 *
252 * @param mixed $value Value of the option. If stored serialized, it will be
253 * unserialized prior to being returned.
254 * @param string $option Option name.
255 */
256 return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option );
257}
258
259/**
260 * Primes specific options into the cache with a single database query.
261 *
262 * Only options that do not already exist in cache will be loaded.
263 *
264 * @since 6.4.0
265 *
266 * @global wpdb $wpdb WordPress database abstraction object.
267 *
268 * @param string[] $options An array of option names to be loaded.
269 */
270function wp_prime_option_caches( $options ) {
271 global $wpdb;
272
273 $alloptions = wp_load_alloptions();
274 $cached_options = wp_cache_get_multiple( $options, 'options' );
275 $notoptions = wp_cache_get( 'notoptions', 'options' );
276 if ( ! is_array( $notoptions ) ) {
277 $notoptions = array();
278 }
279
280 // Filter options that are not in the cache.
281 $options_to_prime = array();
282 foreach ( $options as $option ) {
283 if (
284 ( ! isset( $cached_options[ $option ] ) || false === $cached_options[ $option ] )
285 && ! isset( $alloptions[ $option ] )
286 && ! isset( $notoptions[ $option ] )
287 ) {
288 $options_to_prime[] = $option;
289 }
290 }
291
292 // Bail early if there are no options to be loaded.
293 if ( empty( $options_to_prime ) ) {
294 return;
295 }
296
297 $results = $wpdb->get_results(
298 $wpdb->prepare(
299 sprintf(
300 "SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN (%s)",
301 implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) )
302 ),
303 $options_to_prime
304 )
305 );
306
307 $options_found = array();
308 foreach ( $results as $result ) {
309 /*
310 * The cache is primed with the raw value (i.e. not maybe_unserialized).
311 *
312 * `get_option()` will handle unserializing the value as needed.
313 */
314 $options_found[ $result->option_name ] = $result->option_value;
315 }
316 wp_cache_set_multiple( $options_found, 'options' );
317
318 // If all options were found, no need to update `notoptions` cache.
319 if ( count( $options_found ) === count( $options_to_prime ) ) {
320 return;
321 }
322
323 $options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) );
324
325 // Add the options that were not found to the cache.
326 $update_notoptions = false;
327 foreach ( $options_not_found as $option_name ) {
328 if ( ! isset( $notoptions[ $option_name ] ) ) {
329 $notoptions[ $option_name ] = true;
330 $update_notoptions = true;
331 }
332 }
333
334 // Only update the cache if it was modified.
335 if ( $update_notoptions ) {
336 wp_cache_set( 'notoptions', $notoptions, 'options' );
337 }
338}
339
340/**
341 * Primes the cache of all options registered with a specific option group.
342 *
343 * @since 6.4.0
344 *
345 * @global array $new_allowed_options
346 *
347 * @param string $option_group The option group to load options for.
348 */
349function wp_prime_option_caches_by_group( $option_group ) {
350 global $new_allowed_options;
351
352 if ( isset( $new_allowed_options[ $option_group ] ) ) {
353 wp_prime_option_caches( $new_allowed_options[ $option_group ] );
354 }
355}
356
357/**
358 * Retrieves multiple options.
359 *
360 * Options are loaded as necessary first in order to use a single database query at most.
361 *
362 * @since 6.4.0
363 *
364 * @param string[] $options An array of option names to retrieve.
365 * @return array An array of key-value pairs for the requested options.
366 */
367function get_options( $options ) {
368 wp_prime_option_caches( $options );
369
370 $result = array();
371 foreach ( $options as $option ) {
372 $result[ $option ] = get_option( $option );
373 }
374
375 return $result;
376}
377
378/**
379 * Sets the autoload values for multiple options in the database.
380 *
381 * Autoloading too many options can lead to performance problems, especially if the options are not frequently used.
382 * This function allows modifying the autoload value for multiple options without changing the actual option value.
383 * This is for example recommended for plugin activation and deactivation hooks, to ensure any options exclusively used
384 * by the plugin which are generally autoloaded can be set to not autoload when the plugin is inactive.
385 *
386 * @since 6.4.0
387 * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
388 *
389 * @global wpdb $wpdb WordPress database abstraction object.
390 *
391 * @param array $options Associative array of option names and their autoload values to set. The option names are
392 * expected to not be SQL-escaped. The autoload values should be boolean values. For backward
393 * compatibility 'yes' and 'no' are also accepted, though using these values is deprecated.
394 * @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
395 * was updated.
396 */
397function wp_set_option_autoload_values( array $options ) {
398 global $wpdb;
399
400 if ( ! $options ) {
401 return array();
402 }
403
404 $grouped_options = array(
405 'on' => array(),
406 'off' => array(),
407 );
408 $results = array();
409 foreach ( $options as $option => $autoload ) {
410 wp_protect_special_option( $option ); // Ensure only valid options can be passed.
411
412 /*
413 * Sanitize autoload value and categorize accordingly.
414 * The values 'yes', 'no', 'on', and 'off' are supported for backward compatibility.
415 */
416 if ( 'off' === $autoload || 'no' === $autoload || false === $autoload ) {
417 $grouped_options['off'][] = $option;
418 } else {
419 $grouped_options['on'][] = $option;
420 }
421 $results[ $option ] = false; // Initialize result value.
422 }
423
424 $where = array();
425 $where_args = array();
426 foreach ( $grouped_options as $autoload => $options ) {
427 if ( ! $options ) {
428 continue;
429 }
430 $placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) );
431 $where[] = "autoload != '%s' AND option_name IN ($placeholders)";
432 $where_args[] = $autoload;
433 foreach ( $options as $option ) {
434 $where_args[] = $option;
435 }
436 }
437 $where = 'WHERE ' . implode( ' OR ', $where );
438
439 /*
440 * Determine the relevant options that do not already use the given autoload value.
441 * If no options are returned, no need to update.
442 */
443 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
444 $options_to_update = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options $where", $where_args ) );
445 if ( ! $options_to_update ) {
446 return $results;
447 }
448
449 // Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'.
450 foreach ( $grouped_options as $autoload => $options ) {
451 if ( ! $options ) {
452 continue;
453 }
454 $options = array_intersect( $options, $options_to_update );
455 $grouped_options[ $autoload ] = $options;
456 if ( ! $grouped_options[ $autoload ] ) {
457 continue;
458 }
459
460 // Run query to update autoload value for all the options where it is needed.
461 $success = $wpdb->query(
462 $wpdb->prepare(
463 "UPDATE $wpdb->options SET autoload = %s WHERE option_name IN (" . implode( ',', array_fill( 0, count( $grouped_options[ $autoload ] ), '%s' ) ) . ')',
464 array_merge(
465 array( $autoload ),
466 $grouped_options[ $autoload ]
467 )
468 )
469 );
470 if ( ! $success ) {
471 // Set option list to an empty array to indicate no options were updated.
472 $grouped_options[ $autoload ] = array();
473 continue;
474 }
475
476 // Assume that on success all options were updated, which should be the case given only new values are sent.
477 foreach ( $grouped_options[ $autoload ] as $option ) {
478 $results[ $option ] = true;
479 }
480 }
481
482 /*
483 * If any options were changed to 'on', delete their individual caches, and delete 'alloptions' cache so that it
484 * is refreshed as needed.
485 * If no options were changed to 'on' but any options were changed to 'no', delete them from the 'alloptions'
486 * cache. This is not necessary when options were changed to 'on', since in that situation the entire cache is
487 * deleted anyway.
488 */
489 if ( $grouped_options['on'] ) {
490 wp_cache_delete_multiple( $grouped_options['on'], 'options' );
491 wp_cache_delete( 'alloptions', 'options' );
492 } elseif ( $grouped_options['off'] ) {
493 $alloptions = wp_load_alloptions( true );
494
495 foreach ( $grouped_options['off'] as $option ) {
496 if ( isset( $alloptions[ $option ] ) ) {
497 unset( $alloptions[ $option ] );
498 }
499 }
500
501 wp_cache_set( 'alloptions', $alloptions, 'options' );
502 }
503
504 return $results;
505}
506
507/**
508 * Sets the autoload value for multiple options in the database.
509 *
510 * This is a wrapper for {@see wp_set_option_autoload_values()}, which can be used to set different autoload values for
511 * each option at once.
512 *
513 * @since 6.4.0
514 * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
515 *
516 * @see wp_set_option_autoload_values()
517 *
518 * @param string[] $options List of option names. Expected to not be SQL-escaped.
519 * @param bool $autoload Autoload value to control whether to load the options when WordPress starts up.
520 * For backward compatibility 'yes' and 'no' are also accepted, though using these values is
521 * deprecated.
522 * @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
523 * was updated.
524 */
525function wp_set_options_autoload( array $options, $autoload ) {
526 return wp_set_option_autoload_values(
527 array_fill_keys( $options, $autoload )
528 );
529}
530
531/**
532 * Sets the autoload value for an option in the database.
533 *
534 * This is a wrapper for {@see wp_set_option_autoload_values()}, which can be used to set the autoload value for
535 * multiple options at once.
536 *
537 * @since 6.4.0
538 * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
539 *
540 * @see wp_set_option_autoload_values()
541 *
542 * @param string $option Name of the option. Expected to not be SQL-escaped.
543 * @param bool $autoload Autoload value to control whether to load the option when WordPress starts up.
544 * For backward compatibility 'yes' and 'no' are also accepted, though using these values is
545 * deprecated.
546 * @return bool True if the autoload value was modified, false otherwise.
547 */
548function wp_set_option_autoload( $option, $autoload ) {
549 $result = wp_set_option_autoload_values( array( $option => $autoload ) );
550 if ( isset( $result[ $option ] ) ) {
551 return $result[ $option ];
552 }
553 return false;
554}
555
556/**
557 * Protects WordPress special option from being modified.
558 *
559 * Will die if $option is in protected list. Protected options are 'alloptions'
560 * and 'notoptions' options.
561 *
562 * @since 2.2.0
563 *
564 * @param string $option Option name.
565 */
566function wp_protect_special_option( $option ) {
567 if ( 'alloptions' === $option || 'notoptions' === $option ) {
568 wp_die(
569 sprintf(
570 /* translators: %s: Option name. */
571 __( '%s is a protected WP option and may not be modified' ),
572 esc_html( $option )
573 )
574 );
575 }
576}
577
578/**
579 * Prints option value after sanitizing for forms.
580 *
581 * @since 1.5.0
582 *
583 * @param string $option Option name.
584 */
585function form_option( $option ) {
586 echo esc_attr( get_option( $option ) );
587}
588
589/**
590 * Loads and caches all autoloaded options, if available or all options.
591 *
592 * @since 2.2.0
593 * @since 5.3.1 The `$force_cache` parameter was added.
594 *
595 * @global wpdb $wpdb WordPress database abstraction object.
596 *
597 * @param bool $force_cache Optional. Whether to force an update of the local cache
598 * from the persistent cache. Default false.
599 * @return array List of all options.
600 */
601function wp_load_alloptions( $force_cache = false ) {
602 global $wpdb;
603
604 /**
605 * Filters the array of alloptions before it is populated.
606 *
607 * Returning an array from the filter will effectively short circuit
608 * wp_load_alloptions(), returning that value instead.
609 *
610 * @since 6.2.0
611 *
612 * @param array|null $alloptions An array of alloptions. Default null.
613 * @param bool $force_cache Whether to force an update of the local cache from the persistent cache. Default false.
614 */
615 $alloptions = apply_filters( 'pre_wp_load_alloptions', null, $force_cache );
616 if ( is_array( $alloptions ) ) {
617 return $alloptions;
618 }
619
620 if ( ! wp_installing() || ! is_multisite() ) {
621 $alloptions = wp_cache_get( 'alloptions', 'options', $force_cache );
622 } else {
623 $alloptions = false;
624 }
625
626 if ( ! $alloptions ) {
627 $suppress = $wpdb->suppress_errors();
628 $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload IN ( '" . implode( "', '", esc_sql( wp_autoload_values_to_autoload() ) ) . "' )" );
629
630 if ( ! $alloptions_db ) {
631 $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
632 }
633 $wpdb->suppress_errors( $suppress );
634
635 $alloptions = array();
636 foreach ( (array) $alloptions_db as $o ) {
637 $alloptions[ $o->option_name ] = $o->option_value;
638 }
639
640 if ( ! wp_installing() || ! is_multisite() ) {
641 /**
642 * Filters all options before caching them.
643 *
644 * @since 4.9.0
645 *
646 * @param array $alloptions Array with all options.
647 */
648 $alloptions = apply_filters( 'pre_cache_alloptions', $alloptions );
649
650 wp_cache_add( 'alloptions', $alloptions, 'options' );
651 }
652 }
653
654 /**
655 * Filters all options after retrieving them.
656 *
657 * @since 4.9.0
658 *
659 * @param array $alloptions Array with all options.
660 */
661 return apply_filters( 'alloptions', $alloptions );
662}
663
664/**
665 * Primes specific network options for the current network into the cache with a single database query.
666 *
667 * Only network options that do not already exist in cache will be loaded.
668 *
669 * If site is not multisite, then call wp_prime_option_caches().
670 *
671 * @since 6.6.0
672 *
673 * @see wp_prime_network_option_caches()
674 *
675 * @param string[] $options An array of option names to be loaded.
676 */
677function wp_prime_site_option_caches( array $options ) {
678 wp_prime_network_option_caches( null, $options );
679}
680
681/**
682 * Primes specific network options into the cache with a single database query.
683 *
684 * Only network options that do not already exist in cache will be loaded.
685 *
686 * If site is not multisite, then call wp_prime_option_caches().
687 *
688 * @since 6.6.0
689 *
690 * @global wpdb $wpdb WordPress database abstraction object.
691 *
692 * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
693 * @param string[] $options An array of option names to be loaded.
694 */
695function wp_prime_network_option_caches( $network_id, array $options ) {
696 global $wpdb;
697
698 if ( wp_installing() ) {
699 return;
700 }
701
702 if ( ! is_multisite() ) {
703 wp_prime_option_caches( $options );
704 return;
705 }
706
707 if ( $network_id && ! is_numeric( $network_id ) ) {
708 return;
709 }
710
711 $network_id = (int) $network_id;
712
713 // Fallback to the current network if a network ID is not specified.
714 if ( ! $network_id ) {
715 $network_id = get_current_network_id();
716 }
717
718 $cache_keys = array();
719 foreach ( $options as $option ) {
720 $cache_keys[ $option ] = "{$network_id}:{$option}";
721 }
722
723 $cache_group = 'site-options';
724 $cached_options = wp_cache_get_multiple( array_values( $cache_keys ), $cache_group );
725
726 $notoptions_key = "$network_id:notoptions";
727 $notoptions = wp_cache_get( $notoptions_key, $cache_group );
728
729 if ( ! is_array( $notoptions ) ) {
730 $notoptions = array();
731 }
732
733 // Filter options that are not in the cache.
734 $options_to_prime = array();
735 foreach ( $cache_keys as $option => $cache_key ) {
736 if (
737 ( ! isset( $cached_options[ $cache_key ] ) || false === $cached_options[ $cache_key ] )
738 && ! isset( $notoptions[ $option ] )
739 ) {
740 $options_to_prime[] = $option;
741 }
742 }
743
744 // Bail early if there are no options to be loaded.
745 if ( empty( $options_to_prime ) ) {
746 return;
747 }
748
749 $query_args = $options_to_prime;
750 $query_args[] = $network_id;
751 $results = $wpdb->get_results(
752 $wpdb->prepare(
753 sprintf(
754 "SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN (%s) AND site_id = %s",
755 implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) ),
756 '%d'
757 ),
758 $query_args
759 )
760 );
761
762 $data = array();
763 $options_found = array();
764 foreach ( $results as $result ) {
765 $key = $result->meta_key;
766 $cache_key = $cache_keys[ $key ];
767 $data[ $cache_key ] = maybe_unserialize( $result->meta_value );
768 $options_found[] = $key;
769 }
770 wp_cache_set_multiple( $data, $cache_group );
771 // If all options were found, no need to update `notoptions` cache.
772 if ( count( $options_found ) === count( $options_to_prime ) ) {
773 return;
774 }
775
776 $options_not_found = array_diff( $options_to_prime, $options_found );
777
778 // Add the options that were not found to the cache.
779 $update_notoptions = false;
780 foreach ( $options_not_found as $option_name ) {
781 if ( ! isset( $notoptions[ $option_name ] ) ) {
782 $notoptions[ $option_name ] = true;
783 $update_notoptions = true;
784 }
785 }
786
787 // Only update the cache if it was modified.
788 if ( $update_notoptions ) {
789 wp_cache_set( $notoptions_key, $notoptions, $cache_group );
790 }
791}
792
793/**
794 * Loads and primes caches of certain often requested network options if is_multisite().
795 *
796 * @since 3.0.0
797 * @since 6.3.0 Also prime caches for network options when persistent object cache is enabled.
798 * @since 6.6.0 Uses wp_prime_network_option_caches().
799 *
800 * @param int $network_id Optional. Network ID of network for which to prime network options cache. Defaults to current network.
801 */
802function wp_load_core_site_options( $network_id = null ) {
803 if ( ! is_multisite() || wp_installing() ) {
804 return;
805 }
806 $core_options = array( 'site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled', 'ms_files_rewriting', 'WPLANG' );
807
808 wp_prime_network_option_caches( $network_id, $core_options );
809}
810
811/**
812 * Updates the value of an option that was already added.
813 *
814 * You do not need to serialize values. If the value needs to be serialized,
815 * then it will be serialized before it is inserted into the database.
816 * Remember, resources cannot be serialized or added as an option.
817 *
818 * If the option does not exist, it will be created.
819
820 * This function is designed to work with or without a logged-in user. In terms of security,
821 * plugin developers should check the current user's capabilities before updating any options.
822 *
823 * @since 1.0.0
824 * @since 4.2.0 The `$autoload` parameter was added.
825 * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
826 *
827 * @global wpdb $wpdb WordPress database abstraction object.
828 *
829 * @param string $option Name of the option to update. Expected to not be SQL-escaped.
830 * @param mixed $value Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped.
831 * @param bool|null $autoload Optional. Whether to load the option when WordPress starts up.
832 * Accepts a boolean, or `null` to stick with the initial value or, if no initial value is
833 * set, to leave the decision up to default heuristics in WordPress.
834 * For existing options, `$autoload` can only be updated using `update_option()` if `$value`
835 * is also changed.
836 * For backward compatibility 'yes' and 'no' are also accepted, though using these values is
837 * deprecated.
838 * Autoloading too many options can lead to performance problems, especially if the
839 * options are not frequently used. For options which are accessed across several places
840 * in the frontend, it is recommended to autoload them, by using true.
841 * For options which are accessed only on few specific URLs, it is recommended
842 * to not autoload them, by using false.
843 * For non-existent options, the default is null, which means WordPress will determine
844 * the autoload value.
845 * @return bool True if the value was updated, false otherwise.
846 */
847function update_option( $option, $value, $autoload = null ) {
848 global $wpdb;
849
850 if ( is_scalar( $option ) ) {
851 $option = trim( $option );
852 }
853
854 if ( empty( $option ) ) {
855 return false;
856 }
857
858 /*
859 * Until a proper _deprecated_option() function can be introduced,
860 * redirect requests to deprecated keys to the new, correct ones.
861 */
862 $deprecated_keys = array(
863 'blacklist_keys' => 'disallowed_keys',
864 'comment_whitelist' => 'comment_previously_approved',
865 );
866
867 if ( isset( $deprecated_keys[ $option ] ) && ! wp_installing() ) {
868 _deprecated_argument(
869 __FUNCTION__,
870 '5.5.0',
871 sprintf(
872 /* translators: 1: Deprecated option key, 2: New option key. */
873 __( 'The "%1$s" option key has been renamed to "%2$s".' ),
874 $option,
875 $deprecated_keys[ $option ]
876 )
877 );
878 return update_option( $deprecated_keys[ $option ], $value, $autoload );
879 }
880
881 wp_protect_special_option( $option );
882
883 if ( is_object( $value ) ) {
884 $value = clone $value;
885 }
886
887 $value = sanitize_option( $option, $value );
888 $old_value = get_option( $option );
889
890 /**
891 * Filters a specific option before its value is (maybe) serialized and updated.
892 *
893 * The dynamic portion of the hook name, `$option`, refers to the option name.
894 *
895 * @since 2.6.0
896 * @since 4.4.0 The `$option` parameter was added.
897 *
898 * @param mixed $value The new, unserialized option value.
899 * @param mixed $old_value The old option value.
900 * @param string $option Option name.
901 */
902 $value = apply_filters( "pre_update_option_{$option}", $value, $old_value, $option );
903
904 /**
905 * Filters an option before its value is (maybe) serialized and updated.
906 *
907 * @since 3.9.0
908 *
909 * @param mixed $value The new, unserialized option value.
910 * @param string $option Name of the option.
911 * @param mixed $old_value The old option value.
912 */
913 $value = apply_filters( 'pre_update_option', $value, $option, $old_value );
914
915 /*
916 * If the new and old values are the same, no need to update.
917 *
918 * Unserialized values will be adequate in most cases. If the unserialized
919 * data differs, the (maybe) serialized data is checked to avoid
920 * unnecessary database calls for otherwise identical object instances.
921 *
922 * See https://core.trac.wordpress.org/ticket/38903
923 */
924 if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) {
925 return false;
926 }
927
928 /** This filter is documented in wp-includes/option.php */
929 if ( apply_filters( "default_option_{$option}", false, $option, false ) === $old_value ) {
930 return add_option( $option, $value, '', $autoload );
931 }
932
933 $serialized_value = maybe_serialize( $value );
934
935 /**
936 * Fires immediately before an option value is updated.
937 *
938 * @since 2.9.0
939 *
940 * @param string $option Name of the option to update.
941 * @param mixed $old_value The old option value.
942 * @param mixed $value The new option value.
943 */
944 do_action( 'update_option', $option, $old_value, $value );
945
946 $update_args = array(
947 'option_value' => $serialized_value,
948 );
949
950 if ( null !== $autoload ) {
951 $update_args['autoload'] = wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload );
952 } else {
953 // Retrieve the current autoload value to reevaluate it in case it was set automatically.
954 $raw_autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
955 $allow_values = array( 'auto-on', 'auto-off', 'auto' );
956 if ( in_array( $raw_autoload, $allow_values, true ) ) {
957 $autoload = wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload );
958 if ( $autoload !== $raw_autoload ) {
959 $update_args['autoload'] = $autoload;
960 }
961 }
962 }
963
964 $result = $wpdb->update( $wpdb->options, $update_args, array( 'option_name' => $option ) );
965 if ( ! $result ) {
966 return false;
967 }
968
969 $notoptions = wp_cache_get( 'notoptions', 'options' );
970
971 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
972 unset( $notoptions[ $option ] );
973 wp_cache_set( 'notoptions', $notoptions, 'options' );
974 }
975
976 if ( ! wp_installing() ) {
977 if ( ! isset( $update_args['autoload'] ) ) {
978 // Update the cached value based on where it is currently cached.
979 $alloptions = wp_load_alloptions( true );
980
981 if ( isset( $alloptions[ $option ] ) ) {
982 $alloptions[ $option ] = $serialized_value;
983 wp_cache_set( 'alloptions', $alloptions, 'options' );
984 } else {
985 wp_cache_set( $option, $serialized_value, 'options' );
986 }
987 } elseif ( in_array( $update_args['autoload'], wp_autoload_values_to_autoload(), true ) ) {
988 // Delete the individual cache, then set in alloptions cache.
989 wp_cache_delete( $option, 'options' );
990
991 $alloptions = wp_load_alloptions( true );
992
993 $alloptions[ $option ] = $serialized_value;
994 wp_cache_set( 'alloptions', $alloptions, 'options' );
995 } else {
996 // Delete the alloptions cache, then set the individual cache.
997 $alloptions = wp_load_alloptions( true );
998
999 if ( isset( $alloptions[ $option ] ) ) {
1000 unset( $alloptions[ $option ] );
1001 wp_cache_set( 'alloptions', $alloptions, 'options' );
1002 }
1003
1004 wp_cache_set( $option, $serialized_value, 'options' );
1005 }
1006 }
1007
1008 /**
1009 * Fires after the value of a specific option has been successfully updated.
1010 *
1011 * The dynamic portion of the hook name, `$option`, refers to the option name.
1012 *
1013 * @since 2.0.1
1014 * @since 4.4.0 The `$option` parameter was added.
1015 *
1016 * @param mixed $old_value The old option value.
1017 * @param mixed $value The new option value.
1018 * @param string $option Option name.
1019 */
1020 do_action( "update_option_{$option}", $old_value, $value, $option );
1021
1022 /**
1023 * Fires after the value of an option has been successfully updated.
1024 *
1025 * @since 2.9.0
1026 *
1027 * @param string $option Name of the updated option.
1028 * @param mixed $old_value The old option value.
1029 * @param mixed $value The new option value.
1030 */
1031 do_action( 'updated_option', $option, $old_value, $value );
1032
1033 return true;
1034}
1035
1036/**
1037 * Adds a new option.
1038 *
1039 * You do not need to serialize values. If the value needs to be serialized,
1040 * then it will be serialized before it is inserted into the database.
1041 * Remember, resources cannot be serialized or added as an option.
1042 *
1043 * You can create options without values and then update the values later.
1044 * Existing options will not be updated and checks are performed to ensure that you
1045 * aren't adding a protected WordPress option. Care should be taken to not name
1046 * options the same as the ones which are protected.
1047 *
1048 * @since 1.0.0
1049 * @since 6.6.0 The $autoload parameter's default value was changed to null.
1050 * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
1051 *
1052 * @global wpdb $wpdb WordPress database abstraction object.
1053 *
1054 * @param string $option Name of the option to add. Expected to not be SQL-escaped.
1055 * @param mixed $value Optional. Option value. Must be serializable if non-scalar.
1056 * Expected to not be SQL-escaped.
1057 * @param string $deprecated Optional. Description. Not used anymore.
1058 * @param bool|null $autoload Optional. Whether to load the option when WordPress starts up.
1059 * Accepts a boolean, or `null` to leave the decision up to default heuristics in
1060 * WordPress. For backward compatibility 'yes' and 'no' are also accepted, though using
1061 * these values is deprecated.
1062 * Autoloading too many options can lead to performance problems, especially if the
1063 * options are not frequently used. For options which are accessed across several places
1064 * in the frontend, it is recommended to autoload them, by using true.
1065 * For options which are accessed only on few specific URLs, it is recommended
1066 * to not autoload them, by using false.
1067 * Default is null, which means WordPress will determine the autoload value.
1068 * @return bool True if the option was added, false otherwise.
1069 */
1070function add_option( $option, $value = '', $deprecated = '', $autoload = null ) {
1071 global $wpdb;
1072
1073 if ( ! empty( $deprecated ) ) {
1074 _deprecated_argument( __FUNCTION__, '2.3.0' );
1075 }
1076
1077 if ( is_scalar( $option ) ) {
1078 $option = trim( $option );
1079 }
1080
1081 if ( empty( $option ) ) {
1082 return false;
1083 }
1084
1085 /*
1086 * Until a proper _deprecated_option() function can be introduced,
1087 * redirect requests to deprecated keys to the new, correct ones.
1088 */
1089 $deprecated_keys = array(
1090 'blacklist_keys' => 'disallowed_keys',
1091 'comment_whitelist' => 'comment_previously_approved',
1092 );
1093
1094 if ( isset( $deprecated_keys[ $option ] ) && ! wp_installing() ) {
1095 _deprecated_argument(
1096 __FUNCTION__,
1097 '5.5.0',
1098 sprintf(
1099 /* translators: 1: Deprecated option key, 2: New option key. */
1100 __( 'The "%1$s" option key has been renamed to "%2$s".' ),
1101 $option,
1102 $deprecated_keys[ $option ]
1103 )
1104 );
1105 return add_option( $deprecated_keys[ $option ], $value, $deprecated, $autoload );
1106 }
1107
1108 wp_protect_special_option( $option );
1109
1110 if ( is_object( $value ) ) {
1111 $value = clone $value;
1112 }
1113
1114 $value = sanitize_option( $option, $value );
1115
1116 /*
1117 * Make sure the option doesn't already exist.
1118 * We can check the 'notoptions' cache before we ask for a DB query.
1119 */
1120 $notoptions = wp_cache_get( 'notoptions', 'options' );
1121
1122 if ( ! is_array( $notoptions ) || ! isset( $notoptions[ $option ] ) ) {
1123 /** This filter is documented in wp-includes/option.php */
1124 if ( apply_filters( "default_option_{$option}", false, $option, false ) !== get_option( $option ) ) {
1125 return false;
1126 }
1127 }
1128
1129 $serialized_value = maybe_serialize( $value );
1130
1131 $autoload = wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload );
1132
1133 /**
1134 * Fires before an option is added.
1135 *
1136 * @since 2.9.0
1137 *
1138 * @param string $option Name of the option to add.
1139 * @param mixed $value Value of the option.
1140 */
1141 do_action( 'add_option', $option, $value );
1142
1143 $result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload ) );
1144 if ( ! $result ) {
1145 return false;
1146 }
1147
1148 if ( ! wp_installing() ) {
1149 if ( in_array( $autoload, wp_autoload_values_to_autoload(), true ) ) {
1150 $alloptions = wp_load_alloptions( true );
1151 $alloptions[ $option ] = $serialized_value;
1152 wp_cache_set( 'alloptions', $alloptions, 'options' );
1153 } else {
1154 wp_cache_set( $option, $serialized_value, 'options' );
1155 }
1156 }
1157
1158 // This option exists now.
1159 $notoptions = wp_cache_get( 'notoptions', 'options' ); // Yes, again... we need it to be fresh.
1160
1161 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
1162 unset( $notoptions[ $option ] );
1163 wp_cache_set( 'notoptions', $notoptions, 'options' );
1164 }
1165
1166 /**
1167 * Fires after a specific option has been added.
1168 *
1169 * The dynamic portion of the hook name, `$option`, refers to the option name.
1170 *
1171 * @since 2.5.0 As `add_option_{$name}`
1172 * @since 3.0.0
1173 *
1174 * @param string $option Name of the option to add.
1175 * @param mixed $value Value of the option.
1176 */
1177 do_action( "add_option_{$option}", $option, $value );
1178
1179 /**
1180 * Fires after an option has been added.
1181 *
1182 * @since 2.9.0
1183 *
1184 * @param string $option Name of the added option.
1185 * @param mixed $value Value of the option.
1186 */
1187 do_action( 'added_option', $option, $value );
1188
1189 return true;
1190}
1191
1192/**
1193 * Removes an option by name. Prevents removal of protected WordPress options.
1194 *
1195 * @since 1.2.0
1196 *
1197 * @global wpdb $wpdb WordPress database abstraction object.
1198 *
1199 * @param string $option Name of the option to delete. Expected to not be SQL-escaped.
1200 * @return bool True if the option was deleted, false otherwise.
1201 */
1202function delete_option( $option ) {
1203 global $wpdb;
1204
1205 if ( is_scalar( $option ) ) {
1206 $option = trim( $option );
1207 }
1208
1209 if ( empty( $option ) ) {
1210 return false;
1211 }
1212
1213 wp_protect_special_option( $option );
1214
1215 // Get the ID, if no ID then return.
1216 $row = $wpdb->get_row( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option ) );
1217 if ( is_null( $row ) ) {
1218 return false;
1219 }
1220
1221 /**
1222 * Fires immediately before an option is deleted.
1223 *
1224 * @since 2.9.0
1225 *
1226 * @param string $option Name of the option to delete.
1227 */
1228 do_action( 'delete_option', $option );
1229
1230 $result = $wpdb->delete( $wpdb->options, array( 'option_name' => $option ) );
1231
1232 if ( ! wp_installing() ) {
1233 if ( in_array( $row->autoload, wp_autoload_values_to_autoload(), true ) ) {
1234 $alloptions = wp_load_alloptions( true );
1235
1236 if ( is_array( $alloptions ) && isset( $alloptions[ $option ] ) ) {
1237 unset( $alloptions[ $option ] );
1238 wp_cache_set( 'alloptions', $alloptions, 'options' );
1239 }
1240 } else {
1241 wp_cache_delete( $option, 'options' );
1242 }
1243
1244 $notoptions = wp_cache_get( 'notoptions', 'options' );
1245
1246 if ( ! is_array( $notoptions ) ) {
1247 $notoptions = array();
1248 }
1249 $notoptions[ $option ] = true;
1250
1251 wp_cache_set( 'notoptions', $notoptions, 'options' );
1252 }
1253
1254 if ( $result ) {
1255
1256 /**
1257 * Fires after a specific option has been deleted.
1258 *
1259 * The dynamic portion of the hook name, `$option`, refers to the option name.
1260 *
1261 * @since 3.0.0
1262 *
1263 * @param string $option Name of the deleted option.
1264 */
1265 do_action( "delete_option_{$option}", $option );
1266
1267 /**
1268 * Fires after an option has been deleted.
1269 *
1270 * @since 2.9.0
1271 *
1272 * @param string $option Name of the deleted option.
1273 */
1274 do_action( 'deleted_option', $option );
1275
1276 return true;
1277 }
1278
1279 return false;
1280}
1281
1282/**
1283 * Determines the appropriate autoload value for an option based on input.
1284 *
1285 * This function checks the provided autoload value and returns a standardized value
1286 * ('on', 'off', 'auto-on', 'auto-off', or 'auto') based on specific conditions.
1287 *
1288 * If no explicit autoload value is provided, the function will check for certain heuristics around the given option.
1289 * It will return `auto-on` to indicate autoloading, `auto-off` to indicate not autoloading, or `auto` if no clear
1290 * decision could be made.
1291 *
1292 * @since 6.6.0
1293 * @access private
1294 *
1295 * @param string $option The name of the option.
1296 * @param mixed $value The value of the option to check its autoload value.
1297 * @param mixed $serialized_value The serialized value of the option to check its autoload value.
1298 * @param bool|null $autoload The autoload value to check.
1299 * Accepts 'on'|true to enable or 'off'|false to disable, or
1300 * 'auto-on', 'auto-off', or 'auto' for internal purposes.
1301 * Any other autoload value will be forced to either 'auto-on',
1302 * 'auto-off', or 'auto'.
1303 * 'yes' and 'no' are supported for backward compatibility.
1304 * @return string Returns the original $autoload value if explicit, or 'auto-on', 'auto-off',
1305 * or 'auto' depending on default heuristics.
1306 */
1307function wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload ) {
1308
1309 // Check if autoload is a boolean.
1310 if ( is_bool( $autoload ) ) {
1311 return $autoload ? 'on' : 'off';
1312 }
1313
1314 switch ( $autoload ) {
1315 case 'on':
1316 case 'yes':
1317 return 'on';
1318 case 'off':
1319 case 'no':
1320 return 'off';
1321 }
1322
1323 /**
1324 * Allows to determine the default autoload value for an option where no explicit value is passed.
1325 *
1326 * @since 6.6.0
1327 *
1328 * @param bool|null $autoload The default autoload value to set. Returning true will be set as 'auto-on' in the
1329 * database, false will be set as 'auto-off', and null will be set as 'auto'.
1330 * @param string $option The passed option name.
1331 * @param mixed $value The passed option value to be saved.
1332 */
1333 $autoload = apply_filters( 'wp_default_autoload_value', null, $option, $value, $serialized_value );
1334 if ( is_bool( $autoload ) ) {
1335 return $autoload ? 'auto-on' : 'auto-off';
1336 }
1337
1338 return 'auto';
1339}
1340
1341/**
1342 * Filters the default autoload value to disable autoloading if the option value is too large.
1343 *
1344 * @since 6.6.0
1345 * @access private
1346 *
1347 * @param bool|null $autoload The default autoload value to set.
1348 * @param string $option The passed option name.
1349 * @param mixed $value The passed option value to be saved.
1350 * @param mixed $serialized_value The passed option value to be saved, in serialized form.
1351 * @return bool|null Potentially modified $default.
1352 */
1353function wp_filter_default_autoload_value_via_option_size( $autoload, $option, $value, $serialized_value ) {
1354 /**
1355 * Filters the maximum size of option value in bytes.
1356 *
1357 * @since 6.6.0
1358 *
1359 * @param int $max_option_size The option-size threshold, in bytes. Default 150000.
1360 * @param string $option The name of the option.
1361 */
1362 $max_option_size = (int) apply_filters( 'wp_max_autoloaded_option_size', 150000, $option );
1363 $size = ! empty( $serialized_value ) ? strlen( $serialized_value ) : 0;
1364
1365 if ( $size > $max_option_size ) {
1366 return false;
1367 }
1368
1369 return $autoload;
1370}
1371
1372/**
1373 * Deletes a transient.
1374 *
1375 * @since 2.8.0
1376 *
1377 * @param string $transient Transient name. Expected to not be SQL-escaped.
1378 * @return bool True if the transient was deleted, false otherwise.
1379 */
1380function delete_transient( $transient ) {
1381
1382 /**
1383 * Fires immediately before a specific transient is deleted.
1384 *
1385 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1386 *
1387 * @since 3.0.0
1388 *
1389 * @param string $transient Transient name.
1390 */
1391 do_action( "delete_transient_{$transient}", $transient );
1392
1393 if ( wp_using_ext_object_cache() || wp_installing() ) {
1394 $result = wp_cache_delete( $transient, 'transient' );
1395 } else {
1396 $option_timeout = '_transient_timeout_' . $transient;
1397 $option = '_transient_' . $transient;
1398 $result = delete_option( $option );
1399
1400 if ( $result ) {
1401 delete_option( $option_timeout );
1402 }
1403 }
1404
1405 if ( $result ) {
1406
1407 /**
1408 * Fires after a transient is deleted.
1409 *
1410 * @since 3.0.0
1411 *
1412 * @param string $transient Deleted transient name.
1413 */
1414 do_action( 'deleted_transient', $transient );
1415 }
1416
1417 return $result;
1418}
1419
1420/**
1421 * Retrieves the value of a transient.
1422 *
1423 * If the transient does not exist, does not have a value, or has expired,
1424 * then the return value will be false.
1425 *
1426 * @since 2.8.0
1427 *
1428 * @param string $transient Transient name. Expected to not be SQL-escaped.
1429 * @return mixed Value of transient.
1430 */
1431function get_transient( $transient ) {
1432
1433 /**
1434 * Filters the value of an existing transient before it is retrieved.
1435 *
1436 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1437 *
1438 * Returning a value other than false from the filter will short-circuit retrieval
1439 * and return that value instead.
1440 *
1441 * @since 2.8.0
1442 * @since 4.4.0 The `$transient` parameter was added
1443 *
1444 * @param mixed $pre_transient The default value to return if the transient does not exist.
1445 * Any value other than false will short-circuit the retrieval
1446 * of the transient, and return that value.
1447 * @param string $transient Transient name.
1448 */
1449 $pre = apply_filters( "pre_transient_{$transient}", false, $transient );
1450
1451 if ( false !== $pre ) {
1452 return $pre;
1453 }
1454
1455 if ( wp_using_ext_object_cache() || wp_installing() ) {
1456 $value = wp_cache_get( $transient, 'transient' );
1457 } else {
1458 $transient_option = '_transient_' . $transient;
1459 if ( ! wp_installing() ) {
1460 // If option is not in alloptions, it is not autoloaded and thus has a timeout.
1461 $alloptions = wp_load_alloptions();
1462
1463 if ( ! isset( $alloptions[ $transient_option ] ) ) {
1464 $transient_timeout = '_transient_timeout_' . $transient;
1465 wp_prime_option_caches( array( $transient_option, $transient_timeout ) );
1466 $timeout = get_option( $transient_timeout );
1467 if ( false !== $timeout && $timeout < time() ) {
1468 delete_option( $transient_option );
1469 delete_option( $transient_timeout );
1470 $value = false;
1471 }
1472 }
1473 }
1474
1475 if ( ! isset( $value ) ) {
1476 $value = get_option( $transient_option );
1477 }
1478 }
1479
1480 /**
1481 * Filters an existing transient's value.
1482 *
1483 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1484 *
1485 * @since 2.8.0
1486 * @since 4.4.0 The `$transient` parameter was added
1487 *
1488 * @param mixed $value Value of transient.
1489 * @param string $transient Transient name.
1490 */
1491 return apply_filters( "transient_{$transient}", $value, $transient );
1492}
1493
1494/**
1495 * Sets/updates the value of a transient.
1496 *
1497 * You do not need to serialize values. If the value needs to be serialized,
1498 * then it will be serialized before it is set.
1499 *
1500 * @since 2.8.0
1501 *
1502 * @param string $transient Transient name. Expected to not be SQL-escaped.
1503 * Must be 172 characters or fewer in length.
1504 * @param mixed $value Transient value. Must be serializable if non-scalar.
1505 * Expected to not be SQL-escaped.
1506 * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
1507 * @return bool True if the value was set, false otherwise.
1508 */
1509function set_transient( $transient, $value, $expiration = 0 ) {
1510
1511 $expiration = (int) $expiration;
1512
1513 /**
1514 * Filters a specific transient before its value is set.
1515 *
1516 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1517 *
1518 * @since 3.0.0
1519 * @since 4.2.0 The `$expiration` parameter was added.
1520 * @since 4.4.0 The `$transient` parameter was added.
1521 *
1522 * @param mixed $value New value of transient.
1523 * @param int $expiration Time until expiration in seconds.
1524 * @param string $transient Transient name.
1525 */
1526 $value = apply_filters( "pre_set_transient_{$transient}", $value, $expiration, $transient );
1527
1528 /**
1529 * Filters the expiration for a transient before its value is set.
1530 *
1531 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1532 *
1533 * @since 4.4.0
1534 *
1535 * @param int $expiration Time until expiration in seconds. Use 0 for no expiration.
1536 * @param mixed $value New value of transient.
1537 * @param string $transient Transient name.
1538 */
1539 $expiration = apply_filters( "expiration_of_transient_{$transient}", $expiration, $value, $transient );
1540
1541 if ( wp_using_ext_object_cache() || wp_installing() ) {
1542 $result = wp_cache_set( $transient, $value, 'transient', $expiration );
1543 } else {
1544 $transient_timeout = '_transient_timeout_' . $transient;
1545 $transient_option = '_transient_' . $transient;
1546 wp_prime_option_caches( array( $transient_option, $transient_timeout ) );
1547
1548 if ( false === get_option( $transient_option ) ) {
1549 $autoload = true;
1550 if ( $expiration ) {
1551 $autoload = false;
1552 add_option( $transient_timeout, time() + $expiration, '', false );
1553 }
1554 $result = add_option( $transient_option, $value, '', $autoload );
1555 } else {
1556 /*
1557 * If expiration is requested, but the transient has no timeout option,
1558 * delete, then re-create transient rather than update.
1559 */
1560 $update = true;
1561
1562 if ( $expiration ) {
1563 if ( false === get_option( $transient_timeout ) ) {
1564 delete_option( $transient_option );
1565 add_option( $transient_timeout, time() + $expiration, '', false );
1566 $result = add_option( $transient_option, $value, '', false );
1567 $update = false;
1568 } else {
1569 update_option( $transient_timeout, time() + $expiration );
1570 }
1571 }
1572
1573 if ( $update ) {
1574 $result = update_option( $transient_option, $value );
1575 }
1576 }
1577 }
1578
1579 if ( $result ) {
1580
1581 /**
1582 * Fires after the value for a specific transient has been set.
1583 *
1584 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
1585 *
1586 * @since 3.0.0
1587 * @since 3.6.0 The `$value` and `$expiration` parameters were added.
1588 * @since 4.4.0 The `$transient` parameter was added.
1589 *
1590 * @param mixed $value Transient value.
1591 * @param int $expiration Time until expiration in seconds.
1592 * @param string $transient The name of the transient.
1593 */
1594 do_action( "set_transient_{$transient}", $value, $expiration, $transient );
1595
1596 /**
1597 * Fires after the value for a transient has been set.
1598 *
1599 * @since 6.8.0
1600 *
1601 * @param string $transient The name of the transient.
1602 * @param mixed $value Transient value.
1603 * @param int $expiration Time until expiration in seconds.
1604 */
1605 do_action( 'set_transient', $transient, $value, $expiration );
1606
1607 /**
1608 * Fires after the transient is set.
1609 *
1610 * @since 3.0.0
1611 * @since 3.6.0 The `$value` and `$expiration` parameters were added.
1612 * @deprecated 6.8.0 Use {@see 'set_transient'} instead.
1613 *
1614 * @param string $transient The name of the transient.
1615 * @param mixed $value Transient value.
1616 * @param int $expiration Time until expiration in seconds.
1617 */
1618 do_action_deprecated( 'setted_transient', array( $transient, $value, $expiration ), '6.8.0', 'set_transient' );
1619 }
1620
1621 return $result;
1622}
1623
1624/**
1625 * Deletes all expired transients.
1626 *
1627 * Note that this function won't do anything if an external object cache is in use.
1628 *
1629 * The multi-table delete syntax is used to delete the transient record
1630 * from table a, and the corresponding transient_timeout record from table b.
1631 *
1632 * @since 4.9.0
1633 *
1634 * @global wpdb $wpdb WordPress database abstraction object.
1635 *
1636 * @param bool $force_db Optional. Force cleanup to run against the database even when an external object cache is used.
1637 */
1638function delete_expired_transients( $force_db = false ) {
1639 global $wpdb;
1640
1641 if ( ! $force_db && wp_using_ext_object_cache() ) {
1642 return;
1643 }
1644
1645 $wpdb->query(
1646 $wpdb->prepare(
1647 "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
1648 WHERE a.option_name LIKE %s
1649 AND a.option_name NOT LIKE %s
1650 AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
1651 AND b.option_value < %d",
1652 $wpdb->esc_like( '_transient_' ) . '%',
1653 $wpdb->esc_like( '_transient_timeout_' ) . '%',
1654 time()
1655 )
1656 );
1657
1658 if ( ! is_multisite() ) {
1659 // Single site stores site transients in the options table.
1660 $wpdb->query(
1661 $wpdb->prepare(
1662 "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
1663 WHERE a.option_name LIKE %s
1664 AND a.option_name NOT LIKE %s
1665 AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
1666 AND b.option_value < %d",
1667 $wpdb->esc_like( '_site_transient_' ) . '%',
1668 $wpdb->esc_like( '_site_transient_timeout_' ) . '%',
1669 time()
1670 )
1671 );
1672 } elseif ( is_main_site() && is_main_network() ) {
1673 // Multisite stores site transients in the sitemeta table.
1674 $wpdb->query(
1675 $wpdb->prepare(
1676 "DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b
1677 WHERE a.meta_key LIKE %s
1678 AND a.meta_key NOT LIKE %s
1679 AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
1680 AND b.meta_value < %d",
1681 $wpdb->esc_like( '_site_transient_' ) . '%',
1682 $wpdb->esc_like( '_site_transient_timeout_' ) . '%',
1683 time()
1684 )
1685 );
1686 }
1687}
1688
1689/**
1690 * Saves and restores user interface settings stored in a cookie.
1691 *
1692 * Checks if the current user-settings cookie is updated and stores it. When no
1693 * cookie exists (different browser used), adds the last saved cookie restoring
1694 * the settings.
1695 *
1696 * @since 2.7.0
1697 */
1698function wp_user_settings() {
1699
1700 if ( ! is_admin() || wp_doing_ajax() ) {
1701 return;
1702 }
1703
1704 $user_id = get_current_user_id();
1705 if ( ! $user_id ) {
1706 return;
1707 }
1708
1709 if ( ! is_user_member_of_blog() ) {
1710 return;
1711 }
1712
1713 $settings = (string) get_user_option( 'user-settings', $user_id );
1714
1715 if ( isset( $_COOKIE[ 'wp-settings-' . $user_id ] ) ) {
1716 $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE[ 'wp-settings-' . $user_id ] );
1717
1718 // No change or both empty.
1719 if ( $cookie === $settings ) {
1720 return;
1721 }
1722
1723 $last_saved = (int) get_user_option( 'user-settings-time', $user_id );
1724 $current = 0;
1725
1726 if ( isset( $_COOKIE[ 'wp-settings-time-' . $user_id ] ) ) {
1727 $current = (int) preg_replace( '/[^0-9]/', '', $_COOKIE[ 'wp-settings-time-' . $user_id ] );
1728 }
1729
1730 // The cookie is newer than the saved value. Update the user_option and leave the cookie as-is.
1731 if ( $current > $last_saved ) {
1732 update_user_option( $user_id, 'user-settings', $cookie, false );
1733 update_user_option( $user_id, 'user-settings-time', time() - 5, false );
1734 return;
1735 }
1736 }
1737
1738 // The cookie is not set in the current browser or the saved value is newer.
1739 $secure = ( 'https' === parse_url( admin_url(), PHP_URL_SCHEME ) );
1740 setcookie( 'wp-settings-' . $user_id, $settings, time() + YEAR_IN_SECONDS, SITECOOKIEPATH, '', $secure );
1741 setcookie( 'wp-settings-time-' . $user_id, time(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH, '', $secure );
1742 $_COOKIE[ 'wp-settings-' . $user_id ] = $settings;
1743}
1744
1745/**
1746 * Retrieves user interface setting value based on setting name.
1747 *
1748 * @since 2.7.0
1749 *
1750 * @param string $name The name of the setting.
1751 * @param string|false $default_value Optional. Default value to return when $name is not set. Default false.
1752 * @return mixed The last saved user setting or the default value/false if it doesn't exist.
1753 */
1754function get_user_setting( $name, $default_value = false ) {
1755 $all_user_settings = get_all_user_settings();
1756
1757 return isset( $all_user_settings[ $name ] ) ? $all_user_settings[ $name ] : $default_value;
1758}
1759
1760/**
1761 * Adds or updates user interface setting.
1762 *
1763 * Both `$name` and `$value` can contain only ASCII letters, numbers, hyphens, and underscores.
1764 *
1765 * This function has to be used before any output has started as it calls `setcookie()`.
1766 *
1767 * @since 2.8.0
1768 *
1769 * @param string $name The name of the setting.
1770 * @param string $value The value for the setting.
1771 * @return bool|null True if set successfully, false otherwise.
1772 * Null if the current user is not a member of the site.
1773 */
1774function set_user_setting( $name, $value ) {
1775 if ( headers_sent() ) {
1776 return false;
1777 }
1778
1779 $all_user_settings = get_all_user_settings();
1780 $all_user_settings[ $name ] = $value;
1781
1782 return wp_set_all_user_settings( $all_user_settings );
1783}
1784
1785/**
1786 * Deletes user interface settings.
1787 *
1788 * Deleting settings would reset them to the defaults.
1789 *
1790 * This function has to be used before any output has started as it calls `setcookie()`.
1791 *
1792 * @since 2.7.0
1793 *
1794 * @param string $names The name or array of names of the setting to be deleted.
1795 * @return bool|null True if deleted successfully, false otherwise.
1796 * Null if the current user is not a member of the site.
1797 */
1798function delete_user_setting( $names ) {
1799 if ( headers_sent() ) {
1800 return false;
1801 }
1802
1803 $all_user_settings = get_all_user_settings();
1804 $names = (array) $names;
1805 $deleted = false;
1806
1807 foreach ( $names as $name ) {
1808 if ( isset( $all_user_settings[ $name ] ) ) {
1809 unset( $all_user_settings[ $name ] );
1810 $deleted = true;
1811 }
1812 }
1813
1814 if ( $deleted ) {
1815 return wp_set_all_user_settings( $all_user_settings );
1816 }
1817
1818 return false;
1819}
1820
1821/**
1822 * Retrieves all user interface settings.
1823 *
1824 * @since 2.7.0
1825 *
1826 * @global array $_updated_user_settings
1827 *
1828 * @return array The last saved user settings or empty array.
1829 */
1830function get_all_user_settings() {
1831 global $_updated_user_settings;
1832
1833 $user_id = get_current_user_id();
1834 if ( ! $user_id ) {
1835 return array();
1836 }
1837
1838 if ( isset( $_updated_user_settings ) && is_array( $_updated_user_settings ) ) {
1839 return $_updated_user_settings;
1840 }
1841
1842 $user_settings = array();
1843
1844 if ( isset( $_COOKIE[ 'wp-settings-' . $user_id ] ) ) {
1845 $cookie = preg_replace( '/[^A-Za-z0-9=&_-]/', '', $_COOKIE[ 'wp-settings-' . $user_id ] );
1846
1847 if ( strpos( $cookie, '=' ) ) { // '=' cannot be 1st char.
1848 parse_str( $cookie, $user_settings );
1849 }
1850 } else {
1851 $option = get_user_option( 'user-settings', $user_id );
1852
1853 if ( $option && is_string( $option ) ) {
1854 parse_str( $option, $user_settings );
1855 }
1856 }
1857
1858 $_updated_user_settings = $user_settings;
1859 return $user_settings;
1860}
1861
1862/**
1863 * Private. Sets all user interface settings.
1864 *
1865 * @since 2.8.0
1866 * @access private
1867 *
1868 * @global array $_updated_user_settings
1869 *
1870 * @param array $user_settings User settings.
1871 * @return bool|null True if set successfully, false if the current user could not be found.
1872 * Null if the current user is not a member of the site.
1873 */
1874function wp_set_all_user_settings( $user_settings ) {
1875 global $_updated_user_settings;
1876
1877 $user_id = get_current_user_id();
1878 if ( ! $user_id ) {
1879 return false;
1880 }
1881
1882 if ( ! is_user_member_of_blog() ) {
1883 return null;
1884 }
1885
1886 $settings = '';
1887 foreach ( $user_settings as $name => $value ) {
1888 $_name = preg_replace( '/[^A-Za-z0-9_-]+/', '', $name );
1889 $_value = preg_replace( '/[^A-Za-z0-9_-]+/', '', $value );
1890
1891 if ( ! empty( $_name ) ) {
1892 $settings .= $_name . '=' . $_value . '&';
1893 }
1894 }
1895
1896 $settings = rtrim( $settings, '&' );
1897 parse_str( $settings, $_updated_user_settings );
1898
1899 update_user_option( $user_id, 'user-settings', $settings, false );
1900 update_user_option( $user_id, 'user-settings-time', time(), false );
1901
1902 return true;
1903}
1904
1905/**
1906 * Deletes the user settings of the current user.
1907 *
1908 * @since 2.7.0
1909 */
1910function delete_all_user_settings() {
1911 $user_id = get_current_user_id();
1912 if ( ! $user_id ) {
1913 return;
1914 }
1915
1916 update_user_option( $user_id, 'user-settings', '', false );
1917 setcookie( 'wp-settings-' . $user_id, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH );
1918}
1919
1920/**
1921 * Retrieve an option value for the current network based on name of option.
1922 *
1923 * @since 2.8.0
1924 * @since 4.4.0 The `$use_cache` parameter was deprecated.
1925 * @since 4.4.0 Modified into wrapper for get_network_option()
1926 *
1927 * @see get_network_option()
1928 *
1929 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped.
1930 * @param mixed $default_value Optional. Value to return if the option doesn't exist. Default false.
1931 * @param bool $deprecated Whether to use cache. Multisite only. Always set to true.
1932 * @return mixed Value set for the option.
1933 */
1934function get_site_option( $option, $default_value = false, $deprecated = true ) {
1935 return get_network_option( null, $option, $default_value );
1936}
1937
1938/**
1939 * Adds a new option for the current network.
1940 *
1941 * Existing options will not be updated. Note that prior to 3.3 this wasn't the case.
1942 *
1943 * @since 2.8.0
1944 * @since 4.4.0 Modified into wrapper for add_network_option()
1945 *
1946 * @see add_network_option()
1947 *
1948 * @param string $option Name of the option to add. Expected to not be SQL-escaped.
1949 * @param mixed $value Option value, can be anything. Expected to not be SQL-escaped.
1950 * @return bool True if the option was added, false otherwise.
1951 */
1952function add_site_option( $option, $value ) {
1953 return add_network_option( null, $option, $value );
1954}
1955
1956/**
1957 * Removes an option by name for the current network.
1958 *
1959 * @since 2.8.0
1960 * @since 4.4.0 Modified into wrapper for delete_network_option()
1961 *
1962 * @see delete_network_option()
1963 *
1964 * @param string $option Name of the option to delete. Expected to not be SQL-escaped.
1965 * @return bool True if the option was deleted, false otherwise.
1966 */
1967function delete_site_option( $option ) {
1968 return delete_network_option( null, $option );
1969}
1970
1971/**
1972 * Updates the value of an option that was already added for the current network.
1973 *
1974 * @since 2.8.0
1975 * @since 4.4.0 Modified into wrapper for update_network_option()
1976 *
1977 * @see update_network_option()
1978 *
1979 * @param string $option Name of the option. Expected to not be SQL-escaped.
1980 * @param mixed $value Option value. Expected to not be SQL-escaped.
1981 * @return bool True if the value was updated, false otherwise.
1982 */
1983function update_site_option( $option, $value ) {
1984 return update_network_option( null, $option, $value );
1985}
1986
1987/**
1988 * Retrieves a network's option value based on the option name.
1989 *
1990 * @since 4.4.0
1991 *
1992 * @see get_option()
1993 *
1994 * @global wpdb $wpdb WordPress database abstraction object.
1995 *
1996 * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
1997 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped.
1998 * @param mixed $default_value Optional. Value to return if the option doesn't exist. Default false.
1999 * @return mixed Value set for the option.
2000 */
2001function get_network_option( $network_id, $option, $default_value = false ) {
2002 global $wpdb;
2003
2004 if ( $network_id && ! is_numeric( $network_id ) ) {
2005 return false;
2006 }
2007
2008 $network_id = (int) $network_id;
2009
2010 // Fallback to the current network if a network ID is not specified.
2011 if ( ! $network_id ) {
2012 $network_id = get_current_network_id();
2013 }
2014
2015 /**
2016 * Filters the value of an existing network option before it is retrieved.
2017 *
2018 * The dynamic portion of the hook name, `$option`, refers to the option name.
2019 *
2020 * Returning a value other than false from the filter will short-circuit retrieval
2021 * and return that value instead.
2022 *
2023 * @since 2.9.0 As 'pre_site_option_' . $key
2024 * @since 3.0.0
2025 * @since 4.4.0 The `$option` parameter was added.
2026 * @since 4.7.0 The `$network_id` parameter was added.
2027 * @since 4.9.0 The `$default_value` parameter was added.
2028 *
2029 * @param mixed $pre_site_option The value to return instead of the option value. This differs from
2030 * `$default_value`, which is used as the fallback value in the event
2031 * the option doesn't exist elsewhere in get_network_option().
2032 * Default false (to skip past the short-circuit).
2033 * @param string $option Option name.
2034 * @param int $network_id ID of the network.
2035 * @param mixed $default_value The fallback value to return if the option does not exist.
2036 * Default false.
2037 */
2038 $pre = apply_filters( "pre_site_option_{$option}", false, $option, $network_id, $default_value );
2039
2040 /**
2041 * Filters the value of any existing network option before it is retrieved.
2042 *
2043 * Returning a value other than false from the filter will short-circuit retrieval
2044 * and return that value instead.
2045 *
2046 * @since 6.9.0
2047 *
2048 * @param mixed $pre_option The value to return instead of the network option value. This differs
2049 * from `$default_value`, which is used as the fallback value in the event
2050 * the option doesn't exist elsewhere in get_network_option().
2051 * Default false (to skip past the short-circuit).
2052 * @param string $option Name of the option.
2053 * @param int $network_id ID of the network.
2054 * @param mixed $default_value The fallback value to return if the option does not exist.
2055 * Default false.
2056 */
2057 $pre = apply_filters( 'pre_site_option', $pre, $option, $network_id, $default_value );
2058
2059 if ( false !== $pre ) {
2060 return $pre;
2061 }
2062
2063 // Prevent non-existent options from triggering multiple queries.
2064 $notoptions_key = "$network_id:notoptions";
2065 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
2066
2067 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
2068
2069 /**
2070 * Filters the value of a specific default network option.
2071 *
2072 * The dynamic portion of the hook name, `$option`, refers to the option name.
2073 *
2074 * @since 3.4.0
2075 * @since 4.4.0 The `$option` parameter was added.
2076 * @since 4.7.0 The `$network_id` parameter was added.
2077 *
2078 * @param mixed $default_value The value to return if the site option does not exist
2079 * in the database.
2080 * @param string $option Option name.
2081 * @param int $network_id ID of the network.
2082 */
2083 return apply_filters( "default_site_option_{$option}", $default_value, $option, $network_id );
2084 }
2085
2086 if ( ! is_multisite() ) {
2087 /** This filter is documented in wp-includes/option.php */
2088 $default_value = apply_filters( 'default_site_option_' . $option, $default_value, $option, $network_id );
2089 $value = get_option( $option, $default_value );
2090 } else {
2091 $cache_key = "$network_id:$option";
2092 $value = wp_cache_get( $cache_key, 'site-options' );
2093
2094 if ( ! isset( $value ) || false === $value ) {
2095 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
2096
2097 // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values.
2098 if ( is_object( $row ) ) {
2099 $value = $row->meta_value;
2100 $value = maybe_unserialize( $value );
2101 wp_cache_set( $cache_key, $value, 'site-options' );
2102 } else {
2103 if ( ! is_array( $notoptions ) ) {
2104 $notoptions = array();
2105 }
2106
2107 $notoptions[ $option ] = true;
2108 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
2109
2110 /** This filter is documented in wp-includes/option.php */
2111 $value = apply_filters( 'default_site_option_' . $option, $default_value, $option, $network_id );
2112 }
2113 }
2114 }
2115
2116 if ( ! is_array( $notoptions ) ) {
2117 $notoptions = array();
2118 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
2119 }
2120
2121 /**
2122 * Filters the value of an existing network option.
2123 *
2124 * The dynamic portion of the hook name, `$option`, refers to the option name.
2125 *
2126 * @since 2.9.0 As 'site_option_' . $key
2127 * @since 3.0.0
2128 * @since 4.4.0 The `$option` parameter was added.
2129 * @since 4.7.0 The `$network_id` parameter was added.
2130 *
2131 * @param mixed $value Value of network option.
2132 * @param string $option Option name.
2133 * @param int $network_id ID of the network.
2134 */
2135 return apply_filters( "site_option_{$option}", $value, $option, $network_id );
2136}
2137
2138/**
2139 * Adds a new network option.
2140 *
2141 * Existing options will not be updated.
2142 *
2143 * @since 4.4.0
2144 *
2145 * @see add_option()
2146 *
2147 * @global wpdb $wpdb WordPress database abstraction object.
2148 *
2149 * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
2150 * @param string $option Name of the option to add. Expected to not be SQL-escaped.
2151 * @param mixed $value Option value, can be anything. Expected to not be SQL-escaped.
2152 * @return bool True if the option was added, false otherwise.
2153 */
2154function add_network_option( $network_id, $option, $value ) {
2155 global $wpdb;
2156
2157 if ( $network_id && ! is_numeric( $network_id ) ) {
2158 return false;
2159 }
2160
2161 $network_id = (int) $network_id;
2162
2163 // Fallback to the current network if a network ID is not specified.
2164 if ( ! $network_id ) {
2165 $network_id = get_current_network_id();
2166 }
2167
2168 wp_protect_special_option( $option );
2169
2170 /**
2171 * Filters the value of a specific network option before it is added.
2172 *
2173 * The dynamic portion of the hook name, `$option`, refers to the option name.
2174 *
2175 * @since 2.9.0 As 'pre_add_site_option_' . $key
2176 * @since 3.0.0
2177 * @since 4.4.0 The `$option` parameter was added.
2178 * @since 4.7.0 The `$network_id` parameter was added.
2179 *
2180 * @param mixed $value Value of network option.
2181 * @param string $option Option name.
2182 * @param int $network_id ID of the network.
2183 */
2184 $value = apply_filters( "pre_add_site_option_{$option}", $value, $option, $network_id );
2185
2186 $notoptions_key = "$network_id:notoptions";
2187
2188 if ( ! is_multisite() ) {
2189 $result = add_option( $option, $value, '', false );
2190 } else {
2191 $cache_key = "$network_id:$option";
2192
2193 /*
2194 * Make sure the option doesn't already exist.
2195 * We can check the 'notoptions' cache before we ask for a DB query.
2196 */
2197 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
2198
2199 if ( ! is_array( $notoptions ) || ! isset( $notoptions[ $option ] ) ) {
2200 if ( false !== get_network_option( $network_id, $option, false ) ) {
2201 return false;
2202 }
2203 }
2204
2205 $value = sanitize_option( $option, $value );
2206
2207 $serialized_value = maybe_serialize( $value );
2208 $result = $wpdb->insert(
2209 $wpdb->sitemeta,
2210 array(
2211 'site_id' => $network_id,
2212 'meta_key' => $option,
2213 'meta_value' => $serialized_value,
2214 )
2215 );
2216
2217 if ( ! $result ) {
2218 return false;
2219 }
2220
2221 wp_cache_set( $cache_key, $value, 'site-options' );
2222
2223 // This option exists now.
2224 $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); // Yes, again... we need it to be fresh.
2225
2226 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
2227 unset( $notoptions[ $option ] );
2228 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
2229 }
2230 }
2231
2232 if ( $result ) {
2233
2234 /**
2235 * Fires after a specific network option has been successfully added.
2236 *
2237 * The dynamic portion of the hook name, `$option`, refers to the option name.
2238 *
2239 * @since 2.9.0 As "add_site_option_{$key}"
2240 * @since 3.0.0
2241 * @since 4.7.0 The `$network_id` parameter was added.
2242 *
2243 * @param string $option Name of the network option.
2244 * @param mixed $value Value of the network option.
2245 * @param int $network_id ID of the network.
2246 */
2247 do_action( "add_site_option_{$option}", $option, $value, $network_id );
2248
2249 /**
2250 * Fires after a network option has been successfully added.
2251 *
2252 * @since 3.0.0
2253 * @since 4.7.0 The `$network_id` parameter was added.
2254 *
2255 * @param string $option Name of the network option.
2256 * @param mixed $value Value of the network option.
2257 * @param int $network_id ID of the network.
2258 */
2259 do_action( 'add_site_option', $option, $value, $network_id );
2260
2261 return true;
2262 }
2263
2264 return false;
2265}
2266
2267/**
2268 * Removes a network option by name.
2269 *
2270 * @since 4.4.0
2271 *
2272 * @see delete_option()
2273 *
2274 * @global wpdb $wpdb WordPress database abstraction object.
2275 *
2276 * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
2277 * @param string $option Name of the option to delete. Expected to not be SQL-escaped.
2278 * @return bool True if the option was deleted, false otherwise.
2279 */
2280function delete_network_option( $network_id, $option ) {
2281 global $wpdb;
2282
2283 if ( $network_id && ! is_numeric( $network_id ) ) {
2284 return false;
2285 }
2286
2287 $network_id = (int) $network_id;
2288
2289 // Fallback to the current network if a network ID is not specified.
2290 if ( ! $network_id ) {
2291 $network_id = get_current_network_id();
2292 }
2293
2294 /**
2295 * Fires immediately before a specific network option is deleted.
2296 *
2297 * The dynamic portion of the hook name, `$option`, refers to the option name.
2298 *
2299 * @since 3.0.0
2300 * @since 4.4.0 The `$option` parameter was added.
2301 * @since 4.7.0 The `$network_id` parameter was added.
2302 *
2303 * @param string $option Option name.
2304 * @param int $network_id ID of the network.
2305 */
2306 do_action( "pre_delete_site_option_{$option}", $option, $network_id );
2307
2308 if ( ! is_multisite() ) {
2309 $result = delete_option( $option );
2310 } else {
2311 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->sitemeta} WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
2312 if ( is_null( $row ) || ! $row->meta_id ) {
2313 return false;
2314 }
2315 $cache_key = "$network_id:$option";
2316 wp_cache_delete( $cache_key, 'site-options' );
2317
2318 $result = $wpdb->delete(
2319 $wpdb->sitemeta,
2320 array(
2321 'meta_key' => $option,
2322 'site_id' => $network_id,
2323 )
2324 );
2325
2326 if ( $result ) {
2327 $notoptions_key = "$network_id:notoptions";
2328 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
2329
2330 if ( ! is_array( $notoptions ) ) {
2331 $notoptions = array();
2332 }
2333 $notoptions[ $option ] = true;
2334 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
2335 }
2336 }
2337
2338 if ( $result ) {
2339
2340 /**
2341 * Fires after a specific network option has been deleted.
2342 *
2343 * The dynamic portion of the hook name, `$option`, refers to the option name.
2344 *
2345 * @since 2.9.0 As "delete_site_option_{$key}"
2346 * @since 3.0.0
2347 * @since 4.7.0 The `$network_id` parameter was added.
2348 *
2349 * @param string $option Name of the network option.
2350 * @param int $network_id ID of the network.
2351 */
2352 do_action( "delete_site_option_{$option}", $option, $network_id );
2353
2354 /**
2355 * Fires after a network option has been deleted.
2356 *
2357 * @since 3.0.0
2358 * @since 4.7.0 The `$network_id` parameter was added.
2359 *
2360 * @param string $option Name of the network option.
2361 * @param int $network_id ID of the network.
2362 */
2363 do_action( 'delete_site_option', $option, $network_id );
2364
2365 return true;
2366 }
2367
2368 return false;
2369}
2370
2371/**
2372 * Updates the value of a network option that was already added.
2373 *
2374 * @since 4.4.0
2375 *
2376 * @see update_option()
2377 *
2378 * @global wpdb $wpdb WordPress database abstraction object.
2379 *
2380 * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
2381 * @param string $option Name of the option. Expected to not be SQL-escaped.
2382 * @param mixed $value Option value. Expected to not be SQL-escaped.
2383 * @return bool True if the value was updated, false otherwise.
2384 */
2385function update_network_option( $network_id, $option, $value ) {
2386 global $wpdb;
2387
2388 if ( $network_id && ! is_numeric( $network_id ) ) {
2389 return false;
2390 }
2391
2392 $network_id = (int) $network_id;
2393
2394 // Fallback to the current network if a network ID is not specified.
2395 if ( ! $network_id ) {
2396 $network_id = get_current_network_id();
2397 }
2398
2399 wp_protect_special_option( $option );
2400
2401 $old_value = get_network_option( $network_id, $option );
2402
2403 /**
2404 * Filters a specific network option before its value is updated.
2405 *
2406 * The dynamic portion of the hook name, `$option`, refers to the option name.
2407 *
2408 * @since 2.9.0 As 'pre_update_site_option_' . $key
2409 * @since 3.0.0
2410 * @since 4.4.0 The `$option` parameter was added.
2411 * @since 4.7.0 The `$network_id` parameter was added.
2412 *
2413 * @param mixed $value New value of the network option.
2414 * @param mixed $old_value Old value of the network option.
2415 * @param string $option Option name.
2416 * @param int $network_id ID of the network.
2417 */
2418 $value = apply_filters( "pre_update_site_option_{$option}", $value, $old_value, $option, $network_id );
2419
2420 /*
2421 * If the new and old values are the same, no need to update.
2422 *
2423 * Unserialized values will be adequate in most cases. If the unserialized
2424 * data differs, the (maybe) serialized data is checked to avoid
2425 * unnecessary database calls for otherwise identical object instances.
2426 *
2427 * See https://core.trac.wordpress.org/ticket/44956
2428 */
2429 if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) {
2430 return false;
2431 }
2432
2433 if ( false === $old_value ) {
2434 return add_network_option( $network_id, $option, $value );
2435 }
2436
2437 $notoptions_key = "$network_id:notoptions";
2438 $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
2439
2440 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
2441 unset( $notoptions[ $option ] );
2442 wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
2443 }
2444
2445 if ( ! is_multisite() ) {
2446 $result = update_option( $option, $value, false );
2447 } else {
2448 $value = sanitize_option( $option, $value );
2449
2450 $serialized_value = maybe_serialize( $value );
2451 $result = $wpdb->update(
2452 $wpdb->sitemeta,
2453 array( 'meta_value' => $serialized_value ),
2454 array(
2455 'site_id' => $network_id,
2456 'meta_key' => $option,
2457 )
2458 );
2459
2460 if ( $result ) {
2461 $cache_key = "$network_id:$option";
2462 wp_cache_set( $cache_key, $value, 'site-options' );
2463 }
2464 }
2465
2466 if ( $result ) {
2467
2468 /**
2469 * Fires after the value of a specific network option has been successfully updated.
2470 *
2471 * The dynamic portion of the hook name, `$option`, refers to the option name.
2472 *
2473 * @since 2.9.0 As "update_site_option_{$key}"
2474 * @since 3.0.0
2475 * @since 4.7.0 The `$network_id` parameter was added.
2476 *
2477 * @param string $option Name of the network option.
2478 * @param mixed $value Current value of the network option.
2479 * @param mixed $old_value Old value of the network option.
2480 * @param int $network_id ID of the network.
2481 */
2482 do_action( "update_site_option_{$option}", $option, $value, $old_value, $network_id );
2483
2484 /**
2485 * Fires after the value of a network option has been successfully updated.
2486 *
2487 * @since 3.0.0
2488 * @since 4.7.0 The `$network_id` parameter was added.
2489 *
2490 * @param string $option Name of the network option.
2491 * @param mixed $value Current value of the network option.
2492 * @param mixed $old_value Old value of the network option.
2493 * @param int $network_id ID of the network.
2494 */
2495 do_action( 'update_site_option', $option, $value, $old_value, $network_id );
2496
2497 return true;
2498 }
2499
2500 return false;
2501}
2502
2503/**
2504 * Deletes a site transient.
2505 *
2506 * @since 2.9.0
2507 *
2508 * @param string $transient Transient name. Expected to not be SQL-escaped.
2509 * @return bool True if the transient was deleted, false otherwise.
2510 */
2511function delete_site_transient( $transient ) {
2512
2513 /**
2514 * Fires immediately before a specific site transient is deleted.
2515 *
2516 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2517 *
2518 * @since 3.0.0
2519 *
2520 * @param string $transient Transient name.
2521 */
2522 do_action( "delete_site_transient_{$transient}", $transient );
2523
2524 if ( wp_using_ext_object_cache() || wp_installing() ) {
2525 $result = wp_cache_delete( $transient, 'site-transient' );
2526 } else {
2527 $option_timeout = '_site_transient_timeout_' . $transient;
2528 $option = '_site_transient_' . $transient;
2529 $result = delete_site_option( $option );
2530
2531 if ( $result ) {
2532 delete_site_option( $option_timeout );
2533 }
2534 }
2535
2536 if ( $result ) {
2537
2538 /**
2539 * Fires after a transient is deleted.
2540 *
2541 * @since 3.0.0
2542 *
2543 * @param string $transient Deleted transient name.
2544 */
2545 do_action( 'deleted_site_transient', $transient );
2546 }
2547
2548 return $result;
2549}
2550
2551/**
2552 * Retrieves the value of a site transient.
2553 *
2554 * If the transient does not exist, does not have a value, or has expired,
2555 * then the return value will be false.
2556 *
2557 * @since 2.9.0
2558 *
2559 * @see get_transient()
2560 *
2561 * @param string $transient Transient name. Expected to not be SQL-escaped.
2562 * @return mixed Value of transient.
2563 */
2564function get_site_transient( $transient ) {
2565
2566 /**
2567 * Filters the value of an existing site transient before it is retrieved.
2568 *
2569 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2570 *
2571 * Returning a value other than boolean false will short-circuit retrieval and
2572 * return that value instead.
2573 *
2574 * @since 2.9.0
2575 * @since 4.4.0 The `$transient` parameter was added.
2576 *
2577 * @param mixed $pre_site_transient The default value to return if the site transient does not exist.
2578 * Any value other than false will short-circuit the retrieval
2579 * of the transient, and return that value.
2580 * @param string $transient Transient name.
2581 */
2582 $pre = apply_filters( "pre_site_transient_{$transient}", false, $transient );
2583
2584 if ( false !== $pre ) {
2585 return $pre;
2586 }
2587
2588 if ( wp_using_ext_object_cache() || wp_installing() ) {
2589 $value = wp_cache_get( $transient, 'site-transient' );
2590 } else {
2591 // Core transients that do not have a timeout. Listed here so querying timeouts can be avoided.
2592 $no_timeout = array( 'update_core', 'update_plugins', 'update_themes' );
2593 $transient_option = '_site_transient_' . $transient;
2594 if ( ! in_array( $transient, $no_timeout, true ) ) {
2595 $transient_timeout = '_site_transient_timeout_' . $transient;
2596 wp_prime_site_option_caches( array( $transient_option, $transient_timeout ) );
2597
2598 $timeout = get_site_option( $transient_timeout );
2599 if ( false !== $timeout && $timeout < time() ) {
2600 delete_site_option( $transient_option );
2601 delete_site_option( $transient_timeout );
2602 $value = false;
2603 }
2604 }
2605
2606 if ( ! isset( $value ) ) {
2607 $value = get_site_option( $transient_option );
2608 }
2609 }
2610
2611 /**
2612 * Filters the value of an existing site transient.
2613 *
2614 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2615 *
2616 * @since 2.9.0
2617 * @since 4.4.0 The `$transient` parameter was added.
2618 *
2619 * @param mixed $value Value of site transient.
2620 * @param string $transient Transient name.
2621 */
2622 return apply_filters( "site_transient_{$transient}", $value, $transient );
2623}
2624
2625/**
2626 * Sets/updates the value of a site transient.
2627 *
2628 * You do not need to serialize values. If the value needs to be serialized,
2629 * then it will be serialized before it is set.
2630 *
2631 * @since 2.9.0
2632 *
2633 * @see set_transient()
2634 *
2635 * @param string $transient Transient name. Expected to not be SQL-escaped. Must be
2636 * 167 characters or fewer in length.
2637 * @param mixed $value Transient value. Expected to not be SQL-escaped.
2638 * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
2639 * @return bool True if the value was set, false otherwise.
2640 */
2641function set_site_transient( $transient, $value, $expiration = 0 ) {
2642
2643 /**
2644 * Filters the value of a specific site transient before it is set.
2645 *
2646 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2647 *
2648 * @since 3.0.0
2649 * @since 4.4.0 The `$transient` parameter was added.
2650 *
2651 * @param mixed $value New value of site transient.
2652 * @param string $transient Transient name.
2653 */
2654 $value = apply_filters( "pre_set_site_transient_{$transient}", $value, $transient );
2655
2656 $expiration = (int) $expiration;
2657
2658 /**
2659 * Filters the expiration for a site transient before its value is set.
2660 *
2661 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2662 *
2663 * @since 4.4.0
2664 *
2665 * @param int $expiration Time until expiration in seconds. Use 0 for no expiration.
2666 * @param mixed $value New value of site transient.
2667 * @param string $transient Transient name.
2668 */
2669 $expiration = apply_filters( "expiration_of_site_transient_{$transient}", $expiration, $value, $transient );
2670
2671 if ( wp_using_ext_object_cache() || wp_installing() ) {
2672 $result = wp_cache_set( $transient, $value, 'site-transient', $expiration );
2673 } else {
2674 $transient_timeout = '_site_transient_timeout_' . $transient;
2675 $option = '_site_transient_' . $transient;
2676 wp_prime_site_option_caches( array( $option, $transient_timeout ) );
2677
2678 if ( false === get_site_option( $option ) ) {
2679 if ( $expiration ) {
2680 add_site_option( $transient_timeout, time() + $expiration );
2681 }
2682 $result = add_site_option( $option, $value );
2683 } else {
2684 if ( $expiration ) {
2685 update_site_option( $transient_timeout, time() + $expiration );
2686 }
2687 $result = update_site_option( $option, $value );
2688 }
2689 }
2690
2691 if ( $result ) {
2692
2693 /**
2694 * Fires after the value for a specific site transient has been set.
2695 *
2696 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
2697 *
2698 * @since 3.0.0
2699 * @since 4.4.0 The `$transient` parameter was added
2700 *
2701 * @param mixed $value Site transient value.
2702 * @param int $expiration Time until expiration in seconds.
2703 * @param string $transient Transient name.
2704 */
2705 do_action( "set_site_transient_{$transient}", $value, $expiration, $transient );
2706
2707 /**
2708 * Fires after the value for a site transient has been set.
2709 *
2710 * @since 6.8.0
2711 *
2712 * @param string $transient The name of the site transient.
2713 * @param mixed $value Site transient value.
2714 * @param int $expiration Time until expiration in seconds.
2715 */
2716 do_action( 'set_site_transient', $transient, $value, $expiration );
2717
2718 /**
2719 * Fires after the value for a site transient has been set.
2720 *
2721 * @since 3.0.0
2722 * @deprecated 6.8.0 Use {@see 'set_site_transient'} instead.
2723 *
2724 * @param string $transient The name of the site transient.
2725 * @param mixed $value Site transient value.
2726 * @param int $expiration Time until expiration in seconds.
2727 */
2728 do_action_deprecated( 'setted_site_transient', array( $transient, $value, $expiration ), '6.8.0', 'set_site_transient' );
2729 }
2730
2731 return $result;
2732}
2733
2734/**
2735 * Registers default settings available in WordPress.
2736 *
2737 * The settings registered here are primarily useful for the REST API, so this
2738 * does not encompass all settings available in WordPress.
2739 *
2740 * @since 4.7.0
2741 * @since 6.0.1 The `show_on_front`, `page_on_front`, and `page_for_posts` options were added.
2742 */
2743function register_initial_settings() {
2744 register_setting(
2745 'general',
2746 'blogname',
2747 array(
2748 'show_in_rest' => array(
2749 'name' => 'title',
2750 ),
2751 'type' => 'string',
2752 'label' => __( 'Title' ),
2753 'description' => __( 'Site title.' ),
2754 )
2755 );
2756
2757 register_setting(
2758 'general',
2759 'blogdescription',
2760 array(
2761 'show_in_rest' => array(
2762 'name' => 'description',
2763 ),
2764 'type' => 'string',
2765 'label' => __( 'Tagline' ),
2766 'description' => __( 'Site tagline.' ),
2767 )
2768 );
2769
2770 if ( ! is_multisite() ) {
2771 register_setting(
2772 'general',
2773 'siteurl',
2774 array(
2775 'show_in_rest' => array(
2776 'name' => 'url',
2777 'schema' => array(
2778 'format' => 'uri',
2779 ),
2780 ),
2781 'type' => 'string',
2782 'description' => __( 'Site URL.' ),
2783 )
2784 );
2785 }
2786
2787 if ( ! is_multisite() ) {
2788 register_setting(
2789 'general',
2790 'admin_email',
2791 array(
2792 'show_in_rest' => array(
2793 'name' => 'email',
2794 'schema' => array(
2795 'format' => 'email',
2796 ),
2797 ),
2798 'type' => 'string',
2799 'description' => __( 'This address is used for admin purposes, like new user notification.' ),
2800 )
2801 );
2802 }
2803
2804 register_setting(
2805 'general',
2806 'timezone_string',
2807 array(
2808 'show_in_rest' => array(
2809 'name' => 'timezone',
2810 ),
2811 'type' => 'string',
2812 'description' => __( 'A city in the same timezone as you.' ),
2813 )
2814 );
2815
2816 register_setting(
2817 'general',
2818 'date_format',
2819 array(
2820 'show_in_rest' => true,
2821 'type' => 'string',
2822 'description' => __( 'A date format for all date strings.' ),
2823 )
2824 );
2825
2826 register_setting(
2827 'general',
2828 'time_format',
2829 array(
2830 'show_in_rest' => true,
2831 'type' => 'string',
2832 'description' => __( 'A time format for all time strings.' ),
2833 )
2834 );
2835
2836 register_setting(
2837 'general',
2838 'start_of_week',
2839 array(
2840 'show_in_rest' => true,
2841 'type' => 'integer',
2842 'description' => __( 'A day number of the week that the week should start on.' ),
2843 )
2844 );
2845
2846 register_setting(
2847 'general',
2848 'WPLANG',
2849 array(
2850 'show_in_rest' => array(
2851 'name' => 'language',
2852 ),
2853 'type' => 'string',
2854 'description' => __( 'WordPress locale code.' ),
2855 'default' => 'en_US',
2856 )
2857 );
2858
2859 register_setting(
2860 'writing',
2861 'use_smilies',
2862 array(
2863 'show_in_rest' => true,
2864 'type' => 'boolean',
2865 'description' => __( 'Convert emoticons like :-) and :-P to graphics on display.' ),
2866 'default' => true,
2867 )
2868 );
2869
2870 register_setting(
2871 'writing',
2872 'default_category',
2873 array(
2874 'show_in_rest' => true,
2875 'type' => 'integer',
2876 'description' => __( 'Default post category.' ),
2877 )
2878 );
2879
2880 register_setting(
2881 'writing',
2882 'default_post_format',
2883 array(
2884 'show_in_rest' => true,
2885 'type' => 'string',
2886 'description' => __( 'Default post format.' ),
2887 )
2888 );
2889
2890 register_setting(
2891 'reading',
2892 'posts_per_page',
2893 array(
2894 'show_in_rest' => true,
2895 'type' => 'integer',
2896 'label' => __( 'Maximum posts per page' ),
2897 'description' => __( 'Blog pages show at most.' ),
2898 'default' => 10,
2899 )
2900 );
2901
2902 register_setting(
2903 'reading',
2904 'show_on_front',
2905 array(
2906 'show_in_rest' => true,
2907 'type' => 'string',
2908 'label' => __( 'Show on front' ),
2909 'description' => __( 'What to show on the front page' ),
2910 )
2911 );
2912
2913 register_setting(
2914 'reading',
2915 'page_on_front',
2916 array(
2917 'show_in_rest' => true,
2918 'type' => 'integer',
2919 'label' => __( 'Page on front' ),
2920 'description' => __( 'The ID of the page that should be displayed on the front page' ),
2921 )
2922 );
2923
2924 register_setting(
2925 'reading',
2926 'page_for_posts',
2927 array(
2928 'show_in_rest' => true,
2929 'type' => 'integer',
2930 'description' => __( 'The ID of the page that should display the latest posts' ),
2931 )
2932 );
2933
2934 register_setting(
2935 'discussion',
2936 'default_ping_status',
2937 array(
2938 'show_in_rest' => array(
2939 'schema' => array(
2940 'enum' => array( 'open', 'closed' ),
2941 ),
2942 ),
2943 'type' => 'string',
2944 'description' => __( 'Allow link notifications from other blogs (pingbacks and trackbacks) on new articles.' ),
2945 )
2946 );
2947
2948 register_setting(
2949 'discussion',
2950 'default_comment_status',
2951 array(
2952 'show_in_rest' => array(
2953 'schema' => array(
2954 'enum' => array( 'open', 'closed' ),
2955 ),
2956 ),
2957 'type' => 'string',
2958 'label' => __( 'Allow comments on new posts' ),
2959 'description' => __( 'Allow people to submit comments on new posts.' ),
2960 )
2961 );
2962}
2963
2964/**
2965 * Registers a setting and its data.
2966 *
2967 * @since 2.7.0
2968 * @since 3.0.0 The `misc` option group was deprecated.
2969 * @since 3.5.0 The `privacy` option group was deprecated.
2970 * @since 4.7.0 `$args` can be passed to set flags on the setting, similar to `register_meta()`.
2971 * @since 5.5.0 `$new_whitelist_options` was renamed to `$new_allowed_options`.
2972 * Please consider writing more inclusive code.
2973 * @since 6.6.0 Added the `label` argument.
2974 *
2975 * @global array $new_allowed_options
2976 * @global array $wp_registered_settings
2977 *
2978 * @param string $option_group A settings group name. Should correspond to an allowed option key name.
2979 * Default allowed option key names include 'general', 'discussion', 'media',
2980 * 'reading', 'writing', and 'options'.
2981 * @param string $option_name The name of an option to sanitize and save.
2982 * @param array $args {
2983 * Data used to describe the setting when registered.
2984 *
2985 * @type string $type The type of data associated with this setting.
2986 * Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
2987 * @type string $label A label of the data attached to this setting.
2988 * @type string $description A description of the data attached to this setting.
2989 * @type callable $sanitize_callback A callback function that sanitizes the option's value.
2990 * @type bool|array $show_in_rest Whether data associated with this setting should be included in the REST API.
2991 * When registering complex settings, this argument may optionally be an
2992 * array with a 'schema' key.
2993 * @type mixed $default Default value when calling `get_option()`.
2994 * }
2995 */
2996function register_setting( $option_group, $option_name, $args = array() ) {
2997 global $new_allowed_options, $wp_registered_settings;
2998
2999 /*
3000 * In 5.5.0, the `$new_whitelist_options` global variable was renamed to `$new_allowed_options`.
3001 * Please consider writing more inclusive code.
3002 */
3003 $GLOBALS['new_whitelist_options'] = &$new_allowed_options;
3004
3005 $defaults = array(
3006 'type' => 'string',
3007 'group' => $option_group,
3008 'label' => '',
3009 'description' => '',
3010 'sanitize_callback' => null,
3011 'show_in_rest' => false,
3012 );
3013
3014 // Back-compat: old sanitize callback is added.
3015 if ( is_callable( $args ) ) {
3016 $args = array(
3017 'sanitize_callback' => $args,
3018 );
3019 }
3020
3021 /**
3022 * Filters the registration arguments when registering a setting.
3023 *
3024 * @since 4.7.0
3025 *
3026 * @param array $args Array of setting registration arguments.
3027 * @param array $defaults Array of default arguments.
3028 * @param string $option_group Setting group.
3029 * @param string $option_name Setting name.
3030 */
3031 $args = apply_filters( 'register_setting_args', $args, $defaults, $option_group, $option_name );
3032
3033 $args = wp_parse_args( $args, $defaults );
3034
3035 // Require an item schema when registering settings with an array type.
3036 if ( false !== $args['show_in_rest'] && 'array' === $args['type'] && ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) ) {
3037 _doing_it_wrong( __FUNCTION__, __( 'When registering an "array" setting to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.4.0' );
3038 }
3039
3040 if ( ! is_array( $wp_registered_settings ) ) {
3041 $wp_registered_settings = array();
3042 }
3043
3044 if ( 'misc' === $option_group ) {
3045 _deprecated_argument(
3046 __FUNCTION__,
3047 '3.0.0',
3048 sprintf(
3049 /* translators: %s: misc */
3050 __( 'The "%s" options group has been removed. Use another settings group.' ),
3051 'misc'
3052 )
3053 );
3054 $option_group = 'general';
3055 }
3056
3057 if ( 'privacy' === $option_group ) {
3058 _deprecated_argument(
3059 __FUNCTION__,
3060 '3.5.0',
3061 sprintf(
3062 /* translators: %s: privacy */
3063 __( 'The "%s" options group has been removed. Use another settings group.' ),
3064 'privacy'
3065 )
3066 );
3067 $option_group = 'reading';
3068 }
3069
3070 $new_allowed_options[ $option_group ][] = $option_name;
3071
3072 if ( ! empty( $args['sanitize_callback'] ) ) {
3073 add_filter( "sanitize_option_{$option_name}", $args['sanitize_callback'] );
3074 }
3075 if ( array_key_exists( 'default', $args ) ) {
3076 add_filter( "default_option_{$option_name}", 'filter_default_option', 10, 3 );
3077 }
3078
3079 /**
3080 * Fires immediately before the setting is registered but after its filters are in place.
3081 *
3082 * @since 5.5.0
3083 *
3084 * @param string $option_group Setting group.
3085 * @param string $option_name Setting name.
3086 * @param array $args Array of setting registration arguments.
3087 */
3088 do_action( 'register_setting', $option_group, $option_name, $args );
3089
3090 $wp_registered_settings[ $option_name ] = $args;
3091}
3092
3093/**
3094 * Unregisters a setting.
3095 *
3096 * @since 2.7.0
3097 * @since 4.7.0 `$sanitize_callback` was deprecated. The callback from `register_setting()` is now used instead.
3098 * @since 5.5.0 `$new_whitelist_options` was renamed to `$new_allowed_options`.
3099 * Please consider writing more inclusive code.
3100 *
3101 * @global array $new_allowed_options
3102 * @global array $wp_registered_settings
3103 *
3104 * @param string $option_group The settings group name used during registration.
3105 * @param string $option_name The name of the option to unregister.
3106 * @param callable $deprecated Optional. Deprecated.
3107 */
3108function unregister_setting( $option_group, $option_name, $deprecated = '' ) {
3109 global $new_allowed_options, $wp_registered_settings;
3110
3111 /*
3112 * In 5.5.0, the `$new_whitelist_options` global variable was renamed to `$new_allowed_options`.
3113 * Please consider writing more inclusive code.
3114 */
3115 $GLOBALS['new_whitelist_options'] = &$new_allowed_options;
3116
3117 if ( 'misc' === $option_group ) {
3118 _deprecated_argument(
3119 __FUNCTION__,
3120 '3.0.0',
3121 sprintf(
3122 /* translators: %s: misc */
3123 __( 'The "%s" options group has been removed. Use another settings group.' ),
3124 'misc'
3125 )
3126 );
3127 $option_group = 'general';
3128 }
3129
3130 if ( 'privacy' === $option_group ) {
3131 _deprecated_argument(
3132 __FUNCTION__,
3133 '3.5.0',
3134 sprintf(
3135 /* translators: %s: privacy */
3136 __( 'The "%s" options group has been removed. Use another settings group.' ),
3137 'privacy'
3138 )
3139 );
3140 $option_group = 'reading';
3141 }
3142
3143 $pos = false;
3144 if ( isset( $new_allowed_options[ $option_group ] ) ) {
3145 $pos = array_search( $option_name, (array) $new_allowed_options[ $option_group ], true );
3146 }
3147
3148 if ( false !== $pos ) {
3149 unset( $new_allowed_options[ $option_group ][ $pos ] );
3150 }
3151
3152 if ( '' !== $deprecated ) {
3153 _deprecated_argument(
3154 __FUNCTION__,
3155 '4.7.0',
3156 sprintf(
3157 /* translators: 1: $sanitize_callback, 2: register_setting() */
3158 __( '%1$s is deprecated. The callback from %2$s is used instead.' ),
3159 '<code>$sanitize_callback</code>',
3160 '<code>register_setting()</code>'
3161 )
3162 );
3163 remove_filter( "sanitize_option_{$option_name}", $deprecated );
3164 }
3165
3166 if ( isset( $wp_registered_settings[ $option_name ] ) ) {
3167 // Remove the sanitize callback if one was set during registration.
3168 if ( ! empty( $wp_registered_settings[ $option_name ]['sanitize_callback'] ) ) {
3169 remove_filter( "sanitize_option_{$option_name}", $wp_registered_settings[ $option_name ]['sanitize_callback'] );
3170 }
3171
3172 // Remove the default filter if a default was provided during registration.
3173 if ( array_key_exists( 'default', $wp_registered_settings[ $option_name ] ) ) {
3174 remove_filter( "default_option_{$option_name}", 'filter_default_option', 10 );
3175 }
3176
3177 /**
3178 * Fires immediately before the setting is unregistered and after its filters have been removed.
3179 *
3180 * @since 5.5.0
3181 *
3182 * @param string $option_group Setting group.
3183 * @param string $option_name Setting name.
3184 */
3185 do_action( 'unregister_setting', $option_group, $option_name );
3186
3187 unset( $wp_registered_settings[ $option_name ] );
3188 }
3189}
3190
3191/**
3192 * Retrieves an array of registered settings.
3193 *
3194 * @since 4.7.0
3195 *
3196 * @global array $wp_registered_settings
3197 *
3198 * @return array {
3199 * List of registered settings, keyed by option name.
3200 *
3201 * @type array ...$0 {
3202 * Data used to describe the setting when registered.
3203 *
3204 * @type string $type The type of data associated with this setting.
3205 * Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
3206 * @type string $label A label of the data attached to this setting.
3207 * @type string $description A description of the data attached to this setting.
3208 * @type callable $sanitize_callback A callback function that sanitizes the option's value.
3209 * @type bool|array $show_in_rest Whether data associated with this setting should be included in the REST API.
3210 * When registering complex settings, this argument may optionally be an
3211 * array with a 'schema' key.
3212 * @type mixed $default Default value when calling `get_option()`.
3213 * }
3214 * }
3215 */
3216function get_registered_settings() {
3217 global $wp_registered_settings;
3218
3219 if ( ! is_array( $wp_registered_settings ) ) {
3220 return array();
3221 }
3222
3223 return $wp_registered_settings;
3224}
3225
3226/**
3227 * Filters the default value for the option.
3228 *
3229 * For settings which register a default setting in `register_setting()`, this
3230 * function is added as a filter to `default_option_{$option}`.
3231 *
3232 * @since 4.7.0
3233 *
3234 * @param mixed $default_value Existing default value to return.
3235 * @param string $option Option name.
3236 * @param bool $passed_default Was `get_option()` passed a default value?
3237 * @return mixed Filtered default value.
3238 */
3239function filter_default_option( $default_value, $option, $passed_default ) {
3240 if ( $passed_default ) {
3241 return $default_value;
3242 }
3243
3244 $registered = get_registered_settings();
3245 if ( empty( $registered[ $option ] ) ) {
3246 return $default_value;
3247 }
3248
3249 return $registered[ $option ]['default'];
3250}
3251
3252/**
3253 * Returns the values that trigger autoloading from the options table.
3254 *
3255 * @since 6.6.0
3256 *
3257 * @return string[] The values that trigger autoloading.
3258 */
3259function wp_autoload_values_to_autoload() {
3260 $autoload_values = array( 'yes', 'on', 'auto-on', 'auto' );
3261
3262 /**
3263 * Filters the autoload values that should be considered for autoloading from the options table.
3264 *
3265 * The filter can only be used to remove autoload values from the default list.
3266 *
3267 * @since 6.6.0
3268 *
3269 * @param string[] $autoload_values Autoload values used to autoload option.
3270 * Default list contains 'yes', 'on', 'auto-on', and 'auto'.
3271 */
3272 $filtered_values = apply_filters( 'wp_autoload_values_to_autoload', $autoload_values );
3273
3274 return array_intersect( $filtered_values, $autoload_values );
3275}
3276
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1