| @@ -18,10 +18,12 @@ | ||
| 18 | 18 | * |
| 19 | 19 | * @return bool Whether or not function is disabled. |
| 20 | 20 | */ |
| 21 | 21 | function is_func_disabled( $func ) { |
| 22 | - $disabled = explode( ',', ini_get( 'disable_functions' ) ); | |
| 22 | + $disabled_functions = ini_get( 'disable_functions' ); | |
| 23 | 23 | |
| 24 | + $disabled = $disabled_functions ? explode( ',', $disabled_functions ) : []; | |
| 25 | + | |
| 24 | 26 | return in_array( $func, $disabled, true ); |
| 25 | 27 | } |
| 26 | 28 | |
| 27 | 29 | /** |
| @@ -35,29 +37,68 @@ | ||
| 35 | 37 | * Also supports WP installations in subfolders |
| 36 | 38 | * |
| 37 | 39 | * @returns boolean |
| 38 | 40 | * @author matzeeable |
| 41 | + * | |
| 42 | + * @return bool | |
| 39 | 43 | */ |
| 40 | 44 | function is_rest() { |
| 41 | - // phpcs:disable WordPress.Security.NonceVerification.Recommended | |
| 42 | - if ( defined( 'REST_REQUEST' ) && REST_REQUEST // (#1) | |
| 43 | - || isset( $_GET['rest_route'] ) // (#2) | |
| 44 | - && strpos( sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ), '/', 0 ) === 0 ) { | |
| 45 | - return true; | |
| 45 | + static $is_rest; | |
| 46 | + | |
| 47 | + if ( isset( $is_rest ) ) { | |
| 48 | + return $is_rest; | |
| 46 | 49 | } |
| 47 | 50 | |
| 48 | - // (#3) | |
| 49 | - global $wp_rewrite; | |
| 50 | - if ( null === $wp_rewrite ) { | |
| 51 | - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited | |
| 52 | - $wp_rewrite = new \WP_Rewrite(); | |
| 51 | + // Callback to avoid duplicative $is_rest assignments, only runs once. | |
| 52 | + $is_rest = ( function () { | |
| 53 | + // phpcs:disable WordPress.Security.NonceVerification.Recommended | |
| 54 | + if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST )// (#1) | |
| 55 | + || ( isset( $_GET['rest_route'] ) // (#2) | |
| 56 | + && strpos( sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ), '/', 0 ) === 0 ) ) { | |
| 57 | + return true; | |
| 58 | + } | |
| 59 | + | |
| 60 | + // (#4) | |
| 61 | + $rest_url = wp_parse_url( trailingslashit( rest_url() ) ); | |
| 62 | + $current_url = wp_parse_url( add_query_arg( [] ) ); | |
| 63 | + | |
| 64 | + if ( ! $rest_url || ! $current_url ) { | |
| 65 | + return false; | |
| 66 | + } | |
| 67 | + | |
| 68 | + $current_path = isset( $current_url['path'] ) ? $current_url['path'] : false; | |
| 69 | + $rest_path = isset( $rest_url['path'] ) ? $rest_url['path'] : false; | |
| 70 | + | |
| 71 | + // If one of the URLs failed to parse, then the current request isn't a REST request. | |
| 72 | + if ( ! $current_path || ! $rest_path ) { | |
| 73 | + return false; | |
| 74 | + } | |
| 75 | + | |
| 76 | + return strpos( $current_path, $rest_path, 0 ) === 0; | |
| 77 | + // phpcs:enable WordPress.Security.NonceVerification.Recommended | |
| 78 | + } )(); | |
| 79 | + | |
| 80 | + return $is_rest; | |
| 81 | +} | |
| 82 | + | |
| 83 | +/** | |
| 84 | + * Check if this is a core WP REST namespace. | |
| 85 | + * | |
| 86 | + * @return boolean | |
| 87 | + * | |
| 88 | + * @since 2.2.0 | |
| 89 | + */ | |
| 90 | +function is_wp_core_rest_namespace() { | |
| 91 | + if ( ! is_rest() ) { | |
| 92 | + return false; | |
| 53 | 93 | } |
| 54 | 94 | |
| 55 | - // (#4) | |
| 56 | - $rest_url = wp_parse_url( trailingslashit( rest_url() ) ); | |
| 57 | - $current_url = wp_parse_url( add_query_arg( [] ) ); | |
| 58 | - return strpos( $current_url['path'] ? $current_url['path'] : '/', $rest_url['path'], 0 ) === 0; | |
| 59 | - // phpcs:enable WordPress.Security.NonceVerification.Recommended | |
| 95 | + global $wp; | |
| 96 | + | |
| 97 | + $rest_route = isset( $wp->query_vars['rest_route'] ) ? $wp->query_vars['rest_route'] : ''; | |
| 98 | + | |
| 99 | + // Check if this is core WP REST namespace. | |
| 100 | + return strpos( $rest_route, '/wp/v2' ) === 0; | |
| 60 | 101 | } |
| 61 | 102 | |
| 62 | 103 | /** |
| 63 | 104 | * Check if this is a cron request. |
| @@ -82,32 +123,43 @@ | ||
| 82 | 123 | * |
| 83 | 124 | * @return boolean |
| 84 | 125 | */ |
| 85 | 126 | function is_frontend() { |
| 86 | - /** | |
| 87 | - * WP Query. | |
| 88 | - * | |
| 89 | - * @var \WP_Query $query | |
| 90 | - */ | |
| 127 | + // Cached. | |
| 128 | + static $is_frontend; | |
| 129 | + | |
| 130 | + // phpcs:ignore | |
| 131 | + if ( isset( $is_frontend ) ) { | |
| 132 | + // Not fully tested, but if we have a cached value, we can return it. | |
| 133 | + // return $is_frontend;. | |
| 134 | + $temp = $is_frontend; | |
| 135 | + } | |
| 136 | + | |
| 91 | 137 | $query = get_query(); |
| 92 | 138 | |
| 139 | + $wp_query = $query instanceof \WP_Query ? $query : null; | |
| 140 | + | |
| 93 | 141 | $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; |
| 94 | 142 | |
| 95 | 143 | if ( |
| 96 | - is_rest() || | |
| 144 | + // Check if is CLI. | |
| 145 | + ( defined( 'WP_CLI' ) && WP_CLI ) || | |
| 146 | + // Check if is REST. | |
| 147 | + is_admin() || | |
| 148 | + is_ajax() || | |
| 97 | 149 | is_cron() || |
| 98 | - is_ajax() || | |
| 99 | - is_admin() || | |
| 100 | - $query->is_admin() || | |
| 101 | - $query->is_favicon() || | |
| 102 | - strpos( $request_uri, 'favicon.ico' ) || | |
| 103 | - $query->is_robots() || | |
| 104 | - strpos( $request_uri, 'robots.txt' ) | |
| 150 | + ( $wp_query && $wp_query->is_admin ) || | |
| 151 | + ( $wp_query && $wp_query->is_favicon() ) || | |
| 152 | + ( $wp_query && $wp_query->is_robots() ) || | |
| 153 | + strpos( $request_uri, 'favicon.ico' ) !== false || | |
| 154 | + strpos( $request_uri, 'robots.txt' ) !== false | |
| 105 | 155 | ) { |
| 106 | - return false; | |
| 156 | + $is_frontend = false; | |
| 157 | + } else { | |
| 158 | + $is_frontend = true; | |
| 107 | 159 | } |
| 108 | 160 | |
| 109 | - return true; | |
| 161 | + return $is_frontend; | |
| 110 | 162 | } |
| 111 | 163 | |
| 112 | 164 | /** |
| 113 | 165 | * Change camelCase to snake_case. |
| @@ -119,22 +171,96 @@ | ||
| 119 | 171 | function camel_case_to_snake_case( $str ) { |
| 120 | 172 | return strtolower( preg_replace( '/(?<!^)[A-Z]/', '_$0', $str ) ); |
| 121 | 173 | } |
| 122 | 174 | |
| 175 | +/** | |
| 176 | + * Change snake_case to camelCase. | |
| 177 | + * | |
| 178 | + * @param string $str String to convert. | |
| 179 | + * | |
| 180 | + * @return string Converted string. | |
| 181 | + */ | |
| 182 | +function snake_case_to_camel_case( $str ) { | |
| 183 | + return lcfirst( str_replace( '_', '', ucwords( $str, '_' ) ) ); | |
| 184 | +} | |
| 123 | 185 | |
| 124 | 186 | /** |
| 187 | + * Get array values using dot.notation. | |
| 188 | + * | |
| 189 | + * @param string $key Key to fetch. | |
| 190 | + * @param array<string,mixed> $data Array to fetch from. | |
| 191 | + * @param string|null $key_case Case to use for key (snake_case|camelCase). | |
| 192 | + * | |
| 193 | + * @return mixed|null | |
| 194 | + */ | |
| 195 | +function fetch_key_from_array( $key, $data, $key_case = null ) { | |
| 196 | + // If key is .notation, then we need to traverse the array. | |
| 197 | + $dotted_keys = explode( '.', $key ); | |
| 198 | + | |
| 199 | + foreach ( $dotted_keys as $key ) { | |
| 200 | + if ( $key_case ) { | |
| 201 | + switch ( $key_case ) { | |
| 202 | + case 'snake_case': | |
| 203 | + // Check if key is camelCase & convert to snake_case. | |
| 204 | + $key = camel_case_to_snake_case( $key ); | |
| 205 | + break; | |
| 206 | + case 'camelCase': | |
| 207 | + // Check if key is snake_case & convert to camelCase. | |
| 208 | + $key = snake_case_to_camel_case( $key ); | |
| 209 | + break; | |
| 210 | + } | |
| 211 | + } | |
| 212 | + | |
| 213 | + if ( ! isset( $data[ $key ] ) ) { | |
| 214 | + return null; | |
| 215 | + } | |
| 216 | + | |
| 217 | + $data = $data[ $key ]; | |
| 218 | + } | |
| 219 | + | |
| 220 | + return $data ? $data : null; | |
| 221 | +} | |
| 222 | + | |
| 223 | +/** | |
| 224 | + * Convert hex to rgba. | |
| 225 | + * | |
| 226 | + * @param string $hex_code Hex code to convert. | |
| 227 | + * @param float $opacity Opacity to use. | |
| 228 | + * | |
| 229 | + * @return string Converted rgba string. | |
| 230 | + */ | |
| 231 | +function convert_hex_to_rgba( $hex_code, $opacity = 1 ) { | |
| 232 | + $hex = str_replace( '#', '', $hex_code ); | |
| 233 | + | |
| 234 | + if ( strlen( $hex ) === 3 ) { | |
| 235 | + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; | |
| 236 | + } | |
| 237 | + | |
| 238 | + $r = hexdec( substr( $hex, 0, 2 ) ); | |
| 239 | + $g = hexdec( substr( $hex, 2, 2 ) ); | |
| 240 | + $b = hexdec( substr( $hex, 4, 2 ) ); | |
| 241 | + | |
| 242 | + /* Backward compatibility for whole number based opacity values. */ | |
| 243 | + if ( $opacity > 1 && $opacity <= 100 ) { | |
| 244 | + $opacity = $opacity / 100; | |
| 245 | + } | |
| 246 | + | |
| 247 | + return "rgba($r,$g,$b,$opacity)"; | |
| 248 | +} | |
| 249 | + | |
| 250 | +/** | |
| 125 | 251 | * Function that deeply cleans arrays for wp_maybe_serialize |
| 126 | 252 | * |
| 127 | 253 | * Gets rid of Closure and other invalid data types. |
| 128 | 254 | * |
| 129 | - * @param array $array Array to clean. | |
| 255 | + * @param array<mixed> $arr Array to clean. | |
| 130 | 256 | * |
| 131 | - * @return array Cleaned array. | |
| 257 | + * @return array<mixed> Cleaned array. | |
| 132 | 258 | */ |
| 133 | -function deep_clean_array( $array ) { | |
| 259 | +function deep_clean_array( $arr ) { | |
| 134 | 260 | // Clean \Closure values deeply. |
| 135 | 261 | array_walk_recursive( |
| 136 | - $array, | |
| 262 | + $arr, | |
| 137 | 263 | function ( &$value ) { |
| 138 | 264 | if ( $value instanceof \Closure ) { |
| 139 | 265 | $value = null; |
| 140 | 266 | } |
| @@ -140,6 +266,6 @@ | ||
| 140 | 266 | } |
| 141 | 267 | } |
| 142 | 268 | ); |
| 143 | 269 | |
| 144 | - return $array; | |
| 270 | + return $arr; | |
| 145 | 271 | } |