File: /home/kusanagi/geriatrics.jp/DocumentRoot/optimized_wp_settings.php
<?php
$kusanagi_optimized_version = '6.9.4';
define( 'WPINC', 'wp-includes' );
global $wp_version, $wp_db_version, $tinymce_version, $required_php_version, $required_php_extensions, $required_mysql_version, $wp_local_package;
require ABSPATH . WPINC . '/version.php';
###require ABSPATH . WPINC . '/compat-utf8.php';
function _wp_scan_utf8( string $bytes, int &$at, int &$invalid_length, ?int $max_bytes = null, ?int $max_code_points = null, ?bool &$has_noncharacters = null ): int { $byte_length = strlen( $bytes ); $end = min( $byte_length, $at + ( $max_bytes ?? PHP_INT_MAX ) ); $invalid_length = 0; $count = 0; $max_count = $max_code_points ?? PHP_INT_MAX; $has_noncharacters = false; for ( $i = $at; $i < $end && $count <= $max_count; $i++ ) { $ascii_byte_count = strspn( $bytes, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" . " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f", $i, $end - $i ); if ( $count + $ascii_byte_count >= $max_count ) { $at = $i + ( $max_count - $count ); $count = $max_count; return $count; } $count += $ascii_byte_count; $i += $ascii_byte_count; if ( $i >= $end ) { $at = $end; return $count; } $b1 = ord( $bytes[ $i ] ); $b2 = ord( $bytes[ $i + 1 ] ?? "\xC0" ); if ( $b1 >= 0xC2 && $b1 <= 0xDF && $b2 >= 0x80 && $b2 <= 0xBF ) { ++$count; ++$i; continue; } $b3 = ord( $bytes[ $i + 2 ] ?? "\xC0" ); if ( $b3 < 0x80 || $b3 > 0xBF ) { goto invalid_utf8; } if ( ( 0xE0 === $b1 && $b2 >= 0xA0 && $b2 <= 0xBF ) || ( $b1 >= 0xE1 && $b1 <= 0xEC && $b2 >= 0x80 && $b2 <= 0xBF ) || ( 0xED === $b1 && $b2 >= 0x80 && $b2 <= 0x9F ) || ( $b1 >= 0xEE && $b1 <= 0xEF && $b2 >= 0x80 && $b2 <= 0xBF ) ) { ++$count; $i += 2; if ( 0xEF === $b1 ) { $has_noncharacters |= ( ( 0xB7 === $b2 && $b3 >= 0x90 && $b3 <= 0xAF ) || ( 0xBF === $b2 && ( 0xBE === $b3 || 0xBF === $b3 ) ) ); } continue; } $b4 = ord( $bytes[ $i + 3 ] ?? "\xC0" ); if ( $b4 < 0x80 || $b4 > 0xBF ) { goto invalid_utf8; } if ( ( 0xF0 === $b1 && $b2 >= 0x90 && $b2 <= 0xBF ) || ( $b1 >= 0xF1 && $b1 <= 0xF3 && $b2 >= 0x80 && $b2 <= 0xBF ) || ( 0xF4 === $b1 && $b2 >= 0x80 && $b2 <= 0x8F ) ) { ++$count; $i += 3; $has_noncharacters |= ( ( 0x0F === ( $b2 & 0x0F ) ) && 0xBF === $b3 && ( 0xBE === $b4 || 0xBF === $b4 ) ); continue; } invalid_utf8: $at = $i; $invalid_length = 1; if ( ( 0x00 === ( $b1 & 0x80 ) ) || ( 0xC0 === ( $b1 & 0xE0 ) ) ) { return $count; } $b2 = ord( $bytes[ $i + 1 ] ?? "\xC0" ); $b3 = ord( $bytes[ $i + 2 ] ?? "\xC0" ); if ( 0xE0 === ( $b1 & 0xF0 ) ) { $b2_valid = ( ( 0xE0 === $b1 && $b2 >= 0xA0 && $b2 <= 0xBF ) || ( $b1 >= 0xE1 && $b1 <= 0xEC && $b2 >= 0x80 && $b2 <= 0xBF ) || ( 0xED === $b1 && $b2 >= 0x80 && $b2 <= 0x9F ) || ( $b1 >= 0xEE && $b1 <= 0xEF && $b2 >= 0x80 && $b2 <= 0xBF ) ); $invalid_length = min( $end - $i, $b2_valid ? 2 : 1 ); return $count; } elseif ( 0xF0 === ( $b1 & 0xF8 ) ) { $b2_valid = ( ( 0xF0 === $b1 && $b2 >= 0x90 && $b2 <= 0xBF ) || ( $b1 >= 0xF1 && $b1 <= 0xF3 && $b2 >= 0x80 && $b2 <= 0xBF ) || ( 0xF4 === $b1 && $b2 >= 0x80 && $b2 <= 0x8F ) ); $b3_valid = $b3 >= 0x80 && $b3 <= 0xBF; $invalid_length = min( $end - $i, $b2_valid ? ( $b3_valid ? 3 : 2 ) : 1 ); return $count; } return $count; } $at = $i; return $count; } function _wp_is_valid_utf8_fallback( string $bytes ): bool { $bytes_length = strlen( $bytes ); if ( 0 === $bytes_length ) { return true; } $next_byte_at = 0; $invalid_length = 0; _wp_scan_utf8( $bytes, $next_byte_at, $invalid_length ); return $bytes_length === $next_byte_at && 0 === $invalid_length; } function _wp_scrub_utf8_fallback( string $bytes ): string { $bytes_length = strlen( $bytes ); $next_byte_at = 0; $was_at = 0; $invalid_length = 0; $scrubbed = ''; while ( $next_byte_at <= $bytes_length ) { _wp_scan_utf8( $bytes, $next_byte_at, $invalid_length ); if ( $next_byte_at >= $bytes_length ) { if ( 0 === $was_at ) { return $bytes; } return $scrubbed . substr( $bytes, $was_at, $next_byte_at - $was_at - $invalid_length ); } $scrubbed .= substr( $bytes, $was_at, $next_byte_at - $was_at ); $scrubbed .= "\u{FFFD}"; $next_byte_at += $invalid_length; $was_at = $next_byte_at; } return $scrubbed; } function _wp_utf8_codepoint_count( string $text, ?int $byte_offset = 0, ?int $max_byte_length = PHP_INT_MAX ): int { if ( $byte_offset < 0 ) { return 0; } $count = 0; $at = $byte_offset; $end = strlen( $text ); $invalid_length = 0; $max_byte_length = min( $end - $at, $max_byte_length ); while ( $at < $end && ( $at - $byte_offset ) < $max_byte_length ) { $count += _wp_scan_utf8( $text, $at, $invalid_length, $max_byte_length - ( $at - $byte_offset ) ); $count += $invalid_length > 0 ? 1 : 0; $at += $invalid_length; } return $count; } function _wp_utf8_codepoint_span( string $text, int $byte_offset, int $max_code_points, ?int &$found_code_points = 0 ): int { $was_at = $byte_offset; $invalid_length = 0; $end = strlen( $text ); $found_code_points = 0; while ( $byte_offset < $end && $found_code_points < $max_code_points ) { $needed = $max_code_points - $found_code_points; $chunk_count = _wp_scan_utf8( $text, $byte_offset, $invalid_length, null, $needed ); $found_code_points += $chunk_count; if ( 0 !== $invalid_length && $found_code_points < $max_code_points ) { ++$found_code_points; $byte_offset += $invalid_length; } } return $byte_offset - $was_at; } function _wp_has_noncharacters_fallback( string $text ): bool { $at = 0; $invalid_length = 0; $has_noncharacters = false; $end = strlen( $text ); while ( $at < $end && ! $has_noncharacters ) { _wp_scan_utf8( $text, $at, $invalid_length, null, null, $has_noncharacters ); $at += $invalid_length; } return $has_noncharacters; } function _wp_utf8_encode_fallback( $iso_8859_1_text ) { $iso_8859_1_text = (string) $iso_8859_1_text; $at = 0; $was_at = 0; $end = strlen( $iso_8859_1_text ); $utf8 = ''; while ( $at < $end ) { $ascii_byte_count = strspn( $iso_8859_1_text, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" . " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f", $at ); if ( $ascii_byte_count > 0 ) { $at += $ascii_byte_count; continue; } $code_point = ord( $iso_8859_1_text[ $at ] ); $byte1 = chr( 0xC0 | ( $code_point >> 6 ) ); $byte2 = chr( 0x80 | ( $code_point & 0x3F ) ); $utf8 .= substr( $iso_8859_1_text, $was_at, $at - $was_at ); $utf8 .= "{$byte1}{$byte2}"; ++$at; $was_at = $at; } if ( 0 === $was_at ) { return $iso_8859_1_text; } $utf8 .= substr( $iso_8859_1_text, $was_at ); return $utf8; } function _wp_utf8_decode_fallback( $utf8_text ) { $utf8_text = (string) $utf8_text; $at = 0; $was_at = 0; $end = strlen( $utf8_text ); $iso_8859_1_text = ''; while ( $at < $end ) { $ascii_byte_count = strspn( $utf8_text, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" . " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f", $at ); if ( $ascii_byte_count > 0 ) { $at += $ascii_byte_count; continue; } $next_at = $at; $invalid_length = 0; $found = _wp_scan_utf8( $utf8_text, $next_at, $invalid_length, null, 1 ); $span_length = $next_at - $at; $next_byte = '?'; if ( 1 !== $found ) { if ( $invalid_length > 0 ) { $next_byte = ''; goto flush_sub_part; } break; } $byte1 = ord( $utf8_text[ $at ] ); if ( 0xC0 !== ( $byte1 & 0xE0 ) ) { goto flush_sub_part; } $byte2 = ord( $utf8_text[ $at + 1 ] ); $code_point = ( ( $byte1 & 0x1F ) << 6 ) | ( ( $byte2 & 0x3F ) ); if ( $code_point > 0xFF ) { goto flush_sub_part; } $next_byte = chr( $code_point ); flush_sub_part: $iso_8859_1_text .= substr( $utf8_text, $was_at, $at - $was_at ); $iso_8859_1_text .= $next_byte; $at += $span_length; $was_at = $at; if ( $invalid_length > 0 ) { $iso_8859_1_text .= '?'; $at += $invalid_length; $was_at = $at; } } if ( 0 === $was_at ) { return $utf8_text; } $iso_8859_1_text .= substr( $utf8_text, $was_at ); return $iso_8859_1_text; }
###require ABSPATH . WPINC . '/compat.php';
if ( ! function_exists( '_' ) ) { function _( $message ) { return $message; } } function _wp_can_use_pcre_u( $set = null ) { static $utf8_pcre = null; if ( isset( $set ) ) { _deprecated_argument( __FUNCTION__, '6.9.0' ); } if ( isset( $utf8_pcre ) ) { return $utf8_pcre; } $utf8_pcre = true; set_error_handler( function ( $errno, $errstr ) use ( &$utf8_pcre ) { if ( str_starts_with( $errstr, 'preg_match():' ) ) { $utf8_pcre = false; return true; } return false; }, E_WARNING ); preg_match( '//u', '' ); restore_error_handler(); return $utf8_pcre; } function _is_utf8_charset( $charset_slug ) { if ( ! is_string( $charset_slug ) ) { return false; } return ( 0 === strcasecmp( 'UTF-8', $charset_slug ) || 0 === strcasecmp( 'UTF8', $charset_slug ) ); } if ( ! function_exists( 'mb_substr' ) ) : function mb_substr( $string, $start, $length = null, $encoding = null ) { return _mb_substr( $string, $start, $length, $encoding ); } endif; function _mb_substr( $str, $start, $length = null, $encoding = null ) { if ( null === $str ) { return ''; } if ( ! _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ) { return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); } $total_length = ( $start < 0 || $length < 0 ) ? _wp_utf8_codepoint_count( $str ) : 0; $normalized_start = $start < 0 ? max( 0, $total_length + $start ) : $start; $starting_byte_offset = _wp_utf8_codepoint_span( $str, 0, $normalized_start ); $normalized_length = $length < 0 ? max( 0, $total_length - $normalized_start + $length ) : $length; $byte_length = isset( $normalized_length ) ? _wp_utf8_codepoint_span( $str, $starting_byte_offset, $normalized_length ) : ( strlen( $str ) - $starting_byte_offset ); return substr( $str, $starting_byte_offset, $byte_length ); } if ( ! function_exists( 'mb_strlen' ) ) : function mb_strlen( $string, $encoding = null ) { return _mb_strlen( $string, $encoding ); } endif; function _mb_strlen( $str, $encoding = null ) { return _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ? _wp_utf8_codepoint_count( $str ) : strlen( $str ); } if ( ! function_exists( 'utf8_encode' ) ) : if ( extension_loaded( 'mbstring' ) ) : function utf8_encode( $iso_8859_1_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return mb_convert_encoding( $iso_8859_1_text, 'UTF-8', 'ISO-8859-1' ); } else : function utf8_encode( $iso_8859_1_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return _wp_utf8_encode_fallback( $iso_8859_1_text ); } endif; endif; if ( ! function_exists( 'utf8_decode' ) ) : if ( extension_loaded( 'mbstring' ) ) : function utf8_decode( $utf8_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return mb_convert_encoding( $utf8_text, 'ISO-8859-1', 'UTF-8' ); } else : function utf8_decode( $utf8_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return _wp_utf8_decode_fallback( $utf8_text ); } endif; endif; if ( ! function_exists( 'sodium_crypto_box' ) ) { require ABSPATH . WPINC . '/sodium_compat/autoload.php'; } if ( ! function_exists( 'is_countable' ) ) { function is_countable( $value ) { return ( is_array( $value ) || $value instanceof Countable || $value instanceof SimpleXMLElement || $value instanceof ResourceBundle ); } } if ( ! function_exists( 'array_key_first' ) ) { function array_key_first( array $array ) { if ( empty( $array ) ) { return null; } foreach ( $array as $key => $value ) { return $key; } } } if ( ! function_exists( 'array_key_last' ) ) { function array_key_last( array $array ) { if ( empty( $array ) ) { return null; } end( $array ); return key( $array ); } } if ( ! function_exists( 'array_is_list' ) ) { function array_is_list( $arr ) { if ( ( array() === $arr ) || ( array_values( $arr ) === $arr ) ) { return true; } $next_key = -1; foreach ( $arr as $k => $v ) { if ( ++$next_key !== $k ) { return false; } } return true; } } if ( ! function_exists( 'str_contains' ) ) { function str_contains( $haystack, $needle ) { if ( '' === $needle ) { return true; } return false !== strpos( $haystack, $needle ); } } if ( ! function_exists( 'str_starts_with' ) ) { function str_starts_with( $haystack, $needle ) { if ( '' === $needle ) { return true; } return 0 === strpos( $haystack, $needle ); } } if ( ! function_exists( 'str_ends_with' ) ) { function str_ends_with( $haystack, $needle ) { if ( '' === $haystack ) { return '' === $needle; } $len = strlen( $needle ); return substr( $haystack, -$len, $len ) === $needle; } } if ( ! function_exists( 'array_find' ) ) { function array_find( array $array, callable $callback ) { foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return $value; } } return null; } } if ( ! function_exists( 'array_find_key' ) ) { function array_find_key( array $array, callable $callback ) { foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return $key; } } return null; } } if ( ! function_exists( 'array_any' ) ) { function array_any( array $array, callable $callback ): bool { foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return true; } } return false; } } if ( ! function_exists( 'array_all' ) ) { function array_all( array $array, callable $callback ): bool { foreach ( $array as $key => $value ) { if ( ! $callback( $value, $key ) ) { return false; } } return true; } } if ( ! function_exists( 'array_first' ) ) { function array_first( array $array ) { if ( empty( $array ) ) { return null; } foreach ( $array as $value ) { return $value; } } } if ( ! function_exists( 'array_last' ) ) { function array_last( array $array ) { if ( empty( $array ) ) { return null; } return $array[ array_key_last( $array ) ]; } } if ( ! defined( 'IMAGETYPE_AVIF' ) ) { define( 'IMAGETYPE_AVIF', 19 ); } if ( ! defined( 'IMG_AVIF' ) ) { define( 'IMG_AVIF', IMAGETYPE_AVIF ); } if ( ! defined( 'IMAGETYPE_HEIF' ) ) { define( 'IMAGETYPE_HEIF', 20 ); }
###require ABSPATH . WPINC . '/load.php';
function wp_get_server_protocol() { $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : ''; if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0', 'HTTP/3' ), true ) ) { $protocol = 'HTTP/1.0'; } return $protocol; } function wp_fix_server_vars() { global $PHP_SELF; $default_server_values = array( 'SERVER_SOFTWARE' => '', 'REQUEST_URI' => '', ); $_SERVER = array_merge( $default_server_values, $_SERVER ); if ( empty( $_SERVER['REQUEST_URI'] ) || ( 'cgi-fcgi' !== PHP_SAPI && preg_match( '/^Microsoft-IIS\//', $_SERVER['SERVER_SOFTWARE'] ) ) ) { if ( isset( $_SERVER['HTTP_X_ORIGINAL_URL'] ) ) { $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL']; } elseif ( isset( $_SERVER['HTTP_X_REWRITE_URL'] ) ) { $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL']; } else { if ( ! isset( $_SERVER['PATH_INFO'] ) && isset( $_SERVER['ORIG_PATH_INFO'] ) ) { $_SERVER['PATH_INFO'] = $_SERVER['ORIG_PATH_INFO']; } if ( isset( $_SERVER['PATH_INFO'] ) ) { if ( $_SERVER['PATH_INFO'] === $_SERVER['SCRIPT_NAME'] ) { $_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO']; } else { $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO']; } } if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; } } } if ( isset( $_SERVER['SCRIPT_FILENAME'] ) && str_ends_with( $_SERVER['SCRIPT_FILENAME'], 'php.cgi' ) ) { $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED']; } if ( isset( $_SERVER['SCRIPT_NAME'] ) && str_contains( $_SERVER['SCRIPT_NAME'], 'php.cgi' ) ) { unset( $_SERVER['PATH_INFO'] ); } $PHP_SELF = $_SERVER['PHP_SELF']; if ( empty( $PHP_SELF ) ) { $_SERVER['PHP_SELF'] = preg_replace( '/(\?.*)?$/', '', $_SERVER['REQUEST_URI'] ); $PHP_SELF = $_SERVER['PHP_SELF']; } wp_populate_basic_auth_from_authorization_header(); } function wp_populate_basic_auth_from_authorization_header() { if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) && ! isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) { return; } if ( isset( $_SERVER['PHP_AUTH_USER'] ) || isset( $_SERVER['PHP_AUTH_PW'] ) ) { return; } $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; if ( ! preg_match( '%^Basic [a-z\d/+]*={0,2}$%i', $header ) ) { return; } $token = substr( $header, 6 ); $userpass = base64_decode( $token ); if ( ! str_contains( $userpass, ':' ) ) { return; } list( $user, $pass ) = explode( ':', $userpass, 2 ); $_SERVER['PHP_AUTH_USER'] = $user; $_SERVER['PHP_AUTH_PW'] = $pass; } function wp_check_php_mysql_versions() { global $required_php_version, $required_php_extensions, $wp_version; $php_version = PHP_VERSION; if ( version_compare( $required_php_version, $php_version, '>' ) ) { $protocol = wp_get_server_protocol(); header( sprintf( '%s 500 Internal Server Error', $protocol ), true, 500 ); header( 'Content-Type: text/html; charset=utf-8' ); printf( 'Your server is running PHP version %1$s but WordPress %2$s requires at least %3$s.', $php_version, $wp_version, $required_php_version ); exit( 1 ); } $missing_extensions = array(); if ( isset( $required_php_extensions ) && is_array( $required_php_extensions ) ) { foreach ( $required_php_extensions as $extension ) { if ( extension_loaded( $extension ) ) { continue; } $missing_extensions[] = sprintf( 'WordPress %1$s requires the <code>%2$s</code> PHP extension.', $wp_version, $extension ); } } if ( count( $missing_extensions ) > 0 ) { $protocol = wp_get_server_protocol(); header( sprintf( '%s 500 Internal Server Error', $protocol ), true, 500 ); header( 'Content-Type: text/html; charset=utf-8' ); echo implode( '<br>', $missing_extensions ); exit( 1 ); } $wp_content_dir = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR : ABSPATH . 'wp-content'; if ( ! function_exists( 'mysqli_connect' ) && ! file_exists( $wp_content_dir . '/db.php' ) ) { require_once ABSPATH . WPINC . '/functions.php'; wp_load_translations_early(); $message = '<p>' . __( 'Your PHP installation appears to be missing the MySQL extension which is required by WordPress.' ) . "</p>\n"; $message .= '<p>' . sprintf( __( 'Please check that the %s PHP extension is installed and enabled.' ), '<code>mysqli</code>' ) . "</p>\n"; $message .= '<p>' . sprintf( __( 'If you are unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress support forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ) . "</p>\n"; $args = array( 'exit' => false, 'code' => 'mysql_not_found', ); wp_die( $message, __( 'Requirements Not Met' ), $args ); exit( 1 ); } } function wp_get_environment_type() { static $current_env = ''; if ( ! defined( 'WP_RUN_CORE_TESTS' ) && $current_env ) { return $current_env; } $wp_environments = array( 'local', 'development', 'staging', 'production', ); if ( defined( 'WP_ENVIRONMENT_TYPES' ) && function_exists( '_deprecated_argument' ) ) { if ( function_exists( '__' ) ) { $message = sprintf( __( 'The %s constant is no longer supported.' ), 'WP_ENVIRONMENT_TYPES' ); } else { $message = sprintf( 'The %s constant is no longer supported.', 'WP_ENVIRONMENT_TYPES' ); } _deprecated_argument( 'define()', '5.5.1', $message ); } if ( function_exists( 'getenv' ) ) { $has_env = getenv( 'WP_ENVIRONMENT_TYPE' ); if ( false !== $has_env ) { $current_env = $has_env; } } if ( defined( 'WP_ENVIRONMENT_TYPE' ) && WP_ENVIRONMENT_TYPE ) { $current_env = WP_ENVIRONMENT_TYPE; } if ( ! in_array( $current_env, $wp_environments, true ) ) { $current_env = 'production'; } return $current_env; } function wp_get_development_mode() { static $current_mode = null; if ( ! defined( 'WP_RUN_CORE_TESTS' ) && null !== $current_mode ) { return $current_mode; } $development_mode = WP_DEVELOPMENT_MODE; if ( defined( 'WP_RUN_CORE_TESTS' ) && isset( $GLOBALS['_wp_tests_development_mode'] ) ) { $development_mode = $GLOBALS['_wp_tests_development_mode']; } $valid_modes = array( 'core', 'plugin', 'theme', 'all', '', ); if ( ! in_array( $development_mode, $valid_modes, true ) ) { $development_mode = ''; } $current_mode = $development_mode; return $current_mode; } function wp_is_development_mode( $mode ) { $current_mode = wp_get_development_mode(); if ( empty( $current_mode ) ) { return false; } if ( 'all' === $current_mode ) { return true; } return $mode === $current_mode; } function wp_favicon_request() { if ( '/favicon.ico' === $_SERVER['REQUEST_URI'] ) { header( 'Content-Type: image/vnd.microsoft.icon' ); exit; } } function wp_maintenance() { if ( ! wp_is_maintenance_mode() ) { return; } if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) { require_once WP_CONTENT_DIR . '/maintenance.php'; die(); } require_once ABSPATH . WPINC . '/functions.php'; wp_load_translations_early(); header( 'Retry-After: 600' ); wp_die( __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ), __( 'Maintenance' ), 503 ); } function wp_is_maintenance_mode() { global $upgrading; if ( ! file_exists( ABSPATH . '.maintenance' ) || wp_installing() ) { return false; } require ABSPATH . '.maintenance'; if ( ( time() - $upgrading ) >= 10 * MINUTE_IN_SECONDS ) { return false; } if ( is_int( $upgrading ) && isset( $_REQUEST['wp_scrape_key'], $_REQUEST['wp_scrape_nonce'] ) ) { $key = stripslashes( $_REQUEST['wp_scrape_key'] ); $nonce = stripslashes( $_REQUEST['wp_scrape_nonce'] ); if ( md5( $upgrading ) === $key && (int) $nonce === $upgrading ) { return false; } } if ( ! apply_filters( 'enable_maintenance_mode', true, $upgrading ) ) { return false; } return true; } function timer_float() { return microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT']; } function timer_start() { global $timestart; $timestart = microtime( true ); return true; } function timer_stop( $display = 0, $precision = 3 ) { global $timestart, $timeend; $timeend = microtime( true ); $timetotal = $timeend - $timestart; if ( function_exists( 'number_format_i18n' ) ) { $r = number_format_i18n( $timetotal, $precision ); } else { $r = number_format( $timetotal, $precision ); } if ( $display ) { echo $r; } return $r; } function wp_debug_mode() { if ( ! apply_filters( 'enable_wp_debug_mode_checks', true ) ) { return; } if ( WP_DEBUG ) { error_reporting( E_ALL ); if ( WP_DEBUG_DISPLAY ) { ini_set( 'display_errors', 1 ); } elseif ( null !== WP_DEBUG_DISPLAY ) { ini_set( 'display_errors', 0 ); } if ( in_array( strtolower( (string) WP_DEBUG_LOG ), array( 'true', '1' ), true ) ) { $log_path = WP_CONTENT_DIR . '/debug.log'; } elseif ( is_string( WP_DEBUG_LOG ) ) { $log_path = WP_DEBUG_LOG; } else { $log_path = false; } if ( $log_path ) { ini_set( 'log_errors', 1 ); ini_set( 'error_log', $log_path ); } } else { error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); } if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || defined( 'MS_FILES_REQUEST' ) || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) || wp_doing_ajax() || wp_is_json_request() ) { ini_set( 'display_errors', 0 ); } } function wp_set_lang_dir() { if ( ! defined( 'WP_LANG_DIR' ) ) { if ( file_exists( WP_CONTENT_DIR . '/languages' ) && @is_dir( WP_CONTENT_DIR . '/languages' ) || ! @is_dir( ABSPATH . WPINC . '/languages' ) ) { define( 'WP_LANG_DIR', WP_CONTENT_DIR . '/languages' ); if ( ! defined( 'LANGDIR' ) ) { define( 'LANGDIR', 'wp-content/languages' ); } } else { define( 'WP_LANG_DIR', ABSPATH . WPINC . '/languages' ); if ( ! defined( 'LANGDIR' ) ) { define( 'LANGDIR', WPINC . '/languages' ); } } } } function require_wp_db() { global $wpdb; require_once ABSPATH . WPINC . '/class-wpdb.php'; if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) { require_once WP_CONTENT_DIR . '/db.php'; } if ( isset( $wpdb ) ) { return; } $dbuser = defined( 'DB_USER' ) ? DB_USER : ''; $dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : ''; $dbname = defined( 'DB_NAME' ) ? DB_NAME : ''; $dbhost = defined( 'DB_HOST' ) ? DB_HOST : ''; $wpdb = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost ); } function wp_set_wpdb_vars() { global $wpdb, $table_prefix; if ( ! empty( $wpdb->error ) ) { dead_db(); } $wpdb->field_types = array( 'post_author' => '%d', 'post_parent' => '%d', 'menu_order' => '%d', 'term_id' => '%d', 'term_group' => '%d', 'term_taxonomy_id' => '%d', 'parent' => '%d', 'count' => '%d', 'object_id' => '%d', 'term_order' => '%d', 'ID' => '%d', 'comment_ID' => '%d', 'comment_post_ID' => '%d', 'comment_parent' => '%d', 'user_id' => '%d', 'link_id' => '%d', 'link_owner' => '%d', 'link_rating' => '%d', 'option_id' => '%d', 'blog_id' => '%d', 'meta_id' => '%d', 'post_id' => '%d', 'user_status' => '%d', 'umeta_id' => '%d', 'comment_karma' => '%d', 'comment_count' => '%d', 'active' => '%d', 'cat_id' => '%d', 'deleted' => '%d', 'lang_id' => '%d', 'mature' => '%d', 'public' => '%d', 'site_id' => '%d', 'spam' => '%d', ); $prefix = $wpdb->set_prefix( $table_prefix ); if ( is_wp_error( $prefix ) ) { wp_load_translations_early(); wp_die( sprintf( __( '<strong>Error:</strong> %1$s in %2$s can only contain numbers, letters, and underscores.' ), '<code>$table_prefix</code>', '<code>wp-config.php</code>' ) ); } } function wp_using_ext_object_cache( $using = null ) { global $_wp_using_ext_object_cache; $current_using = $_wp_using_ext_object_cache; if ( null !== $using ) { $_wp_using_ext_object_cache = $using; } return $current_using; } function wp_start_object_cache() { global $wp_filter; static $first_init = true; if ( $first_init && apply_filters( 'enable_loading_object_cache_dropin', true ) ) { if ( ! function_exists( 'wp_cache_init' ) ) { if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { require_once WP_CONTENT_DIR . '/object-cache.php'; if ( function_exists( 'wp_cache_init' ) ) { wp_using_ext_object_cache( true ); } if ( $wp_filter ) { $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter ); } } } elseif ( ! wp_using_ext_object_cache() && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { wp_using_ext_object_cache( true ); } } if ( ! wp_using_ext_object_cache() ) { require_once ABSPATH . WPINC . '/cache.php'; } require_once ABSPATH . WPINC . '/cache-compat.php'; if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) ) { wp_cache_switch_to_blog( get_current_blog_id() ); } elseif ( function_exists( 'wp_cache_init' ) ) { wp_cache_init(); } if ( function_exists( 'wp_cache_add_global_groups' ) ) { wp_cache_add_global_groups( array( 'blog-details', 'blog-id-cache', 'blog-lookup', 'blog_meta', 'global-posts', 'image_editor', 'networks', 'network-queries', 'sites', 'site-details', 'site-options', 'site-queries', 'site-transient', 'theme_files', 'translation_files', 'rss', 'users', 'user-queries', 'user_meta', 'useremail', 'userlogins', 'userslugs', ) ); wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } $first_init = false; } function wp_not_installed() { if ( is_blog_installed() || wp_installing() ) { return; } nocache_headers(); if ( is_multisite() ) { wp_die( __( 'The site you have requested is not installed properly. Please contact the system administrator.' ) ); } require ABSPATH . WPINC . '/kses.php'; require ABSPATH . WPINC . '/pluggable.php'; $link = wp_guess_url() . '/wp-admin/install.php'; wp_redirect( $link ); die(); } function wp_get_mu_plugins() { $mu_plugins = array(); if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { return $mu_plugins; } $dh = opendir( WPMU_PLUGIN_DIR ); if ( ! $dh ) { return $mu_plugins; } while ( ( $plugin = readdir( $dh ) ) !== false ) { if ( str_ends_with( $plugin, '.php' ) ) { $mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin; } } closedir( $dh ); sort( $mu_plugins ); return $mu_plugins; } function wp_get_active_and_valid_plugins() { $plugins = array(); $active_plugins = (array) get_option( 'active_plugins', array() ); if ( get_option( 'hack_file' ) && file_exists( ABSPATH . 'my-hacks.php' ) ) { _deprecated_file( 'my-hacks.php', '1.5.0' ); array_unshift( $plugins, ABSPATH . 'my-hacks.php' ); } if ( empty( $active_plugins ) || wp_installing() ) { return $plugins; } $network_plugins = is_multisite() ? wp_get_active_network_plugins() : false; foreach ( $active_plugins as $plugin ) { if ( ! validate_file( $plugin ) && str_ends_with( $plugin, '.php' ) && file_exists( WP_PLUGIN_DIR . '/' . $plugin ) && ( ! $network_plugins || ! in_array( WP_PLUGIN_DIR . '/' . $plugin, $network_plugins, true ) ) ) { $plugins[] = WP_PLUGIN_DIR . '/' . $plugin; } } if ( wp_is_recovery_mode() ) { $plugins = wp_skip_paused_plugins( $plugins ); } return $plugins; } function wp_skip_paused_plugins( array $plugins ) { $paused_plugins = wp_paused_plugins()->get_all(); if ( empty( $paused_plugins ) ) { return $plugins; } foreach ( $plugins as $index => $plugin ) { list( $plugin ) = explode( '/', plugin_basename( $plugin ) ); if ( array_key_exists( $plugin, $paused_plugins ) ) { unset( $plugins[ $index ] ); $GLOBALS['_paused_plugins'][ $plugin ] = $paused_plugins[ $plugin ]; } } return $plugins; } function wp_get_active_and_valid_themes() { global $pagenow, $wp_stylesheet_path, $wp_template_path; $themes = array(); if ( wp_installing() && 'wp-activate.php' !== $pagenow ) { return $themes; } if ( is_child_theme() ) { $themes[] = $wp_stylesheet_path; } $themes[] = $wp_template_path; if ( wp_is_recovery_mode() ) { $themes = wp_skip_paused_themes( $themes ); if ( empty( $themes ) ) { add_filter( 'wp_using_themes', '__return_false' ); } } return $themes; } function wp_skip_paused_themes( array $themes ) { $paused_themes = wp_paused_themes()->get_all(); if ( empty( $paused_themes ) ) { return $themes; } foreach ( $themes as $index => $theme ) { $theme = basename( $theme ); if ( array_key_exists( $theme, $paused_themes ) ) { unset( $themes[ $index ] ); $GLOBALS['_paused_themes'][ $theme ] = $paused_themes[ $theme ]; } } return $themes; } function wp_is_recovery_mode() { return wp_recovery_mode()->is_active(); } function is_protected_endpoint() { if ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) { return true; } if ( is_admin() && ! wp_doing_ajax() ) { return true; } if ( is_protected_ajax_action() ) { return true; } return (bool) apply_filters( 'is_protected_endpoint', false ); } function is_protected_ajax_action() { if ( ! wp_doing_ajax() ) { return false; } if ( ! isset( $_REQUEST['action'] ) ) { return false; } $actions_to_protect = array( 'edit-theme-plugin-file', 'heartbeat', 'install-plugin', 'install-theme', 'search-plugins', 'search-install-plugins', 'update-plugin', 'update-theme', 'activate-plugin', ); $actions_to_protect = (array) apply_filters( 'wp_protected_ajax_actions', $actions_to_protect ); if ( ! in_array( $_REQUEST['action'], $actions_to_protect, true ) ) { return false; } return true; } function wp_set_internal_encoding() { if ( function_exists( 'mb_internal_encoding' ) ) { $charset = get_option( 'blog_charset' ); if ( ! $charset || ! @mb_internal_encoding( $charset ) ) { mb_internal_encoding( 'UTF-8' ); } } } function wp_magic_quotes() { $_GET = add_magic_quotes( $_GET ); $_POST = add_magic_quotes( $_POST ); $_COOKIE = add_magic_quotes( $_COOKIE ); $_SERVER = add_magic_quotes( $_SERVER ); $_REQUEST = array_merge( $_GET, $_POST ); } function shutdown_action_hook() { do_action( 'shutdown' ); wp_cache_close(); } function wp_clone( $input_object ) { return clone( $input_object ); } function is_login() { return false !== stripos( wp_login_url(), $_SERVER['SCRIPT_NAME'] ); } function is_admin() { if ( isset( $GLOBALS['current_screen'] ) ) { return $GLOBALS['current_screen']->in_admin(); } elseif ( defined( 'WP_ADMIN' ) ) { return WP_ADMIN; } return false; } function is_blog_admin() { if ( isset( $GLOBALS['current_screen'] ) ) { return $GLOBALS['current_screen']->in_admin( 'site' ); } elseif ( defined( 'WP_BLOG_ADMIN' ) ) { return WP_BLOG_ADMIN; } return false; } function is_network_admin() { if ( isset( $GLOBALS['current_screen'] ) ) { return $GLOBALS['current_screen']->in_admin( 'network' ); } elseif ( defined( 'WP_NETWORK_ADMIN' ) ) { return WP_NETWORK_ADMIN; } return false; } function is_user_admin() { if ( isset( $GLOBALS['current_screen'] ) ) { return $GLOBALS['current_screen']->in_admin( 'user' ); } elseif ( defined( 'WP_USER_ADMIN' ) ) { return WP_USER_ADMIN; } return false; } function is_multisite() { if ( defined( 'MULTISITE' ) ) { return MULTISITE; } if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) ) { return true; } return false; } function absint( $maybeint ) { return abs( (int) $maybeint ); } function get_current_blog_id() { global $blog_id; return absint( $blog_id ); } function get_current_network_id() { if ( ! is_multisite() ) { return 1; } $current_network = get_network(); if ( ! isset( $current_network->id ) ) { return get_main_network_id(); } return absint( $current_network->id ); } function wp_load_translations_early() { global $wp_textdomain_registry, $wp_locale; static $loaded = false; if ( $loaded ) { return; } $loaded = true; if ( function_exists( 'did_action' ) && did_action( 'init' ) ) { return; } require ABSPATH . WPINC . '/version.php'; require_once ABSPATH . WPINC . '/pomo/mo.php'; require_once ABSPATH . WPINC . '/l10n/class-wp-translation-controller.php'; require_once ABSPATH . WPINC . '/l10n/class-wp-translations.php'; require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file.php'; require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file-mo.php'; require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file-php.php'; require_once ABSPATH . WPINC . '/l10n.php'; require_once ABSPATH . WPINC . '/class-wp-textdomain-registry.php'; require_once ABSPATH . WPINC . '/class-wp-locale.php'; require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php'; require_once ABSPATH . WPINC . '/plugin.php'; $locales = array(); $locations = array(); if ( ! $wp_textdomain_registry instanceof WP_Textdomain_Registry ) { $wp_textdomain_registry = new WP_Textdomain_Registry(); } while ( true ) { if ( defined( 'WPLANG' ) ) { if ( '' === WPLANG ) { break; } $locales[] = WPLANG; } if ( isset( $wp_local_package ) ) { $locales[] = $wp_local_package; } if ( ! $locales ) { break; } if ( defined( 'WP_LANG_DIR' ) && @is_dir( WP_LANG_DIR ) ) { $locations[] = WP_LANG_DIR; } if ( defined( 'WP_CONTENT_DIR' ) && @is_dir( WP_CONTENT_DIR . '/languages' ) ) { $locations[] = WP_CONTENT_DIR . '/languages'; } if ( @is_dir( ABSPATH . 'wp-content/languages' ) ) { $locations[] = ABSPATH . 'wp-content/languages'; } if ( @is_dir( ABSPATH . WPINC . '/languages' ) ) { $locations[] = ABSPATH . WPINC . '/languages'; } if ( ! $locations ) { break; } $locations = array_unique( $locations ); foreach ( $locales as $locale ) { foreach ( $locations as $location ) { if ( file_exists( $location . '/' . $locale . '.mo' ) ) { load_textdomain( 'default', $location . '/' . $locale . '.mo', $locale ); if ( defined( 'WP_SETUP_CONFIG' ) && file_exists( $location . '/admin-' . $locale . '.mo' ) ) { load_textdomain( 'default', $location . '/admin-' . $locale . '.mo', $locale ); } break 2; } } } break; } $wp_locale = new WP_Locale(); } function wp_installing( $is_installing = null ) { static $installing = null; if ( is_null( $installing ) ) { $installing = defined( 'WP_INSTALLING' ) && WP_INSTALLING; } if ( ! is_null( $is_installing ) ) { $old_installing = $installing; $installing = $is_installing; return (bool) $old_installing; } return (bool) $installing; } function is_ssl() { if ( isset( $_SERVER['HTTPS'] ) ) { if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) { return true; } if ( '1' === (string) $_SERVER['HTTPS'] ) { return true; } } elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) { return true; } return false; } function wp_convert_hr_to_bytes( $value ) { $value = strtolower( trim( $value ) ); $bytes = (int) $value; if ( str_contains( $value, 'g' ) ) { $bytes *= GB_IN_BYTES; } elseif ( str_contains( $value, 'm' ) ) { $bytes *= MB_IN_BYTES; } elseif ( str_contains( $value, 'k' ) ) { $bytes *= KB_IN_BYTES; } return min( $bytes, PHP_INT_MAX ); } function wp_is_ini_value_changeable( $setting ) { static $ini_all; if ( ! isset( $ini_all ) ) { $ini_all = false; if ( function_exists( 'ini_get_all' ) ) { $ini_all = ini_get_all(); } } if ( isset( $ini_all[ $setting ]['access'] ) && ( INI_ALL === $ini_all[ $setting ]['access'] || INI_USER === $ini_all[ $setting ]['access'] ) ) { return true; } if ( ! is_array( $ini_all ) ) { return true; } return false; } function wp_doing_ajax() { return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX ); } function wp_using_themes() { return apply_filters( 'wp_using_themes', defined( 'WP_USE_THEMES' ) && WP_USE_THEMES ); } function wp_doing_cron() { return apply_filters( 'wp_doing_cron', defined( 'DOING_CRON' ) && DOING_CRON ); } function is_wp_error( $thing ) { $is_wp_error = ( $thing instanceof WP_Error ); if ( $is_wp_error ) { do_action( 'is_wp_error_instance', $thing ); } return $is_wp_error; } function wp_is_file_mod_allowed( $context ) { return apply_filters( 'file_mod_allowed', ! defined( 'DISALLOW_FILE_MODS' ) || ! DISALLOW_FILE_MODS, $context ); } function wp_start_scraping_edited_file_errors() { if ( ! isset( $_REQUEST['wp_scrape_key'] ) || ! isset( $_REQUEST['wp_scrape_nonce'] ) ) { return; } $key = substr( sanitize_key( wp_unslash( $_REQUEST['wp_scrape_key'] ) ), 0, 32 ); $nonce = wp_unslash( $_REQUEST['wp_scrape_nonce'] ); if ( empty( $key ) || empty( $nonce ) ) { return; } $transient = get_transient( 'scrape_key_' . $key ); if ( false === $transient ) { return; } if ( $transient !== $nonce ) { if ( ! headers_sent() ) { header( 'X-Robots-Tag: noindex' ); nocache_headers(); } echo "###### wp_scraping_result_start:$key ######"; echo wp_json_encode( array( 'code' => 'scrape_nonce_failure', 'message' => __( 'Scrape key check failed. Please try again.' ), ) ); echo "###### wp_scraping_result_end:$key ######"; die(); } if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) { define( 'WP_SANDBOX_SCRAPING', true ); } register_shutdown_function( 'wp_finalize_scraping_edited_file_errors', $key ); } function wp_finalize_scraping_edited_file_errors( $scrape_key ) { $error = error_get_last(); echo "\n###### wp_scraping_result_start:$scrape_key ######\n"; if ( ! empty( $error ) && in_array( $error['type'], array( E_CORE_ERROR, E_COMPILE_ERROR, E_ERROR, E_PARSE, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) { $error = str_replace( ABSPATH, '', $error ); echo wp_json_encode( $error ); } else { echo wp_json_encode( true ); } echo "\n###### wp_scraping_result_end:$scrape_key ######\n"; } function wp_is_json_request() { if ( isset( $_SERVER['HTTP_ACCEPT'] ) && wp_is_json_media_type( $_SERVER['HTTP_ACCEPT'] ) ) { return true; } if ( isset( $_SERVER['CONTENT_TYPE'] ) && wp_is_json_media_type( $_SERVER['CONTENT_TYPE'] ) ) { return true; } return false; } function wp_is_jsonp_request() { if ( ! isset( $_GET['_jsonp'] ) ) { return false; } if ( ! function_exists( 'wp_check_jsonp_callback' ) ) { require_once ABSPATH . WPINC . '/functions.php'; } $jsonp_callback = $_GET['_jsonp']; if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { return false; } $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true ); return $jsonp_enabled; } function wp_is_json_media_type( $media_type ) { static $cache = array(); if ( ! isset( $cache[ $media_type ] ) ) { $cache[ $media_type ] = (bool) preg_match( '/(^|\s|,)application\/([\w!#\$&-\^\.\+]+\+)?json(\+oembed)?($|\s|;|,)/i', $media_type ); } return $cache[ $media_type ]; } function wp_is_xml_request() { $accepted = array( 'text/xml', 'application/rss+xml', 'application/atom+xml', 'application/rdf+xml', 'text/xml+oembed', 'application/xml+oembed', ); if ( isset( $_SERVER['HTTP_ACCEPT'] ) ) { foreach ( $accepted as $type ) { if ( str_contains( $_SERVER['HTTP_ACCEPT'], $type ) ) { return true; } } } if ( isset( $_SERVER['CONTENT_TYPE'] ) && in_array( $_SERVER['CONTENT_TYPE'], $accepted, true ) ) { return true; } return false; } function wp_is_site_protected_by_basic_auth( $context = '' ) { global $pagenow; if ( ! $context ) { if ( 'wp-login.php' === $pagenow ) { $context = 'login'; } elseif ( is_admin() ) { $context = 'admin'; } else { $context = 'front'; } } $is_protected = ! empty( $_SERVER['PHP_AUTH_USER'] ) || ! empty( $_SERVER['PHP_AUTH_PW'] ); return apply_filters( 'wp_is_site_protected_by_basic_auth', $is_protected, $context ); }
wp_check_php_mysql_versions();
###require ABSPATH . WPINC . '/class-wp-paused-extensions-storage.php';
class WP_Paused_Extensions_Storage { protected $type; public function __construct( $extension_type ) { $this->type = $extension_type; } public function set( $extension, $error ) { if ( ! $this->is_api_loaded() ) { return false; } $option_name = $this->get_option_name(); if ( ! $option_name ) { return false; } $paused_extensions = (array) get_option( $option_name, array() ); if ( isset( $paused_extensions[ $this->type ][ $extension ] ) && $paused_extensions[ $this->type ][ $extension ] === $error ) { return true; } $paused_extensions[ $this->type ][ $extension ] = $error; return update_option( $option_name, $paused_extensions, false ); } public function delete( $extension ) { if ( ! $this->is_api_loaded() ) { return false; } $option_name = $this->get_option_name(); if ( ! $option_name ) { return false; } $paused_extensions = (array) get_option( $option_name, array() ); if ( ! isset( $paused_extensions[ $this->type ][ $extension ] ) ) { return true; } unset( $paused_extensions[ $this->type ][ $extension ] ); if ( empty( $paused_extensions[ $this->type ] ) ) { unset( $paused_extensions[ $this->type ] ); } if ( ! $paused_extensions ) { return delete_option( $option_name ); } return update_option( $option_name, $paused_extensions, false ); } public function get( $extension ) { if ( ! $this->is_api_loaded() ) { return null; } $paused_extensions = $this->get_all(); if ( ! isset( $paused_extensions[ $extension ] ) ) { return null; } return $paused_extensions[ $extension ]; } public function get_all() { if ( ! $this->is_api_loaded() ) { return array(); } $option_name = $this->get_option_name(); if ( ! $option_name ) { return array(); } $paused_extensions = (array) get_option( $option_name, array() ); return isset( $paused_extensions[ $this->type ] ) ? $paused_extensions[ $this->type ] : array(); } public function delete_all() { if ( ! $this->is_api_loaded() ) { return false; } $option_name = $this->get_option_name(); if ( ! $option_name ) { return false; } $paused_extensions = (array) get_option( $option_name, array() ); unset( $paused_extensions[ $this->type ] ); if ( ! $paused_extensions ) { return delete_option( $option_name ); } return update_option( $option_name, $paused_extensions, false ); } protected function is_api_loaded() { return function_exists( 'get_option' ); } protected function get_option_name() { if ( ! wp_recovery_mode()->is_active() ) { return ''; } $session_id = wp_recovery_mode()->get_session_id(); if ( empty( $session_id ) ) { return ''; } return "{$session_id}_paused_extensions"; } }
###require ABSPATH . WPINC . '/class-wp-exception.php';
class WP_Exception extends Exception {}
###require ABSPATH . WPINC . '/class-wp-fatal-error-handler.php';
class WP_Fatal_Error_Handler { public function handle() { if ( defined( 'WP_SANDBOX_SCRAPING' ) && WP_SANDBOX_SCRAPING ) { return; } if ( wp_is_maintenance_mode() ) { return; } try { $error = $this->detect_error(); if ( ! $error ) { return; } if ( ! isset( $GLOBALS['wp_locale'] ) && function_exists( 'load_default_textdomain' ) ) { load_default_textdomain(); } $handled = false; if ( ! is_multisite() && wp_recovery_mode()->is_initialized() ) { $handled = wp_recovery_mode()->handle_error( $error ); } if ( is_admin() || ! headers_sent() ) { $this->display_error_template( $error, $handled ); } } catch ( Exception $e ) { } } protected function detect_error() { $error = error_get_last(); if ( null === $error ) { return null; } if ( ! $this->should_handle_error( $error ) ) { return null; } return $error; } protected function should_handle_error( $error ) { $error_types_to_handle = array( E_ERROR, E_PARSE, E_USER_ERROR, E_COMPILE_ERROR, E_RECOVERABLE_ERROR, ); if ( isset( $error['type'] ) && in_array( $error['type'], $error_types_to_handle, true ) ) { return true; } return (bool) apply_filters( 'wp_should_handle_php_error', false, $error ); } protected function display_error_template( $error, $handled ) { if ( defined( 'WP_CONTENT_DIR' ) ) { $php_error_pluggable = WP_CONTENT_DIR . '/php-error.php'; if ( is_readable( $php_error_pluggable ) ) { require_once $php_error_pluggable; return; } } $this->display_default_error_template( $error, $handled ); } protected function display_default_error_template( $error, $handled ) { if ( ! function_exists( '__' ) ) { wp_load_translations_early(); } if ( ! function_exists( 'wp_die' ) ) { require_once ABSPATH . WPINC . '/functions.php'; } if ( ! class_exists( 'WP_Error' ) ) { require_once ABSPATH . WPINC . '/class-wp-error.php'; } if ( true === $handled && wp_is_recovery_mode() ) { $message = __( 'There has been a critical error on this website, putting it in recovery mode. Please check the Themes and Plugins screens for more details. If you just installed or updated a theme or plugin, check the relevant page for that first.' ); } elseif ( is_protected_endpoint() && wp_recovery_mode()->is_initialized() ) { if ( is_multisite() ) { $message = __( 'There has been a critical error on this website. Please reach out to your site administrator, and inform them of this error for further assistance.' ); } else { $message = sprintf( __( 'There has been a critical error on this website. Please check your site admin email inbox for instructions. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ); } } else { $message = __( 'There has been a critical error on this website.' ); } $message = sprintf( '<p>%s</p><p><a href="%s">%s</a></p>', $message, __( 'https://wordpress.org/documentation/article/faq-troubleshooting/' ), __( 'Learn more about troubleshooting WordPress.' ) ); $args = array( 'response' => 500, 'exit' => false, ); $message = apply_filters( 'wp_php_error_message', $message, $error ); $args = apply_filters( 'wp_php_error_args', $args, $error ); $wp_error = new WP_Error( 'internal_server_error', $message, array( 'error' => $error, ) ); wp_die( $wp_error, '', $args ); } }
###require ABSPATH . WPINC . '/class-wp-recovery-mode-cookie-service.php';
final class WP_Recovery_Mode_Cookie_Service { public function is_cookie_set() { return ! empty( $_COOKIE[ RECOVERY_MODE_COOKIE ] ); } public function set_cookie() { $value = $this->generate_cookie(); $length = apply_filters( 'recovery_mode_cookie_length', WEEK_IN_SECONDS ); $expire = time() + $length; setcookie( RECOVERY_MODE_COOKIE, $value, $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true ); if ( COOKIEPATH !== SITECOOKIEPATH ) { setcookie( RECOVERY_MODE_COOKIE, $value, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, is_ssl(), true ); } } public function clear_cookie() { setcookie( RECOVERY_MODE_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); setcookie( RECOVERY_MODE_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); } public function validate_cookie( $cookie = '' ) { if ( ! $cookie ) { if ( empty( $_COOKIE[ RECOVERY_MODE_COOKIE ] ) ) { return new WP_Error( 'no_cookie', __( 'No cookie present.' ) ); } $cookie = $_COOKIE[ RECOVERY_MODE_COOKIE ]; } $parts = $this->parse_cookie( $cookie ); if ( is_wp_error( $parts ) ) { return $parts; } list( , $created_at, $random, $signature ) = $parts; if ( ! ctype_digit( $created_at ) ) { return new WP_Error( 'invalid_created_at', __( 'Invalid cookie format.' ) ); } $length = apply_filters( 'recovery_mode_cookie_length', WEEK_IN_SECONDS ); if ( time() > $created_at + $length ) { return new WP_Error( 'expired', __( 'Cookie expired.' ) ); } $to_sign = sprintf( 'recovery_mode|%s|%s', $created_at, $random ); $hashed = $this->recovery_mode_hash( $to_sign ); if ( ! hash_equals( $signature, $hashed ) ) { return new WP_Error( 'signature_mismatch', __( 'Invalid cookie.' ) ); } return true; } public function get_session_id_from_cookie( $cookie = '' ) { if ( ! $cookie ) { if ( empty( $_COOKIE[ RECOVERY_MODE_COOKIE ] ) ) { return new WP_Error( 'no_cookie', __( 'No cookie present.' ) ); } $cookie = $_COOKIE[ RECOVERY_MODE_COOKIE ]; } $parts = $this->parse_cookie( $cookie ); if ( is_wp_error( $parts ) ) { return $parts; } list( , , $random ) = $parts; return sha1( $random ); } private function parse_cookie( $cookie ) { $cookie = base64_decode( $cookie ); $parts = explode( '|', $cookie ); if ( 4 !== count( $parts ) ) { return new WP_Error( 'invalid_format', __( 'Invalid cookie format.' ) ); } return $parts; } private function generate_cookie() { $to_sign = sprintf( 'recovery_mode|%s|%s', time(), wp_generate_password( 20, false ) ); $signed = $this->recovery_mode_hash( $to_sign ); return base64_encode( sprintf( '%s|%s', $to_sign, $signed ) ); } private function recovery_mode_hash( $data ) { $default_keys = array_unique( array( 'put your unique phrase here', __( 'put your unique phrase here' ), ) ); if ( ! defined( 'AUTH_KEY' ) || in_array( AUTH_KEY, $default_keys, true ) ) { $auth_key = get_site_option( 'recovery_mode_auth_key' ); if ( ! $auth_key ) { if ( ! function_exists( 'wp_generate_password' ) ) { require_once ABSPATH . WPINC . '/pluggable.php'; } $auth_key = wp_generate_password( 64, true, true ); update_site_option( 'recovery_mode_auth_key', $auth_key ); } } else { $auth_key = AUTH_KEY; } if ( ! defined( 'AUTH_SALT' ) || in_array( AUTH_SALT, $default_keys, true ) || AUTH_SALT === $auth_key ) { $auth_salt = get_site_option( 'recovery_mode_auth_salt' ); if ( ! $auth_salt ) { if ( ! function_exists( 'wp_generate_password' ) ) { require_once ABSPATH . WPINC . '/pluggable.php'; } $auth_salt = wp_generate_password( 64, true, true ); update_site_option( 'recovery_mode_auth_salt', $auth_salt ); } } else { $auth_salt = AUTH_SALT; } $secret = $auth_key . $auth_salt; return hash_hmac( 'sha1', $data, $secret ); } }
###require ABSPATH . WPINC . '/class-wp-recovery-mode-key-service.php';
final class WP_Recovery_Mode_Key_Service { private $option_name = 'recovery_keys'; public function generate_recovery_mode_token() { return wp_generate_password( 22, false ); } public function generate_and_store_recovery_mode_key( $token ) { $key = wp_generate_password( 22, false ); $records = $this->get_keys(); $records[ $token ] = array( 'hashed_key' => wp_fast_hash( $key ), 'created_at' => time(), ); $this->update_keys( $records ); do_action( 'generate_recovery_mode_key', $token, $key ); return $key; } public function validate_recovery_mode_key( $token, $key, $ttl ) { $records = $this->get_keys(); if ( ! isset( $records[ $token ] ) ) { return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) ); } $record = $records[ $token ]; $this->remove_key( $token ); if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) { return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) ); } if ( ! wp_verify_fast_hash( $key, $record['hashed_key'] ) ) { return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) ); } if ( time() > $record['created_at'] + $ttl ) { return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) ); } return true; } public function clean_expired_keys( $ttl ) { $records = $this->get_keys(); foreach ( $records as $key => $record ) { if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) { unset( $records[ $key ] ); } } $this->update_keys( $records ); } private function remove_key( $token ) { $records = $this->get_keys(); if ( ! isset( $records[ $token ] ) ) { return; } unset( $records[ $token ] ); $this->update_keys( $records ); } private function get_keys() { return (array) get_option( $this->option_name, array() ); } private function update_keys( array $keys ) { return update_option( $this->option_name, $keys, false ); } }
###require ABSPATH . WPINC . '/class-wp-recovery-mode-link-service.php';
class WP_Recovery_Mode_Link_Service { const LOGIN_ACTION_ENTER = 'enter_recovery_mode'; const LOGIN_ACTION_ENTERED = 'entered_recovery_mode'; private $key_service; private $cookie_service; public function __construct( WP_Recovery_Mode_Cookie_Service $cookie_service, WP_Recovery_Mode_Key_Service $key_service ) { $this->cookie_service = $cookie_service; $this->key_service = $key_service; } public function generate_url() { $token = $this->key_service->generate_recovery_mode_token(); $key = $this->key_service->generate_and_store_recovery_mode_key( $token ); return $this->get_recovery_mode_begin_url( $token, $key ); } public function handle_begin_link( $ttl ) { if ( ! isset( $GLOBALS['pagenow'] ) || 'wp-login.php' !== $GLOBALS['pagenow'] ) { return; } if ( ! isset( $_GET['action'], $_GET['rm_token'], $_GET['rm_key'] ) || self::LOGIN_ACTION_ENTER !== $_GET['action'] ) { return; } if ( ! function_exists( 'wp_generate_password' ) ) { require_once ABSPATH . WPINC . '/pluggable.php'; } $validated = $this->key_service->validate_recovery_mode_key( $_GET['rm_token'], $_GET['rm_key'], $ttl ); if ( is_wp_error( $validated ) ) { wp_die( $validated, '' ); } $this->cookie_service->set_cookie(); $url = add_query_arg( 'action', self::LOGIN_ACTION_ENTERED, wp_login_url() ); wp_redirect( $url ); die; } private function get_recovery_mode_begin_url( $token, $key ) { $url = add_query_arg( array( 'action' => self::LOGIN_ACTION_ENTER, 'rm_token' => $token, 'rm_key' => $key, ), wp_login_url() ); return apply_filters( 'recovery_mode_begin_url', $url, $token, $key ); } }
###require ABSPATH . WPINC . '/class-wp-recovery-mode-email-service.php';
final class WP_Recovery_Mode_Email_Service { const RATE_LIMIT_OPTION = 'recovery_mode_email_last_sent'; private $link_service; public function __construct( WP_Recovery_Mode_Link_Service $link_service ) { $this->link_service = $link_service; } public function maybe_send_recovery_mode_email( $rate_limit, $error, $extension ) { $last_sent = get_option( self::RATE_LIMIT_OPTION ); if ( ! $last_sent || time() > $last_sent + $rate_limit ) { if ( ! update_option( self::RATE_LIMIT_OPTION, time() ) ) { return new WP_Error( 'storage_error', __( 'Could not update the email last sent time.' ) ); } $sent = $this->send_recovery_mode_email( $rate_limit, $error, $extension ); if ( $sent ) { return true; } return new WP_Error( 'email_failed', sprintf( __( 'The email could not be sent. Possible reason: your host may have disabled the %s function.' ), 'mail()' ) ); } $err_message = sprintf( __( 'A recovery link was already sent %1$s ago. Please wait another %2$s before requesting a new email.' ), human_time_diff( $last_sent ), human_time_diff( $last_sent + $rate_limit ) ); return new WP_Error( 'email_sent_already', $err_message ); } public function clear_rate_limit() { return delete_option( self::RATE_LIMIT_OPTION ); } private function send_recovery_mode_email( $rate_limit, $error, $extension ) { $url = $this->link_service->generate_url(); $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $switched_locale = switch_to_locale( get_locale() ); if ( $extension ) { $cause = $this->get_cause( $extension ); $details = wp_strip_all_tags( wp_get_extension_error_description( $error ) ); if ( $details ) { $header = __( 'Error Details' ); $details = "\n\n" . $header . "\n" . str_pad( '', strlen( $header ), '=' ) . "\n" . $details; } } else { $cause = ''; $details = ''; } $support = apply_filters( 'recovery_email_support_info', __( 'Please contact your host for assistance with investigating this issue further.' ) ); $debug = apply_filters( 'recovery_email_debug_info', $this->get_debug( $extension ) ); $message = __( 'Howdy!
WordPress has a built-in feature that detects when a plugin or theme causes a fatal error on your site, and notifies you with this automated email.
###CAUSE###
First, visit your website (###SITEURL###) and check for any visible issues. Next, visit the page where the error was caught (###PAGEURL###) and check for any visible issues.
###SUPPORT###
If your site appears broken and you can\'t access your dashboard normally, WordPress now has a special "recovery mode". This lets you safely login to your dashboard and investigate further.
###LINK###
To keep your site safe, this link will expire in ###EXPIRES###. Don\'t worry about that, though: a new link will be emailed to you if the error occurs again after it expires.
When seeking help with this issue, you may be asked for some of the following information:
###DEBUG###
###DETAILS###' ); $message = str_replace( array( '###LINK###', '###EXPIRES###', '###CAUSE###', '###DETAILS###', '###SITEURL###', '###PAGEURL###', '###SUPPORT###', '###DEBUG###', ), array( $url, human_time_diff( time() + $rate_limit ), $cause ? "\n{$cause}\n" : "\n", $details, home_url( '/' ), home_url( $_SERVER['REQUEST_URI'] ), $support, implode( "\r\n", $debug ), ), $message ); $email = array( 'to' => $this->get_recovery_mode_email_address(), 'subject' => __( '[%s] Your Site is Experiencing a Technical Issue' ), 'message' => $message, 'headers' => '', 'attachments' => '', ); $email = apply_filters( 'recovery_mode_email', $email, $url ); $sent = wp_mail( $email['to'], wp_specialchars_decode( sprintf( $email['subject'], $blogname ) ), $email['message'], $email['headers'], $email['attachments'] ); if ( $switched_locale ) { restore_previous_locale(); } return $sent; } private function get_recovery_mode_email_address() { if ( defined( 'RECOVERY_MODE_EMAIL' ) && is_email( RECOVERY_MODE_EMAIL ) ) { return RECOVERY_MODE_EMAIL; } return get_option( 'admin_email' ); } private function get_cause( $extension ) { if ( 'plugin' === $extension['type'] ) { $plugin = $this->get_plugin( $extension ); if ( false === $plugin ) { $name = $extension['slug']; } else { $name = $plugin['Name']; } $cause = sprintf( __( 'In this case, WordPress caught an error with one of your plugins, %s.' ), $name ); } else { $theme = wp_get_theme( $extension['slug'] ); $name = $theme->exists() ? $theme->display( 'Name' ) : $extension['slug']; $cause = sprintf( __( 'In this case, WordPress caught an error with your theme, %s.' ), $name ); } return $cause; } private function get_plugin( $extension ) { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $plugins = get_plugins(); if ( isset( $plugins[ "{$extension['slug']}/{$extension['slug']}.php" ] ) ) { return $plugins[ "{$extension['slug']}/{$extension['slug']}.php" ]; } else { foreach ( $plugins as $file => $plugin_data ) { if ( str_starts_with( $file, "{$extension['slug']}/" ) || $file === $extension['slug'] ) { return $plugin_data; } } } return false; } private function get_debug( $extension ) { $theme = wp_get_theme(); $wp_version = get_bloginfo( 'version' ); if ( $extension ) { $plugin = $this->get_plugin( $extension ); } else { $plugin = null; } $debug = array( 'wp' => sprintf( __( 'WordPress version %s' ), $wp_version ), 'theme' => sprintf( __( 'Active theme: %1$s (version %2$s)' ), $theme->get( 'Name' ), $theme->get( 'Version' ) ), ); if ( null !== $plugin ) { $debug['plugin'] = sprintf( __( 'Current plugin: %1$s (version %2$s)' ), $plugin['Name'], $plugin['Version'] ); } $debug['php'] = sprintf( __( 'PHP version %s' ), PHP_VERSION ); return $debug; } }
###require ABSPATH . WPINC . '/class-wp-recovery-mode.php';
class WP_Recovery_Mode { const EXIT_ACTION = 'exit_recovery_mode'; private $cookie_service; private $key_service; private $link_service; private $email_service; private $is_initialized = false; private $is_active = false; private $session_id = ''; public function __construct() { $this->cookie_service = new WP_Recovery_Mode_Cookie_Service(); $this->key_service = new WP_Recovery_Mode_Key_Service(); $this->link_service = new WP_Recovery_Mode_Link_Service( $this->cookie_service, $this->key_service ); $this->email_service = new WP_Recovery_Mode_Email_Service( $this->link_service ); } public function initialize() { $this->is_initialized = true; add_action( 'wp_logout', array( $this, 'exit_recovery_mode' ) ); add_action( 'login_form_' . self::EXIT_ACTION, array( $this, 'handle_exit_recovery_mode' ) ); add_action( 'recovery_mode_clean_expired_keys', array( $this, 'clean_expired_keys' ) ); if ( ! wp_next_scheduled( 'recovery_mode_clean_expired_keys' ) && ! wp_installing() ) { wp_schedule_event( time(), 'daily', 'recovery_mode_clean_expired_keys' ); } if ( defined( 'WP_RECOVERY_MODE_SESSION_ID' ) ) { $this->is_active = true; $this->session_id = WP_RECOVERY_MODE_SESSION_ID; return; } if ( $this->cookie_service->is_cookie_set() ) { $this->handle_cookie(); return; } $this->link_service->handle_begin_link( $this->get_link_ttl() ); } public function is_active() { return $this->is_active; } public function get_session_id() { return $this->session_id; } public function is_initialized() { return $this->is_initialized; } public function handle_error( array $error ) { $extension = $this->get_extension_for_error( $error ); if ( ! $extension || $this->is_network_plugin( $extension ) ) { return new WP_Error( 'invalid_source', __( 'Error not caused by a plugin or theme.' ) ); } if ( ! $this->is_active() ) { if ( ! is_protected_endpoint() ) { return new WP_Error( 'non_protected_endpoint', __( 'Error occurred on a non-protected endpoint.' ) ); } if ( ! function_exists( 'wp_generate_password' ) ) { require_once ABSPATH . WPINC . '/pluggable.php'; } return $this->email_service->maybe_send_recovery_mode_email( $this->get_email_rate_limit(), $error, $extension ); } if ( ! $this->store_error( $error ) ) { return new WP_Error( 'storage_error', __( 'Failed to store the error.' ) ); } if ( headers_sent() ) { return true; } $this->redirect_protected(); } public function exit_recovery_mode() { if ( ! $this->is_active() ) { return false; } $this->email_service->clear_rate_limit(); $this->cookie_service->clear_cookie(); wp_paused_plugins()->delete_all(); wp_paused_themes()->delete_all(); return true; } public function handle_exit_recovery_mode() { $redirect_to = wp_get_referer(); if ( ! $redirect_to ) { $redirect_to = is_user_logged_in() ? admin_url() : home_url(); } if ( ! $this->is_active() ) { wp_safe_redirect( $redirect_to ); die; } if ( ! isset( $_GET['action'] ) || self::EXIT_ACTION !== $_GET['action'] ) { return; } if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], self::EXIT_ACTION ) ) { wp_die( __( 'Exit recovery mode link expired.' ), 403 ); } if ( ! $this->exit_recovery_mode() ) { wp_die( __( 'Failed to exit recovery mode. Please try again later.' ) ); } wp_safe_redirect( $redirect_to ); die; } public function clean_expired_keys() { $this->key_service->clean_expired_keys( $this->get_link_ttl() ); } protected function handle_cookie() { $validated = $this->cookie_service->validate_cookie(); if ( is_wp_error( $validated ) ) { $this->cookie_service->clear_cookie(); $validated->add_data( array( 'status' => 403 ) ); wp_die( $validated ); } $session_id = $this->cookie_service->get_session_id_from_cookie(); if ( is_wp_error( $session_id ) ) { $this->cookie_service->clear_cookie(); $session_id->add_data( array( 'status' => 403 ) ); wp_die( $session_id ); } $this->is_active = true; $this->session_id = $session_id; } protected function get_email_rate_limit() { return apply_filters( 'recovery_mode_email_rate_limit', DAY_IN_SECONDS ); } protected function get_link_ttl() { $rate_limit = $this->get_email_rate_limit(); $valid_for = $rate_limit; $valid_for = apply_filters( 'recovery_mode_email_link_ttl', $valid_for ); return max( $valid_for, $rate_limit ); } protected function get_extension_for_error( $error ) { global $wp_theme_directories; if ( ! isset( $error['file'] ) ) { return false; } if ( ! defined( 'WP_PLUGIN_DIR' ) ) { return false; } $error_file = wp_normalize_path( $error['file'] ); $wp_plugin_dir = wp_normalize_path( WP_PLUGIN_DIR ); if ( str_starts_with( $error_file, $wp_plugin_dir ) ) { $path = str_replace( $wp_plugin_dir . '/', '', $error_file ); $parts = explode( '/', $path ); return array( 'type' => 'plugin', 'slug' => $parts[0], ); } if ( empty( $wp_theme_directories ) ) { return false; } foreach ( $wp_theme_directories as $theme_directory ) { $theme_directory = wp_normalize_path( $theme_directory ); if ( str_starts_with( $error_file, $theme_directory ) ) { $path = str_replace( $theme_directory . '/', '', $error_file ); $parts = explode( '/', $path ); return array( 'type' => 'theme', 'slug' => $parts[0], ); } } return false; } protected function is_network_plugin( $extension ) { if ( 'plugin' !== $extension['type'] ) { return false; } if ( ! is_multisite() ) { return false; } $network_plugins = wp_get_active_network_plugins(); foreach ( $network_plugins as $plugin ) { if ( str_starts_with( $plugin, $extension['slug'] . '/' ) ) { return true; } } return false; } protected function store_error( $error ) { $extension = $this->get_extension_for_error( $error ); if ( ! $extension ) { return false; } switch ( $extension['type'] ) { case 'plugin': return wp_paused_plugins()->set( $extension['slug'], $error ); case 'theme': return wp_paused_themes()->set( $extension['slug'], $error ); default: return false; } } protected function redirect_protected() { if ( ! function_exists( 'wp_safe_redirect' ) ) { require_once ABSPATH . WPINC . '/pluggable.php'; } $scheme = is_ssl() ? 'https://' : 'http://'; $url = "{$scheme}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; wp_safe_redirect( $url ); exit; } }
###require ABSPATH . WPINC . '/error-protection.php';
function wp_paused_plugins() { static $storage = null; if ( null === $storage ) { $storage = new WP_Paused_Extensions_Storage( 'plugin' ); } return $storage; } function wp_paused_themes() { static $storage = null; if ( null === $storage ) { $storage = new WP_Paused_Extensions_Storage( 'theme' ); } return $storage; } function wp_get_extension_error_description( $error ) { $constants = get_defined_constants( true ); $constants = isset( $constants['Core'] ) ? $constants['Core'] : $constants['internal']; $core_errors = array(); foreach ( $constants as $constant => $value ) { if ( str_starts_with( $constant, 'E_' ) ) { $core_errors[ $value ] = $constant; } } if ( isset( $core_errors[ $error['type'] ] ) ) { $error['type'] = $core_errors[ $error['type'] ]; } $error_message = __( 'An error of type %1$s was caused in line %2$s of the file %3$s. Error message: %4$s' ); return sprintf( $error_message, "<code>{$error['type']}</code>", "<code>{$error['line']}</code>", "<code>{$error['file']}</code>", "<code>{$error['message']}</code>" ); } function wp_register_fatal_error_handler() { if ( ! wp_is_fatal_error_handler_enabled() ) { return; } $handler = null; if ( defined( 'WP_CONTENT_DIR' ) && is_readable( WP_CONTENT_DIR . '/fatal-error-handler.php' ) ) { $handler = include WP_CONTENT_DIR . '/fatal-error-handler.php'; } if ( ! is_object( $handler ) || ! is_callable( array( $handler, 'handle' ) ) ) { $handler = new WP_Fatal_Error_Handler(); } register_shutdown_function( array( $handler, 'handle' ) ); } function wp_is_fatal_error_handler_enabled() { $enabled = ! defined( 'WP_DISABLE_FATAL_ERROR_HANDLER' ) || ! WP_DISABLE_FATAL_ERROR_HANDLER; return apply_filters( 'wp_fatal_error_handler_enabled', $enabled ); } function wp_recovery_mode() { static $wp_recovery_mode; if ( ! $wp_recovery_mode ) { $wp_recovery_mode = new WP_Recovery_Mode(); } return $wp_recovery_mode; }
###require ABSPATH . WPINC . '/default-constants.php';
function wp_initial_constants() { global $blog_id, $wp_version; define( 'KB_IN_BYTES', 1024 ); define( 'MB_IN_BYTES', 1024 * KB_IN_BYTES ); define( 'GB_IN_BYTES', 1024 * MB_IN_BYTES ); define( 'TB_IN_BYTES', 1024 * GB_IN_BYTES ); define( 'PB_IN_BYTES', 1024 * TB_IN_BYTES ); define( 'EB_IN_BYTES', 1024 * PB_IN_BYTES ); define( 'ZB_IN_BYTES', 1024 * EB_IN_BYTES ); define( 'YB_IN_BYTES', 1024 * ZB_IN_BYTES ); if ( ! defined( 'WP_START_TIMESTAMP' ) ) { define( 'WP_START_TIMESTAMP', microtime( true ) ); } $current_limit = ini_get( 'memory_limit' ); $current_limit_int = wp_convert_hr_to_bytes( $current_limit ); if ( ! defined( 'WP_MEMORY_LIMIT' ) ) { if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) { define( 'WP_MEMORY_LIMIT', $current_limit ); } elseif ( is_multisite() ) { define( 'WP_MEMORY_LIMIT', '64M' ); } else { define( 'WP_MEMORY_LIMIT', '40M' ); } } if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) { if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) { define( 'WP_MAX_MEMORY_LIMIT', $current_limit ); } elseif ( -1 === $current_limit_int || $current_limit_int > 256 * MB_IN_BYTES ) { define( 'WP_MAX_MEMORY_LIMIT', $current_limit ); } elseif ( wp_convert_hr_to_bytes( WP_MEMORY_LIMIT ) > 256 * MB_IN_BYTES ) { define( 'WP_MAX_MEMORY_LIMIT', WP_MEMORY_LIMIT ); } else { define( 'WP_MAX_MEMORY_LIMIT', '256M' ); } } $wp_limit_int = wp_convert_hr_to_bytes( WP_MEMORY_LIMIT ); if ( -1 !== $current_limit_int && ( -1 === $wp_limit_int || $wp_limit_int > $current_limit_int ) ) { ini_set( 'memory_limit', WP_MEMORY_LIMIT ); } if ( ! isset( $blog_id ) ) { $blog_id = 1; } if ( ! defined( 'WP_CONTENT_DIR' ) ) { define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); } if ( ! defined( 'WP_DEVELOPMENT_MODE' ) ) { define( 'WP_DEVELOPMENT_MODE', '' ); } if ( ! defined( 'WP_DEBUG' ) ) { if ( wp_get_development_mode() || 'development' === wp_get_environment_type() ) { define( 'WP_DEBUG', true ); } else { define( 'WP_DEBUG', false ); } } if ( ! defined( 'WP_DEBUG_DISPLAY' ) ) { define( 'WP_DEBUG_DISPLAY', true ); } if ( ! defined( 'WP_DEBUG_LOG' ) ) { define( 'WP_DEBUG_LOG', false ); } if ( ! defined( 'WP_CACHE' ) ) { define( 'WP_CACHE', false ); } if ( ! defined( 'SCRIPT_DEBUG' ) ) { if ( ! empty( $wp_version ) ) { $develop_src = str_contains( $wp_version, '-src' ); } else { $develop_src = false; } define( 'SCRIPT_DEBUG', $develop_src ); } if ( ! defined( 'MEDIA_TRASH' ) ) { define( 'MEDIA_TRASH', false ); } if ( ! defined( 'SHORTINIT' ) ) { define( 'SHORTINIT', false ); } define( 'WP_FEATURE_BETTER_PASSWORDS', true ); define( 'MINUTE_IN_SECONDS', 60 ); define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS ); define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS ); define( 'WEEK_IN_SECONDS', 7 * DAY_IN_SECONDS ); define( 'MONTH_IN_SECONDS', 30 * DAY_IN_SECONDS ); define( 'YEAR_IN_SECONDS', 365 * DAY_IN_SECONDS ); } function wp_plugin_directory_constants() { if ( ! defined( 'WP_CONTENT_URL' ) ) { define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' ); } if ( ! defined( 'WP_PLUGIN_DIR' ) ) { define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); } if ( ! defined( 'WP_PLUGIN_URL' ) ) { define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' ); } if ( ! defined( 'PLUGINDIR' ) ) { define( 'PLUGINDIR', 'wp-content/plugins' ); } if ( ! defined( 'WPMU_PLUGIN_DIR' ) ) { define( 'WPMU_PLUGIN_DIR', WP_CONTENT_DIR . '/mu-plugins' ); } if ( ! defined( 'WPMU_PLUGIN_URL' ) ) { define( 'WPMU_PLUGIN_URL', WP_CONTENT_URL . '/mu-plugins' ); } if ( ! defined( 'MUPLUGINDIR' ) ) { define( 'MUPLUGINDIR', 'wp-content/mu-plugins' ); } } function wp_cookie_constants() { if ( ! defined( 'COOKIEHASH' ) ) { $siteurl = get_site_option( 'siteurl' ); if ( $siteurl ) { define( 'COOKIEHASH', md5( $siteurl ) ); } else { define( 'COOKIEHASH', '' ); } } if ( ! defined( 'USER_COOKIE' ) ) { define( 'USER_COOKIE', 'wordpressuser_' . COOKIEHASH ); } if ( ! defined( 'PASS_COOKIE' ) ) { define( 'PASS_COOKIE', 'wordpresspass_' . COOKIEHASH ); } if ( ! defined( 'AUTH_COOKIE' ) ) { define( 'AUTH_COOKIE', 'wordpress_' . COOKIEHASH ); } if ( ! defined( 'SECURE_AUTH_COOKIE' ) ) { define( 'SECURE_AUTH_COOKIE', 'wordpress_sec_' . COOKIEHASH ); } if ( ! defined( 'LOGGED_IN_COOKIE' ) ) { define( 'LOGGED_IN_COOKIE', 'wordpress_logged_in_' . COOKIEHASH ); } if ( ! defined( 'TEST_COOKIE' ) ) { define( 'TEST_COOKIE', 'wordpress_test_cookie' ); } if ( ! defined( 'COOKIEPATH' ) ) { define( 'COOKIEPATH', preg_replace( '|https?://[^/]+|i', '', get_option( 'home' ) . '/' ) ); } if ( ! defined( 'SITECOOKIEPATH' ) ) { define( 'SITECOOKIEPATH', preg_replace( '|https?://[^/]+|i', '', get_option( 'siteurl' ) . '/' ) ); } if ( ! defined( 'ADMIN_COOKIE_PATH' ) ) { define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' ); } if ( ! defined( 'PLUGINS_COOKIE_PATH' ) ) { define( 'PLUGINS_COOKIE_PATH', preg_replace( '|https?://[^/]+|i', '', WP_PLUGIN_URL ) ); } if ( ! defined( 'COOKIE_DOMAIN' ) ) { define( 'COOKIE_DOMAIN', '' ); } if ( ! defined( 'RECOVERY_MODE_COOKIE' ) ) { define( 'RECOVERY_MODE_COOKIE', 'wordpress_rec_' . COOKIEHASH ); } } function wp_ssl_constants() { if ( ! defined( 'FORCE_SSL_ADMIN' ) ) { if ( 'https' === parse_url( get_option( 'siteurl' ), PHP_URL_SCHEME ) ) { define( 'FORCE_SSL_ADMIN', true ); } else { define( 'FORCE_SSL_ADMIN', false ); } } force_ssl_admin( FORCE_SSL_ADMIN ); if ( defined( 'FORCE_SSL_LOGIN' ) && FORCE_SSL_LOGIN ) { force_ssl_admin( true ); } } function wp_functionality_constants() { if ( ! defined( 'AUTOSAVE_INTERVAL' ) ) { define( 'AUTOSAVE_INTERVAL', MINUTE_IN_SECONDS ); } if ( ! defined( 'EMPTY_TRASH_DAYS' ) ) { define( 'EMPTY_TRASH_DAYS', 30 ); } if ( ! defined( 'WP_POST_REVISIONS' ) ) { define( 'WP_POST_REVISIONS', true ); } if ( ! defined( 'WP_CRON_LOCK_TIMEOUT' ) ) { define( 'WP_CRON_LOCK_TIMEOUT', MINUTE_IN_SECONDS ); } } function wp_templating_constants() { define( 'TEMPLATEPATH', get_template_directory() ); define( 'STYLESHEETPATH', get_stylesheet_directory() ); if ( ! defined( 'WP_DEFAULT_THEME' ) ) { define( 'WP_DEFAULT_THEME', 'twentytwentyfive' ); } }
require_once ABSPATH . WPINC . '/plugin.php';
global $blog_id;
wp_initial_constants();
wp_register_fatal_error_handler();
date_default_timezone_set( 'UTC' );
wp_fix_server_vars();
wp_maintenance();
timer_start();
wp_debug_mode();
if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) && file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ) ) {
include WP_CONTENT_DIR . '/advanced-cache.php';
if ( $wp_filter ) {
$wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter );
}
}
wp_set_lang_dir();
###require ABSPATH . WPINC . '/class-wp-list-util.php';
class WP_List_Util { private $input = array(); private $output = array(); private $orderby = array(); public function __construct( $input ) { $this->output = $input; $this->input = $input; } public function get_input() { return $this->input; } public function get_output() { return $this->output; } public function filter( $args = array(), $operator = 'AND' ) { if ( empty( $args ) ) { return $this->output; } $operator = strtoupper( $operator ); if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) { $this->output = array(); return $this->output; } $count = count( $args ); $filtered = array(); foreach ( $this->output as $key => $obj ) { $matched = 0; foreach ( $args as $m_key => $m_value ) { if ( is_array( $obj ) ) { if ( array_key_exists( $m_key, $obj ) && ( $m_value == $obj[ $m_key ] ) ) { ++$matched; } } elseif ( is_object( $obj ) ) { if ( isset( $obj->{$m_key} ) && ( $m_value == $obj->{$m_key} ) ) { ++$matched; } } } if ( ( 'AND' === $operator && $matched === $count ) || ( 'OR' === $operator && $matched > 0 ) || ( 'NOT' === $operator && 0 === $matched ) ) { $filtered[ $key ] = $obj; } } $this->output = $filtered; return $this->output; } public function pluck( $field, $index_key = null ) { $newlist = array(); if ( ! $index_key ) { foreach ( $this->output as $key => $value ) { if ( is_object( $value ) ) { $newlist[ $key ] = $value->$field; } elseif ( is_array( $value ) ) { $newlist[ $key ] = $value[ $field ]; } else { _doing_it_wrong( __METHOD__, __( 'Values for the input array must be either objects or arrays.' ), '6.2.0' ); } } $this->output = $newlist; return $this->output; } foreach ( $this->output as $value ) { if ( is_object( $value ) ) { if ( isset( $value->$index_key ) ) { $newlist[ $value->$index_key ] = $value->$field; } else { $newlist[] = $value->$field; } } elseif ( is_array( $value ) ) { if ( isset( $value[ $index_key ] ) ) { $newlist[ $value[ $index_key ] ] = $value[ $field ]; } else { $newlist[] = $value[ $field ]; } } else { _doing_it_wrong( __METHOD__, __( 'Values for the input array must be either objects or arrays.' ), '6.2.0' ); } } $this->output = $newlist; return $this->output; } public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false ) { if ( empty( $orderby ) ) { return $this->output; } if ( is_string( $orderby ) ) { $orderby = array( $orderby => $order ); } foreach ( $orderby as $field => $direction ) { $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC'; } $this->orderby = $orderby; if ( $preserve_keys ) { uasort( $this->output, array( $this, 'sort_callback' ) ); } else { usort( $this->output, array( $this, 'sort_callback' ) ); } $this->orderby = array(); return $this->output; } private function sort_callback( $a, $b ) { if ( empty( $this->orderby ) ) { return 0; } $a = (array) $a; $b = (array) $b; foreach ( $this->orderby as $field => $direction ) { if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) { continue; } if ( $a[ $field ] == $b[ $field ] ) { continue; } $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 ); if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) { return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1]; } return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1]; } return 0; } }
###require ABSPATH . WPINC . '/class-wp-token-map.php';
class WP_Token_Map { const STORAGE_VERSION = '6.6.0-trunk'; const MAX_LENGTH = 256; private $key_length = 2; private $large_words = array(); private $groups = ''; private $small_words = ''; private $small_mappings = array(); public static function from_array( array $mappings, int $key_length = 2 ): ?WP_Token_Map { $map = new WP_Token_Map(); $map->key_length = $key_length; $groups = array(); $shorts = array(); foreach ( $mappings as $word => $mapping ) { if ( self::MAX_LENGTH <= strlen( $word ) || self::MAX_LENGTH <= strlen( $mapping ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Token Map tokens and substitutions must all be shorter than %1$d bytes.' ), self::MAX_LENGTH ), '6.6.0' ); return null; } $length = strlen( $word ); if ( $key_length >= $length ) { $shorts[] = $word; } else { $group = substr( $word, 0, $key_length ); if ( ! isset( $groups[ $group ] ) ) { $groups[ $group ] = array(); } $groups[ $group ][] = array( substr( $word, $key_length ), $mapping ); } } usort( $shorts, 'WP_Token_Map::longest_first_then_alphabetical' ); foreach ( $groups as $group_key => $group ) { usort( $groups[ $group_key ], static function ( array $a, array $b ): int { return self::longest_first_then_alphabetical( $a[0], $b[0] ); } ); } foreach ( $shorts as $word ) { $map->small_words .= str_pad( $word, $key_length + 1, "\x00", STR_PAD_RIGHT ); $map->small_mappings[] = $mappings[ $word ]; } $group_keys = array_keys( $groups ); sort( $group_keys ); foreach ( $group_keys as $group ) { $map->groups .= "{$group}\x00"; $group_string = ''; foreach ( $groups[ $group ] as $group_word ) { list( $word, $mapping ) = $group_word; $word_length = pack( 'C', strlen( $word ) ); $mapping_length = pack( 'C', strlen( $mapping ) ); $group_string .= "{$word_length}{$word}{$mapping_length}{$mapping}"; } $map->large_words[] = $group_string; } return $map; } public static function from_precomputed_table( $state ): ?WP_Token_Map { $has_necessary_state = isset( $state['storage_version'], $state['key_length'], $state['groups'], $state['large_words'], $state['small_words'], $state['small_mappings'] ); if ( ! $has_necessary_state ) { _doing_it_wrong( __METHOD__, __( 'Missing required inputs to pre-computed WP_Token_Map.' ), '6.6.0' ); return null; } if ( self::STORAGE_VERSION !== $state['storage_version'] ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Loaded version \'%1$s\' incompatible with expected version \'%2$s\'.' ), $state['storage_version'], self::STORAGE_VERSION ), '6.6.0' ); return null; } $map = new WP_Token_Map(); $map->key_length = $state['key_length']; $map->groups = $state['groups']; $map->large_words = $state['large_words']; $map->small_words = $state['small_words']; $map->small_mappings = $state['small_mappings']; return $map; } public function contains( string $word, string $case_sensitivity = 'case-sensitive' ): bool { $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; if ( $this->key_length >= strlen( $word ) ) { if ( 0 === strlen( $this->small_words ) ) { return false; } $term = str_pad( $word, $this->key_length + 1, "\x00", STR_PAD_RIGHT ); $word_at = $ignore_case ? stripos( $this->small_words, $term ) : strpos( $this->small_words, $term ); if ( false === $word_at ) { return false; } return true; } $group_key = substr( $word, 0, $this->key_length ); $group_at = $ignore_case ? stripos( $this->groups, $group_key ) : strpos( $this->groups, $group_key ); if ( false === $group_at ) { return false; } $group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ]; $group_length = strlen( $group ); $slug = substr( $word, $this->key_length ); $length = strlen( $slug ); $at = 0; while ( $at < $group_length ) { $token_length = unpack( 'C', $group[ $at++ ] )[1]; $token_at = $at; $at += $token_length; $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; $mapping_at = $at; if ( $token_length === $length && 0 === substr_compare( $group, $slug, $token_at, $token_length, $ignore_case ) ) { return true; } $at = $mapping_at + $mapping_length; } return false; } public function read_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string { $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; $text_length = strlen( $text ); if ( $text_length > $this->key_length ) { $group_key = substr( $text, $offset, $this->key_length ); $group_at = $ignore_case ? stripos( $this->groups, $group_key ) : strpos( $this->groups, $group_key ); if ( false === $group_at ) { return strlen( $this->small_words ) > 0 ? $this->read_small_token( $text, $offset, $matched_token_byte_length, $case_sensitivity ) : null; } $group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ]; $group_length = strlen( $group ); $at = 0; while ( $at < $group_length ) { $token_length = unpack( 'C', $group[ $at++ ] )[1]; $token = substr( $group, $at, $token_length ); $at += $token_length; $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; $mapping_at = $at; if ( 0 === substr_compare( $text, $token, $offset + $this->key_length, $token_length, $ignore_case ) ) { $matched_token_byte_length = $this->key_length + $token_length; return substr( $group, $mapping_at, $mapping_length ); } $at = $mapping_at + $mapping_length; } } return strlen( $this->small_words ) > 0 ? $this->read_small_token( $text, $offset, $matched_token_byte_length, $case_sensitivity ) : null; } private function read_small_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string { $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; $small_length = strlen( $this->small_words ); $search_text = substr( $text, $offset, $this->key_length ); if ( $ignore_case ) { $search_text = strtoupper( $search_text ); } $starting_char = $search_text[0]; $at = 0; while ( $at < $small_length ) { if ( $starting_char !== $this->small_words[ $at ] && ( ! $ignore_case || strtoupper( $this->small_words[ $at ] ) !== $starting_char ) ) { $at += $this->key_length + 1; continue; } for ( $adjust = 1; $adjust < $this->key_length; $adjust++ ) { if ( "\x00" === $this->small_words[ $at + $adjust ] ) { $matched_token_byte_length = $adjust; return $this->small_mappings[ $at / ( $this->key_length + 1 ) ]; } if ( $search_text[ $adjust ] !== $this->small_words[ $at + $adjust ] && ( ! $ignore_case || strtoupper( $this->small_words[ $at + $adjust ] !== $search_text[ $adjust ] ) ) ) { $at += $this->key_length + 1; continue 2; } } $matched_token_byte_length = $adjust; return $this->small_mappings[ $at / ( $this->key_length + 1 ) ]; } return null; } public function to_array(): array { $tokens = array(); $at = 0; $small_mapping = 0; $small_length = strlen( $this->small_words ); while ( $at < $small_length ) { $key = rtrim( substr( $this->small_words, $at, $this->key_length + 1 ), "\x00" ); $value = $this->small_mappings[ $small_mapping++ ]; $tokens[ $key ] = $value; $at += $this->key_length + 1; } foreach ( $this->large_words as $index => $group ) { $prefix = substr( $this->groups, $index * ( $this->key_length + 1 ), 2 ); $group_length = strlen( $group ); $at = 0; while ( $at < $group_length ) { $length = unpack( 'C', $group[ $at++ ] )[1]; $key = $prefix . substr( $group, $at, $length ); $at += $length; $length = unpack( 'C', $group[ $at++ ] )[1]; $value = substr( $group, $at, $length ); $tokens[ $key ] = $value; $at += $length; } } return $tokens; } public function precomputed_php_source_table( string $indent = "\t" ): string { $i1 = $indent; $i2 = $i1 . $indent; $i3 = $i2 . $indent; $class_version = self::STORAGE_VERSION; $output = self::class . "::from_precomputed_table(\n"; $output .= "{$i1}array(\n"; $output .= "{$i2}\"storage_version\" => \"{$class_version}\",\n"; $output .= "{$i2}\"key_length\" => {$this->key_length},\n"; $group_line = str_replace( "\x00", "\\x00", $this->groups ); $output .= "{$i2}\"groups\" => \"{$group_line}\",\n"; $output .= "{$i2}\"large_words\" => array(\n"; $prefixes = explode( "\x00", $this->groups ); foreach ( $prefixes as $index => $prefix ) { if ( '' === $prefix ) { break; } $group = $this->large_words[ $index ]; $group_length = strlen( $group ); $comment_line = "{$i3}//"; $data_line = "{$i3}\""; $at = 0; while ( $at < $group_length ) { $token_length = unpack( 'C', $group[ $at++ ] )[1]; $token = substr( $group, $at, $token_length ); $at += $token_length; $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; $mapping = substr( $group, $at, $mapping_length ); $at += $mapping_length; $token_digits = str_pad( dechex( $token_length ), 2, '0', STR_PAD_LEFT ); $mapping_digits = str_pad( dechex( $mapping_length ), 2, '0', STR_PAD_LEFT ); $mapping = preg_replace_callback( "~[\\x00-\\x1f\\x22\\x5c]~", static function ( $match_result ) { switch ( $match_result[0] ) { case '"': return '\\"'; case '\\': return '\\\\'; default: $hex = dechex( ord( $match_result[0] ) ); return "\\x{$hex}"; } }, $mapping ); $comment_line .= " {$prefix}{$token}[{$mapping}]"; $data_line .= "\\x{$token_digits}{$token}\\x{$mapping_digits}{$mapping}"; } $comment_line .= ".\n"; $data_line .= "\",\n"; $output .= $comment_line; $output .= $data_line; } $output .= "{$i2}),\n"; $small_words = array(); $small_length = strlen( $this->small_words ); $at = 0; while ( $at < $small_length ) { $small_words[] = substr( $this->small_words, $at, $this->key_length + 1 ); $at += $this->key_length + 1; } $small_text = str_replace( "\x00", '\x00', implode( '', $small_words ) ); $output .= "{$i2}\"small_words\" => \"{$small_text}\",\n"; $output .= "{$i2}\"small_mappings\" => array(\n"; foreach ( $this->small_mappings as $mapping ) { $output .= "{$i3}\"{$mapping}\",\n"; } $output .= "{$i2})\n"; $output .= "{$i1})\n"; $output .= ')'; return $output; } private static function longest_first_then_alphabetical( string $a, string $b ): int { if ( $a === $b ) { return 0; } $length_a = strlen( $a ); $length_b = strlen( $b ); if ( $length_a !== $length_b ) { return $length_b - $length_a; } return strcmp( $a, $b ); } }
###require ABSPATH . WPINC . '/utf8.php';
if ( extension_loaded( 'mbstring' ) ) : function wp_is_valid_utf8( string $bytes ): bool { return mb_check_encoding( $bytes, 'UTF-8' ); } else : function wp_is_valid_utf8( string $string ): bool { return _wp_is_valid_utf8_fallback( $string ); } endif; if ( extension_loaded( 'mbstring' ) && version_compare( PHP_VERSION, '8.1.6', '>=' ) ) : function wp_scrub_utf8( $text ) { $prev_replacement_character = mb_substitute_character(); mb_substitute_character( 0xFFFD ); $scrubbed = mb_scrub( $text, 'UTF-8' ); mb_substitute_character( $prev_replacement_character ); return $scrubbed; } else : function wp_scrub_utf8( $text ) { return _wp_scrub_utf8_fallback( $text ); } endif; if ( _wp_can_use_pcre_u() ) : function wp_has_noncharacters( string $text ): bool { return 1 === preg_match( '/[\x{FDD0}-\x{FDEF}\x{FFFE}\x{FFFF}\x{1FFFE}\x{1FFFF}\x{2FFFE}\x{2FFFF}\x{3FFFE}\x{3FFFF}\x{4FFFE}\x{4FFFF}\x{5FFFE}\x{5FFFF}\x{6FFFE}\x{6FFFF}\x{7FFFE}\x{7FFFF}\x{8FFFE}\x{8FFFF}\x{9FFFE}\x{9FFFF}\x{AFFFE}\x{AFFFF}\x{BFFFE}\x{BFFFF}\x{CFFFE}\x{CFFFF}\x{DFFFE}\x{DFFFF}\x{EFFFE}\x{EFFFF}\x{FFFFE}\x{FFFFF}\x{10FFFE}\x{10FFFF}]/u', $text ); } else : function wp_has_noncharacters( string $text ): bool { return _wp_has_noncharacters_fallback( $text ); } endif;
###require ABSPATH . WPINC . '/formatting.php';
function wptexturize( $text, $reset = false ) { global $wp_cockneyreplace, $shortcode_tags; static $static_characters = null, $static_replacements = null, $dynamic_characters = null, $dynamic_replacements = null, $default_no_texturize_tags = null, $default_no_texturize_shortcodes = null, $run_texturize = true, $apos = null, $prime = null, $double_prime = null, $opening_quote = null, $closing_quote = null, $opening_single_quote = null, $closing_single_quote = null, $open_q_flag = '<!--oq-->', $open_sq_flag = '<!--osq-->', $apos_flag = '<!--apos-->'; if ( empty( $text ) || false === $run_texturize ) { return $text; } if ( $reset || ! isset( $static_characters ) ) { $run_texturize = apply_filters( 'run_wptexturize', $run_texturize ); if ( false === $run_texturize ) { return $text; } $opening_quote = _x( '“', 'opening curly double quote' ); $closing_quote = _x( '”', 'closing curly double quote' ); $apos = _x( '’', 'apostrophe' ); $prime = _x( '′', 'prime' ); $double_prime = _x( '″', 'double prime' ); $opening_single_quote = _x( '‘', 'opening curly single quote' ); $closing_single_quote = _x( '’', 'closing curly single quote' ); $en_dash = _x( '–', 'en dash' ); $em_dash = _x( '—', 'em dash' ); $default_no_texturize_tags = array( 'pre', 'code', 'kbd', 'style', 'script', 'tt' ); $default_no_texturize_shortcodes = array( 'code' ); if ( isset( $wp_cockneyreplace ) ) { $cockney = array_keys( $wp_cockneyreplace ); $cockneyreplace = array_values( $wp_cockneyreplace ); } else { $cockney = explode( ',', _x( "'tain't,'twere,'twas,'tis,'twill,'til,'bout,'nuff,'round,'cause,'em", 'Comma-separated list of words to texturize in your language' ) ); $cockneyreplace = explode( ',', _x( '’tain’t,’twere,’twas,’tis,’twill,’til,’bout,’nuff,’round,’cause,’em', 'Comma-separated list of replacement words in your language' ) ); } $static_characters = array_merge( array( '...', '``', '\'\'', ' (tm)' ), $cockney ); $static_replacements = array_merge( array( '…', $opening_quote, $closing_quote, ' ™' ), $cockneyreplace ); $dynamic_characters = array( 'apos' => array(), 'quote' => array(), 'dash' => array(), ); $dynamic_replacements = array( 'apos' => array(), 'quote' => array(), 'dash' => array(), ); $dynamic = array(); $spaces = wp_spaces_regexp(); if ( "'" !== $apos || "'" !== $closing_single_quote ) { $dynamic[ '/\'(\d\d)\'(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_single_quote; } if ( "'" !== $apos || '"' !== $closing_quote ) { $dynamic[ '/\'(\d\d)"(?=\Z|[.,:;!?)}\-\]]|>|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_quote; } if ( "'" !== $apos ) { $dynamic['/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/'] = $apos_flag; } if ( "'" !== $opening_single_quote && "'" !== $closing_single_quote ) { $dynamic[ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $open_sq_flag . '$1' . $closing_single_quote; } if ( "'" !== $opening_single_quote ) { $dynamic[ '/(?<=\A|[([{"\-]|<|' . $spaces . ')\'/' ] = $open_sq_flag; } if ( "'" !== $apos ) { $dynamic[ '/(?<!' . $spaces . ')\'(?!\Z|[.,:;!?"\'(){}[\]\-]|&[lg]t;|' . $spaces . ')/' ] = $apos_flag; } $dynamic_characters['apos'] = array_keys( $dynamic ); $dynamic_replacements['apos'] = array_values( $dynamic ); $dynamic = array(); if ( '"' !== $opening_quote && '"' !== $closing_quote ) { $dynamic[ '/(?<=\A|' . $spaces . ')"(\d[.,\d]*)"/' ] = $open_q_flag . '$1' . $closing_quote; } if ( '"' !== $opening_quote ) { $dynamic[ '/(?<=\A|[([{\-]|<|' . $spaces . ')"(?!' . $spaces . ')/' ] = $open_q_flag; } $dynamic_characters['quote'] = array_keys( $dynamic ); $dynamic_replacements['quote'] = array_values( $dynamic ); $dynamic = array(); $dynamic['/---/'] = $em_dash; $dynamic[ '/(?<=^|' . $spaces . ')--(?=$|' . $spaces . ')/' ] = $em_dash; $dynamic['/(?<!xn)--/'] = $en_dash; $dynamic[ '/(?<=^|' . $spaces . ')-(?=$|' . $spaces . ')/' ] = $en_dash; $dynamic_characters['dash'] = array_keys( $dynamic ); $dynamic_replacements['dash'] = array_values( $dynamic ); } $no_texturize_tags = apply_filters( 'no_texturize_tags', $default_no_texturize_tags ); $no_texturize_shortcodes = apply_filters( 'no_texturize_shortcodes', $default_no_texturize_shortcodes ); $no_texturize_tags_stack = array(); $no_texturize_shortcodes_stack = array(); preg_match_all( '@\[/?([^<>&/\[\]\x00-\x20=]++)@', $text, $matches ); $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); $found_shortcodes = ! empty( $tagnames ); $shortcode_regex = $found_shortcodes ? _get_wptexturize_shortcode_regex( $tagnames ) : ''; $regex = _get_wptexturize_split_regex( $shortcode_regex ); $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); foreach ( $textarr as &$curl ) { $first = $curl[0]; if ( '<' === $first ) { if ( str_starts_with( $curl, '<!--' ) ) { continue; } else { $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&', $curl ); _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags ); } } elseif ( '' === trim( $curl ) ) { continue; } elseif ( '[' === $first && $found_shortcodes && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) { if ( ! str_starts_with( $curl, '[[' ) && ! str_ends_with( $curl, ']]' ) ) { _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes ); } else { continue; } } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) { $curl = str_replace( $static_characters, $static_replacements, $curl ); if ( str_contains( $curl, "'" ) ) { $curl = preg_replace( $dynamic_characters['apos'], $dynamic_replacements['apos'], $curl ); $curl = wptexturize_primes( $curl, "'", $prime, $open_sq_flag, $closing_single_quote ); $curl = str_replace( $apos_flag, $apos, $curl ); $curl = str_replace( $open_sq_flag, $opening_single_quote, $curl ); } if ( str_contains( $curl, '"' ) ) { $curl = preg_replace( $dynamic_characters['quote'], $dynamic_replacements['quote'], $curl ); $curl = wptexturize_primes( $curl, '"', $double_prime, $open_q_flag, $closing_quote ); $curl = str_replace( $open_q_flag, $opening_quote, $curl ); } if ( str_contains( $curl, '-' ) ) { $curl = preg_replace( $dynamic_characters['dash'], $dynamic_replacements['dash'], $curl ); } if ( 1 === preg_match( '/(?<=\d)x\d/', $curl ) ) { $curl = preg_replace( '/\b(\d(?(?<=0)[\d\.,]+|[\d\.,]*))x(\d[\d\.,]*)\b/', '$1×$2', $curl ); } $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&', $curl ); } } return implode( '', $textarr ); } function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) { $spaces = wp_spaces_regexp(); $flag = '<!--wp-prime-or-quote-->'; $quote_pattern = "/$needle(?=\\Z|[.,:;!?)}\\-\\]]|>|" . $spaces . ')/'; $prime_pattern = "/(?<=\\d)$needle/"; $flag_after_digit = "/(?<=\\d)$flag/"; $flag_no_digit = "/(?<!\\d)$flag/"; $sentences = explode( $open_quote, $haystack ); foreach ( $sentences as $key => &$sentence ) { if ( ! str_contains( $sentence, $needle ) ) { continue; } elseif ( 0 !== $key && 0 === substr_count( $sentence, $close_quote ) ) { $sentence = preg_replace( $quote_pattern, $flag, $sentence, -1, $count ); if ( $count > 1 ) { $sentence = preg_replace( $flag_no_digit, $close_quote, $sentence, -1, $count2 ); if ( 0 === $count2 ) { $count2 = substr_count( $sentence, "$flag." ); if ( $count2 > 0 ) { $pos = strrpos( $sentence, "$flag." ); } else { $pos = strrpos( $sentence, $flag ); } $sentence = substr_replace( $sentence, $close_quote, $pos, strlen( $flag ) ); } $sentence = preg_replace( $prime_pattern, $prime, $sentence ); $sentence = preg_replace( $flag_after_digit, $prime, $sentence ); $sentence = str_replace( $flag, $close_quote, $sentence ); } elseif ( 1 === $count ) { $sentence = str_replace( $flag, $close_quote, $sentence ); $sentence = preg_replace( $prime_pattern, $prime, $sentence ); } else { $sentence = preg_replace( $prime_pattern, $prime, $sentence ); } } else { $sentence = preg_replace( $prime_pattern, $prime, $sentence ); $sentence = preg_replace( $quote_pattern, $close_quote, $sentence ); } if ( '"' === $needle && str_contains( $sentence, '"' ) ) { $sentence = str_replace( '"', $close_quote, $sentence ); } } return implode( $open_quote, $sentences ); } function _wptexturize_pushpop_element( $text, &$stack, $disabled_elements ) { if ( isset( $text[1] ) && '/' !== $text[1] ) { $opening_tag = true; $name_offset = 1; } elseif ( 0 === count( $stack ) ) { return; } else { $opening_tag = false; $name_offset = 2; } $space = strpos( $text, ' ' ); if ( false === $space ) { $space = -1; } else { $space -= $name_offset; } $tag = substr( $text, $name_offset, $space ); if ( in_array( $tag, $disabled_elements, true ) ) { if ( $opening_tag ) { array_push( $stack, $tag ); } elseif ( end( $stack ) === $tag ) { array_pop( $stack ); } } } function wpautop( $text, $br = true ) { $pre_tags = array(); if ( '' === trim( $text ) ) { return ''; } $text = $text . "\n"; if ( str_contains( $text, '<pre' ) ) { $text_parts = explode( '</pre>', $text ); $last_part = array_pop( $text_parts ); $text = ''; $i = 0; foreach ( $text_parts as $text_part ) { $start = strpos( $text_part, '<pre' ); if ( false === $start ) { $text .= $text_part; continue; } $name = "<pre wp-pre-tag-$i></pre>"; $pre_tags[ $name ] = substr( $text_part, $start ) . '</pre>'; $text .= substr( $text_part, 0, $start ) . $name; ++$i; } $text .= $last_part; } $text = preg_replace( '|<br\s*/?>\s*<br\s*/?>|', "\n\n", $text ); $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)'; $text = preg_replace( '!(<' . $allblocks . '[\s/>])!', "\n\n$1", $text ); $text = preg_replace( '!(</' . $allblocks . '>)!', "$1\n\n", $text ); $text = preg_replace( '!(<hr\s*?/?>)!', "$1\n\n", $text ); $text = str_replace( array( "\r\n", "\r" ), "\n", $text ); $text = wp_replace_in_html_tags( $text, array( "\n" => ' <!-- wpnl --> ' ) ); if ( str_contains( $text, '<option' ) ) { $text = preg_replace( '|\s*<option|', '<option', $text ); $text = preg_replace( '|</option>\s*|', '</option>', $text ); } if ( str_contains( $text, '</object>' ) ) { $text = preg_replace( '|(<object[^>]*>)\s*|', '$1', $text ); $text = preg_replace( '|\s*</object>|', '</object>', $text ); $text = preg_replace( '%\s*(</?(?:param|embed)[^>]*>)\s*%', '$1', $text ); } if ( str_contains( $text, '<source' ) || str_contains( $text, '<track' ) ) { $text = preg_replace( '%([<\[](?:audio|video)[^>\]]*[>\]])\s*%', '$1', $text ); $text = preg_replace( '%\s*([<\[]/(?:audio|video)[>\]])%', '$1', $text ); $text = preg_replace( '%\s*(<(?:source|track)[^>]*>)\s*%', '$1', $text ); } if ( str_contains( $text, '<figcaption' ) ) { $text = preg_replace( '|\s*(<figcaption[^>]*>)|', '$1', $text ); $text = preg_replace( '|</figcaption>\s*|', '</figcaption>', $text ); } $text = preg_replace( "/\n\n+/", "\n\n", $text ); $paragraphs = preg_split( '/\n\s*\n/', $text, -1, PREG_SPLIT_NO_EMPTY ); $text = ''; foreach ( $paragraphs as $paragraph ) { $text .= '<p>' . trim( $paragraph, "\n" ) . "</p>\n"; } $text = preg_replace( '|<p>\s*</p>|', '', $text ); $text = preg_replace( '!<p>([^<]+)</(div|address|form)>!', '<p>$1</p></$2>', $text ); $text = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $text ); $text = preg_replace( '|<p>(<li.+?)</p>|', '$1', $text ); $text = preg_replace( '|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $text ); $text = str_replace( '</blockquote></p>', '</p></blockquote>', $text ); $text = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)!', '$1', $text ); $text = preg_replace( '!(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $text ); if ( $br ) { $text = preg_replace_callback( '/<(script|style|svg|math).*?<\/\\1>/s', '_autop_newline_preservation_helper', $text ); $text = str_replace( array( '<br>', '<br/>' ), '<br />', $text ); $text = preg_replace( '|(?<!<br />)\s*\n|', "<br />\n", $text ); $text = str_replace( '<WPPreserveNewline />', "\n", $text ); } $text = preg_replace( '!(</?' . $allblocks . '[^>]*>)\s*<br />!', '$1', $text ); $text = preg_replace( '!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $text ); $text = preg_replace( "|\n</p>$|", '</p>', $text ); if ( ! empty( $pre_tags ) ) { $text = str_replace( array_keys( $pre_tags ), array_values( $pre_tags ), $text ); } if ( str_contains( $text, '<!-- wpnl -->' ) ) { $text = str_replace( array( ' <!-- wpnl --> ', '<!-- wpnl -->' ), "\n", $text ); } return $text; } function wp_html_split( $input ) { return preg_split( get_html_split_regex(), $input, -1, PREG_SPLIT_DELIM_CAPTURE ); } function get_html_split_regex() { static $regex; if ( ! isset( $regex ) ) { $comments = '!' . '(?:' . '-(?!->)' . '[^\-]*+' . ')*+' . '(?:-->)?'; $cdata = '!\[CDATA\[' . '[^\]]*+' . '(?:' . '](?!]>)' . '[^\]]*+' . ')*+' . '(?:]]>)?'; $escaped = '(?=' . '!--' . '|' . '!\[CDATA\[' . ')' . '(?(?=!-)' . $comments . '|' . $cdata . ')'; $regex = '/(' . '<' . '(?' . $escaped . '|' . '[^>]*>?' . ')' . ')/'; } return $regex; } function _get_wptexturize_split_regex( $shortcode_regex = '' ) { static $html_regex; if ( ! isset( $html_regex ) ) { $comment_regex = '!' . '(?:' . '-(?!->)' . '[^\-]*+' . ')*+' . '(?:-->)?'; $html_regex = '<' . '(?(?=!--)' . $comment_regex . '|' . '[^>]*>?' . ')'; } if ( empty( $shortcode_regex ) ) { $regex = '/(' . $html_regex . ')/'; } else { $regex = '/(' . $html_regex . '|' . $shortcode_regex . ')/'; } return $regex; } function _get_wptexturize_shortcode_regex( $tagnames ) { $tagregexp = implode( '|', array_map( 'preg_quote', $tagnames ) ); $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; $regex = '\[' . '[\/\[]?' . $tagregexp . '(?:' . '[^\[\]<>]+' . '|' . '<[^\[\]>]*>' . ')*+' . '\]' . '\]?'; return $regex; } function wp_replace_in_html_tags( $haystack, $replace_pairs ) { $textarr = wp_html_split( $haystack ); $changed = false; if ( 1 === count( $replace_pairs ) ) { $needle = array_key_first( $replace_pairs ); $replace = $replace_pairs[ $needle ]; for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { if ( str_contains( $textarr[ $i ], $needle ) ) { $textarr[ $i ] = str_replace( $needle, $replace, $textarr[ $i ] ); $changed = true; } } } else { $needles = array_keys( $replace_pairs ); for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { foreach ( $needles as $needle ) { if ( str_contains( $textarr[ $i ], $needle ) ) { $textarr[ $i ] = strtr( $textarr[ $i ], $replace_pairs ); $changed = true; break; } } } } if ( $changed ) { $haystack = implode( $textarr ); } return $haystack; } function _autop_newline_preservation_helper( $matches ) { return str_replace( "\n", '<WPPreserveNewline />', $matches[0] ); } function shortcode_unautop( $text ) { global $shortcode_tags; if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) { return $text; } $tagregexp = implode( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) ); $spaces = wp_spaces_regexp(); $pattern = '/' . '<p>' . '(?:' . $spaces . ')*+' . '(' . '\\[' . "($tagregexp)" . '(?![\\w-])' . '[^\\]\\/]*' . '(?:' . '\\/(?!\\])' . '[^\\]\\/]*' . ')*?' . '(?:' . '\\/\\]' . '|' . '\\]' . '(?:' . '[^\\[]*+' . '(?:' . '\\[(?!\\/\\2\\])' . '[^\\[]*+' . ')*+' . '\\[\\/\\2\\]' . ')?' . ')' . ')' . '(?:' . $spaces . ')*+' . '<\\/p>' . '/'; return preg_replace( $pattern, '$1', $text ); } function seems_utf8( $str ) { _deprecated_function( __FUNCTION__, '6.9.0', 'wp_is_valid_utf8()' ); mbstring_binary_safe_encoding(); $length = strlen( $str ); reset_mbstring_encoding(); for ( $i = 0; $i < $length; $i++ ) { $c = ord( $str[ $i ] ); if ( $c < 0x80 ) { $n = 0; } elseif ( ( $c & 0xE0 ) === 0xC0 ) { $n = 1; } elseif ( ( $c & 0xF0 ) === 0xE0 ) { $n = 2; } elseif ( ( $c & 0xF8 ) === 0xF0 ) { $n = 3; } elseif ( ( $c & 0xFC ) === 0xF8 ) { $n = 4; } elseif ( ( $c & 0xFE ) === 0xFC ) { $n = 5; } else { return false; } for ( $j = 0; $j < $n; $j++ ) { if ( ( ++$i === $length ) || ( ( ord( $str[ $i ] ) & 0xC0 ) !== 0x80 ) ) { return false; } } } return true; } function _wp_specialchars( $text, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { $text = (string) $text; if ( 0 === strlen( $text ) ) { return ''; } if ( ! preg_match( '/[&<>"\']/', $text ) ) { return $text; } if ( empty( $quote_style ) ) { $quote_style = ENT_NOQUOTES; } elseif ( ENT_XML1 === $quote_style ) { $quote_style = ENT_QUOTES | ENT_XML1; } elseif ( ! in_array( $quote_style, array( ENT_NOQUOTES, ENT_COMPAT, ENT_QUOTES, 'single', 'double' ), true ) ) { $quote_style = ENT_QUOTES; } $charset = _canonical_charset( $charset ? $charset : get_option( 'blog_charset' ) ); $_quote_style = $quote_style; if ( 'double' === $quote_style ) { $quote_style = ENT_COMPAT; $_quote_style = ENT_COMPAT; } elseif ( 'single' === $quote_style ) { $quote_style = ENT_NOQUOTES; } if ( ! $double_encode ) { $text = wp_kses_normalize_entities( $text, ( $quote_style & ENT_XML1 ) ? 'xml' : 'html' ); } $text = htmlspecialchars( $text, $quote_style, $charset, $double_encode ); if ( 'single' === $_quote_style ) { $text = str_replace( "'", ''', $text ); } return $text; } function wp_specialchars_decode( $text, $quote_style = ENT_NOQUOTES ) { $text = (string) $text; if ( 0 === strlen( $text ) ) { return ''; } if ( ! str_contains( $text, '&' ) ) { return $text; } if ( empty( $quote_style ) ) { $quote_style = ENT_NOQUOTES; } elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { $quote_style = ENT_QUOTES; } $single = array( ''' => '\'', ''' => '\'', ); $single_preg = array( '/�*39;/' => ''', '/�*27;/i' => ''', ); $double = array( '"' => '"', '"' => '"', '"' => '"', ); $double_preg = array( '/�*34;/' => '"', '/�*22;/i' => '"', ); $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&', ); $others_preg = array( '/�*60;/' => '<', '/�*62;/' => '>', '/�*38;/' => '&', '/�*26;/i' => '&', ); if ( ENT_QUOTES === $quote_style ) { $translation = array_merge( $single, $double, $others ); $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); } elseif ( ENT_COMPAT === $quote_style || 'double' === $quote_style ) { $translation = array_merge( $double, $others ); $translation_preg = array_merge( $double_preg, $others_preg ); } elseif ( 'single' === $quote_style ) { $translation = array_merge( $single, $others ); $translation_preg = array_merge( $single_preg, $others_preg ); } elseif ( ENT_NOQUOTES === $quote_style ) { $translation = $others; $translation_preg = $others_preg; } $text = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $text ); return strtr( $text, $translation ); } function wp_check_invalid_utf8( $text, $strip = false ) { $text = (string) $text; if ( 0 === strlen( $text ) ) { return ''; } static $is_utf8 = null; if ( ! isset( $is_utf8 ) ) { $is_utf8 = is_utf8_charset(); } if ( ! $is_utf8 || wp_is_valid_utf8( $text ) ) { return $text; } return $strip ? wp_scrub_utf8( $text ) : ''; } function utf8_uri_encode( $utf8_string, $length = 0, $encode_ascii_characters = false ) { $unicode = ''; $values = array(); $num_octets = 1; $unicode_length = 0; mbstring_binary_safe_encoding(); $string_length = strlen( $utf8_string ); reset_mbstring_encoding(); for ( $i = 0; $i < $string_length; $i++ ) { $value = ord( $utf8_string[ $i ] ); if ( $value < 128 ) { $char = chr( $value ); $encoded_char = $encode_ascii_characters ? rawurlencode( $char ) : $char; $encoded_char_length = strlen( $encoded_char ); if ( $length && ( $unicode_length + $encoded_char_length ) > $length ) { break; } $unicode .= $encoded_char; $unicode_length += $encoded_char_length; } else { if ( 0 === count( $values ) ) { if ( $value < 224 ) { $num_octets = 2; } elseif ( $value < 240 ) { $num_octets = 3; } else { $num_octets = 4; } } $values[] = $value; if ( $length && ( $unicode_length + ( $num_octets * 3 ) ) > $length ) { break; } if ( count( $values ) === $num_octets ) { for ( $j = 0; $j < $num_octets; $j++ ) { $unicode .= '%' . dechex( $values[ $j ] ); } $unicode_length += $num_octets * 3; $values = array(); $num_octets = 1; } } } return $unicode; } function remove_accents( $text, $locale = '' ) { if ( ! preg_match( '/[\x80-\xff]/', $text ) ) { return $text; } if ( wp_is_valid_utf8( $text ) ) { if ( function_exists( 'normalizer_is_normalized' ) && function_exists( 'normalizer_normalize' ) ) { if ( ! normalizer_is_normalized( $text ) ) { $text = normalizer_normalize( $text ); } } $chars = array( 'ª' => 'a', 'º' => 'o', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'AE', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'TH', 'ß' => 's', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y', 'Ø' => 'O', 'Ā' => 'A', 'ā' => 'a', 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a', 'Ć' => 'C', 'ć' => 'c', 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c', 'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd', 'Ē' => 'E', 'ē' => 'e', 'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 'Ě' => 'E', 'ě' => 'e', 'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G', 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g', 'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I', 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 'ı' => 'i', 'IJ' => 'IJ', 'ij' => 'ij', 'Ĵ' => 'J', 'ĵ' => 'j', 'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L', 'ł' => 'l', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N', 'ň' => 'n', 'ʼn' => 'n', 'Ŋ' => 'N', 'ŋ' => 'n', 'Ō' => 'O', 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o', 'Œ' => 'OE', 'œ' => 'oe', 'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 'ř' => 'r', 'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 'ş' => 's', 'Š' => 'S', 'š' => 's', 'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T', 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U', 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U', 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u', 'Ŵ' => 'W', 'ŵ' => 'w', 'Ŷ' => 'Y', 'ŷ' => 'y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 'Ž' => 'Z', 'ž' => 'z', 'ſ' => 's', 'Ə' => 'E', 'ǝ' => 'e', 'Ș' => 'S', 'ș' => 's', 'Ț' => 'T', 'ț' => 't', '€' => 'E', '£' => '', 'Ơ' => 'O', 'ơ' => 'o', 'Ư' => 'U', 'ư' => 'u', 'Ầ' => 'A', 'ầ' => 'a', 'Ằ' => 'A', 'ằ' => 'a', 'Ề' => 'E', 'ề' => 'e', 'Ồ' => 'O', 'ồ' => 'o', 'Ờ' => 'O', 'ờ' => 'o', 'Ừ' => 'U', 'ừ' => 'u', 'Ỳ' => 'Y', 'ỳ' => 'y', 'Ả' => 'A', 'ả' => 'a', 'Ẩ' => 'A', 'ẩ' => 'a', 'Ẳ' => 'A', 'ẳ' => 'a', 'Ẻ' => 'E', 'ẻ' => 'e', 'Ể' => 'E', 'ể' => 'e', 'Ỉ' => 'I', 'ỉ' => 'i', 'Ỏ' => 'O', 'ỏ' => 'o', 'Ổ' => 'O', 'ổ' => 'o', 'Ở' => 'O', 'ở' => 'o', 'Ủ' => 'U', 'ủ' => 'u', 'Ử' => 'U', 'ử' => 'u', 'Ỷ' => 'Y', 'ỷ' => 'y', 'Ẫ' => 'A', 'ẫ' => 'a', 'Ẵ' => 'A', 'ẵ' => 'a', 'Ẽ' => 'E', 'ẽ' => 'e', 'Ễ' => 'E', 'ễ' => 'e', 'Ỗ' => 'O', 'ỗ' => 'o', 'Ỡ' => 'O', 'ỡ' => 'o', 'Ữ' => 'U', 'ữ' => 'u', 'Ỹ' => 'Y', 'ỹ' => 'y', 'Ấ' => 'A', 'ấ' => 'a', 'Ắ' => 'A', 'ắ' => 'a', 'Ế' => 'E', 'ế' => 'e', 'Ố' => 'O', 'ố' => 'o', 'Ớ' => 'O', 'ớ' => 'o', 'Ứ' => 'U', 'ứ' => 'u', 'Ạ' => 'A', 'ạ' => 'a', 'Ậ' => 'A', 'ậ' => 'a', 'Ặ' => 'A', 'ặ' => 'a', 'Ẹ' => 'E', 'ẹ' => 'e', 'Ệ' => 'E', 'ệ' => 'e', 'Ị' => 'I', 'ị' => 'i', 'Ọ' => 'O', 'ọ' => 'o', 'Ộ' => 'O', 'ộ' => 'o', 'Ợ' => 'O', 'ợ' => 'o', 'Ụ' => 'U', 'ụ' => 'u', 'Ự' => 'U', 'ự' => 'u', 'Ỵ' => 'Y', 'ỵ' => 'y', 'ɑ' => 'a', 'Ǖ' => 'U', 'ǖ' => 'u', 'Ǘ' => 'U', 'ǘ' => 'u', 'Ǎ' => 'A', 'ǎ' => 'a', 'Ǐ' => 'I', 'ǐ' => 'i', 'Ǒ' => 'O', 'ǒ' => 'o', 'Ǔ' => 'U', 'ǔ' => 'u', 'Ǚ' => 'U', 'ǚ' => 'u', 'Ǜ' => 'U', 'ǜ' => 'u', ); if ( empty( $locale ) ) { $locale = get_locale(); } if ( str_starts_with( $locale, 'de' ) ) { $chars['Ä'] = 'Ae'; $chars['ä'] = 'ae'; $chars['Ö'] = 'Oe'; $chars['ö'] = 'oe'; $chars['Ü'] = 'Ue'; $chars['ü'] = 'ue'; $chars['ß'] = 'ss'; } elseif ( 'da_DK' === $locale ) { $chars['Æ'] = 'Ae'; $chars['æ'] = 'ae'; $chars['Ø'] = 'Oe'; $chars['ø'] = 'oe'; $chars['Å'] = 'Aa'; $chars['å'] = 'aa'; } elseif ( 'ca' === $locale ) { $chars['l·l'] = 'll'; } elseif ( 'sr_RS' === $locale || 'bs_BA' === $locale ) { $chars['Đ'] = 'DJ'; $chars['đ'] = 'dj'; } $text = strtr( $text, $chars ); } else { $chars = array(); $chars['in'] = "\x80\x83\x8a\x8e\x9a\x9e" . "\x9f\xa2\xa5\xb5\xc0\xc1\xc2" . "\xc3\xc4\xc5\xc7\xc8\xc9\xca" . "\xcb\xcc\xcd\xce\xcf\xd1\xd2" . "\xd3\xd4\xd5\xd6\xd8\xd9\xda" . "\xdb\xdc\xdd\xe0\xe1\xe2\xe3" . "\xe4\xe5\xe7\xe8\xe9\xea\xeb" . "\xec\xed\xee\xef\xf1\xf2\xf3" . "\xf4\xf5\xf6\xf8\xf9\xfa\xfb" . "\xfc\xfd\xff"; $chars['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'; $text = strtr( $text, $chars['in'], $chars['out'] ); $double_chars = array(); $double_chars['in'] = array( "\x8c", "\x9c", "\xc6", "\xd0", "\xde", "\xdf", "\xe6", "\xf0", "\xfe" ); $double_chars['out'] = array( 'OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th' ); $text = str_replace( $double_chars['in'], $double_chars['out'], $text ); } return $text; } function sanitize_file_name( $filename ) { $filename_raw = $filename; $filename = remove_accents( $filename ); $special_chars = array( '?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"', '&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}', '%', '+', '’', '«', '»', '”', '“', chr( 0 ) ); if ( ! wp_is_valid_utf8( $filename ) ) { $_ext = pathinfo( $filename, PATHINFO_EXTENSION ); $_name = pathinfo( $filename, PATHINFO_FILENAME ); $filename = sanitize_title_with_dashes( $_name ) . '.' . $_ext; } if ( _wp_can_use_pcre_u() ) { $filename = preg_replace( '#\p{Zs}#siu', ' ', $filename ); } $special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw ); $filename = str_replace( $special_chars, '', $filename ); $filename = str_replace( array( '%20', '+' ), '-', $filename ); $filename = preg_replace( '/\.{2,}/', '.', $filename ); $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); $filename = trim( $filename, '.-_' ); if ( ! str_contains( $filename, '.' ) ) { $mime_types = wp_get_mime_types(); $filetype = wp_check_filetype( 'test.' . $filename, $mime_types ); if ( $filetype['ext'] === $filename ) { $filename = 'unnamed-file.' . $filetype['ext']; } } $parts = explode( '.', $filename ); if ( count( $parts ) <= 2 ) { return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); } $filename = array_shift( $parts ); $extension = array_pop( $parts ); $mimes = get_allowed_mime_types(); foreach ( (array) $parts as $part ) { $filename .= '.' . $part; if ( preg_match( '/^[a-zA-Z]{2,5}\d?$/', $part ) ) { $allowed = false; foreach ( $mimes as $ext_preg => $mime_match ) { $ext_preg = '!^(' . $ext_preg . ')$!i'; if ( preg_match( $ext_preg, $part ) ) { $allowed = true; break; } } if ( ! $allowed ) { $filename .= '_'; } } } $filename .= '.' . $extension; return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); } function sanitize_user( $username, $strict = false ) { $raw_username = $username; $username = wp_strip_all_tags( $username ); $username = remove_accents( $username ); $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username ); $username = preg_replace( '/&.+?;/', '', $username ); if ( $strict ) { $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username ); } $username = trim( $username ); $username = preg_replace( '|\s+|', ' ', $username ); return apply_filters( 'sanitize_user', $username, $raw_username, $strict ); } function sanitize_key( $key ) { $sanitized_key = ''; if ( is_scalar( $key ) ) { $sanitized_key = strtolower( $key ); $sanitized_key = preg_replace( '/[^a-z0-9_\-]/', '', $sanitized_key ); } return apply_filters( 'sanitize_key', $sanitized_key, $key ); } function sanitize_title( $title, $fallback_title = '', $context = 'save' ) { $raw_title = $title; if ( 'save' === $context ) { $title = remove_accents( $title ); } $title = apply_filters( 'sanitize_title', $title, $raw_title, $context ); if ( '' === $title || false === $title ) { $title = $fallback_title; } return $title; } function sanitize_title_for_query( $title ) { return sanitize_title( $title, '', 'query' ); } function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) { $title = strip_tags( $title ); $title = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title ); $title = str_replace( '%', '', $title ); $title = preg_replace( '|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title ); if ( wp_is_valid_utf8( $title ) ) { if ( function_exists( 'mb_strtolower' ) ) { $title = mb_strtolower( $title, 'UTF-8' ); } $title = utf8_uri_encode( $title, 200 ); } $title = strtolower( $title ); if ( 'save' === $context ) { $title = str_replace( array( '%c2%a0', '%e2%80%91', '%e2%80%93', '%e2%80%94' ), '-', $title ); $title = str_replace( array( ' ', '‑', ' ', '–', '–', '—', '—' ), '-', $title ); $title = str_replace( '/', '-', $title ); $title = str_replace( array( '%c2%ad', '%c2%a1', '%c2%bf', '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba', '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d', '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f', '%e2%80%a2', '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2', '%c2%b4', '%cb%8a', '%cc%81', '%cd%81', '%cc%80', '%cc%84', '%cc%8c', '%e2%80%8b', '%e2%80%8c', '%e2%80%8d', '%e2%80%8e', '%e2%80%8f', '%e2%80%aa', '%e2%80%ab', '%e2%80%ac', '%e2%80%ad', '%e2%80%ae', '%ef%bb%bf', '%ef%bf%bc', ), '', $title ); $title = str_replace( array( '%e2%80%80', '%e2%80%81', '%e2%80%82', '%e2%80%83', '%e2%80%84', '%e2%80%85', '%e2%80%86', '%e2%80%87', '%e2%80%88', '%e2%80%89', '%e2%80%8a', '%e2%80%a8', '%e2%80%a9', '%e2%80%af', ), '-', $title ); $title = str_replace( '%c3%97', 'x', $title ); } $title = preg_replace( '/&.+?;/', '', $title ); $title = str_replace( '.', '-', $title ); $title = preg_replace( '/[^%a-z0-9 _-]/', '', $title ); $title = preg_replace( '/\s+/', '-', $title ); $title = preg_replace( '|-+|', '-', $title ); $title = trim( $title, '-' ); return $title; } function sanitize_sql_orderby( $orderby ) { if ( preg_match( '/^\s*(([a-z0-9_]+|`[a-z0-9_]+`)(\s+(ASC|DESC))?\s*(,\s*(?=[a-z0-9_`])|$))+$/i', $orderby ) || preg_match( '/^\s*RAND\(\s*\)\s*$/i', $orderby ) ) { return $orderby; } return false; } function sanitize_html_class( $classname, $fallback = '' ) { $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $classname ); $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized ); if ( '' === $sanitized && $fallback ) { return sanitize_html_class( $fallback ); } return apply_filters( 'sanitize_html_class', $sanitized, $classname, $fallback ); } function sanitize_locale_name( $locale_name ) { $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $locale_name ); return apply_filters( 'sanitize_locale_name', $sanitized, $locale_name ); } function convert_chars( $content, $deprecated = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '0.71' ); } if ( str_contains( $content, '&' ) ) { $content = preg_replace( '/&([^#])(?![a-z1-4]{1,8};)/i', '&$1', $content ); } return $content; } function convert_invalid_entities( $content ) { $wp_htmltranswinuni = array( '€' => '€', '' => '', '‚' => '‚', 'ƒ' => 'ƒ', '„' => '„', '…' => '…', '†' => '†', '‡' => '‡', 'ˆ' => 'ˆ', '‰' => '‰', 'Š' => 'Š', '‹' => '‹', 'Œ' => 'Œ', '' => '', 'Ž' => 'Ž', '' => '', '' => '', '‘' => '‘', '’' => '’', '“' => '“', '”' => '”', '•' => '•', '–' => '–', '—' => '—', '˜' => '˜', '™' => '™', 'š' => 'š', '›' => '›', 'œ' => 'œ', '' => '', 'ž' => 'ž', 'Ÿ' => 'Ÿ', ); if ( str_contains( $content, '' ) ) { $content = strtr( $content, $wp_htmltranswinuni ); } return $content; } function balanceTags( $text, $force = false ) { if ( $force || 1 === (int) get_option( 'use_balanceTags' ) ) { return force_balance_tags( $text ); } else { return $text; } } function force_balance_tags( $text ) { $tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = ''; $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source', 'track', 'wbr' ); $nestable_tags = array( 'article', 'aside', 'blockquote', 'details', 'div', 'figure', 'object', 'q', 'section', 'span' ); $text = str_replace( '< !--', '< !--', $text ); $text = preg_replace( '#<([0-9]{1})#', '<$1', $text ); $tag_pattern = ( '#<' . '(/?)' . '(' . '(?:[a-z](?:[a-z0-9._]*)-(?:[a-z0-9._-]+)+)' . '|' . '(?:[\w:]+)' . ')' . '(?:' . '\s*' . '(/?)' . '|' . '(\s+)' . '([^>]*)' . ')' . '>#' ); while ( preg_match( $tag_pattern, $text, $regex ) ) { $full_match = $regex[0]; $has_leading_slash = ! empty( $regex[1] ); $tag_name = $regex[2]; $tag = strtolower( $tag_name ); $is_single_tag = in_array( $tag, $single_tags, true ); $pre_attribute_ws = isset( $regex[4] ) ? $regex[4] : ''; $attributes = trim( isset( $regex[5] ) ? $regex[5] : $regex[3] ); $has_self_closer = str_ends_with( $attributes, '/' ); $newtext .= $tagqueue; $i = strpos( $text, $full_match ); $l = strlen( $full_match ); $tagqueue = ''; if ( $has_leading_slash ) { if ( $stacksize <= 0 ) { $tag = ''; } elseif ( $tagstack[ $stacksize - 1 ] === $tag ) { $tag = '</' . $tag . '>'; array_pop( $tagstack ); --$stacksize; } else { for ( $j = $stacksize - 1; $j >= 0; $j-- ) { if ( $tagstack[ $j ] === $tag ) { for ( $k = $stacksize - 1; $k >= $j; $k-- ) { $tagqueue .= '</' . array_pop( $tagstack ) . '>'; --$stacksize; } break; } } $tag = ''; } } else { if ( $has_self_closer ) { if ( ! $is_single_tag ) { $attributes = trim( substr( $attributes, 0, -1 ) ) . "></$tag"; } } elseif ( $is_single_tag ) { $pre_attribute_ws = ' '; $attributes .= '/'; } else { if ( $stacksize > 0 && ! in_array( $tag, $nestable_tags, true ) && $tagstack[ $stacksize - 1 ] === $tag ) { $tagqueue = '</' . array_pop( $tagstack ) . '>'; --$stacksize; } $stacksize = array_push( $tagstack, $tag ); } if ( $has_self_closer && $is_single_tag ) { $pre_attribute_ws = ' '; } $tag = '<' . $tag . $pre_attribute_ws . $attributes . '>'; if ( ! empty( $tagqueue ) ) { $tagqueue .= $tag; $tag = ''; } } $newtext .= substr( $text, 0, $i ) . $tag; $text = substr( $text, $i + $l ); } $newtext .= $tagqueue; $newtext .= $text; while ( $x = array_pop( $tagstack ) ) { $newtext .= '</' . $x . '>'; } $newtext = str_replace( '< !--', '<!--', $newtext ); $newtext = str_replace( '< !--', '< !--', $newtext ); return $newtext; } function format_to_edit( $content, $rich_text = false ) { $content = apply_filters( 'format_to_edit', $content ); if ( ! $rich_text ) { $content = esc_textarea( $content ); } return $content; } function zeroise( $number, $threshold ) { return sprintf( '%0' . $threshold . 's', $number ); } function backslashit( $value ) { if ( isset( $value[0] ) && $value[0] >= '0' && $value[0] <= '9' ) { $value = '\\\\' . $value; } return addcslashes( $value, 'A..Za..z' ); } function trailingslashit( $value ) { return untrailingslashit( $value ) . '/'; } function untrailingslashit( $value ) { return rtrim( $value, '/\\' ); } function addslashes_gpc( $gpc ) { return wp_slash( $gpc ); } function stripslashes_deep( $value ) { return map_deep( $value, 'stripslashes_from_strings_only' ); } function stripslashes_from_strings_only( $value ) { return is_string( $value ) ? stripslashes( $value ) : $value; } function urlencode_deep( $value ) { return map_deep( $value, 'urlencode' ); } function rawurlencode_deep( $value ) { return map_deep( $value, 'rawurlencode' ); } function urldecode_deep( $value ) { return map_deep( $value, 'urldecode' ); } function antispambot( $email_address, $hex_encoding = 0 ) { $email_no_spam_address = ''; for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) { $j = rand( 0, 1 + $hex_encoding ); if ( 0 === $j ) { $email_no_spam_address .= '&#' . ord( $email_address[ $i ] ) . ';'; } elseif ( 1 === $j ) { $email_no_spam_address .= $email_address[ $i ]; } elseif ( 2 === $j ) { $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[ $i ] ) ), 2 ); } } return str_replace( '@', '@', $email_no_spam_address ); } function _make_url_clickable_cb( $matches ) { $url = $matches[2]; if ( ')' === $matches[3] && strpos( $url, '(' ) ) { $url .= $matches[3]; $suffix = ''; } else { $suffix = $matches[3]; } if ( isset( $matches[4] ) && ! empty( $matches[4] ) ) { $url .= $matches[4]; } while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) { $suffix = strrchr( $url, ')' ) . $suffix; $url = substr( $url, 0, strrpos( $url, ')' ) ); } $url = esc_url( $url ); if ( empty( $url ) ) { return $matches[0]; } $rel_attr = _make_clickable_rel_attr( $url ); return $matches[1] . "<a href=\"{$url}\"{$rel_attr}>{$url}</a>" . $suffix; } function _make_web_ftp_clickable_cb( $matches ) { $ret = ''; $dest = $matches[2]; $dest = 'http://' . $dest; $last_char = substr( $dest, -1 ); if ( in_array( $last_char, array( '.', ',', ';', ':', ')' ), true ) ) { $ret = $last_char; $dest = substr( $dest, 0, strlen( $dest ) - 1 ); } $dest = esc_url( $dest ); if ( empty( $dest ) ) { return $matches[0]; } $rel_attr = _make_clickable_rel_attr( $dest ); return $matches[1] . "<a href=\"{$dest}\"{$rel_attr}>{$dest}</a>{$ret}"; } function _make_email_clickable_cb( $matches ) { $email = $matches[2] . '@' . $matches[3]; return $matches[1] . "<a href=\"mailto:{$email}\">{$email}</a>"; } function _make_clickable_rel_attr( $url ) { $rel_parts = array(); $scheme = strtolower( wp_parse_url( $url, PHP_URL_SCHEME ) ); $nofollow_schemes = array_intersect( wp_allowed_protocols(), array( 'https', 'http' ) ); if ( ! wp_is_internal_link( $url ) && in_array( $scheme, $nofollow_schemes, true ) ) { $rel_parts[] = 'nofollow'; } if ( 'comment_text' === current_filter() ) { $rel_parts[] = 'ugc'; } $rel = implode( ' ', $rel_parts ); $rel = apply_filters( 'make_clickable_rel', $rel, $url ); $rel_attr = $rel ? ' rel="' . esc_attr( $rel ) . '"' : ''; return $rel_attr; } function make_clickable( $text ) { $r = ''; $textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); $nested_code_pre = 0; foreach ( $textarr as $piece ) { if ( preg_match( '|^<code[\s>]|i', $piece ) || preg_match( '|^<pre[\s>]|i', $piece ) || preg_match( '|^<script[\s>]|i', $piece ) || preg_match( '|^<style[\s>]|i', $piece ) ) { ++$nested_code_pre; } elseif ( $nested_code_pre && ( '</code>' === strtolower( $piece ) || '</pre>' === strtolower( $piece ) || '</script>' === strtolower( $piece ) || '</style>' === strtolower( $piece ) ) ) { --$nested_code_pre; } if ( $nested_code_pre || empty( $piece ) || ( '<' === $piece[0] && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) { $r .= $piece; continue; } if ( 10000 < strlen( $piece ) ) { foreach ( _split_str_by_whitespace( $piece, 2100 ) as $chunk ) { if ( 2101 < strlen( $chunk ) ) { $r .= $chunk; } else { $r .= make_clickable( $chunk ); } } } else { $ret = " $piece "; $url_clickable = '~
([\\s(<.,;:!?]) # 1: Leading whitespace, or punctuation.
( # 2: URL.
[\\w]{1,20}+:// # Scheme and hier-part prefix.
(?=\S{1,2000}\s) # Limit to URLs less than about 2000 characters long.
[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character.
(?: # Unroll the Loop: Only allow punctuation URL character if followed by a non-punctuation URL character.
[\'.,;:!?)] # Punctuation URL character.
[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character.
)*
)
(\)?) # 3: Trailing closing parenthesis (for parenthesis balancing post processing).
(\\.\\w{2,6})? # 4: Allowing file extensions (e.g., .jpg, .png).
~xS'; $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret ); $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret ); $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret ); $ret = substr( $ret, 1, -1 ); $r .= $ret; } } return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', '$1$3</a>', $r ); } function _split_str_by_whitespace( $text, $goal ) { $chunks = array(); $string_nullspace = strtr( $text, "\r\n\t\v\f ", "\000\000\000\000\000\000" ); while ( $goal < strlen( $string_nullspace ) ) { $pos = strrpos( substr( $string_nullspace, 0, $goal + 1 ), "\000" ); if ( false === $pos ) { $pos = strpos( $string_nullspace, "\000", $goal + 1 ); if ( false === $pos ) { break; } } $chunks[] = substr( $text, 0, $pos + 1 ); $text = substr( $text, $pos + 1 ); $string_nullspace = substr( $string_nullspace, $pos + 1 ); } if ( $text ) { $chunks[] = $text; } return $chunks; } function wp_rel_callback( $matches, $rel ) { $text = $matches[1]; $atts = wp_kses_hair( $matches[1], wp_allowed_protocols() ); if ( ! empty( $atts['href'] ) && wp_is_internal_link( $atts['href']['value'] ) ) { $rel = trim( str_replace( 'nofollow', '', $rel ) ); } if ( ! empty( $atts['rel'] ) ) { $parts = array_map( 'trim', explode( ' ', $atts['rel']['value'] ) ); $rel_array = array_map( 'trim', explode( ' ', $rel ) ); $parts = array_unique( array_merge( $parts, $rel_array ) ); $rel = implode( ' ', $parts ); unset( $atts['rel'] ); $html = ''; foreach ( $atts as $name => $value ) { if ( isset( $value['vless'] ) && 'y' === $value['vless'] ) { $html .= $name . ' '; } else { $html .= "{$name}=\"" . esc_attr( $value['value'] ) . '" '; } } $text = trim( $html ); } $rel_attr = $rel ? ' rel="' . esc_attr( $rel ) . '"' : ''; return "<a {$text}{$rel_attr}>"; } function wp_rel_nofollow( $text ) { $text = stripslashes( $text ); $text = preg_replace_callback( '|<a (.+?)>|i', static function ( $matches ) { return wp_rel_callback( $matches, 'nofollow' ); }, $text ); return wp_slash( $text ); } function wp_rel_nofollow_callback( $matches ) { return wp_rel_callback( $matches, 'nofollow' ); } function wp_rel_ugc( $text ) { $text = stripslashes( $text ); $text = preg_replace_callback( '|<a (.+?)>|i', static function ( $matches ) { return wp_rel_callback( $matches, 'nofollow ugc' ); }, $text ); return wp_slash( $text ); } function wp_targeted_link_rel( $text ) { _deprecated_function( __FUNCTION__, '6.7.0' ); if ( false === stripos( $text, 'target' ) || false === stripos( $text, '<a ' ) || is_serialized( $text ) ) { return $text; } $script_and_style_regex = '/<(script|style).*?<\/\\1>/si'; preg_match_all( $script_and_style_regex, $text, $matches ); $extra_parts = $matches[0]; $html_parts = preg_split( $script_and_style_regex, $text ); foreach ( $html_parts as &$part ) { $part = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $part ); } $text = ''; for ( $i = 0; $i < count( $html_parts ); $i++ ) { $text .= $html_parts[ $i ]; if ( isset( $extra_parts[ $i ] ) ) { $text .= $extra_parts[ $i ]; } } return $text; } function wp_targeted_link_rel_callback( $matches ) { _deprecated_function( __FUNCTION__, '6.7.0' ); $link_html = $matches[1]; $original_link_html = $link_html; $is_escaped = ! preg_match( '/(^|[^\\\\])[\'"]/', $link_html ); if ( $is_escaped ) { $link_html = preg_replace( '/\\\\([\'"])/', '$1', $link_html ); } $atts = wp_kses_hair( $link_html, wp_allowed_protocols() ); $rel = apply_filters( 'wp_targeted_link_rel', 'noopener', $link_html ); if ( ! $rel || ! isset( $atts['target'] ) ) { return "<a $original_link_html>"; } if ( isset( $atts['rel'] ) ) { $all_parts = preg_split( '/\s/', "{$atts['rel']['value']} $rel", -1, PREG_SPLIT_NO_EMPTY ); $rel = implode( ' ', array_unique( $all_parts ) ); } $atts['rel']['whole'] = 'rel="' . esc_attr( $rel ) . '"'; $link_html = implode( ' ', array_column( $atts, 'whole' ) ); if ( $is_escaped ) { $link_html = preg_replace( '/[\'"]/', '\\\\$0', $link_html ); } return "<a $link_html>"; } function wp_init_targeted_link_rel_filters() { _deprecated_function( __FUNCTION__, '6.7.0' ); } function wp_remove_targeted_link_rel_filters() { _deprecated_function( __FUNCTION__, '6.7.0' ); } function translate_smiley( $matches ) { global $wpsmiliestrans; if ( 0 === count( $matches ) ) { return ''; } $smiley = trim( reset( $matches ) ); $img = $wpsmiliestrans[ $smiley ]; $matches = array(); $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false; $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif' ); if ( ! in_array( $ext, $image_exts, true ) ) { return $img; } $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() ); return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', esc_url( $src_url ), esc_attr( $smiley ) ); } function convert_smilies( $text ) { global $wp_smiliessearch; if ( ! get_option( 'use_smilies' ) || empty( $wp_smiliessearch ) ) { return $text; } $textarr = preg_split( '/(<[^>]*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); if ( false === $textarr ) { return $text; } $stop = count( $textarr ); $output = ''; $tags_to_ignore = 'code|pre|style|script|textarea'; $ignore_block_element = ''; for ( $i = 0; $i < $stop; $i++ ) { $content = $textarr[ $i ]; if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[^>]*>/', $content, $matches ) ) { $ignore_block_element = $matches[1]; } if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) { $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content ); } if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) { $ignore_block_element = ''; } $output .= $content; } return $output; } function is_email( $email, $deprecated = false ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '3.0.0' ); } if ( strlen( $email ) < 6 ) { return apply_filters( 'is_email', false, $email, 'email_too_short' ); } if ( false === strpos( $email, '@', 1 ) ) { return apply_filters( 'is_email', false, $email, 'email_no_at' ); } list( $local, $domain ) = explode( '@', $email, 2 ); if ( ! preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) { return apply_filters( 'is_email', false, $email, 'local_invalid_chars' ); } if ( preg_match( '/\.{2,}/', $domain ) ) { return apply_filters( 'is_email', false, $email, 'domain_period_sequence' ); } if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) { return apply_filters( 'is_email', false, $email, 'domain_period_limits' ); } $subs = explode( '.', $domain ); if ( 2 > count( $subs ) ) { return apply_filters( 'is_email', false, $email, 'domain_no_periods' ); } foreach ( $subs as $sub ) { if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) { return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' ); } if ( ! preg_match( '/^[a-z0-9-]+$/i', $sub ) ) { return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' ); } } return apply_filters( 'is_email', $email, $email, null ); } function wp_iso_descrambler( $subject ) { if ( ! preg_match( '#\=\?(.+)\?Q\?(.+)\?\=#i', $subject, $matches ) ) { return $subject; } $subject = str_replace( '_', ' ', $matches[2] ); return preg_replace_callback( '#\=([0-9a-f]{2})#i', '_wp_iso_convert', $subject ); } function _wp_iso_convert( $matches ) { return chr( hexdec( strtolower( $matches[1] ) ) ); } function get_gmt_from_date( $date_string, $format = 'Y-m-d H:i:s' ) { $datetime = date_create( $date_string, wp_timezone() ); if ( false === $datetime ) { return gmdate( $format, 0 ); } return $datetime->setTimezone( new DateTimeZone( 'UTC' ) )->format( $format ); } function get_date_from_gmt( $date_string, $format = 'Y-m-d H:i:s' ) { $datetime = date_create( $date_string, new DateTimeZone( 'UTC' ) ); if ( false === $datetime ) { return gmdate( $format, 0 ); } return $datetime->setTimezone( wp_timezone() )->format( $format ); } function iso8601_timezone_to_offset( $timezone ) { if ( 'Z' === $timezone ) { $offset = 0; } else { $sign = ( str_starts_with( $timezone, '+' ) ) ? 1 : -1; $hours = (int) substr( $timezone, 1, 2 ); $minutes = (int) substr( $timezone, 3, 4 ) / 60; $offset = $sign * HOUR_IN_SECONDS * ( $hours + $minutes ); } return $offset; } function iso8601_to_datetime( $date_string, $timezone = 'user' ) { $timezone = strtolower( $timezone ); $wp_timezone = wp_timezone(); $datetime = date_create( $date_string, $wp_timezone ); if ( false === $datetime ) { return false; } if ( 'gmt' === $timezone ) { return $datetime->setTimezone( new DateTimeZone( 'UTC' ) )->format( 'Y-m-d H:i:s' ); } if ( 'user' === $timezone ) { return $datetime->setTimezone( $wp_timezone )->format( 'Y-m-d H:i:s' ); } return false; } function sanitize_email( $email ) { if ( strlen( $email ) < 6 ) { return apply_filters( 'sanitize_email', '', $email, 'email_too_short' ); } if ( false === strpos( $email, '@', 1 ) ) { return apply_filters( 'sanitize_email', '', $email, 'email_no_at' ); } list( $local, $domain ) = explode( '@', $email, 2 ); $local = preg_replace( '/[^a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]/', '', $local ); if ( '' === $local ) { return apply_filters( 'sanitize_email', '', $email, 'local_invalid_chars' ); } $domain = preg_replace( '/\.{2,}/', '', $domain ); if ( '' === $domain ) { return apply_filters( 'sanitize_email', '', $email, 'domain_period_sequence' ); } $domain = trim( $domain, " \t\n\r\0\x0B." ); if ( '' === $domain ) { return apply_filters( 'sanitize_email', '', $email, 'domain_period_limits' ); } $subs = explode( '.', $domain ); if ( 2 > count( $subs ) ) { return apply_filters( 'sanitize_email', '', $email, 'domain_no_periods' ); } $new_subs = array(); foreach ( $subs as $sub ) { $sub = trim( $sub, " \t\n\r\0\x0B-" ); $sub = preg_replace( '/[^a-z0-9-]+/i', '', $sub ); if ( '' !== $sub ) { $new_subs[] = $sub; } } if ( 2 > count( $new_subs ) ) { return apply_filters( 'sanitize_email', '', $email, 'domain_no_valid_subs' ); } $domain = implode( '.', $new_subs ); $sanitized_email = $local . '@' . $domain; return apply_filters( 'sanitize_email', $sanitized_email, $email, null ); } function human_time_diff( $from, $to = 0 ) { if ( empty( $to ) ) { $to = time(); } $diff = (int) abs( $to - $from ); if ( $diff < MINUTE_IN_SECONDS ) { $secs = $diff; if ( $secs <= 1 ) { $secs = 1; } $since = sprintf( _n( '%s second', '%s seconds', $secs ), $secs ); } elseif ( $diff < HOUR_IN_SECONDS && $diff >= MINUTE_IN_SECONDS ) { $mins = round( $diff / MINUTE_IN_SECONDS ); if ( $mins <= 1 ) { $mins = 1; } $since = sprintf( _n( '%s minute', '%s minutes', $mins ), $mins ); } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) { $hours = round( $diff / HOUR_IN_SECONDS ); if ( $hours <= 1 ) { $hours = 1; } $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours ); } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) { $days = round( $diff / DAY_IN_SECONDS ); if ( $days <= 1 ) { $days = 1; } $since = sprintf( _n( '%s day', '%s days', $days ), $days ); } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) { $weeks = round( $diff / WEEK_IN_SECONDS ); if ( $weeks <= 1 ) { $weeks = 1; } $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks ); } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) { $months = round( $diff / MONTH_IN_SECONDS ); if ( $months <= 1 ) { $months = 1; } $since = sprintf( _n( '%s month', '%s months', $months ), $months ); } elseif ( $diff >= YEAR_IN_SECONDS ) { $years = round( $diff / YEAR_IN_SECONDS ); if ( $years <= 1 ) { $years = 1; } $since = sprintf( _n( '%s year', '%s years', $years ), $years ); } return apply_filters( 'human_time_diff', $since, $diff, $from, $to ); } function wp_trim_excerpt( $text = '', $post = null ) { $raw_excerpt = $text; if ( '' === trim( $text ) ) { $post = get_post( $post ); $text = get_the_content( '', false, $post ); $text = strip_shortcodes( $text ); $text = excerpt_remove_blocks( $text ); $text = excerpt_remove_footnotes( $text ); $filter_image_removed = remove_filter( 'the_content', 'wp_filter_content_tags', 12 ); $filter_block_removed = remove_filter( 'the_content', 'do_blocks', 9 ); $text = apply_filters( 'the_content', $text ); $text = str_replace( ']]>', ']]>', $text ); if ( $filter_block_removed ) { add_filter( 'the_content', 'do_blocks', 9 ); } if ( $filter_image_removed ) { add_filter( 'the_content', 'wp_filter_content_tags', 12 ); } $excerpt_length = (int) _x( '55', 'excerpt_length' ); $excerpt_length = (int) apply_filters( 'excerpt_length', $excerpt_length ); $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); $text = wp_trim_words( $text, $excerpt_length, $excerpt_more ); } return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt ); } function wp_trim_words( $text, $num_words = 55, $more = null ) { if ( null === $more ) { $more = __( '…' ); } $original_text = $text; $text = wp_strip_all_tags( $text ); $num_words = (int) $num_words; if ( str_starts_with( wp_get_word_count_type(), 'characters' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) { $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' ); preg_match_all( '/./u', $text, $words_array ); $words_array = array_slice( $words_array[0], 0, $num_words + 1 ); $sep = ''; } else { $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY ); $sep = ' '; } if ( count( $words_array ) > $num_words ) { array_pop( $words_array ); $text = implode( $sep, $words_array ); $text = $text . $more; } else { $text = implode( $sep, $words_array ); } return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text ); } function ent2ncr( $text ) { $filtered = apply_filters( 'pre_ent2ncr', null, $text ); if ( null !== $filtered ) { return $filtered; } $to_ncr = array( '"' => '"', '&' => '&', '<' => '<', '>' => '>', '|' => '|', ' ' => ' ', '¡' => '¡', '¢' => '¢', '£' => '£', '¤' => '¤', '¥' => '¥', '¦' => '¦', '&brkbar;' => '¦', '§' => '§', '¨' => '¨', '¨' => '¨', '©' => '©', 'ª' => 'ª', '«' => '«', '¬' => '¬', '­' => '­', '®' => '®', '¯' => '¯', '&hibar;' => '¯', '°' => '°', '±' => '±', '²' => '²', '³' => '³', '´' => '´', 'µ' => 'µ', '¶' => '¶', '·' => '·', '¸' => '¸', '¹' => '¹', 'º' => 'º', '»' => '»', '¼' => '¼', '½' => '½', '¾' => '¾', '¿' => '¿', 'À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Æ' => 'Æ', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ð' => 'Ð', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', '×' => '×', 'Ø' => 'Ø', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'Þ' => 'Þ', 'ß' => 'ß', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'æ' => 'æ', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ð' => 'ð', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', '÷' => '÷', 'ø' => 'ø', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'þ' => 'þ', 'ÿ' => 'ÿ', 'Œ' => 'Œ', 'œ' => 'œ', 'Š' => 'Š', 'š' => 'š', 'Ÿ' => 'Ÿ', 'ƒ' => 'ƒ', 'ˆ' => 'ˆ', '˜' => '˜', 'Α' => 'Α', 'Β' => 'Β', 'Γ' => 'Γ', 'Δ' => 'Δ', 'Ε' => 'Ε', 'Ζ' => 'Ζ', 'Η' => 'Η', 'Θ' => 'Θ', 'Ι' => 'Ι', 'Κ' => 'Κ', 'Λ' => 'Λ', 'Μ' => 'Μ', 'Ν' => 'Ν', 'Ξ' => 'Ξ', 'Ο' => 'Ο', 'Π' => 'Π', 'Ρ' => 'Ρ', 'Σ' => 'Σ', 'Τ' => 'Τ', 'Υ' => 'Υ', 'Φ' => 'Φ', 'Χ' => 'Χ', 'Ψ' => 'Ψ', 'Ω' => 'Ω', 'α' => 'α', 'β' => 'β', 'γ' => 'γ', 'δ' => 'δ', 'ε' => 'ε', 'ζ' => 'ζ', 'η' => 'η', 'θ' => 'θ', 'ι' => 'ι', 'κ' => 'κ', 'λ' => 'λ', 'μ' => 'μ', 'ν' => 'ν', 'ξ' => 'ξ', 'ο' => 'ο', 'π' => 'π', 'ρ' => 'ρ', 'ς' => 'ς', 'σ' => 'σ', 'τ' => 'τ', 'υ' => 'υ', 'φ' => 'φ', 'χ' => 'χ', 'ψ' => 'ψ', 'ω' => 'ω', 'ϑ' => 'ϑ', 'ϒ' => 'ϒ', 'ϖ' => 'ϖ', ' ' => ' ', ' ' => ' ', ' ' => ' ', '‌' => '‌', '‍' => '‍', '‎' => '‎', '‏' => '‏', '–' => '–', '—' => '—', '‘' => '‘', '’' => '’', '‚' => '‚', '“' => '“', '”' => '”', '„' => '„', '†' => '†', '‡' => '‡', '•' => '•', '…' => '…', '‰' => '‰', '′' => '′', '″' => '″', '‹' => '‹', '›' => '›', '‾' => '‾', '⁄' => '⁄', '€' => '€', 'ℑ' => 'ℑ', '℘' => '℘', 'ℜ' => 'ℜ', '™' => '™', 'ℵ' => 'ℵ', '↵' => '↵', '⇐' => '⇐', '⇑' => '⇑', '⇒' => '⇒', '⇓' => '⇓', '⇔' => '⇔', '∀' => '∀', '∂' => '∂', '∃' => '∃', '∅' => '∅', '∇' => '∇', '∈' => '∈', '∉' => '∉', '∋' => '∋', '∏' => '∏', '∑' => '∑', '−' => '−', '∗' => '∗', '√' => '√', '∝' => '∝', '∞' => '∞', '∠' => '∠', '∧' => '∧', '∨' => '∨', '∩' => '∩', '∪' => '∪', '∫' => '∫', '∴' => '∴', '∼' => '∼', '≅' => '≅', '≈' => '≈', '≠' => '≠', '≡' => '≡', '≤' => '≤', '≥' => '≥', '⊂' => '⊂', '⊃' => '⊃', '⊄' => '⊄', '⊆' => '⊆', '⊇' => '⊇', '⊕' => '⊕', '⊗' => '⊗', '⊥' => '⊥', '⋅' => '⋅', '⌈' => '⌈', '⌉' => '⌉', '⌊' => '⌊', '⌋' => '⌋', '⟨' => '〈', '⟩' => '〉', '←' => '←', '↑' => '↑', '→' => '→', '↓' => '↓', '↔' => '↔', '◊' => '◊', '♠' => '♠', '♣' => '♣', '♥' => '♥', '♦' => '♦', ); return str_replace( array_keys( $to_ncr ), array_values( $to_ncr ), $text ); } function format_for_editor( $text, $default_editor = null ) { if ( $text ) { $text = htmlspecialchars( $text, ENT_NOQUOTES, get_option( 'blog_charset' ) ); } return apply_filters( 'format_for_editor', $text, $default_editor ); } function _deep_replace( $search, $subject ) { $subject = (string) $subject; $count = 1; while ( $count ) { $subject = str_replace( $search, '', $subject, $count ); } return $subject; } function esc_sql( $data ) { global $wpdb; return $wpdb->_escape( $data ); } function esc_url( $url, $protocols = null, $_context = 'display' ) { $original_url = $url; if ( '' === $url ) { return $url; } $url = str_replace( ' ', '%20', ltrim( $url ) ); $url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url ); if ( '' === $url ) { return $url; } if ( 0 !== stripos( $url, 'mailto:' ) ) { $strip = array( '%0d', '%0a', '%0D', '%0A' ); $url = _deep_replace( $strip, $url ); } $url = str_replace( ';//', '://', $url ); if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '/', '#', '?' ), true ) && ! preg_match( '/^[a-z0-9-]+?\.php/i', $url ) ) { $scheme = ( is_array( $protocols ) && 'https' === array_first( $protocols ) ) ? 'https://' : 'http://'; $url = $scheme . $url; } if ( 'display' === $_context ) { $url = wp_kses_normalize_entities( $url ); $url = str_replace( '&', '&', $url ); $url = str_replace( "'", ''', $url ); } if ( str_contains( $url, '[' ) || str_contains( $url, ']' ) ) { $parsed = wp_parse_url( $url ); $front = ''; if ( isset( $parsed['scheme'] ) ) { $front .= $parsed['scheme'] . '://'; } elseif ( '/' === $url[0] ) { $front .= '//'; } if ( isset( $parsed['user'] ) ) { $front .= $parsed['user']; } if ( isset( $parsed['pass'] ) ) { $front .= ':' . $parsed['pass']; } if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) { $front .= '@'; } if ( isset( $parsed['host'] ) ) { $front .= $parsed['host']; } if ( isset( $parsed['port'] ) ) { $front .= ':' . $parsed['port']; } $end_dirty = str_replace( $front, '', $url ); $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty ); $url = str_replace( $end_dirty, $end_clean, $url ); } if ( '/' === $url[0] ) { $good_protocol_url = $url; } else { if ( ! is_array( $protocols ) ) { $protocols = wp_allowed_protocols(); } $good_protocol_url = wp_kses_bad_protocol( $url, $protocols ); if ( strtolower( $good_protocol_url ) !== strtolower( $url ) ) { return ''; } } return apply_filters( 'clean_url', $good_protocol_url, $original_url, $_context ); } function esc_url_raw( $url, $protocols = null ) { return sanitize_url( $url, $protocols ); } function sanitize_url( $url, $protocols = null ) { return esc_url( $url, $protocols, 'db' ); } function htmlentities2( $text ) { $translation_table = get_html_translation_table( HTML_ENTITIES, ENT_QUOTES ); $translation_table[ chr( 38 ) ] = '&'; return preg_replace( '/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/', '&', strtr( $text, $translation_table ) ); } function esc_js( $text ) { $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_COMPAT ); $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) ); $safe_text = str_replace( "\r", '', $safe_text ); $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) ); return apply_filters( 'js_escape', $safe_text, $text ); } function esc_html( $text ) { $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES ); return apply_filters( 'esc_html', $safe_text, $text ); } function esc_attr( $text ) { $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES ); return apply_filters( 'attribute_escape', $safe_text, $text ); } function esc_textarea( $text ) { $safe_text = htmlspecialchars( $text, ENT_QUOTES, get_option( 'blog_charset' ) ); return apply_filters( 'esc_textarea', $safe_text, $text ); } function esc_xml( $text ) { $safe_text = wp_check_invalid_utf8( $text ); $cdata_regex = '\<\!\[CDATA\[.*?\]\]\>'; $regex = <<<EOF
/
(?=.*?{$cdata_regex}) # lookahead that will match anything followed by a CDATA Section
(?<non_cdata_followed_by_cdata>(.*?)) # the "anything" matched by the lookahead
(?<cdata>({$cdata_regex})) # the CDATA Section matched by the lookahead
| # alternative
(?<non_cdata>(.*)) # non-CDATA Section
/sx
EOF;
$safe_text = (string) preg_replace_callback( $regex, static function ( $matches ) { if ( ! isset( $matches[0] ) ) { return ''; } if ( isset( $matches['non_cdata'] ) ) { return _wp_specialchars( $matches['non_cdata'], ENT_XML1 ); } return _wp_specialchars( $matches['non_cdata_followed_by_cdata'], ENT_XML1 ) . $matches['cdata']; }, $safe_text ); return apply_filters( 'esc_xml', $safe_text, $text ); } function tag_escape( $tag_name ) { $safe_tag = strtolower( preg_replace( '/[^a-zA-Z0-9-_:]/', '', $tag_name ) ); return apply_filters( 'tag_escape', $safe_tag, $tag_name ); } function wp_make_link_relative( $link ) { return preg_replace( '|^(https?:)?//[^/]+(/?.*)|i', '$2', $link ); } function sanitize_option( $option, $value ) { global $wpdb; $original_value = $value; $error = null; switch ( $option ) { case 'admin_email': case 'new_admin_email': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { $value = sanitize_email( $value ); if ( ! is_email( $value ) ) { $error = __( 'The email address entered did not appear to be a valid email address. Please enter a valid email address.' ); } } break; case 'thumbnail_size_w': case 'thumbnail_size_h': case 'medium_size_w': case 'medium_size_h': case 'medium_large_size_w': case 'medium_large_size_h': case 'large_size_w': case 'large_size_h': case 'mailserver_port': case 'comment_max_links': case 'page_on_front': case 'page_for_posts': case 'rss_excerpt_length': case 'default_category': case 'default_email_category': case 'default_link_category': case 'close_comments_days_old': case 'comments_per_page': case 'thread_comments_depth': case 'users_can_register': case 'start_of_week': case 'site_icon': case 'fileupload_maxk': $value = absint( $value ); break; case 'posts_per_page': case 'posts_per_rss': $value = (int) $value; if ( empty( $value ) ) { $value = 1; } if ( $value < -1 ) { $value = abs( $value ); } break; case 'default_ping_status': case 'default_comment_status': if ( '0' === (string) $value || '' === $value ) { $value = 'closed'; } break; case 'blogdescription': case 'blogname': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( $value !== $original_value ) { $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', wp_encode_emoji( $original_value ) ); } if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { $value = esc_html( $value ); } break; case 'blog_charset': if ( is_string( $value ) ) { $value = preg_replace( '/[^a-zA-Z0-9_-]/', '', $value ); } else { $value = ''; } break; case 'blog_public': if ( null === $value ) { $value = 1; } else { $value = (int) $value; } break; case 'date_format': case 'time_format': case 'mailserver_url': case 'mailserver_login': case 'mailserver_pass': case 'upload_path': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { $value = strip_tags( $value ); $value = wp_kses_data( $value ); } break; case 'ping_sites': $value = explode( "\n", $value ); $value = array_filter( array_map( 'trim', $value ) ); $value = array_filter( array_map( 'sanitize_url', $value ) ); $value = implode( "\n", $value ); break; case 'gmt_offset': if ( is_numeric( $value ) ) { $value = preg_replace( '/[^0-9:.-]/', '', $value ); } else { $value = ''; } break; case 'siteurl': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { if ( preg_match( '#http(s?)://(.+)#i', $value ) ) { $value = sanitize_url( $value ); } else { $error = __( 'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.' ); } } break; case 'home': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { if ( preg_match( '#http(s?)://(.+)#i', $value ) ) { $value = sanitize_url( $value ); } else { $error = __( 'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.' ); } } break; case 'WPLANG': $allowed = get_available_languages(); if ( ! is_multisite() && defined( 'WPLANG' ) && '' !== WPLANG && 'en_US' !== WPLANG ) { $allowed[] = WPLANG; } if ( ! in_array( $value, $allowed, true ) && ! empty( $value ) ) { $value = get_option( $option ); } break; case 'illegal_names': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { if ( ! is_array( $value ) ) { $value = explode( ' ', $value ); } $value = array_values( array_filter( array_map( 'trim', $value ) ) ); if ( ! $value ) { $value = ''; } } break; case 'limited_email_domains': case 'banned_email_domains': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { if ( ! is_array( $value ) ) { $value = explode( "\n", $value ); } $domains = array_values( array_filter( array_map( 'trim', $value ) ) ); $value = array(); foreach ( $domains as $domain ) { if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) { $value[] = $domain; } } if ( ! $value ) { $value = ''; } } break; case 'timezone_string': $allowed_zones = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ); if ( ! in_array( $value, $allowed_zones, true ) && ! empty( $value ) ) { $error = __( 'The timezone you have entered is not valid. Please select a valid timezone.' ); } break; case 'permalink_structure': case 'category_base': case 'tag_base': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { $value = sanitize_url( $value ); $value = str_replace( 'http://', '', $value ); } if ( 'permalink_structure' === $option && null === $error && '' !== $value && ! preg_match( '/%[^\/%]+%/', $value ) ) { $error = sprintf( __( 'A structure tag is required when using custom permalinks. <a href="%s">Learn more</a>' ), __( 'https://wordpress.org/documentation/article/customize-permalinks/#choosing-your-permalink-structure' ) ); } break; case 'default_role': if ( ! get_role( $value ) && get_role( 'subscriber' ) ) { $value = 'subscriber'; } break; case 'moderation_keys': case 'disallowed_keys': $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { $value = explode( "\n", $value ); $value = array_filter( array_map( 'trim', $value ) ); $value = array_unique( $value ); $value = implode( "\n", $value ); } break; } if ( null !== $error ) { if ( '' === $error && is_wp_error( $value ) ) { $error = sprintf( __( 'Could not sanitize the %1$s option. Error code: %2$s' ), $option, $value->get_error_code() ); } $value = get_option( $option ); if ( function_exists( 'add_settings_error' ) ) { add_settings_error( $option, "invalid_{$option}", $error ); } } return apply_filters( "sanitize_option_{$option}", $value, $option, $original_value ); } function map_deep( $value, $callback ) { if ( is_array( $value ) ) { foreach ( $value as $index => $item ) { $value[ $index ] = map_deep( $item, $callback ); } } elseif ( is_object( $value ) ) { $object_vars = get_object_vars( $value ); foreach ( $object_vars as $property_name => $property_value ) { $value->$property_name = map_deep( $property_value, $callback ); } } else { $value = call_user_func( $callback, $value ); } return $value; } function wp_parse_str( $input_string, &$result ) { parse_str( (string) $input_string, $result ); $result = apply_filters( 'wp_parse_str', $result ); } function wp_pre_kses_less_than( $content ) { return preg_replace_callback( '%<[^>]*?((?=<)|>|$)%', 'wp_pre_kses_less_than_callback', $content ); } function wp_pre_kses_less_than_callback( $matches ) { if ( ! str_contains( $matches[0], '>' ) ) { return esc_html( $matches[0] ); } return $matches[0]; } function wp_pre_kses_block_attributes( $content, $allowed_html, $allowed_protocols ) { remove_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10 ); $content = filter_block_content( $content, $allowed_html, $allowed_protocols ); add_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10, 3 ); return $content; } function wp_sprintf( $pattern, ...$args ) { $len = strlen( $pattern ); $start = 0; $result = ''; $arg_index = 0; while ( $len > $start ) { if ( strlen( $pattern ) - 1 === $start ) { $result .= substr( $pattern, -1 ); break; } if ( '%%' === substr( $pattern, $start, 2 ) ) { $start += 2; $result .= '%'; continue; } $end = strpos( $pattern, '%', $start + 1 ); if ( false === $end ) { $end = $len; } $fragment = substr( $pattern, $start, $end - $start ); if ( '%' === $pattern[ $start ] ) { if ( preg_match( '/^%(\d+)\$/', $fragment, $matches ) ) { $index = $matches[1] - 1; $arg = isset( $args[ $index ] ) ? $args[ $index ] : ''; $fragment = str_replace( "%{$matches[1]}$", '%', $fragment ); } else { $arg = isset( $args[ $arg_index ] ) ? $args[ $arg_index ] : ''; ++$arg_index; } $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg ); if ( $_fragment !== $fragment ) { $fragment = $_fragment; } else { $fragment = sprintf( $fragment, (string) $arg ); } } $result .= $fragment; $start = $end; } return $result; } function wp_sprintf_l( $pattern, $args ) { if ( ! str_starts_with( $pattern, '%l' ) ) { return $pattern; } if ( empty( $args ) ) { return ''; } $l = apply_filters( 'wp_sprintf_l', array( 'between' => sprintf( __( '%1$s, %2$s' ), '', '' ), 'between_last_two' => sprintf( __( '%1$s, and %2$s' ), '', '' ), 'between_only_two' => sprintf( __( '%1$s and %2$s' ), '', '' ), ) ); $args = (array) $args; $result = array_shift( $args ); if ( 1 === count( $args ) ) { $result .= $l['between_only_two'] . array_shift( $args ); } $i = count( $args ); while ( $i ) { $arg = array_shift( $args ); --$i; if ( 0 === $i ) { $result .= $l['between_last_two'] . $arg; } else { $result .= $l['between'] . $arg; } } return $result . substr( $pattern, 2 ); } function wp_html_excerpt( $str, $count, $more = null ) { if ( null === $more ) { $more = ''; } $str = wp_strip_all_tags( $str, true ); $excerpt = mb_substr( $str, 0, $count ); $excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt ); if ( $str !== $excerpt ) { $excerpt = trim( $excerpt ) . $more; } return $excerpt; } function links_add_base_url( $content, $base, $attrs = array( 'src', 'href' ) ) { global $_links_add_base; $_links_add_base = $base; $attrs = implode( '|', (array) $attrs ); return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content ); } function _links_add_base( $m ) { global $_links_add_base; return $m[1] . '=' . $m[2] . ( preg_match( '#^(\w{1,20}):#', $m[3], $protocol ) && in_array( $protocol[1], wp_allowed_protocols(), true ) ? $m[3] : WP_Http::make_absolute_url( $m[3], $_links_add_base ) ) . $m[2]; } function links_add_target( $content, $target = '_blank', $tags = array( 'a' ) ) { global $_links_add_target; $_links_add_target = $target; $tags = implode( '|', (array) $tags ); return preg_replace_callback( "!<($tags)((\s[^>]*)?)>!i", '_links_add_target', $content ); } function _links_add_target( $m ) { global $_links_add_target; $tag = $m[1]; $link = preg_replace( '|( target=([\'"])(.*?)\2)|i', '', $m[2] ); return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">'; } function normalize_whitespace( $str ) { $str = trim( $str ); $str = str_replace( "\r", "\n", $str ); $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str ); return $str; } function wp_strip_all_tags( $text, $remove_breaks = false ) { if ( is_null( $text ) ) { return ''; } if ( ! is_scalar( $text ) ) { wp_trigger_error( '', sprintf( __( 'Warning: %1$s expects parameter %2$s (%3$s) to be a %4$s, %5$s given.' ), __FUNCTION__, '#1', '$text', 'string', gettype( $text ) ), E_USER_WARNING ); return ''; } $text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text ); $text = strip_tags( $text ); if ( $remove_breaks ) { $text = preg_replace( '/[\r\n\t ]+/', ' ', $text ); } return trim( $text ); } function sanitize_text_field( $str ) { $filtered = _sanitize_text_fields( $str, false ); return apply_filters( 'sanitize_text_field', $filtered, $str ); } function sanitize_textarea_field( $str ) { $filtered = _sanitize_text_fields( $str, true ); return apply_filters( 'sanitize_textarea_field', $filtered, $str ); } function _sanitize_text_fields( $str, $keep_newlines = false ) { if ( is_object( $str ) || is_array( $str ) ) { return ''; } $str = (string) $str; $filtered = wp_check_invalid_utf8( $str ); if ( str_contains( $filtered, '<' ) ) { $filtered = wp_pre_kses_less_than( $filtered ); $filtered = wp_strip_all_tags( $filtered, false ); $filtered = str_replace( "<\n", "<\n", $filtered ); } if ( ! $keep_newlines ) { $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered ); } $filtered = trim( $filtered ); $found = false; while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) { $filtered = str_replace( $match[0], '', $filtered ); $found = true; } if ( $found ) { $filtered = trim( preg_replace( '/ +/', ' ', $filtered ) ); } return $filtered; } function wp_basename( $path, $suffix = '' ) { return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) ); } function capital_P_dangit( $text ) { $current_filter = current_filter(); if ( 'the_title' === $current_filter || 'wp_title' === $current_filter ) { return str_replace( 'Wordpress', 'WordPress', $text ); } static $dblq = false; if ( false === $dblq ) { $dblq = _x( '“', 'opening curly double quote' ); } return str_replace( array( ' Wordpress', '‘Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ), array( ' WordPress', '‘WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ), $text ); } function sanitize_mime_type( $mime_type ) { $sani_mime_type = preg_replace( '/[^-+*.a-zA-Z0-9\/]/', '', $mime_type ); return apply_filters( 'sanitize_mime_type', $sani_mime_type, $mime_type ); } function sanitize_trackback_urls( $to_ping ) { $urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY ); foreach ( $urls_to_ping as $k => $url ) { if ( ! preg_match( '#^https?://.#i', $url ) ) { unset( $urls_to_ping[ $k ] ); } } $urls_to_ping = array_map( 'sanitize_url', $urls_to_ping ); $urls_to_ping = implode( "\n", $urls_to_ping ); return apply_filters( 'sanitize_trackback_urls', $urls_to_ping, $to_ping ); } function wp_slash( $value ) { if ( is_array( $value ) ) { return array_map( 'wp_slash', $value ); } if ( is_string( $value ) ) { return addslashes( $value ); } return $value; } function wp_unslash( $value ) { return stripslashes_deep( $value ); } function get_url_in_content( $content ) { if ( empty( $content ) ) { return false; } $processor = new WP_HTML_Tag_Processor( $content ); while ( $processor->next_tag( 'A' ) ) { $href = $processor->get_attribute( 'href' ); if ( is_string( $href ) && '' !== $href ) { return sanitize_url( $href ); } } return false; } function wp_spaces_regexp() { static $spaces = ''; if ( empty( $spaces ) ) { $spaces = apply_filters( 'wp_spaces_regexp', '[\r\n\t ]|\xC2\xA0| ' ); } return $spaces; } function wp_enqueue_emoji_styles() { $action = is_admin() ? 'admin_print_styles' : 'wp_print_styles'; if ( ! has_action( $action, 'print_emoji_styles' ) ) { return; } remove_action( $action, 'print_emoji_styles' ); $emoji_styles = '
img.wp-smiley, img.emoji {
display: inline !important;
border: none !important;
box-shadow: none !important;
height: 1em !important;
width: 1em !important;
margin: 0 0.07em !important;
vertical-align: -0.1em !important;
background: none !important;
padding: 0 !important;
}'; $handle = 'wp-emoji-styles'; wp_register_style( $handle, false ); wp_add_inline_style( $handle, $emoji_styles ); wp_enqueue_style( $handle ); } function print_emoji_detection_script() { static $printed = false; if ( $printed ) { return; } $printed = true; if ( did_action( 'wp_print_footer_scripts' ) ) { _print_emoji_detection_script(); } else { add_action( 'wp_print_footer_scripts', '_print_emoji_detection_script' ); } } function _print_emoji_detection_script() { $settings = array( 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/17.0.2/72x72/' ), 'ext' => apply_filters( 'emoji_ext', '.png' ), 'svgUrl' => apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/17.0.2/svg/' ), 'svgExt' => apply_filters( 'emoji_svg_ext', '.svg' ), ); $version = 'ver=' . get_bloginfo( 'version' ); if ( SCRIPT_DEBUG ) { $settings['source'] = array( 'wpemoji' => apply_filters( 'script_loader_src', includes_url( "js/wp-emoji.js?$version" ), 'wpemoji' ), 'twemoji' => apply_filters( 'script_loader_src', includes_url( "js/twemoji.js?$version" ), 'twemoji' ), ); } else { $settings['source'] = array( 'concatemoji' => apply_filters( 'script_loader_src', includes_url( "js/wp-emoji-release.min.js?$version" ), 'concatemoji' ), ); } wp_print_inline_script_tag( wp_json_encode( $settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ), array( 'id' => 'wp-emoji-settings', 'type' => 'application/json', ) ); $emoji_loader_script_path = '/js/wp-emoji-loader' . wp_scripts_get_suffix() . '.js'; wp_print_inline_script_tag( rtrim( file_get_contents( ABSPATH . WPINC . $emoji_loader_script_path ) ) . "\n" . '//# sourceURL=' . esc_url_raw( includes_url( $emoji_loader_script_path ) ), array( 'type' => 'module', ) ); } function wp_encode_emoji( $content ) { $emoji = _wp_emoji_list( 'partials' ); foreach ( $emoji as $emojum ) { $emoji_char = html_entity_decode( $emojum ); if ( str_contains( $content, $emoji_char ) ) { $content = preg_replace( "/$emoji_char/", $emojum, $content ); } } return $content; } function wp_staticize_emoji( $text ) { if ( ! str_contains( $text, '&#x' ) ) { if ( ( function_exists( 'mb_check_encoding' ) && mb_check_encoding( $text, 'ASCII' ) ) || ! preg_match( '/[^\x00-\x7F]/', $text ) ) { return $text; } else { $encoded_text = wp_encode_emoji( $text ); if ( $encoded_text === $text ) { return $encoded_text; } $text = $encoded_text; } } $emoji = _wp_emoji_list( 'entities' ); $possible_emoji = array(); foreach ( $emoji as $emojum ) { if ( str_contains( $text, $emojum ) ) { $possible_emoji[ $emojum ] = html_entity_decode( $emojum ); } } if ( ! $possible_emoji ) { return $text; } $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/17.0.2/72x72/' ); $ext = apply_filters( 'emoji_ext', '.png' ); $output = ''; $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); $stop = count( $textarr ); $tags_to_ignore = 'code|pre|style|script|textarea'; $ignore_block_element = ''; for ( $i = 0; $i < $stop; $i++ ) { $content = $textarr[ $i ]; if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { $ignore_block_element = $matches[1]; } if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] && str_contains( $content, '&#x' ) ) { foreach ( $possible_emoji as $emojum => $emoji_char ) { if ( ! str_contains( $content, $emojum ) ) { continue; } $file = str_replace( ';&#x', '-', $emojum ); $file = str_replace( array( '&#x', ';' ), '', $file ); $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $file . $ext, $emoji_char ); $content = str_replace( $emojum, $entity, $content ); } } if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) { $ignore_block_element = ''; } $output .= $content; } $output = str_replace( '️', '', $output ); return $output; } function wp_staticize_emoji_for_email( $mail ) { if ( ! isset( $mail['message'] ) ) { return $mail; } $headers = array(); if ( isset( $mail['headers'] ) ) { if ( is_array( $mail['headers'] ) ) { $headers = $mail['headers']; } else { $headers = explode( "\n", str_replace( "\r\n", "\n", $mail['headers'] ) ); } } foreach ( $headers as $header ) { if ( ! str_contains( $header, ':' ) ) { continue; } list( $name, $content ) = explode( ':', trim( $header ), 2 ); $name = trim( $name ); $content = trim( $content ); if ( 'content-type' === strtolower( $name ) ) { if ( str_contains( $content, ';' ) ) { list( $type, $charset ) = explode( ';', $content ); $content_type = trim( $type ); } else { $content_type = trim( $content ); } break; } } if ( ! isset( $content_type ) ) { $content_type = 'text/plain'; } $content_type = apply_filters( 'wp_mail_content_type', $content_type ); if ( 'text/html' === $content_type ) { $mail['message'] = wp_staticize_emoji( $mail['message'] ); } return $mail; } function _wp_emoji_list( $type = 'entities' ) { $entities = array( '👨🏻‍❤️‍💋‍👨🏻', '👨🏻‍❤️‍💋‍👨🏼', '👨🏻‍❤️‍💋‍👨🏽', '👨🏻‍❤️‍💋‍👨🏾', '👨🏻‍❤️‍💋‍👨🏿', '👨🏼‍❤️‍💋‍👨🏻', '👨🏼‍❤️‍💋‍👨🏼', '👨🏼‍❤️‍💋‍👨🏽', '👨🏼‍❤️‍💋‍👨🏾', '👨🏼‍❤️‍💋‍👨🏿', '👨🏽‍❤️‍💋‍👨🏻', '👨🏽‍❤️‍💋‍👨🏼', '👨🏽‍❤️‍💋‍👨🏽', '👨🏽‍❤️‍💋‍👨🏾', '👨🏽‍❤️‍💋‍👨🏿', '👨🏾‍❤️‍💋‍👨🏻', '👨🏾‍❤️‍💋‍👨🏼', '👨🏾‍❤️‍💋‍👨🏽', '👨🏾‍❤️‍💋‍👨🏾', '👨🏾‍❤️‍💋‍👨🏿', '👨🏿‍❤️‍💋‍👨🏻', '👨🏿‍❤️‍💋‍👨🏼', '👨🏿‍❤️‍💋‍👨🏽', '👨🏿‍❤️‍💋‍👨🏾', '👨🏿‍❤️‍💋‍👨🏿', '👩🏻‍❤️‍💋‍👨🏻', '👩🏻‍❤️‍💋‍👨🏼', '👩🏻‍❤️‍💋‍👨🏽', '👩🏻‍❤️‍💋‍👨🏾', '👩🏻‍❤️‍💋‍👨🏿', '👩🏻‍❤️‍💋‍👩🏻', '👩🏻‍❤️‍💋‍👩🏼', '👩🏻‍❤️‍💋‍👩🏽', '👩🏻‍❤️‍💋‍👩🏾', '👩🏻‍❤️‍💋‍👩🏿', '👩🏼‍❤️‍💋‍👨🏻', '👩🏼‍❤️‍💋‍👨🏼', '👩🏼‍❤️‍💋‍👨🏽', '👩🏼‍❤️‍💋‍👨🏾', '👩🏼‍❤️‍💋‍👨🏿', '👩🏼‍❤️‍💋‍👩🏻', '👩🏼‍❤️‍💋‍👩🏼', '👩🏼‍❤️‍💋‍👩🏽', '👩🏼‍❤️‍💋‍👩🏾', '👩🏼‍❤️‍💋‍👩🏿', '👩🏽‍❤️‍💋‍👨🏻', '👩🏽‍❤️‍💋‍👨🏼', '👩🏽‍❤️‍💋‍👨🏽', '👩🏽‍❤️‍💋‍👨🏾', '👩🏽‍❤️‍💋‍👨🏿', '👩🏽‍❤️‍💋‍👩🏻', '👩🏽‍❤️‍💋‍👩🏼', '👩🏽‍❤️‍💋‍👩🏽', '👩🏽‍❤️‍💋‍👩🏾', '👩🏽‍❤️‍💋‍👩🏿', '👩🏾‍❤️‍💋‍👨🏻', '👩🏾‍❤️‍💋‍👨🏼', '👩🏾‍❤️‍💋‍👨🏽', '👩🏾‍❤️‍💋‍👨🏾', '👩🏾‍❤️‍💋‍👨🏿', '👩🏾‍❤️‍💋‍👩🏻', '👩🏾‍❤️‍💋‍👩🏼', '👩🏾‍❤️‍💋‍👩🏽', '👩🏾‍❤️‍💋‍👩🏾', '👩🏾‍❤️‍💋‍👩🏿', '👩🏿‍❤️‍💋‍👨🏻', '👩🏿‍❤️‍💋‍👨🏼', '👩🏿‍❤️‍💋‍👨🏽', '👩🏿‍❤️‍💋‍👨🏾', '👩🏿‍❤️‍💋‍👨🏿', '👩🏿‍❤️‍💋‍👩🏻', '👩🏿‍❤️‍💋‍👩🏼', '👩🏿‍❤️‍💋‍👩🏽', '👩🏿‍❤️‍💋‍👩🏾', '👩🏿‍❤️‍💋‍👩🏿', '🧑🏻‍❤️‍💋‍🧑🏼', '🧑🏻‍❤️‍💋‍🧑🏽', '🧑🏻‍❤️‍💋‍🧑🏾', '🧑🏻‍❤️‍💋‍🧑🏿', '🧑🏼‍❤️‍💋‍🧑🏻', '🧑🏼‍❤️‍💋‍🧑🏽', '🧑🏼‍❤️‍💋‍🧑🏾', '🧑🏼‍❤️‍💋‍🧑🏿', '🧑🏽‍❤️‍💋‍🧑🏻', '🧑🏽‍❤️‍💋‍🧑🏼', '🧑🏽‍❤️‍💋‍🧑🏾', '🧑🏽‍❤️‍💋‍🧑🏿', '🧑🏾‍❤️‍💋‍🧑🏻', '🧑🏾‍❤️‍💋‍🧑🏼', '🧑🏾‍❤️‍💋‍🧑🏽', '🧑🏾‍❤️‍💋‍🧑🏿', '🧑🏿‍❤️‍💋‍🧑🏻', '🧑🏿‍❤️‍💋‍🧑🏼', '🧑🏿‍❤️‍💋‍🧑🏽', '🧑🏿‍❤️‍💋‍🧑🏾', '👨🏻‍❤️‍👨🏻', '👨🏻‍❤️‍👨🏼', '👨🏻‍❤️‍👨🏽', '👨🏻‍❤️‍👨🏾', '👨🏻‍❤️‍👨🏿', '👨🏼‍❤️‍👨🏻', '👨🏼‍❤️‍👨🏼', '👨🏼‍❤️‍👨🏽', '👨🏼‍❤️‍👨🏾', '👨🏼‍❤️‍👨🏿', '👨🏽‍❤️‍👨🏻', '👨🏽‍❤️‍👨🏼', '👨🏽‍❤️‍👨🏽', '👨🏽‍❤️‍👨🏾', '👨🏽‍❤️‍👨🏿', '👨🏾‍❤️‍👨🏻', '👨🏾‍❤️‍👨🏼', '👨🏾‍❤️‍👨🏽', '👨🏾‍❤️‍👨🏾', '👨🏾‍❤️‍👨🏿', '👨🏿‍❤️‍👨🏻', '👨🏿‍❤️‍👨🏼', '👨🏿‍❤️‍👨🏽', '👨🏿‍❤️‍👨🏾', '👨🏿‍❤️‍👨🏿', '👩🏻‍❤️‍👨🏻', '👩🏻‍❤️‍👨🏼', '👩🏻‍❤️‍👨🏽', '👩🏻‍❤️‍👨🏾', '👩🏻‍❤️‍👨🏿', '👩🏻‍❤️‍👩🏻', '👩🏻‍❤️‍👩🏼', '👩🏻‍❤️‍👩🏽', '👩🏻‍❤️‍👩🏾', '👩🏻‍❤️‍👩🏿', '👩🏼‍❤️‍👨🏻', '👩🏼‍❤️‍👨🏼', '👩🏼‍❤️‍👨🏽', '👩🏼‍❤️‍👨🏾', '👩🏼‍❤️‍👨🏿', '👩🏼‍❤️‍👩🏻', '👩🏼‍❤️‍👩🏼', '👩🏼‍❤️‍👩🏽', '👩🏼‍❤️‍👩🏾', '👩🏼‍❤️‍👩🏿', '👩🏽‍❤️‍👨🏻', '👩🏽‍❤️‍👨🏼', '👩🏽‍❤️‍👨🏽', '👩🏽‍❤️‍👨🏾', '👩🏽‍❤️‍👨🏿', '👩🏽‍❤️‍👩🏻', '👩🏽‍❤️‍👩🏼', '👩🏽‍❤️‍👩🏽', '👩🏽‍❤️‍👩🏾', '👩🏽‍❤️‍👩🏿', '👩🏾‍❤️‍👨🏻', '👩🏾‍❤️‍👨🏼', '👩🏾‍❤️‍👨🏽', '👩🏾‍❤️‍👨🏾', '👩🏾‍❤️‍👨🏿', '👩🏾‍❤️‍👩🏻', '👩🏾‍❤️‍👩🏼', '👩🏾‍❤️‍👩🏽', '👩🏾‍❤️‍👩🏾', '👩🏾‍❤️‍👩🏿', '👩🏿‍❤️‍👨🏻', '👩🏿‍❤️‍👨🏼', '👩🏿‍❤️‍👨🏽', '👩🏿‍❤️‍👨🏾', '👩🏿‍❤️‍👨🏿', '👩🏿‍❤️‍👩🏻', '👩🏿‍❤️‍👩🏼', '👩🏿‍❤️‍👩🏽', '👩🏿‍❤️‍👩🏾', '👩🏿‍❤️‍👩🏿', '🧑🏻‍❤️‍🧑🏼', '🧑🏻‍❤️‍🧑🏽', '🧑🏻‍❤️‍🧑🏾', '🧑🏻‍❤️‍🧑🏿', '🧑🏼‍❤️‍🧑🏻', '🧑🏼‍❤️‍🧑🏽', '🧑🏼‍❤️‍🧑🏾', '🧑🏼‍❤️‍🧑🏿', '🧑🏽‍❤️‍🧑🏻', '🧑🏽‍❤️‍🧑🏼', '🧑🏽‍❤️‍🧑🏾', '🧑🏽‍❤️‍🧑🏿', '🧑🏾‍❤️‍🧑🏻', '🧑🏾‍❤️‍🧑🏼', '🧑🏾‍❤️‍🧑🏽', '🧑🏾‍❤️‍🧑🏿', '🧑🏿‍❤️‍🧑🏻', '🧑🏿‍❤️‍🧑🏼', '🧑🏿‍❤️‍🧑🏽', '🧑🏿‍❤️‍🧑🏾', '👨‍❤️‍💋‍👨', '👩‍❤️‍💋‍👨', '👩‍❤️‍💋‍👩', '🏃🏻‍♀️‍➡️', '🏃🏻‍♂️‍➡️', '🏃🏼‍♀️‍➡️', '🏃🏼‍♂️‍➡️', '🏃🏽‍♀️‍➡️', '🏃🏽‍♂️‍➡️', '🏃🏾‍♀️‍➡️', '🏃🏾‍♂️‍➡️', '🏃🏿‍♀️‍➡️', '🏃🏿‍♂️‍➡️', '🚶🏻‍♀️‍➡️', '🚶🏻‍♂️‍➡️', '🚶🏼‍♀️‍➡️', '🚶🏼‍♂️‍➡️', '🚶🏽‍♀️‍➡️', '🚶🏽‍♂️‍➡️', '🚶🏾‍♀️‍➡️', '🚶🏾‍♂️‍➡️', '🚶🏿‍♀️‍➡️', '🚶🏿‍♂️‍➡️', '🧎🏻‍♀️‍➡️', '🧎🏻‍♂️‍➡️', '🧎🏼‍♀️‍➡️', '🧎🏼‍♂️‍➡️', '🧎🏽‍♀️‍➡️', '🧎🏽‍♂️‍➡️', '🧎🏾‍♀️‍➡️', '🧎🏾‍♂️‍➡️', '🧎🏿‍♀️‍➡️', '🧎🏿‍♂️‍➡️', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', '🏴󠁧󠁢󠁳󠁣󠁴󠁿', '🏴󠁧󠁢󠁷󠁬󠁳󠁿', '👨🏻‍🐰‍👨🏼', '👨🏻‍🐰‍👨🏽', '👨🏻‍🐰‍👨🏾', '👨🏻‍🐰‍👨🏿', '👨🏻‍🤝‍👨🏼', '👨🏻‍🤝‍👨🏽', '👨🏻‍🤝‍👨🏾', '👨🏻‍🤝‍👨🏿', '👨🏻‍🫯‍👨🏼', '👨🏻‍🫯‍👨🏽', '👨🏻‍🫯‍👨🏾', '👨🏻‍🫯‍👨🏿', '👨🏼‍🐰‍👨🏻', '👨🏼‍🐰‍👨🏼', '👨🏼‍🐰‍👨🏽', '👨🏼‍🐰‍👨🏾', '👨🏼‍🐰‍👨🏿', '👨🏼‍🤝‍👨🏻', '👨🏼‍🤝‍👨🏽', '👨🏼‍🤝‍👨🏾', '👨🏼‍🤝‍👨🏿', '👨🏼‍🫯‍👨🏻', '👨🏼‍🫯‍👨🏽', '👨🏼‍🫯‍👨🏾', '👨🏼‍🫯‍👨🏿', '👨🏽‍🐰‍👨🏻', '👨🏽‍🐰‍👨🏼', '👨🏽‍🐰‍👨🏾', '👨🏽‍🐰‍👨🏿', '👨🏽‍🤝‍👨🏻', '👨🏽‍🤝‍👨🏼', '👨🏽‍🤝‍👨🏾', '👨🏽‍🤝‍👨🏿', '👨🏽‍🫯‍👨🏻', '👨🏽‍🫯‍👨🏼', '👨🏽‍🫯‍👨🏾', '👨🏽‍🫯‍👨🏿', '👨🏾‍🐰‍👨🏻', '👨🏾‍🐰‍👨🏼', '👨🏾‍🐰‍👨🏽', '👨🏾‍🐰‍👨🏿', '👨🏾‍🤝‍👨🏻', '👨🏾‍🤝‍👨🏼', '👨🏾‍🤝‍👨🏽', '👨🏾‍🤝‍👨🏿', '👨🏾‍🫯‍👨🏻', '👨🏾‍🫯‍👨🏼', '👨🏾‍🫯‍👨🏽', '👨🏾‍🫯‍👨🏿', '👨🏿‍🐰‍👨🏻', '👨🏿‍🐰‍👨🏼', '👨🏿‍🐰‍👨🏽', '👨🏿‍🐰‍👨🏾', '👨🏿‍🤝‍👨🏻', '👨🏿‍🤝‍👨🏼', '👨🏿‍🤝‍👨🏽', '👨🏿‍🤝‍👨🏾', '👨🏿‍🫯‍👨🏻', '👨🏿‍🫯‍👨🏼', '👨🏿‍🫯‍👨🏽', '👨🏿‍🫯‍👨🏾', '👩🏻‍🐰‍👩🏼', '👩🏻‍🐰‍👩🏽', '👩🏻‍🐰‍👩🏾', '👩🏻‍🐰‍👩🏿', '👩🏻‍🤝‍👨🏼', '👩🏻‍🤝‍👨🏽', '👩🏻‍🤝‍👨🏾', '👩🏻‍🤝‍👨🏿', '👩🏻‍🤝‍👩🏼', '👩🏻‍🤝‍👩🏽', '👩🏻‍🤝‍👩🏾', '👩🏻‍🤝‍👩🏿', '👩🏻‍🫯‍👩🏼', '👩🏻‍🫯‍👩🏽', '👩🏻‍🫯‍👩🏾', '👩🏻‍🫯‍👩🏿', '👩🏼‍🐰‍👩🏻', '👩🏼‍🐰‍👩🏽', '👩🏼‍🐰‍👩🏾', '👩🏼‍🐰‍👩🏿', '👩🏼‍🤝‍👨🏻', '👩🏼‍🤝‍👨🏽', '👩🏼‍🤝‍👨🏾', '👩🏼‍🤝‍👨🏿', '👩🏼‍🤝‍👩🏻', '👩🏼‍🤝‍👩🏽', '👩🏼‍🤝‍👩🏾', '👩🏼‍🤝‍👩🏿', '👩🏼‍🫯‍👩🏻', '👩🏼‍🫯‍👩🏽', '👩🏼‍🫯‍👩🏾', '👩🏼‍🫯‍👩🏿', '👩🏽‍🐰‍👩🏻', '👩🏽‍🐰‍👩🏼', '👩🏽‍🐰‍👩🏾', '👩🏽‍🐰‍👩🏿', '👩🏽‍🤝‍👨🏻', '👩🏽‍🤝‍👨🏼', '👩🏽‍🤝‍👨🏾', '👩🏽‍🤝‍👨🏿', '👩🏽‍🤝‍👩🏻', '👩🏽‍🤝‍👩🏼', '👩🏽‍🤝‍👩🏾', '👩🏽‍🤝‍👩🏿', '👩🏽‍🫯‍👩🏻', '👩🏽‍🫯‍👩🏼', '👩🏽‍🫯‍👩🏾', '👩🏽‍🫯‍👩🏿', '👩🏾‍🐰‍👩🏻', '👩🏾‍🐰‍👩🏼', '👩🏾‍🐰‍👩🏽', '👩🏾‍🐰‍👩🏿', '👩🏾‍🤝‍👨🏻', '👩🏾‍🤝‍👨🏼', '👩🏾‍🤝‍👨🏽', '👩🏾‍🤝‍👨🏿', '👩🏾‍🤝‍👩🏻', '👩🏾‍🤝‍👩🏼', '👩🏾‍🤝‍👩🏽', '👩🏾‍🤝‍👩🏿', '👩🏾‍🫯‍👩🏻', '👩🏾‍🫯‍👩🏼', '👩🏾‍🫯‍👩🏽', '👩🏾‍🫯‍👩🏿', '👩🏿‍🐰‍👩🏻', '👩🏿‍🐰‍👩🏼', '👩🏿‍🐰‍👩🏽', '👩🏿‍🐰‍👩🏾', '👩🏿‍🤝‍👨🏻', '👩🏿‍🤝‍👨🏼', '👩🏿‍🤝‍👨🏽', '👩🏿‍🤝‍👨🏾', '👩🏿‍🤝‍👩🏻', '👩🏿‍🤝‍👩🏼', '👩🏿‍🤝‍👩🏽', '👩🏿‍🤝‍👩🏾', '👩🏿‍🫯‍👩🏻', '👩🏿‍🫯‍👩🏼', '👩🏿‍🫯‍👩🏽', '👩🏿‍🫯‍👩🏾', '🧑🏻‍🐰‍🧑🏼', '🧑🏻‍🐰‍🧑🏽', '🧑🏻‍🐰‍🧑🏾', '🧑🏻‍🐰‍🧑🏿', '🧑🏻‍🤝‍🧑🏻', '🧑🏻‍🤝‍🧑🏼', '🧑🏻‍🤝‍🧑🏽', '🧑🏻‍🤝‍🧑🏾', '🧑🏻‍🤝‍🧑🏿', '🧑🏻‍🫯‍🧑🏼', '🧑🏻‍🫯‍🧑🏽', '🧑🏻‍🫯‍🧑🏾', '🧑🏻‍🫯‍🧑🏿', '🧑🏼‍🐰‍🧑🏻', '🧑🏼‍🐰‍🧑🏽', '🧑🏼‍🐰‍🧑🏾', '🧑🏼‍🐰‍🧑🏿', '🧑🏼‍🤝‍🧑🏻', '🧑🏼‍🤝‍🧑🏼', '🧑🏼‍🤝‍🧑🏽', '🧑🏼‍🤝‍🧑🏾', '🧑🏼‍🤝‍🧑🏿', '🧑🏼‍🫯‍🧑🏻', '🧑🏼‍🫯‍🧑🏽', '🧑🏼‍🫯‍🧑🏾', '🧑🏼‍🫯‍🧑🏿', '🧑🏽‍🐰‍🧑🏻', '🧑🏽‍🐰‍🧑🏼', '🧑🏽‍🐰‍🧑🏾', '🧑🏽‍🐰‍🧑🏿', '🧑🏽‍🤝‍🧑🏻', '🧑🏽‍🤝‍🧑🏼', '🧑🏽‍🤝‍🧑🏽', '🧑🏽‍🤝‍🧑🏾', '🧑🏽‍🤝‍🧑🏿', '🧑🏽‍🫯‍🧑🏻', '🧑🏽‍🫯‍🧑🏼', '🧑🏽‍🫯‍🧑🏾', '🧑🏽‍🫯‍🧑🏿', '🧑🏾‍🐰‍🧑🏻', '🧑🏾‍🐰‍🧑🏼', '🧑🏾‍🐰‍🧑🏽', '🧑🏾‍🐰‍🧑🏿', '🧑🏾‍🤝‍🧑🏻', '🧑🏾‍🤝‍🧑🏼', '🧑🏾‍🤝‍🧑🏽', '🧑🏾‍🤝‍🧑🏾', '🧑🏾‍🤝‍🧑🏿', '🧑🏾‍🫯‍🧑🏻', '🧑🏾‍🫯‍🧑🏼', '🧑🏾‍🫯‍🧑🏽', '🧑🏾‍🫯‍🧑🏿', '🧑🏿‍🐰‍🧑🏻', '🧑🏿‍🐰‍🧑🏼', '🧑🏿‍🐰‍🧑🏽', '🧑🏿‍🐰‍🧑🏾', '🧑🏿‍🤝‍🧑🏻', '🧑🏿‍🤝‍🧑🏼', '🧑🏿‍🤝‍🧑🏽', '🧑🏿‍🤝‍🧑🏾', '🧑🏿‍🤝‍🧑🏿', '🧑🏿‍🫯‍🧑🏻', '🧑🏿‍🫯‍🧑🏼', '🧑🏿‍🫯‍🧑🏽', '🧑🏿‍🫯‍🧑🏾', '👨‍👨‍👦‍👦', '👨‍👨‍👧‍👦', '👨‍👨‍👧‍👧', '👨‍👩‍👦‍👦', '👨‍👩‍👧‍👦', '👨‍👩‍👧‍👧', '👩‍👩‍👦‍👦', '👩‍👩‍👧‍👦', '👩‍👩‍👧‍👧', '🧑‍🧑‍🧒‍🧒', '👨🏻‍🦯‍➡️', '👨🏻‍🦼‍➡️', '👨🏻‍🦽‍➡️', '👨🏼‍🦯‍➡️', '👨🏼‍🦼‍➡️', '👨🏼‍🦽‍➡️', '👨🏽‍🦯‍➡️', '👨🏽‍🦼‍➡️', '👨🏽‍🦽‍➡️', '👨🏾‍🦯‍➡️', '👨🏾‍🦼‍➡️', '👨🏾‍🦽‍➡️', '👨🏿‍🦯‍➡️', '👨🏿‍🦼‍➡️', '👨🏿‍🦽‍➡️', '👩🏻‍🦯‍➡️', '👩🏻‍🦼‍➡️', '👩🏻‍🦽‍➡️', '👩🏼‍🦯‍➡️', '👩🏼‍🦼‍➡️', '👩🏼‍🦽‍➡️', '👩🏽‍🦯‍➡️', '👩🏽‍🦼‍➡️', '👩🏽‍🦽‍➡️', '👩🏾‍🦯‍➡️', '👩🏾‍🦼‍➡️', '👩🏾‍🦽‍➡️', '👩🏿‍🦯‍➡️', '👩🏿‍🦼‍➡️', '👩🏿‍🦽‍➡️', '🧑🏻‍🦯‍➡️', '🧑🏻‍🦼‍➡️', '🧑🏻‍🦽‍➡️', '🧑🏼‍🦯‍➡️', '🧑🏼‍🦼‍➡️', '🧑🏼‍🦽‍➡️', '🧑🏽‍🦯‍➡️', '🧑🏽‍🦼‍➡️', '🧑🏽‍🦽‍➡️', '🧑🏾‍🦯‍➡️', '🧑🏾‍🦼‍➡️', '🧑🏾‍🦽‍➡️', '🧑🏿‍🦯‍➡️', '🧑🏿‍🦼‍➡️', '🧑🏿‍🦽‍➡️', '🏃‍♀️‍➡️', '🏃‍♂️‍➡️', '🚶‍♀️‍➡️', '🚶‍♂️‍➡️', '🧎‍♀️‍➡️', '🧎‍♂️‍➡️', '👨‍🦯‍➡️', '👨‍🦼‍➡️', '👨‍🦽‍➡️', '👨‍❤️‍👨', '👩‍🦯‍➡️', '👩‍🦼‍➡️', '👩‍🦽‍➡️', '👩‍❤️‍👨', '👩‍❤️‍👩', '🧑‍🦯‍➡️', '🧑‍🦼‍➡️', '🧑‍🦽‍➡️', '🫱🏻‍🫲🏼', '🫱🏻‍🫲🏽', '🫱🏻‍🫲🏾', '🫱🏻‍🫲🏿', '🫱🏼‍🫲🏻', '🫱🏼‍🫲🏽', '🫱🏼‍🫲🏾', '🫱🏼‍🫲🏿', '🫱🏽‍🫲🏻', '🫱🏽‍🫲🏼', '🫱🏽‍🫲🏾', '🫱🏽‍🫲🏿', '🫱🏾‍🫲🏻', '🫱🏾‍🫲🏼', '🫱🏾‍🫲🏽', '🫱🏾‍🫲🏿', '🫱🏿‍🫲🏻', '🫱🏿‍🫲🏼', '🫱🏿‍🫲🏽', '🫱🏿‍🫲🏾', '👨‍👦‍👦', '👨‍👧‍👦', '👨‍👧‍👧', '👨‍👨‍👦', '👨‍👨‍👧', '👨‍👩‍👦', '👨‍👩‍👧', '👩‍👦‍👦', '👩‍👧‍👦', '👩‍👧‍👧', '👩‍👩‍👦', '👩‍👩‍👧', '🧑‍🤝‍🧑', '🧑‍🧑‍🧒', '🧑‍🧒‍🧒', '🏃🏻‍♀️', '🏃🏻‍♂️', '🏃🏻‍➡️', '🏃🏼‍♀️', '🏃🏼‍♂️', '🏃🏼‍➡️', '🏃🏽‍♀️', '🏃🏽‍♂️', '🏃🏽‍➡️', '🏃🏾‍♀️', '🏃🏾‍♂️', '🏃🏾‍➡️', '🏃🏿‍♀️', '🏃🏿‍♂️', '🏃🏿‍➡️', '🏄🏻‍♀️', '🏄🏻‍♂️', '🏄🏼‍♀️', '🏄🏼‍♂️', '🏄🏽‍♀️', '🏄🏽‍♂️', '🏄🏾‍♀️', '🏄🏾‍♂️', '🏄🏿‍♀️', '🏄🏿‍♂️', '🏊🏻‍♀️', '🏊🏻‍♂️', '🏊🏼‍♀️', '🏊🏼‍♂️', '🏊🏽‍♀️', '🏊🏽‍♂️', '🏊🏾‍♀️', '🏊🏾‍♂️', '🏊🏿‍♀️', '🏊🏿‍♂️', '🏋🏻‍♀️', '🏋🏻‍♂️', '🏋🏼‍♀️', '🏋🏼‍♂️', '🏋🏽‍♀️', '🏋🏽‍♂️', '🏋🏾‍♀️', '🏋🏾‍♂️', '🏋🏿‍♀️', '🏋🏿‍♂️', '🏌🏻‍♀️', '🏌🏻‍♂️', '🏌🏼‍♀️', '🏌🏼‍♂️', '🏌🏽‍♀️', '🏌🏽‍♂️', '🏌🏾‍♀️', '🏌🏾‍♂️', '🏌🏿‍♀️', '🏌🏿‍♂️', '👨🏻‍⚕️', '👨🏻‍⚖️', '👨🏻‍✈️', '👨🏼‍⚕️', '👨🏼‍⚖️', '👨🏼‍✈️', '👨🏽‍⚕️', '👨🏽‍⚖️', '👨🏽‍✈️', '👨🏾‍⚕️', '👨🏾‍⚖️', '👨🏾‍✈️', '👨🏿‍⚕️', '👨🏿‍⚖️', '👨🏿‍✈️', '👩🏻‍⚕️', '👩🏻‍⚖️', '👩🏻‍✈️', '👩🏼‍⚕️', '👩🏼‍⚖️', '👩🏼‍✈️', '👩🏽‍⚕️', '👩🏽‍⚖️', '👩🏽‍✈️', '👩🏾‍⚕️', '👩🏾‍⚖️', '👩🏾‍✈️', '👩🏿‍⚕️', '👩🏿‍⚖️', '👩🏿‍✈️', '👮🏻‍♀️', '👮🏻‍♂️', '👮🏼‍♀️', '👮🏼‍♂️', '👮🏽‍♀️', '👮🏽‍♂️', '👮🏾‍♀️', '👮🏾‍♂️', '👮🏿‍♀️', '👮🏿‍♂️', '👯🏻‍♀️', '👯🏻‍♂️', '👯🏼‍♀️', '👯🏼‍♂️', '👯🏽‍♀️', '👯🏽‍♂️', '👯🏾‍♀️', '👯🏾‍♂️', '👯🏿‍♀️', '👯🏿‍♂️', '👰🏻‍♀️', '👰🏻‍♂️', '👰🏼‍♀️', '👰🏼‍♂️', '👰🏽‍♀️', '👰🏽‍♂️', '👰🏾‍♀️', '👰🏾‍♂️', '👰🏿‍♀️', '👰🏿‍♂️', '👱🏻‍♀️', '👱🏻‍♂️', '👱🏼‍♀️', '👱🏼‍♂️', '👱🏽‍♀️', '👱🏽‍♂️', '👱🏾‍♀️', '👱🏾‍♂️', '👱🏿‍♀️', '👱🏿‍♂️', '👳🏻‍♀️', '👳🏻‍♂️', '👳🏼‍♀️', '👳🏼‍♂️', '👳🏽‍♀️', '👳🏽‍♂️', '👳🏾‍♀️', '👳🏾‍♂️', '👳🏿‍♀️', '👳🏿‍♂️', '👷🏻‍♀️', '👷🏻‍♂️', '👷🏼‍♀️', '👷🏼‍♂️', '👷🏽‍♀️', '👷🏽‍♂️', '👷🏾‍♀️', '👷🏾‍♂️', '👷🏿‍♀️', '👷🏿‍♂️', '💁🏻‍♀️', '💁🏻‍♂️', '💁🏼‍♀️', '💁🏼‍♂️', '💁🏽‍♀️', '💁🏽‍♂️', '💁🏾‍♀️', '💁🏾‍♂️', '💁🏿‍♀️', '💁🏿‍♂️', '💂🏻‍♀️', '💂🏻‍♂️', '💂🏼‍♀️', '💂🏼‍♂️', '💂🏽‍♀️', '💂🏽‍♂️', '💂🏾‍♀️', '💂🏾‍♂️', '💂🏿‍♀️', '💂🏿‍♂️', '💆🏻‍♀️', '💆🏻‍♂️', '💆🏼‍♀️', '💆🏼‍♂️', '💆🏽‍♀️', '💆🏽‍♂️', '💆🏾‍♀️', '💆🏾‍♂️', '💆🏿‍♀️', '💆🏿‍♂️', '💇🏻‍♀️', '💇🏻‍♂️', '💇🏼‍♀️', '💇🏼‍♂️', '💇🏽‍♀️', '💇🏽‍♂️', '💇🏾‍♀️', '💇🏾‍♂️', '💇🏿‍♀️', '💇🏿‍♂️', '🕴🏻‍♀️', '🕴🏻‍♂️', '🕴🏼‍♀️', '🕴🏼‍♂️', '🕴🏽‍♀️', '🕴🏽‍♂️', '🕴🏾‍♀️', '🕴🏾‍♂️', '🕴🏿‍♀️', '🕴🏿‍♂️', '🕵🏻‍♀️', '🕵🏻‍♂️', '🕵🏼‍♀️', '🕵🏼‍♂️', '🕵🏽‍♀️', '🕵🏽‍♂️', '🕵🏾‍♀️', '🕵🏾‍♂️', '🕵🏿‍♀️', '🕵🏿‍♂️', '🙅🏻‍♀️', '🙅🏻‍♂️', '🙅🏼‍♀️', '🙅🏼‍♂️', '🙅🏽‍♀️', '🙅🏽‍♂️', '🙅🏾‍♀️', '🙅🏾‍♂️', '🙅🏿‍♀️', '🙅🏿‍♂️', '🙆🏻‍♀️', '🙆🏻‍♂️', '🙆🏼‍♀️', '🙆🏼‍♂️', '🙆🏽‍♀️', '🙆🏽‍♂️', '🙆🏾‍♀️', '🙆🏾‍♂️', '🙆🏿‍♀️', '🙆🏿‍♂️', '🙇🏻‍♀️', '🙇🏻‍♂️', '🙇🏼‍♀️', '🙇🏼‍♂️', '🙇🏽‍♀️', '🙇🏽‍♂️', '🙇🏾‍♀️', '🙇🏾‍♂️', '🙇🏿‍♀️', '🙇🏿‍♂️', '🙋🏻‍♀️', '🙋🏻‍♂️', '🙋🏼‍♀️', '🙋🏼‍♂️', '🙋🏽‍♀️', '🙋🏽‍♂️', '🙋🏾‍♀️', '🙋🏾‍♂️', '🙋🏿‍♀️', '🙋🏿‍♂️', '🙍🏻‍♀️', '🙍🏻‍♂️', '🙍🏼‍♀️', '🙍🏼‍♂️', '🙍🏽‍♀️', '🙍🏽‍♂️', '🙍🏾‍♀️', '🙍🏾‍♂️', '🙍🏿‍♀️', '🙍🏿‍♂️', '🙎🏻‍♀️', '🙎🏻‍♂️', '🙎🏼‍♀️', '🙎🏼‍♂️', '🙎🏽‍♀️', '🙎🏽‍♂️', '🙎🏾‍♀️', '🙎🏾‍♂️', '🙎🏿‍♀️', '🙎🏿‍♂️', '🚣🏻‍♀️', '🚣🏻‍♂️', '🚣🏼‍♀️', '🚣🏼‍♂️', '🚣🏽‍♀️', '🚣🏽‍♂️', '🚣🏾‍♀️', '🚣🏾‍♂️', '🚣🏿‍♀️', '🚣🏿‍♂️', '🚴🏻‍♀️', '🚴🏻‍♂️', '🚴🏼‍♀️', '🚴🏼‍♂️', '🚴🏽‍♀️', '🚴🏽‍♂️', '🚴🏾‍♀️', '🚴🏾‍♂️', '🚴🏿‍♀️', '🚴🏿‍♂️', '🚵🏻‍♀️', '🚵🏻‍♂️', '🚵🏼‍♀️', '🚵🏼‍♂️', '🚵🏽‍♀️', '🚵🏽‍♂️', '🚵🏾‍♀️', '🚵🏾‍♂️', '🚵🏿‍♀️', '🚵🏿‍♂️', '🚶🏻‍♀️', '🚶🏻‍♂️', '🚶🏻‍➡️', '🚶🏼‍♀️', '🚶🏼‍♂️', '🚶🏼‍➡️', '🚶🏽‍♀️', '🚶🏽‍♂️', '🚶🏽‍➡️', '🚶🏾‍♀️', '🚶🏾‍♂️', '🚶🏾‍➡️', '🚶🏿‍♀️', '🚶🏿‍♂️', '🚶🏿‍➡️', '🤦🏻‍♀️', '🤦🏻‍♂️', '🤦🏼‍♀️', '🤦🏼‍♂️', '🤦🏽‍♀️', '🤦🏽‍♂️', '🤦🏾‍♀️', '🤦🏾‍♂️', '🤦🏿‍♀️', '🤦🏿‍♂️', '🤵🏻‍♀️', '🤵🏻‍♂️', '🤵🏼‍♀️', '🤵🏼‍♂️', '🤵🏽‍♀️', '🤵🏽‍♂️', '🤵🏾‍♀️', '🤵🏾‍♂️', '🤵🏿‍♀️', '🤵🏿‍♂️', '🤷🏻‍♀️', '🤷🏻‍♂️', '🤷🏼‍♀️', '🤷🏼‍♂️', '🤷🏽‍♀️', '🤷🏽‍♂️', '🤷🏾‍♀️', '🤷🏾‍♂️', '🤷🏿‍♀️', '🤷🏿‍♂️', '🤸🏻‍♀️', '🤸🏻‍♂️', '🤸🏼‍♀️', '🤸🏼‍♂️', '🤸🏽‍♀️', '🤸🏽‍♂️', '🤸🏾‍♀️', '🤸🏾‍♂️', '🤸🏿‍♀️', '🤸🏿‍♂️', '🤹🏻‍♀️', '🤹🏻‍♂️', '🤹🏼‍♀️', '🤹🏼‍♂️', '🤹🏽‍♀️', '🤹🏽‍♂️', '🤹🏾‍♀️', '🤹🏾‍♂️', '🤹🏿‍♀️', '🤹🏿‍♂️', '🤼🏻‍♀️', '🤼🏻‍♂️', '🤼🏼‍♀️', '🤼🏼‍♂️', '🤼🏽‍♀️', '🤼🏽‍♂️', '🤼🏾‍♀️', '🤼🏾‍♂️', '🤼🏿‍♀️', '🤼🏿‍♂️', '🤽🏻‍♀️', '🤽🏻‍♂️', '🤽🏼‍♀️', '🤽🏼‍♂️', '🤽🏽‍♀️', '🤽🏽‍♂️', '🤽🏾‍♀️', '🤽🏾‍♂️', '🤽🏿‍♀️', '🤽🏿‍♂️', '🤾🏻‍♀️', '🤾🏻‍♂️', '🤾🏼‍♀️', '🤾🏼‍♂️', '🤾🏽‍♀️', '🤾🏽‍♂️', '🤾🏾‍♀️', '🤾🏾‍♂️', '🤾🏿‍♀️', '🤾🏿‍♂️', '🦸🏻‍♀️', '🦸🏻‍♂️', '🦸🏼‍♀️', '🦸🏼‍♂️', '🦸🏽‍♀️', '🦸🏽‍♂️', '🦸🏾‍♀️', '🦸🏾‍♂️', '🦸🏿‍♀️', '🦸🏿‍♂️', '🦹🏻‍♀️', '🦹🏻‍♂️', '🦹🏼‍♀️', '🦹🏼‍♂️', '🦹🏽‍♀️', '🦹🏽‍♂️', '🦹🏾‍♀️', '🦹🏾‍♂️', '🦹🏿‍♀️', '🦹🏿‍♂️', '🧍🏻‍♀️', '🧍🏻‍♂️', '🧍🏼‍♀️', '🧍🏼‍♂️', '🧍🏽‍♀️', '🧍🏽‍♂️', '🧍🏾‍♀️', '🧍🏾‍♂️', '🧍🏿‍♀️', '🧍🏿‍♂️', '🧎🏻‍♀️', '🧎🏻‍♂️', '🧎🏻‍➡️', '🧎🏼‍♀️', '🧎🏼‍♂️', '🧎🏼‍➡️', '🧎🏽‍♀️', '🧎🏽‍♂️', '🧎🏽‍➡️', '🧎🏾‍♀️', '🧎🏾‍♂️', '🧎🏾‍➡️', '🧎🏿‍♀️', '🧎🏿‍♂️', '🧎🏿‍➡️', '🧏🏻‍♀️', '🧏🏻‍♂️', '🧏🏼‍♀️', '🧏🏼‍♂️', '🧏🏽‍♀️', '🧏🏽‍♂️', '🧏🏾‍♀️', '🧏🏾‍♂️', '🧏🏿‍♀️', '🧏🏿‍♂️', '🧑🏻‍⚕️', '🧑🏻‍⚖️', '🧑🏻‍✈️', '🧑🏼‍⚕️', '🧑🏼‍⚖️', '🧑🏼‍✈️', '🧑🏽‍⚕️', '🧑🏽‍⚖️', '🧑🏽‍✈️', '🧑🏾‍⚕️', '🧑🏾‍⚖️', '🧑🏾‍✈️', '🧑🏿‍⚕️', '🧑🏿‍⚖️', '🧑🏿‍✈️', '🧔🏻‍♀️', '🧔🏻‍♂️', '🧔🏼‍♀️', '🧔🏼‍♂️', '🧔🏽‍♀️', '🧔🏽‍♂️', '🧔🏾‍♀️', '🧔🏾‍♂️', '🧔🏿‍♀️', '🧔🏿‍♂️', '🧖🏻‍♀️', '🧖🏻‍♂️', '🧖🏼‍♀️', '🧖🏼‍♂️', '🧖🏽‍♀️', '🧖🏽‍♂️', '🧖🏾‍♀️', '🧖🏾‍♂️', '🧖🏿‍♀️', '🧖🏿‍♂️', '🧗🏻‍♀️', '🧗🏻‍♂️', '🧗🏼‍♀️', '🧗🏼‍♂️', '🧗🏽‍♀️', '🧗🏽‍♂️', '🧗🏾‍♀️', '🧗🏾‍♂️', '🧗🏿‍♀️', '🧗🏿‍♂️', '🧘🏻‍♀️', '🧘🏻‍♂️', '🧘🏼‍♀️', '🧘🏼‍♂️', '🧘🏽‍♀️', '🧘🏽‍♂️', '🧘🏾‍♀️', '🧘🏾‍♂️', '🧘🏿‍♀️', '🧘🏿‍♂️', '🧙🏻‍♀️', '🧙🏻‍♂️', '🧙🏼‍♀️', '🧙🏼‍♂️', '🧙🏽‍♀️', '🧙🏽‍♂️', '🧙🏾‍♀️', '🧙🏾‍♂️', '🧙🏿‍♀️', '🧙🏿‍♂️', '🧚🏻‍♀️', '🧚🏻‍♂️', '🧚🏼‍♀️', '🧚🏼‍♂️', '🧚🏽‍♀️', '🧚🏽‍♂️', '🧚🏾‍♀️', '🧚🏾‍♂️', '🧚🏿‍♀️', '🧚🏿‍♂️', '🧛🏻‍♀️', '🧛🏻‍♂️', '🧛🏼‍♀️', '🧛🏼‍♂️', '🧛🏽‍♀️', '🧛🏽‍♂️', '🧛🏾‍♀️', '🧛🏾‍♂️', '🧛🏿‍♀️', '🧛🏿‍♂️', '🧜🏻‍♀️', '🧜🏻‍♂️', '🧜🏼‍♀️', '🧜🏼‍♂️', '🧜🏽‍♀️', '🧜🏽‍♂️', '🧜🏾‍♀️', '🧜🏾‍♂️', '🧜🏿‍♀️', '🧜🏿‍♂️', '🧝🏻‍♀️', '🧝🏻‍♂️', '🧝🏼‍♀️', '🧝🏼‍♂️', '🧝🏽‍♀️', '🧝🏽‍♂️', '🧝🏾‍♀️', '🧝🏾‍♂️', '🧝🏿‍♀️', '🧝🏿‍♂️', '🏋️‍♀️', '🏋️‍♂️', '🏌️‍♀️', '🏌️‍♂️', '🏳️‍⚧️', '🕴️‍♀️', '🕴️‍♂️', '🕵️‍♀️', '🕵️‍♂️', '⛹🏻‍♀️', '⛹🏻‍♂️', '⛹🏼‍♀️', '⛹🏼‍♂️', '⛹🏽‍♀️', '⛹🏽‍♂️', '⛹🏾‍♀️', '⛹🏾‍♂️', '⛹🏿‍♀️', '⛹🏿‍♂️', '⛹️‍♀️', '⛹️‍♂️', '👨🏻‍🌾', '👨🏻‍🍳', '👨🏻‍🍼', '👨🏻‍🎄', '👨🏻‍🎓', '👨🏻‍🎤', '👨🏻‍🎨', '👨🏻‍🏫', '👨🏻‍🏭', '👨🏻‍💻', '👨🏻‍💼', '👨🏻‍🔧', '👨🏻‍🔬', '👨🏻‍🚀', '👨🏻‍🚒', '👨🏻‍🦯', '👨🏻‍🦰', '👨🏻‍🦱', '👨🏻‍🦲', '👨🏻‍🦳', '👨🏻‍🦼', '👨🏻‍🦽', '👨🏼‍🌾', '👨🏼‍🍳', '👨🏼‍🍼', '👨🏼‍🎄', '👨🏼‍🎓', '👨🏼‍🎤', '👨🏼‍🎨', '👨🏼‍🏫', '👨🏼‍🏭', '👨🏼‍💻', '👨🏼‍💼', '👨🏼‍🔧', '👨🏼‍🔬', '👨🏼‍🚀', '👨🏼‍🚒', '👨🏼‍🦯', '👨🏼‍🦰', '👨🏼‍🦱', '👨🏼‍🦲', '👨🏼‍🦳', '👨🏼‍🦼', '👨🏼‍🦽', '👨🏽‍🌾', '👨🏽‍🍳', '👨🏽‍🍼', '👨🏽‍🎄', '👨🏽‍🎓', '👨🏽‍🎤', '👨🏽‍🎨', '👨🏽‍🏫', '👨🏽‍🏭', '👨🏽‍💻', '👨🏽‍💼', '👨🏽‍🔧', '👨🏽‍🔬', '👨🏽‍🚀', '👨🏽‍🚒', '👨🏽‍🦯', '👨🏽‍🦰', '👨🏽‍🦱', '👨🏽‍🦲', '👨🏽‍🦳', '👨🏽‍🦼', '👨🏽‍🦽', '👨🏾‍🌾', '👨🏾‍🍳', '👨🏾‍🍼', '👨🏾‍🎄', '👨🏾‍🎓', '👨🏾‍🎤', '👨🏾‍🎨', '👨🏾‍🏫', '👨🏾‍🏭', '👨🏾‍💻', '👨🏾‍💼', '👨🏾‍🔧', '👨🏾‍🔬', '👨🏾‍🚀', '👨🏾‍🚒', '👨🏾‍🦯', '👨🏾‍🦰', '👨🏾‍🦱', '👨🏾‍🦲', '👨🏾‍🦳', '👨🏾‍🦼', '👨🏾‍🦽', '👨🏿‍🌾', '👨🏿‍🍳', '👨🏿‍🍼', '👨🏿‍🎄', '👨🏿‍🎓', '👨🏿‍🎤', '👨🏿‍🎨', '👨🏿‍🏫', '👨🏿‍🏭', '👨🏿‍💻', '👨🏿‍💼', '👨🏿‍🔧', '👨🏿‍🔬', '👨🏿‍🚀', '👨🏿‍🚒', '👨🏿‍🦯', '👨🏿‍🦰', '👨🏿‍🦱', '👨🏿‍🦲', '👨🏿‍🦳', '👨🏿‍🦼', '👨🏿‍🦽', '👩🏻‍🌾', '👩🏻‍🍳', '👩🏻‍🍼', '👩🏻‍🎄', '👩🏻‍🎓', '👩🏻‍🎤', '👩🏻‍🎨', '👩🏻‍🏫', '👩🏻‍🏭', '👩🏻‍💻', '👩🏻‍💼', '👩🏻‍🔧', '👩🏻‍🔬', '👩🏻‍🚀', '👩🏻‍🚒', '👩🏻‍🦯', '👩🏻‍🦰', '👩🏻‍🦱', '👩🏻‍🦲', '👩🏻‍🦳', '👩🏻‍🦼', '👩🏻‍🦽', '👩🏼‍🌾', '👩🏼‍🍳', '👩🏼‍🍼', '👩🏼‍🎄', '👩🏼‍🎓', '👩🏼‍🎤', '👩🏼‍🎨', '👩🏼‍🏫', '👩🏼‍🏭', '👩🏼‍💻', '👩🏼‍💼', '👩🏼‍🔧', '👩🏼‍🔬', '👩🏼‍🚀', '👩🏼‍🚒', '👩🏼‍🦯', '👩🏼‍🦰', '👩🏼‍🦱', '👩🏼‍🦲', '👩🏼‍🦳', '👩🏼‍🦼', '👩🏼‍🦽', '👩🏽‍🌾', '👩🏽‍🍳', '👩🏽‍🍼', '👩🏽‍🎄', '👩🏽‍🎓', '👩🏽‍🎤', '👩🏽‍🎨', '👩🏽‍🏫', '👩🏽‍🏭', '👩🏽‍💻', '👩🏽‍💼', '👩🏽‍🔧', '👩🏽‍🔬', '👩🏽‍🚀', '👩🏽‍🚒', '👩🏽‍🦯', '👩🏽‍🦰', '👩🏽‍🦱', '👩🏽‍🦲', '👩🏽‍🦳', '👩🏽‍🦼', '👩🏽‍🦽', '👩🏾‍🌾', '👩🏾‍🍳', '👩🏾‍🍼', '👩🏾‍🎄', '👩🏾‍🎓', '👩🏾‍🎤', '👩🏾‍🎨', '👩🏾‍🏫', '👩🏾‍🏭', '👩🏾‍💻', '👩🏾‍💼', '👩🏾‍🔧', '👩🏾‍🔬', '👩🏾‍🚀', '👩🏾‍🚒', '👩🏾‍🦯', '👩🏾‍🦰', '👩🏾‍🦱', '👩🏾‍🦲', '👩🏾‍🦳', '👩🏾‍🦼', '👩🏾‍🦽', '👩🏿‍🌾', '👩🏿‍🍳', '👩🏿‍🍼', '👩🏿‍🎄', '👩🏿‍🎓', '👩🏿‍🎤', '👩🏿‍🎨', '👩🏿‍🏫', '👩🏿‍🏭', '👩🏿‍💻', '👩🏿‍💼', '👩🏿‍🔧', '👩🏿‍🔬', '👩🏿‍🚀', '👩🏿‍🚒', '👩🏿‍🦯', '👩🏿‍🦰', '👩🏿‍🦱', '👩🏿‍🦲', '👩🏿‍🦳', '👩🏿‍🦼', '👩🏿‍🦽', '🧑🏻‍🌾', '🧑🏻‍🍳', '🧑🏻‍🍼', '🧑🏻‍🎄', '🧑🏻‍🎓', '🧑🏻‍🎤', '🧑🏻‍🎨', '🧑🏻‍🏫', '🧑🏻‍🏭', '🧑🏻‍💻', '🧑🏻‍💼', '🧑🏻‍🔧', '🧑🏻‍🔬', '🧑🏻‍🚀', '🧑🏻‍🚒', '🧑🏻‍🦯', '🧑🏻‍🦰', '🧑🏻‍🦱', '🧑🏻‍🦲', '🧑🏻‍🦳', '🧑🏻‍🦼', '🧑🏻‍🦽', '🧑🏻‍🩰', '🧑🏼‍🌾', '🧑🏼‍🍳', '🧑🏼‍🍼', '🧑🏼‍🎄', '🧑🏼‍🎓', '🧑🏼‍🎤', '🧑🏼‍🎨', '🧑🏼‍🏫', '🧑🏼‍🏭', '🧑🏼‍💻', '🧑🏼‍💼', '🧑🏼‍🔧', '🧑🏼‍🔬', '🧑🏼‍🚀', '🧑🏼‍🚒', '🧑🏼‍🦯', '🧑🏼‍🦰', '🧑🏼‍🦱', '🧑🏼‍🦲', '🧑🏼‍🦳', '🧑🏼‍🦼', '🧑🏼‍🦽', '🧑🏼‍🩰', '🧑🏽‍🌾', '🧑🏽‍🍳', '🧑🏽‍🍼', '🧑🏽‍🎄', '🧑🏽‍🎓', '🧑🏽‍🎤', '🧑🏽‍🎨', '🧑🏽‍🏫', '🧑🏽‍🏭', '🧑🏽‍💻', '🧑🏽‍💼', '🧑🏽‍🔧', '🧑🏽‍🔬', '🧑🏽‍🚀', '🧑🏽‍🚒', '🧑🏽‍🦯', '🧑🏽‍🦰', '🧑🏽‍🦱', '🧑🏽‍🦲', '🧑🏽‍🦳', '🧑🏽‍🦼', '🧑🏽‍🦽', '🧑🏽‍🩰', '🧑🏾‍🌾', '🧑🏾‍🍳', '🧑🏾‍🍼', '🧑🏾‍🎄', '🧑🏾‍🎓', '🧑🏾‍🎤', '🧑🏾‍🎨', '🧑🏾‍🏫', '🧑🏾‍🏭', '🧑🏾‍💻', '🧑🏾‍💼', '🧑🏾‍🔧', '🧑🏾‍🔬', '🧑🏾‍🚀', '🧑🏾‍🚒', '🧑🏾‍🦯', '🧑🏾‍🦰', '🧑🏾‍🦱', '🧑🏾‍🦲', '🧑🏾‍🦳', '🧑🏾‍🦼', '🧑🏾‍🦽', '🧑🏾‍🩰', '🧑🏿‍🌾', '🧑🏿‍🍳', '🧑🏿‍🍼', '🧑🏿‍🎄', '🧑🏿‍🎓', '🧑🏿‍🎤', '🧑🏿‍🎨', '🧑🏿‍🏫', '🧑🏿‍🏭', '🧑🏿‍💻', '🧑🏿‍💼', '🧑🏿‍🔧', '🧑🏿‍🔬', '🧑🏿‍🚀', '🧑🏿‍🚒', '🧑🏿‍🦯', '🧑🏿‍🦰', '🧑🏿‍🦱', '🧑🏿‍🦲', '🧑🏿‍🦳', '🧑🏿‍🦼', '🧑🏿‍🦽', '🧑🏿‍🩰', '🏳️‍🌈', '😶‍🌫️', '🏃‍♀️', '🏃‍♂️', '🏃‍➡️', '🏄‍♀️', '🏄‍♂️', '🏊‍♀️', '🏊‍♂️', '🏴‍☠️', '🐻‍❄️', '👨‍⚕️', '👨‍⚖️', '👨‍✈️', '👩‍⚕️', '👩‍⚖️', '👩‍✈️', '👮‍♀️', '👮‍♂️', '👯‍♀️', '👯‍♂️', '👰‍♀️', '👰‍♂️', '👱‍♀️', '👱‍♂️', '👳‍♀️', '👳‍♂️', '👷‍♀️', '👷‍♂️', '💁‍♀️', '💁‍♂️', '💂‍♀️', '💂‍♂️', '💆‍♀️', '💆‍♂️', '💇‍♀️', '💇‍♂️', '🙂‍↔️', '🙂‍↕️', '🙅‍♀️', '🙅‍♂️', '🙆‍♀️', '🙆‍♂️', '🙇‍♀️', '🙇‍♂️', '🙋‍♀️', '🙋‍♂️', '🙍‍♀️', '🙍‍♂️', '🙎‍♀️', '🙎‍♂️', '🚣‍♀️', '🚣‍♂️', '🚴‍♀️', '🚴‍♂️', '🚵‍♀️', '🚵‍♂️', '🚶‍♀️', '🚶‍♂️', '🚶‍➡️', '🤦‍♀️', '🤦‍♂️', '🤵‍♀️', '🤵‍♂️', '🤷‍♀️', '🤷‍♂️', '🤸‍♀️', '🤸‍♂️', '🤹‍♀️', '🤹‍♂️', '🤼‍♀️', '🤼‍♂️', '🤽‍♀️', '🤽‍♂️', '🤾‍♀️', '🤾‍♂️', '🦸‍♀️', '🦸‍♂️', '🦹‍♀️', '🦹‍♂️', '🧍‍♀️', '🧍‍♂️', '🧎‍♀️', '🧎‍♂️', '🧎‍➡️', '🧏‍♀️', '🧏‍♂️', '🧑‍⚕️', '🧑‍⚖️', '🧑‍✈️', '🧔‍♀️', '🧔‍♂️', '🧖‍♀️', '🧖‍♂️', '🧗‍♀️', '🧗‍♂️', '🧘‍♀️', '🧘‍♂️', '🧙‍♀️', '🧙‍♂️', '🧚‍♀️', '🧚‍♂️', '🧛‍♀️', '🧛‍♂️', '🧜‍♀️', '🧜‍♂️', '🧝‍♀️', '🧝‍♂️', '🧞‍♀️', '🧞‍♂️', '🧟‍♀️', '🧟‍♂️', '⛓️‍💥', '❤️‍🔥', '❤️‍🩹', '🍄‍🟫', '🍋‍🟩', '🐕‍🦺', '🐦‍🔥', '👁‍🗨', '👨‍🌾', '👨‍🍳', '👨‍🍼', '👨‍🎄', '👨‍🎓', '👨‍🎤', '👨‍🎨', '👨‍🏫', '👨‍🏭', '👨‍👦', '👨‍👧', '👨‍💻', '👨‍💼', '👨‍🔧', '👨‍🔬', '👨‍🚀', '👨‍🚒', '👨‍🦯', '👨‍🦰', '👨‍🦱', '👨‍🦲', '👨‍🦳', '👨‍🦼', '👨‍🦽', '👩‍🌾', '👩‍🍳', '👩‍🍼', '👩‍🎄', '👩‍🎓', '👩‍🎤', '👩‍🎨', '👩‍🏫', '👩‍🏭', '👩‍👦', '👩‍👧', '👩‍💻', '👩‍💼', '👩‍🔧', '👩‍🔬', '👩‍🚀', '👩‍🚒', '👩‍🦯', '👩‍🦰', '👩‍🦱', '👩‍🦲', '👩‍🦳', '👩‍🦼', '👩‍🦽', '😮‍💨', '😵‍💫', '🧑‍🌾', '🧑‍🍳', '🧑‍🍼', '🧑‍🎄', '🧑‍🎓', '🧑‍🎤', '🧑‍🎨', '🧑‍🏫', '🧑‍🏭', '🧑‍💻', '🧑‍💼', '🧑‍🔧', '🧑‍🔬', '🧑‍🚀', '🧑‍🚒', '🧑‍🦯', '🧑‍🦰', '🧑‍🦱', '🧑‍🦲', '🧑‍🦳', '🧑‍🦼', '🧑‍🦽', '🧑‍🧒', '🧑‍🩰', '🐈‍⬛', '🐦‍⬛', '🇦🇨', '🇦🇩', '🇦🇪', '🇦🇫', '🇦🇬', '🇦🇮', '🇦🇱', '🇦🇲', '🇦🇴', '🇦🇶', '🇦🇷', '🇦🇸', '🇦🇹', '🇦🇺', '🇦🇼', '🇦🇽', '🇦🇿', '🇧🇦', '🇧🇧', '🇧🇩', '🇧🇪', '🇧🇫', '🇧🇬', '🇧🇭', '🇧🇮', '🇧🇯', '🇧🇱', '🇧🇲', '🇧🇳', '🇧🇴', '🇧🇶', '🇧🇷', '🇧🇸', '🇧🇹', '🇧🇻', '🇧🇼', '🇧🇾', '🇧🇿', '🇨🇦', '🇨🇨', '🇨🇩', '🇨🇫', '🇨🇬', '🇨🇭', '🇨🇮', '🇨🇰', '🇨🇱', '🇨🇲', '🇨🇳', '🇨🇴', '🇨🇵', '🇨🇶', '🇨🇷', '🇨🇺', '🇨🇻', '🇨🇼', '🇨🇽', '🇨🇾', '🇨🇿', '🇩🇪', '🇩🇬', '🇩🇯', '🇩🇰', '🇩🇲', '🇩🇴', '🇩🇿', '🇪🇦', '🇪🇨', '🇪🇪', '🇪🇬', '🇪🇭', '🇪🇷', '🇪🇸', '🇪🇹', '🇪🇺', '🇫🇮', '🇫🇯', '🇫🇰', '🇫🇲', '🇫🇴', '🇫🇷', '🇬🇦', '🇬🇧', '🇬🇩', '🇬🇪', '🇬🇫', '🇬🇬', '🇬🇭', '🇬🇮', '🇬🇱', '🇬🇲', '🇬🇳', '🇬🇵', '🇬🇶', '🇬🇷', '🇬🇸', '🇬🇹', '🇬🇺', '🇬🇼', '🇬🇾', '🇭🇰', '🇭🇲', '🇭🇳', '🇭🇷', '🇭🇹', '🇭🇺', '🇮🇨', '🇮🇩', '🇮🇪', '🇮🇱', '🇮🇲', '🇮🇳', '🇮🇴', '🇮🇶', '🇮🇷', '🇮🇸', '🇮🇹', '🇯🇪', '🇯🇲', '🇯🇴', '🇯🇵', '🇰🇪', '🇰🇬', '🇰🇭', '🇰🇮', '🇰🇲', '🇰🇳', '🇰🇵', '🇰🇷', '🇰🇼', '🇰🇾', '🇰🇿', '🇱🇦', '🇱🇧', '🇱🇨', '🇱🇮', '🇱🇰', '🇱🇷', '🇱🇸', '🇱🇹', '🇱🇺', '🇱🇻', '🇱🇾', '🇲🇦', '🇲🇨', '🇲🇩', '🇲🇪', '🇲🇫', '🇲🇬', '🇲🇭', '🇲🇰', '🇲🇱', '🇲🇲', '🇲🇳', '🇲🇴', '🇲🇵', '🇲🇶', '🇲🇷', '🇲🇸', '🇲🇹', '🇲🇺', '🇲🇻', '🇲🇼', '🇲🇽', '🇲🇾', '🇲🇿', '🇳🇦', '🇳🇨', '🇳🇪', '🇳🇫', '🇳🇬', '🇳🇮', '🇳🇱', '🇳🇴', '🇳🇵', '🇳🇷', '🇳🇺', '🇳🇿', '🇴🇲', '🇵🇦', '🇵🇪', '🇵🇫', '🇵🇬', '🇵🇭', '🇵🇰', '🇵🇱', '🇵🇲', '🇵🇳', '🇵🇷', '🇵🇸', '🇵🇹', '🇵🇼', '🇵🇾', '🇶🇦', '🇷🇪', '🇷🇴', '🇷🇸', '🇷🇺', '🇷🇼', '🇸🇦', '🇸🇧', '🇸🇨', '🇸🇩', '🇸🇪', '🇸🇬', '🇸🇭', '🇸🇮', '🇸🇯', '🇸🇰', '🇸🇱', '🇸🇲', '🇸🇳', '🇸🇴', '🇸🇷', '🇸🇸', '🇸🇹', '🇸🇻', '🇸🇽', '🇸🇾', '🇸🇿', '🇹🇦', '🇹🇨', '🇹🇩', '🇹🇫', '🇹🇬', '🇹🇭', '🇹🇯', '🇹🇰', '🇹🇱', '🇹🇲', '🇹🇳', '🇹🇴', '🇹🇷', '🇹🇹', '🇹🇻', '🇹🇼', '🇹🇿', '🇺🇦', '🇺🇬', '🇺🇲', '🇺🇳', '🇺🇸', '🇺🇾', '🇺🇿', '🇻🇦', '🇻🇨', '🇻🇪', '🇻🇬', '🇻🇮', '🇻🇳', '🇻🇺', '🇼🇫', '🇼🇸', '🇽🇰', '🇾🇪', '🇾🇹', '🇿🇦', '🇿🇲', '🇿🇼', '🎅🏻', '🎅🏼', '🎅🏽', '🎅🏾', '🎅🏿', '🏂🏻', '🏂🏼', '🏂🏽', '🏂🏾', '🏂🏿', '🏃🏻', '🏃🏼', '🏃🏽', '🏃🏾', '🏃🏿', '🏄🏻', '🏄🏼', '🏄🏽', '🏄🏾', '🏄🏿', '🏇🏻', '🏇🏼', '🏇🏽', '🏇🏾', '🏇🏿', '🏊🏻', '🏊🏼', '🏊🏽', '🏊🏾', '🏊🏿', '🏋🏻', '🏋🏼', '🏋🏽', '🏋🏾', '🏋🏿', '🏌🏻', '🏌🏼', '🏌🏽', '🏌🏾', '🏌🏿', '👂🏻', '👂🏼', '👂🏽', '👂🏾', '👂🏿', '👃🏻', '👃🏼', '👃🏽', '👃🏾', '👃🏿', '👆🏻', '👆🏼', '👆🏽', '👆🏾', '👆🏿', '👇🏻', '👇🏼', '👇🏽', '👇🏾', '👇🏿', '👈🏻', '👈🏼', '👈🏽', '👈🏾', '👈🏿', '👉🏻', '👉🏼', '👉🏽', '👉🏾', '👉🏿', '👊🏻', '👊🏼', '👊🏽', '👊🏾', '👊🏿', '👋🏻', '👋🏼', '👋🏽', '👋🏾', '👋🏿', '👌🏻', '👌🏼', '👌🏽', '👌🏾', '👌🏿', '👍🏻', '👍🏼', '👍🏽', '👍🏾', '👍🏿', '👎🏻', '👎🏼', '👎🏽', '👎🏾', '👎🏿', '👏🏻', '👏🏼', '👏🏽', '👏🏾', '👏🏿', '👐🏻', '👐🏼', '👐🏽', '👐🏾', '👐🏿', '👦🏻', '👦🏼', '👦🏽', '👦🏾', '👦🏿', '👧🏻', '👧🏼', '👧🏽', '👧🏾', '👧🏿', '👨🏻', '👨🏼', '👨🏽', '👨🏾', '👨🏿', '👩🏻', '👩🏼', '👩🏽', '👩🏾', '👩🏿', '👫🏻', '👫🏼', '👫🏽', '👫🏾', '👫🏿', '👬🏻', '👬🏼', '👬🏽', '👬🏾', '👬🏿', '👭🏻', '👭🏼', '👭🏽', '👭🏾', '👭🏿', '👮🏻', '👮🏼', '👮🏽', '👮🏾', '👮🏿', '👯🏻', '👯🏼', '👯🏽', '👯🏾', '👯🏿', '👰🏻', '👰🏼', '👰🏽', '👰🏾', '👰🏿', '👱🏻', '👱🏼', '👱🏽', '👱🏾', '👱🏿', '👲🏻', '👲🏼', '👲🏽', '👲🏾', '👲🏿', '👳🏻', '👳🏼', '👳🏽', '👳🏾', '👳🏿', '👴🏻', '👴🏼', '👴🏽', '👴🏾', '👴🏿', '👵🏻', '👵🏼', '👵🏽', '👵🏾', '👵🏿', '👶🏻', '👶🏼', '👶🏽', '👶🏾', '👶🏿', '👷🏻', '👷🏼', '👷🏽', '👷🏾', '👷🏿', '👸🏻', '👸🏼', '👸🏽', '👸🏾', '👸🏿', '👼🏻', '👼🏼', '👼🏽', '👼🏾', '👼🏿', '💁🏻', '💁🏼', '💁🏽', '💁🏾', '💁🏿', '💂🏻', '💂🏼', '💂🏽', '💂🏾', '💂🏿', '💃🏻', '💃🏼', '💃🏽', '💃🏾', '💃🏿', '💅🏻', '💅🏼', '💅🏽', '💅🏾', '💅🏿', '💆🏻', '💆🏼', '💆🏽', '💆🏾', '💆🏿', '💇🏻', '💇🏼', '💇🏽', '💇🏾', '💇🏿', '💏🏻', '💏🏼', '💏🏽', '💏🏾', '💏🏿', '💑🏻', '💑🏼', '💑🏽', '💑🏾', '💑🏿', '💪🏻', '💪🏼', '💪🏽', '💪🏾', '💪🏿', '🕴🏻', '🕴🏼', '🕴🏽', '🕴🏾', '🕴🏿', '🕵🏻', '🕵🏼', '🕵🏽', '🕵🏾', '🕵🏿', '🕺🏻', '🕺🏼', '🕺🏽', '🕺🏾', '🕺🏿', '🖐🏻', '🖐🏼', '🖐🏽', '🖐🏾', '🖐🏿', '🖕🏻', '🖕🏼', '🖕🏽', '🖕🏾', '🖕🏿', '🖖🏻', '🖖🏼', '🖖🏽', '🖖🏾', '🖖🏿', '🙅🏻', '🙅🏼', '🙅🏽', '🙅🏾', '🙅🏿', '🙆🏻', '🙆🏼', '🙆🏽', '🙆🏾', '🙆🏿', '🙇🏻', '🙇🏼', '🙇🏽', '🙇🏾', '🙇🏿', '🙋🏻', '🙋🏼', '🙋🏽', '🙋🏾', '🙋🏿', '🙌🏻', '🙌🏼', '🙌🏽', '🙌🏾', '🙌🏿', '🙍🏻', '🙍🏼', '🙍🏽', '🙍🏾', '🙍🏿', '🙎🏻', '🙎🏼', '🙎🏽', '🙎🏾', '🙎🏿', '🙏🏻', '🙏🏼', '🙏🏽', '🙏🏾', '🙏🏿', '🚣🏻', '🚣🏼', '🚣🏽', '🚣🏾', '🚣🏿', '🚴🏻', '🚴🏼', '🚴🏽', '🚴🏾', '🚴🏿', '🚵🏻', '🚵🏼', '🚵🏽', '🚵🏾', '🚵🏿', '🚶🏻', '🚶🏼', '🚶🏽', '🚶🏾', '🚶🏿', '🛀🏻', '🛀🏼', '🛀🏽', '🛀🏾', '🛀🏿', '🛌🏻', '🛌🏼', '🛌🏽', '🛌🏾', '🛌🏿', '🤌🏻', '🤌🏼', '🤌🏽', '🤌🏾', '🤌🏿', '🤏🏻', '🤏🏼', '🤏🏽', '🤏🏾', '🤏🏿', '🤘🏻', '🤘🏼', '🤘🏽', '🤘🏾', '🤘🏿', '🤙🏻', '🤙🏼', '🤙🏽', '🤙🏾', '🤙🏿', '🤚🏻', '🤚🏼', '🤚🏽', '🤚🏾', '🤚🏿', '🤛🏻', '🤛🏼', '🤛🏽', '🤛🏾', '🤛🏿', '🤜🏻', '🤜🏼', '🤜🏽', '🤜🏾', '🤜🏿', '🤝🏻', '🤝🏼', '🤝🏽', '🤝🏾', '🤝🏿', '🤞🏻', '🤞🏼', '🤞🏽', '🤞🏾', '🤞🏿', '🤟🏻', '🤟🏼', '🤟🏽', '🤟🏾', '🤟🏿', '🤦🏻', '🤦🏼', '🤦🏽', '🤦🏾', '🤦🏿', '🤰🏻', '🤰🏼', '🤰🏽', '🤰🏾', '🤰🏿', '🤱🏻', '🤱🏼', '🤱🏽', '🤱🏾', '🤱🏿', '🤲🏻', '🤲🏼', '🤲🏽', '🤲🏾', '🤲🏿', '🤳🏻', '🤳🏼', '🤳🏽', '🤳🏾', '🤳🏿', '🤴🏻', '🤴🏼', '🤴🏽', '🤴🏾', '🤴🏿', '🤵🏻', '🤵🏼', '🤵🏽', '🤵🏾', '🤵🏿', '🤶🏻', '🤶🏼', '🤶🏽', '🤶🏾', '🤶🏿', '🤷🏻', '🤷🏼', '🤷🏽', '🤷🏾', '🤷🏿', '🤸🏻', '🤸🏼', '🤸🏽', '🤸🏾', '🤸🏿', '🤹🏻', '🤹🏼', '🤹🏽', '🤹🏾', '🤹🏿', '🤼🏻', '🤼🏼', '🤼🏽', '🤼🏾', '🤼🏿', '🤽🏻', '🤽🏼', '🤽🏽', '🤽🏾', '🤽🏿', '🤾🏻', '🤾🏼', '🤾🏽', '🤾🏾', '🤾🏿', '🥷🏻', '🥷🏼', '🥷🏽', '🥷🏾', '🥷🏿', '🦵🏻', '🦵🏼', '🦵🏽', '🦵🏾', '🦵🏿', '🦶🏻', '🦶🏼', '🦶🏽', '🦶🏾', '🦶🏿', '🦸🏻', '🦸🏼', '🦸🏽', '🦸🏾', '🦸🏿', '🦹🏻', '🦹🏼', '🦹🏽', '🦹🏾', '🦹🏿', '🦻🏻', '🦻🏼', '🦻🏽', '🦻🏾', '🦻🏿', '🧍🏻', '🧍🏼', '🧍🏽', '🧍🏾', '🧍🏿', '🧎🏻', '🧎🏼', '🧎🏽', '🧎🏾', '🧎🏿', '🧏🏻', '🧏🏼', '🧏🏽', '🧏🏾', '🧏🏿', '🧑🏻', '🧑🏼', '🧑🏽', '🧑🏾', '🧑🏿', '🧒🏻', '🧒🏼', '🧒🏽', '🧒🏾', '🧒🏿', '🧓🏻', '🧓🏼', '🧓🏽', '🧓🏾', '🧓🏿', '🧔🏻', '🧔🏼', '🧔🏽', '🧔🏾', '🧔🏿', '🧕🏻', '🧕🏼', '🧕🏽', '🧕🏾', '🧕🏿', '🧖🏻', '🧖🏼', '🧖🏽', '🧖🏾', '🧖🏿', '🧗🏻', '🧗🏼', '🧗🏽', '🧗🏾', '🧗🏿', '🧘🏻', '🧘🏼', '🧘🏽', '🧘🏾', '🧘🏿', '🧙🏻', '🧙🏼', '🧙🏽', '🧙🏾', '🧙🏿', '🧚🏻', '🧚🏼', '🧚🏽', '🧚🏾', '🧚🏿', '🧛🏻', '🧛🏼', '🧛🏽', '🧛🏾', '🧛🏿', '🧜🏻', '🧜🏼', '🧜🏽', '🧜🏾', '🧜🏿', '🧝🏻', '🧝🏼', '🧝🏽', '🧝🏾', '🧝🏿', '🫃🏻', '🫃🏼', '🫃🏽', '🫃🏾', '🫃🏿', '🫄🏻', '🫄🏼', '🫄🏽', '🫄🏾', '🫄🏿', '🫅🏻', '🫅🏼', '🫅🏽', '🫅🏾', '🫅🏿', '🫰🏻', '🫰🏼', '🫰🏽', '🫰🏾', '🫰🏿', '🫱🏻', '🫱🏼', '🫱🏽', '🫱🏾', '🫱🏿', '🫲🏻', '🫲🏼', '🫲🏽', '🫲🏾', '🫲🏿', '🫳🏻', '🫳🏼', '🫳🏽', '🫳🏾', '🫳🏿', '🫴🏻', '🫴🏼', '🫴🏽', '🫴🏾', '🫴🏿', '🫵🏻', '🫵🏼', '🫵🏽', '🫵🏾', '🫵🏿', '🫶🏻', '🫶🏼', '🫶🏽', '🫶🏾', '🫶🏿', '🫷🏻', '🫷🏼', '🫷🏽', '🫷🏾', '🫷🏿', '🫸🏻', '🫸🏼', '🫸🏽', '🫸🏾', '🫸🏿', '☝🏻', '☝🏼', '☝🏽', '☝🏾', '☝🏿', '⛷🏻', '⛷🏼', '⛷🏽', '⛷🏾', '⛷🏿', '⛹🏻', '⛹🏼', '⛹🏽', '⛹🏾', '⛹🏿', '✊🏻', '✊🏼', '✊🏽', '✊🏾', '✊🏿', '✋🏻', '✋🏼', '✋🏽', '✋🏾', '✋🏿', '✌🏻', '✌🏼', '✌🏽', '✌🏾', '✌🏿', '✍🏻', '✍🏼', '✍🏽', '✍🏾', '✍🏿', '#⃣', '*⃣', '0⃣', '1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🀄', '🃏', '🅰', '🅱', '🅾', '🅿', '🆎', '🆑', '🆒', '🆓', '🆔', '🆕', '🆖', '🆗', '🆘', '🆙', '🆚', '🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮', '🇯', '🇰', '🇱', '🇲', '🇳', '🇴', '🇵', '🇶', '🇷', '🇸', '🇹', '🇺', '🇻', '🇼', '🇽', '🇾', '🇿', '🈁', '🈂', '🈚', '🈯', '🈲', '🈳', '🈴', '🈵', '🈶', '🈷', '🈸', '🈹', '🈺', '🉐', '🉑', '🌀', '🌁', '🌂', '🌃', '🌄', '🌅', '🌆', '🌇', '🌈', '🌉', '🌊', '🌋', '🌌', '🌍', '🌎', '🌏', '🌐', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘', '🌙', '🌚', '🌛', '🌜', '🌝', '🌞', '🌟', '🌠', '🌡', '🌤', '🌥', '🌦', '🌧', '🌨', '🌩', '🌪', '🌫', '🌬', '🌭', '🌮', '🌯', '🌰', '🌱', '🌲', '🌳', '🌴', '🌵', '🌶', '🌷', '🌸', '🌹', '🌺', '🌻', '🌼', '🌽', '🌾', '🌿', '🍀', '🍁', '🍂', '🍃', '🍄', '🍅', '🍆', '🍇', '🍈', '🍉', '🍊', '🍋', '🍌', '🍍', '🍎', '🍏', '🍐', '🍑', '🍒', '🍓', '🍔', '🍕', '🍖', '🍗', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍞', '🍟', '🍠', '🍡', '🍢', '🍣', '🍤', '🍥', '🍦', '🍧', '🍨', '🍩', '🍪', '🍫', '🍬', '🍭', '🍮', '🍯', '🍰', '🍱', '🍲', '🍳', '🍴', '🍵', '🍶', '🍷', '🍸', '🍹', '🍺', '🍻', '🍼', '🍽', '🍾', '🍿', '🎀', '🎁', '🎂', '🎃', '🎄', '🎅', '🎆', '🎇', '🎈', '🎉', '🎊', '🎋', '🎌', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '🎙', '🎚', '🎛', '🎞', '🎟', '🎠', '🎡', '🎢', '🎣', '🎤', '🎥', '🎦', '🎧', '🎨', '🎩', '🎪', '🎫', '🎬', '🎭', '🎮', '🎯', '🎰', '🎱', '🎲', '🎳', '🎴', '🎵', '🎶', '🎷', '🎸', '🎹', '🎺', '🎻', '🎼', '🎽', '🎾', '🎿', '🏀', '🏁', '🏂', '🏃', '🏄', '🏅', '🏆', '🏇', '🏈', '🏉', '🏊', '🏋', '🏌', '🏍', '🏎', '🏏', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🏚', '🏛', '🏜', '🏝', '🏞', '🏟', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨', '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '🏳', '🏴', '🏵', '🏷', '🏸', '🏹', '🏺', '🏻', '🏼', '🏽', '🏾', '🏿', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '🐉', '🐊', '🐋', '🐌', '🐍', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🐕', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '👩', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💋', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💻', '💼', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔥', '🔦', '🔧', '🔨', '🔩', '🔪', '🔫', '🔬', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗨', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚀', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚒', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛖', '🛗', '🛘', '🛜', '🛝', '🛞', '🛟', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🛻', '🛼', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🟰', '🤌', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤝', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥲', '🥳', '🥴', '🥵', '🥶', '🥷', '🥸', '🥹', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦣', '🦤', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦫', '🦬', '🦭', '🦮', '🦯', '🦰', '🦱', '🦲', '🦳', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦺', '🦻', '🦼', '🦽', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧋', '🧌', '🧍', '🧎', '🧏', '🧐', '🧑', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩴', '🩵', '🩶', '🩷', '🩸', '🩹', '🩺', '🩻', '🩼', '🪀', '🪁', '🪂', '🪃', '🪄', '🪅', '🪆', '🪇', '🪈', '🪉', '🪊', '🪎', '🪏', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🪖', '🪗', '🪘', '🪙', '🪚', '🪛', '🪜', '🪝', '🪞', '🪟', '🪠', '🪡', '🪢', '🪣', '🪤', '🪥', '🪦', '🪧', '🪨', '🪩', '🪪', '🪫', '🪬', '🪭', '🪮', '🪯', '🪰', '🪱', '🪲', '🪳', '🪴', '🪵', '🪶', '🪷', '🪸', '🪹', '🪺', '🪻', '🪼', '🪽', '🪾', '🪿', '🫀', '🫁', '🫂', '🫃', '🫄', '🫅', '🫆', '🫈', '🫍', '🫎', '🫏', '🫐', '🫑', '🫒', '🫓', '🫔', '🫕', '🫖', '🫗', '🫘', '🫙', '🫚', '🫛', '🫜', '🫟', '🫠', '🫡', '🫢', '🫣', '🫤', '🫥', '🫦', '🫧', '🫨', '🫩', '🫪', '🫯', '🫰', '🫱', '🫲', '🫳', '🫴', '🫵', '🫶', '🫷', '🫸', '‼', '⁉', '™', 'ℹ', '↔', '↕', '↖', '↗', '↘', '↙', '↩', '↪', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☠', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♀', '♂', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚕', '⚖', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚧', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✈', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❄', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '❤', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬛', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' ); $partials = array( '🀄', '🃏', '🅰', '🅱', '🅾', '🅿', '🆎', '🆑', '🆒', '🆓', '🆔', '🆕', '🆖', '🆗', '🆘', '🆙', '🆚', '🇦', '🇨', '🇩', '🇪', '🇫', '🇬', '🇮', '🇱', '🇲', '🇴', '🇶', '🇷', '🇸', '🇹', '🇺', '🇼', '🇽', '🇿', '🇧', '🇭', '🇯', '🇳', '🇻', '🇾', '🇰', '🇵', '🈁', '🈂', '🈚', '🈯', '🈲', '🈳', '🈴', '🈵', '🈶', '🈷', '🈸', '🈹', '🈺', '🉐', '🉑', '🌀', '🌁', '🌂', '🌃', '🌄', '🌅', '🌆', '🌇', '🌈', '🌉', '🌊', '🌋', '🌌', '🌍', '🌎', '🌏', '🌐', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘', '🌙', '🌚', '🌛', '🌜', '🌝', '🌞', '🌟', '🌠', '🌡', '🌤', '🌥', '🌦', '🌧', '🌨', '🌩', '🌪', '🌫', '🌬', '🌭', '🌮', '🌯', '🌰', '🌱', '🌲', '🌳', '🌴', '🌵', '🌶', '🌷', '🌸', '🌹', '🌺', '🌻', '🌼', '🌽', '🌾', '🌿', '🍀', '🍁', '🍂', '🍃', '🍄', '‍', '🟫', '🍅', '🍆', '🍇', '🍈', '🍉', '🍊', '🍋', '🟩', '🍌', '🍍', '🍎', '🍏', '🍐', '🍑', '🍒', '🍓', '🍔', '🍕', '🍖', '🍗', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍞', '🍟', '🍠', '🍡', '🍢', '🍣', '🍤', '🍥', '🍦', '🍧', '🍨', '🍩', '🍪', '🍫', '🍬', '🍭', '🍮', '🍯', '🍰', '🍱', '🍲', '🍳', '🍴', '🍵', '🍶', '🍷', '🍸', '🍹', '🍺', '🍻', '🍼', '🍽', '🍾', '🍿', '🎀', '🎁', '🎂', '🎃', '🎄', '🎅', '🏻', '🏼', '🏽', '🏾', '🏿', '🎆', '🎇', '🎈', '🎉', '🎊', '🎋', '🎌', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '🎙', '🎚', '🎛', '🎞', '🎟', '🎠', '🎡', '🎢', '🎣', '🎤', '🎥', '🎦', '🎧', '🎨', '🎩', '🎪', '🎫', '🎬', '🎭', '🎮', '🎯', '🎰', '🎱', '🎲', '🎳', '🎴', '🎵', '🎶', '🎷', '🎸', '🎹', '🎺', '🎻', '🎼', '🎽', '🎾', '🎿', '🏀', '🏁', '🏂', '🏃', '♀', '️', '➡', '♂', '🏄', '🏅', '🏆', '🏇', '🏈', '🏉', '🏊', '🏋', '🏌', '🏍', '🏎', '🏏', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🏚', '🏛', '🏜', '🏝', '🏞', '🏟', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨', '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '🏳', '⚧', '🏴', '☠', '󠁧', '󠁢', '󠁥', '󠁮', '󠁿', '󠁳', '󠁣', '󠁴', '󠁷', '󠁬', '🏵', '🏷', '🏸', '🏹', '🏺', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '⬛', '🐉', '🐊', '🐋', '🐌', '🐍', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🐕', '🦺', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🔥', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '❄', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '🗨', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '💻', '💼', '🔧', '🔬', '🚀', '🚒', '🤝', '🦯', '🦰', '🦱', '🦲', '🦳', '🦼', '🦽', '🫯', '⚕', '⚖', '✈', '❤', '💋', '👩', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔦', '🔨', '🔩', '🔪', '🔫', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '↔', '↕', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛖', '🛗', '🛘', '🛜', '🛝', '🛞', '🛟', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🛻', '🛼', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟪', '🟰', '🤌', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥲', '🥳', '🥴', '🥵', '🥶', '🥷', '🥸', '🥹', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦣', '🦤', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦫', '🦬', '🦭', '🦮', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦻', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧋', '🧌', '🧍', '🧎', '🧏', '🧐', '🧑', '🩰', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩱', '🩲', '🩳', '🩴', '🩵', '🩶', '🩷', '🩸', '🩹', '🩺', '🩻', '🩼', '🪀', '🪁', '🪂', '🪃', '🪄', '🪅', '🪆', '🪇', '🪈', '🪉', '🪊', '🪎', '🪏', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🪖', '🪗', '🪘', '🪙', '🪚', '🪛', '🪜', '🪝', '🪞', '🪟', '🪠', '🪡', '🪢', '🪣', '🪤', '🪥', '🪦', '🪧', '🪨', '🪩', '🪪', '🪫', '🪬', '🪭', '🪮', '🪯', '🪰', '🪱', '🪲', '🪳', '🪴', '🪵', '🪶', '🪷', '🪸', '🪹', '🪺', '🪻', '🪼', '🪽', '🪾', '🪿', '🫀', '🫁', '🫂', '🫃', '🫄', '🫅', '🫆', '🫈', '🫍', '🫎', '🫏', '🫐', '🫑', '🫒', '🫓', '🫔', '🫕', '🫖', '🫗', '🫘', '🫙', '🫚', '🫛', '🫜', '🫟', '🫠', '🫡', '🫢', '🫣', '🫤', '🫥', '🫦', '🫧', '🫨', '🫩', '🫪', '🫰', '🫱', '🫲', '🫳', '🫴', '🫵', '🫶', '🫷', '🫸', '‼', '⁉', '™', 'ℹ', '↖', '↗', '↘', '↙', '↩', '↪', '⃣', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '➕', '➖', '➗', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' ); if ( 'entities' === $type ) { return $entities; } return $partials; } function url_shorten( $url, $length = 35 ) { $stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url ); $short_url = untrailingslashit( $stripped ); if ( strlen( $short_url ) > $length ) { $short_url = substr( $short_url, 0, $length - 3 ) . '…'; } return $short_url; } function sanitize_hex_color( $color ) { if ( '' === $color ) { return ''; } if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) { return $color; } } function sanitize_hex_color_no_hash( $color ) { $color = ltrim( $color, '#' ); if ( '' === $color ) { return ''; } return sanitize_hex_color( '#' . $color ) ? $color : null; } function maybe_hash_hex_color( $color ) { $unhashed = sanitize_hex_color_no_hash( $color ); if ( $unhashed ) { return '#' . $unhashed; } return $color; }
###require ABSPATH . WPINC . '/meta.php';
require ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php'; function add_metadata( $meta_type, $object_id, $meta_key, $meta_value, $unique = false ) { global $wpdb; if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { return false; } $object_id = absint( $object_id ); if ( ! $object_id ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $meta_subtype = get_object_subtype( $meta_type, $object_id ); $column = sanitize_key( $meta_type . '_id' ); $meta_key = wp_unslash( $meta_key ); $meta_value = wp_unslash( $meta_value ); $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique ); if ( null !== $check ) { return $check; } if ( $unique && $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ) ) { return false; } $_meta_value = $meta_value; $meta_value = maybe_serialize( $meta_value ); do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value ); $result = $wpdb->insert( $table, array( $column => $object_id, 'meta_key' => $meta_key, 'meta_value' => $meta_value, ) ); if ( ! $result ) { return false; } $mid = (int) $wpdb->insert_id; wp_cache_delete( $object_id, $meta_type . '_meta' ); do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value ); return $mid; } function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) { global $wpdb; if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) { return false; } $object_id = absint( $object_id ); if ( ! $object_id ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $meta_subtype = get_object_subtype( $meta_type, $object_id ); $column = sanitize_key( $meta_type . '_id' ); $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $raw_meta_key = $meta_key; $meta_key = wp_unslash( $meta_key ); $passed_value = $meta_value; $meta_value = wp_unslash( $meta_value ); $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value ); if ( null !== $check ) { return (bool) $check; } if ( empty( $prev_value ) ) { $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key ); if ( is_countable( $old_value ) && count( $old_value ) === 1 ) { if ( $old_value[0] === $meta_value ) { return false; } } } $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ); if ( empty( $meta_ids ) ) { return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value ); } $_meta_value = $meta_value; $meta_value = maybe_serialize( $meta_value ); $data = compact( 'meta_value' ); $where = array( $column => $object_id, 'meta_key' => $meta_key, ); if ( ! empty( $prev_value ) ) { $prev_value = maybe_serialize( $prev_value ); $where['meta_value'] = $prev_value; } foreach ( $meta_ids as $meta_id ) { do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); } } $result = $wpdb->update( $table, $data, $where ); if ( ! $result ) { return false; } wp_cache_delete( $object_id, $meta_type . '_meta' ); foreach ( $meta_ids as $meta_id ) { do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); } } return true; } function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) { global $wpdb; if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) { return false; } $object_id = absint( $object_id ); if ( ! $object_id && ! $delete_all ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $type_column = sanitize_key( $meta_type . '_id' ); $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $meta_key = wp_unslash( $meta_key ); $meta_value = wp_unslash( $meta_value ); $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all ); if ( null !== $check ) { return (bool) $check; } $_meta_value = $meta_value; $meta_value = maybe_serialize( $meta_value ); $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key ); if ( ! $delete_all ) { $query .= $wpdb->prepare( " AND $type_column = %d", $object_id ); } if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { $query .= $wpdb->prepare( ' AND meta_value = %s', $meta_value ); } $meta_ids = $wpdb->get_col( $query ); if ( ! count( $meta_ids ) ) { return false; } if ( $delete_all ) { if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) ); } else { $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) ); } } do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'delete_postmeta', $meta_ids ); } $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . ' )'; $count = $wpdb->query( $query ); if ( ! $count ) { return false; } if ( $delete_all ) { $data = (array) $object_ids; } else { $data = array( $object_id ); } wp_cache_delete_multiple( $data, $meta_type . '_meta' ); do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'deleted_postmeta', $meta_ids ); } return true; } function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) { $value = get_metadata_raw( $meta_type, $object_id, $meta_key, $single ); if ( ! is_null( $value ) ) { return $value; } return get_metadata_default( $meta_type, $object_id, $meta_key, $single ); } function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false ) { if ( ! $meta_type || ! is_numeric( $object_id ) ) { return false; } $object_id = absint( $object_id ); if ( ! $object_id ) { return false; } $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $meta_type ); if ( null !== $check ) { if ( $single && is_array( $check ) ) { return $check[0]; } else { return $check; } } $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); if ( ! $meta_cache ) { $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); if ( isset( $meta_cache[ $object_id ] ) ) { $meta_cache = $meta_cache[ $object_id ]; } else { $meta_cache = null; } } if ( ! $meta_key ) { return $meta_cache; } if ( isset( $meta_cache[ $meta_key ] ) ) { if ( $single ) { return maybe_unserialize( $meta_cache[ $meta_key ][0] ); } else { return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] ); } } return null; } function get_metadata_default( $meta_type, $object_id, $meta_key, $single = false ) { if ( $single ) { $value = ''; } else { $value = array(); } $value = apply_filters( "default_{$meta_type}_metadata", $value, $object_id, $meta_key, $single, $meta_type ); if ( ! $single && ! wp_is_numeric_array( $value ) ) { $value = array( $value ); } return $value; } function metadata_exists( $meta_type, $object_id, $meta_key ) { if ( ! $meta_type || ! is_numeric( $object_id ) ) { return false; } $object_id = absint( $object_id ); if ( ! $object_id ) { return false; } $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true, $meta_type ); if ( null !== $check ) { return (bool) $check; } $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); if ( ! $meta_cache ) { $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); $meta_cache = $meta_cache[ $object_id ]; } if ( isset( $meta_cache[ $meta_key ] ) ) { return true; } return false; } function get_metadata_by_mid( $meta_type, $meta_id ) { global $wpdb; if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) { return false; } $meta_id = (int) $meta_id; if ( $meta_id <= 0 ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id ); if ( null !== $check ) { return $check; } $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) ); if ( empty( $meta ) ) { return false; } if ( isset( $meta->meta_value ) ) { $meta->meta_value = maybe_unserialize( $meta->meta_value ); } return $meta; } function update_metadata_by_mid( $meta_type, $meta_id, $meta_value, $meta_key = false ) { global $wpdb; if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) { return false; } $meta_id = (int) $meta_id; if ( $meta_id <= 0 ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $column = sanitize_key( $meta_type . '_id' ); $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key ); if ( null !== $check ) { return (bool) $check; } $meta = get_metadata_by_mid( $meta_type, $meta_id ); if ( $meta ) { $original_key = $meta->meta_key; $object_id = $meta->{$column}; if ( false === $meta_key ) { $meta_key = $original_key; } elseif ( ! is_string( $meta_key ) ) { return false; } $meta_subtype = get_object_subtype( $meta_type, $object_id ); $_meta_value = $meta_value; $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); $meta_value = maybe_serialize( $meta_value ); $data = array( 'meta_key' => $meta_key, 'meta_value' => $meta_value, ); $where = array(); $where[ $id_column ] = $meta_id; do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); } $result = $wpdb->update( $table, $data, $where, '%s', '%d' ); if ( ! $result ) { return false; } wp_cache_delete( $object_id, $meta_type . '_meta' ); do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); if ( 'post' === $meta_type ) { do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); } return true; } return false; } function delete_metadata_by_mid( $meta_type, $meta_id ) { global $wpdb; if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) { return false; } $meta_id = (int) $meta_id; if ( $meta_id <= 0 ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $column = sanitize_key( $meta_type . '_id' ); $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id ); if ( null !== $check ) { return (bool) $check; } $meta = get_metadata_by_mid( $meta_type, $meta_id ); if ( $meta ) { $object_id = (int) $meta->{$column}; do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value ); if ( 'post' === $meta_type || 'comment' === $meta_type ) { do_action( "delete_{$meta_type}meta", $meta_id ); } $result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) ); wp_cache_delete( $object_id, $meta_type . '_meta' ); do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value ); if ( 'post' === $meta_type || 'comment' === $meta_type ) { do_action( "deleted_{$meta_type}meta", $meta_id ); } return $result; } return false; } function update_meta_cache( $meta_type, $object_ids ) { global $wpdb; if ( ! $meta_type || ! $object_ids ) { return false; } $table = _get_meta_table( $meta_type ); if ( ! $table ) { return false; } $column = sanitize_key( $meta_type . '_id' ); if ( ! is_array( $object_ids ) ) { $object_ids = preg_replace( '|[^0-9,]|', '', $object_ids ); $object_ids = explode( ',', $object_ids ); } $object_ids = array_map( 'intval', $object_ids ); $check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids ); if ( null !== $check ) { return (bool) $check; } $cache_group = $meta_type . '_meta'; $non_cached_ids = array(); $cache = array(); $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); foreach ( $cache_values as $id => $cached_object ) { if ( false === $cached_object ) { $non_cached_ids[] = $id; } else { $cache[ $id ] = $cached_object; } } if ( empty( $non_cached_ids ) ) { return $cache; } $id_list = implode( ',', $non_cached_ids ); $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A ); if ( ! empty( $meta_list ) ) { foreach ( $meta_list as $metarow ) { $mpid = (int) $metarow[ $column ]; $mkey = $metarow['meta_key']; $mval = $metarow['meta_value']; if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) { $cache[ $mpid ] = array(); } if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) { $cache[ $mpid ][ $mkey ] = array(); } $cache[ $mpid ][ $mkey ][] = $mval; } } $data = array(); foreach ( $non_cached_ids as $id ) { if ( ! isset( $cache[ $id ] ) ) { $cache[ $id ] = array(); } $data[ $id ] = $cache[ $id ]; } wp_cache_add_multiple( $data, $cache_group ); return $cache; } function wp_metadata_lazyloader() { static $wp_metadata_lazyloader; if ( null === $wp_metadata_lazyloader ) { $wp_metadata_lazyloader = new WP_Metadata_Lazyloader(); } return $wp_metadata_lazyloader; } function get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) { $meta_query_obj = new WP_Meta_Query( $meta_query ); return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context ); } function _get_meta_table( $type ) { global $wpdb; $table_name = $type . 'meta'; if ( empty( $wpdb->$table_name ) ) { return false; } return $wpdb->$table_name; } function is_protected_meta( $meta_key, $meta_type = '' ) { $sanitized_key = preg_replace( "/[^\x20-\x7E\p{L}]/", '', $meta_key ); $protected = strlen( $sanitized_key ) > 0 && ( '_' === $sanitized_key[0] ); return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); } function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) { if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $meta_value, $meta_key, $object_type, $object_subtype ); } return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type ); } function register_meta( $object_type, $meta_key, $args, $deprecated = null ) { global $wp_meta_keys; if ( ! is_array( $wp_meta_keys ) ) { $wp_meta_keys = array(); } $defaults = array( 'object_subtype' => '', 'type' => 'string', 'label' => '', 'description' => '', 'default' => '', 'single' => false, 'sanitize_callback' => null, 'auth_callback' => null, 'show_in_rest' => false, 'revisions_enabled' => false, ); $has_old_sanitize_cb = false; $has_old_auth_cb = false; if ( is_callable( $args ) ) { $args = array( 'sanitize_callback' => $args, ); $has_old_sanitize_cb = true; } else { $args = (array) $args; } if ( is_callable( $deprecated ) ) { $args['auth_callback'] = $deprecated; $has_old_auth_cb = true; } $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key ); unset( $defaults['default'] ); $args = wp_parse_args( $args, $defaults ); if ( false !== $args['show_in_rest'] && 'array' === $args['type'] ) { if ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) { _doing_it_wrong( __FUNCTION__, __( 'When registering an "array" meta type to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.3.0' ); return false; } } $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : ''; if ( $args['revisions_enabled'] ) { if ( 'post' !== $object_type ) { _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object type supports revisions.' ), '6.4.0' ); return false; } elseif ( ! empty( $object_subtype ) && ! post_type_supports( $object_subtype, 'revisions' ) ) { _doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object subtype supports revisions.' ), '6.4.0' ); return false; } } if ( empty( $args['auth_callback'] ) ) { if ( is_protected_meta( $meta_key, $object_type ) ) { $args['auth_callback'] = '__return_false'; } else { $args['auth_callback'] = '__return_true'; } } if ( is_callable( $args['sanitize_callback'] ) ) { if ( ! empty( $object_subtype ) ) { add_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'], 10, 4 ); } else { add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 ); } } if ( is_callable( $args['auth_callback'] ) ) { if ( ! empty( $object_subtype ) ) { add_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'], 10, 6 ); } else { add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 ); } } if ( array_key_exists( 'default', $args ) ) { $schema = $args; if ( is_array( $args['show_in_rest'] ) && isset( $args['show_in_rest']['schema'] ) ) { $schema = array_merge( $schema, $args['show_in_rest']['schema'] ); } $check = rest_validate_value_from_schema( $args['default'], $schema ); if ( is_wp_error( $check ) ) { _doing_it_wrong( __FUNCTION__, __( 'When registering a default meta value the data must match the type provided.' ), '5.5.0' ); return false; } if ( ! has_filter( "default_{$object_type}_metadata", 'filter_default_metadata' ) ) { add_filter( "default_{$object_type}_metadata", 'filter_default_metadata', 10, 5 ); } } if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) { unset( $args['object_subtype'] ); $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args; return true; } return false; } function filter_default_metadata( $value, $object_id, $meta_key, $single, $meta_type ) { global $wp_meta_keys; if ( wp_installing() ) { return $value; } if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $meta_type ] ) ) { return $value; } $defaults = array(); foreach ( $wp_meta_keys[ $meta_type ] as $sub_type => $meta_data ) { foreach ( $meta_data as $_meta_key => $args ) { if ( $_meta_key === $meta_key && array_key_exists( 'default', $args ) ) { $defaults[ $sub_type ] = $args; } } } if ( ! $defaults ) { return $value; } if ( isset( $defaults[''] ) ) { $metadata = $defaults['']; } else { $sub_type = get_object_subtype( $meta_type, $object_id ); if ( ! isset( $defaults[ $sub_type ] ) ) { return $value; } $metadata = $defaults[ $sub_type ]; } if ( $single ) { $value = $metadata['default']; } else { $value = array( $metadata['default'] ); } return $value; } function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) { $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); return isset( $meta_keys[ $meta_key ] ); } function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) { global $wp_meta_keys; if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { return false; } $args = $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ]; if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) { if ( ! empty( $object_subtype ) ) { remove_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'] ); } else { remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] ); } } if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) { if ( ! empty( $object_subtype ) ) { remove_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'] ); } else { remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] ); } } unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] ); if ( empty( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { unset( $wp_meta_keys[ $object_type ][ $object_subtype ] ); } if ( empty( $wp_meta_keys[ $object_type ] ) ) { unset( $wp_meta_keys[ $object_type ] ); } return true; } function get_registered_meta_keys( $object_type, $object_subtype = '' ) { global $wp_meta_keys; if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) || ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { return array(); } return $wp_meta_keys[ $object_type ][ $object_subtype ]; } function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) { $object_subtype = get_object_subtype( $object_type, $object_id ); if ( ! empty( $meta_key ) ) { if ( ! empty( $object_subtype ) && ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { $object_subtype = ''; } if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { return false; } $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); $meta_key_data = $meta_keys[ $meta_key ]; $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] ); return $data; } $data = get_metadata( $object_type, $object_id ); if ( ! $data ) { return array(); } $meta_keys = get_registered_meta_keys( $object_type ); if ( ! empty( $object_subtype ) ) { $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $object_type, $object_subtype ) ); } return array_intersect_key( $data, $meta_keys ); } function _wp_register_meta_args_allowed_list( $args, $default_args ) { return array_intersect_key( $args, $default_args ); } function get_object_subtype( $object_type, $object_id ) { $object_id = (int) $object_id; $object_subtype = ''; switch ( $object_type ) { case 'post': $post_type = get_post_type( $object_id ); if ( ! empty( $post_type ) ) { $object_subtype = $post_type; } break; case 'term': $term = get_term( $object_id ); if ( ! $term instanceof WP_Term ) { break; } $object_subtype = $term->taxonomy; break; case 'comment': $comment = get_comment( $object_id ); if ( ! $comment ) { break; } $object_subtype = 'comment'; break; case 'user': $user = get_user_by( 'id', $object_id ); if ( ! $user ) { break; } $object_subtype = 'user'; break; } return apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id ); }
###require ABSPATH . WPINC . '/functions.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } require ABSPATH . WPINC . '/option.php'; function mysql2date( $format, $date, $translate = true ) { if ( empty( $date ) ) { return false; } $timezone = wp_timezone(); $datetime = date_create( $date, $timezone ); if ( false === $datetime ) { return false; } if ( 'G' === $format || 'U' === $format ) { return $datetime->getTimestamp() + $datetime->getOffset(); } if ( $translate ) { return wp_date( $format, $datetime->getTimestamp(), $timezone ); } return $datetime->format( $format ); } function current_time( $type, $gmt = false ) { if ( 'timestamp' === $type || 'U' === $type ) { return $gmt ? time() : time() + (int) ( (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); } if ( 'mysql' === $type ) { $type = 'Y-m-d H:i:s'; } $timezone = $gmt ? new DateTimeZone( 'UTC' ) : wp_timezone(); $datetime = new DateTime( 'now', $timezone ); return $datetime->format( $type ); } function current_datetime() { return new DateTimeImmutable( 'now', wp_timezone() ); } function wp_timezone_string() { $timezone_string = get_option( 'timezone_string' ); if ( $timezone_string ) { return $timezone_string; } $offset = (float) get_option( 'gmt_offset' ); $hours = (int) $offset; $minutes = ( $offset - $hours ); $sign = ( $offset < 0 ) ? '-' : '+'; $abs_hour = abs( $hours ); $abs_mins = abs( $minutes * 60 ); $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins ); return $tz_offset; } function wp_timezone() { return new DateTimeZone( wp_timezone_string() ); } function date_i18n( $format, $timestamp_with_offset = false, $gmt = false ) { $timestamp = $timestamp_with_offset; if ( ! is_numeric( $timestamp ) ) { $timestamp = current_time( 'timestamp', $gmt ); } if ( 'U' === $format ) { $date = $timestamp; } elseif ( $gmt && false === $timestamp_with_offset ) { $date = wp_date( $format, null, new DateTimeZone( 'UTC' ) ); } elseif ( false === $timestamp_with_offset ) { $date = wp_date( $format ); } else { $local_time = gmdate( 'Y-m-d H:i:s', $timestamp ); $timezone = wp_timezone(); $datetime = date_create( $local_time, $timezone ); $date = wp_date( $format, $datetime->getTimestamp(), $timezone ); } $date = apply_filters( 'date_i18n', $date, $format, $timestamp, $gmt ); return $date; } function wp_date( $format, $timestamp = null, $timezone = null ) { global $wp_locale; if ( null === $timestamp ) { $timestamp = time(); } elseif ( ! is_numeric( $timestamp ) ) { return false; } if ( ! $timezone ) { $timezone = wp_timezone(); } $datetime = date_create( '@' . $timestamp ); $datetime->setTimezone( $timezone ); if ( empty( $wp_locale->month ) || empty( $wp_locale->weekday ) ) { $date = $datetime->format( $format ); } else { $format = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $format ); $new_format = ''; $format_length = strlen( $format ); $month = $wp_locale->get_month( $datetime->format( 'm' ) ); $weekday = $wp_locale->get_weekday( $datetime->format( 'w' ) ); for ( $i = 0; $i < $format_length; $i++ ) { switch ( $format[ $i ] ) { case 'D': $new_format .= addcslashes( $wp_locale->get_weekday_abbrev( $weekday ), '\\A..Za..z' ); break; case 'F': $new_format .= addcslashes( $month, '\\A..Za..z' ); break; case 'l': $new_format .= addcslashes( $weekday, '\\A..Za..z' ); break; case 'M': $new_format .= addcslashes( $wp_locale->get_month_abbrev( $month ), '\\A..Za..z' ); break; case 'a': $new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'a' ) ), '\\A..Za..z' ); break; case 'A': $new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'A' ) ), '\\A..Za..z' ); break; case '\\': $new_format .= $format[ $i ]; if ( $i < $format_length ) { $new_format .= $format[ ++$i ]; } break; default: $new_format .= $format[ $i ]; break; } } $date = $datetime->format( $new_format ); $date = wp_maybe_decline_date( $date, $format ); } $date = apply_filters( 'wp_date', $date, $format, $timestamp, $timezone ); return $date; } function wp_maybe_decline_date( $date, $format = '' ) { global $wp_locale; if ( ! function_exists( '_x' ) ) { return $date; } if ( 'on' === _x( 'off', 'decline months names: on or off' ) ) { $months = $wp_locale->month; $months_genitive = $wp_locale->month_genitive; if ( $format ) { $decline = preg_match( '#[dj]\.? F#', $format ); } else { $decline = preg_match( '#\b\d{1,2}\.? [^\d ]+\b#u', $date ); } if ( $decline ) { foreach ( $months as $key => $month ) { $months[ $key ] = '# ' . preg_quote( $month, '#' ) . '\b#u'; } foreach ( $months_genitive as $key => $month ) { $months_genitive[ $key ] = ' ' . $month; } $date = preg_replace( $months, $months_genitive, $date ); } if ( $format ) { $decline = preg_match( '#F [dj]#', $format ); } else { $decline = preg_match( '#\b[^\d ]+ \d{1,2}(st|nd|rd|th)?\b#u', trim( $date ) ); } if ( $decline ) { foreach ( $months as $key => $month ) { $months[ $key ] = '#\b' . preg_quote( $month, '#' ) . ' (\d{1,2})(st|nd|rd|th)?([-–]\d{1,2})?(st|nd|rd|th)?\b#u'; } foreach ( $months_genitive as $key => $month ) { $months_genitive[ $key ] = '$1$3 ' . $month; } $date = preg_replace( $months, $months_genitive, $date ); } } $locale = get_locale(); if ( 'ca' === $locale ) { $date = preg_replace( '# de ([ao])#i', " d'\\1", $date ); } return $date; } function number_format_i18n( $number, $decimals = 0 ) { global $wp_locale; if ( isset( $wp_locale ) ) { $formatted = number_format( $number, absint( $decimals ), $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] ); } else { $formatted = number_format( $number, absint( $decimals ) ); } return apply_filters( 'number_format_i18n', $formatted, $number, $decimals ); } function size_format( $bytes, $decimals = 0 ) { $quant = array( _x( 'YB', 'unit symbol' ) => YB_IN_BYTES, _x( 'ZB', 'unit symbol' ) => ZB_IN_BYTES, _x( 'EB', 'unit symbol' ) => EB_IN_BYTES, _x( 'PB', 'unit symbol' ) => PB_IN_BYTES, _x( 'TB', 'unit symbol' ) => TB_IN_BYTES, _x( 'GB', 'unit symbol' ) => GB_IN_BYTES, _x( 'MB', 'unit symbol' ) => MB_IN_BYTES, _x( 'KB', 'unit symbol' ) => KB_IN_BYTES, _x( 'B', 'unit symbol' ) => 1, ); if ( 0 === $bytes ) { return number_format_i18n( 0, $decimals ) . ' ' . _x( 'B', 'unit symbol' ); } foreach ( $quant as $unit => $mag ) { if ( (float) $bytes >= $mag ) { return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit; } } return false; } function human_readable_duration( $duration = '' ) { if ( ( empty( $duration ) || ! is_string( $duration ) ) ) { return false; } $duration = trim( $duration ); if ( str_starts_with( $duration, '-' ) ) { $duration = substr( $duration, 1 ); } $duration_parts = array_reverse( explode( ':', $duration ) ); $duration_count = count( $duration_parts ); $hour = null; $minute = null; $second = null; if ( 3 === $duration_count ) { if ( ! ( (bool) preg_match( '/^([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) { return false; } list( $second, $minute, $hour ) = $duration_parts; } elseif ( 2 === $duration_count ) { if ( ! ( (bool) preg_match( '/^([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) { return false; } list( $second, $minute ) = $duration_parts; } else { return false; } $human_readable_duration = array(); if ( is_numeric( $hour ) ) { $human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour ); } if ( is_numeric( $minute ) ) { $human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute ); } if ( is_numeric( $second ) ) { $human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second ); } return implode( ', ', $human_readable_duration ); } function get_weekstartend( $mysqlstring, $start_of_week = '' ) { $my = substr( $mysqlstring, 0, 4 ); $mm = substr( $mysqlstring, 8, 2 ); $md = substr( $mysqlstring, 5, 2 ); $day = mktime( 0, 0, 0, $md, $mm, $my ); $weekday = (int) gmdate( 'w', $day ); if ( ! is_numeric( $start_of_week ) ) { $start_of_week = (int) get_option( 'start_of_week' ); } if ( $weekday < $start_of_week ) { $weekday += 7; } $start = $day - DAY_IN_SECONDS * ( $weekday - $start_of_week ); $end = $start + WEEK_IN_SECONDS - 1; return compact( 'start', 'end' ); } function maybe_serialize( $data ) { if ( is_array( $data ) || is_object( $data ) ) { return serialize( $data ); } if ( is_serialized( $data, false ) ) { return serialize( $data ); } return $data; } function maybe_unserialize( $data ) { if ( is_serialized( $data ) ) { return @unserialize( trim( $data ) ); } return $data; } function is_serialized( $data, $strict = true ) { if ( ! is_string( $data ) ) { return false; } $data = trim( $data ); if ( 'N;' === $data ) { return true; } if ( strlen( $data ) < 4 ) { return false; } if ( ':' !== $data[1] ) { return false; } if ( $strict ) { $lastc = substr( $data, -1 ); if ( ';' !== $lastc && '}' !== $lastc ) { return false; } } else { $semicolon = strpos( $data, ';' ); $brace = strpos( $data, '}' ); if ( false === $semicolon && false === $brace ) { return false; } if ( false !== $semicolon && $semicolon < 3 ) { return false; } if ( false !== $brace && $brace < 4 ) { return false; } } $token = $data[0]; switch ( $token ) { case 's': if ( $strict ) { if ( '"' !== substr( $data, -2, 1 ) ) { return false; } } elseif ( ! str_contains( $data, '"' ) ) { return false; } case 'a': case 'O': case 'E': return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data ); case 'b': case 'i': case 'd': $end = $strict ? '$' : ''; return (bool) preg_match( "/^{$token}:[0-9.E+-]+;$end/", $data ); } return false; } function is_serialized_string( $data ) { if ( ! is_string( $data ) ) { return false; } $data = trim( $data ); if ( strlen( $data ) < 4 ) { return false; } elseif ( ':' !== $data[1] ) { return false; } elseif ( ! str_ends_with( $data, ';' ) ) { return false; } elseif ( 's' !== $data[0] ) { return false; } elseif ( '"' !== substr( $data, -2, 1 ) ) { return false; } else { return true; } } function xmlrpc_getposttitle( $content ) { global $post_default_title; if ( preg_match( '/<title>(.+?)<\/title>/is', $content, $matchtitle ) ) { $post_title = $matchtitle[1]; } else { $post_title = $post_default_title; } return $post_title; } function xmlrpc_getpostcategory( $content ) { global $post_default_category; if ( preg_match( '/<category>(.+?)<\/category>/is', $content, $matchcat ) ) { $post_category = trim( $matchcat[1], ',' ); $post_category = explode( ',', $post_category ); } else { $post_category = $post_default_category; } return $post_category; } function xmlrpc_removepostdata( $content ) { $content = preg_replace( '/<title>(.+?)<\/title>/si', '', $content ); $content = preg_replace( '/<category>(.+?)<\/category>/si', '', $content ); $content = trim( $content ); return $content; } function wp_extract_urls( $content ) { preg_match_all( "#([\"']?)(" . '(?:([\w-]+:)?//?)' . '[^\s()<>]+' . '[.]' . '(?:' . '\([\w\d]+\)|' . '(?:' . "[^`!()\[\]{}:'\".,<>«»“”‘’\s]|" . '(?:[:]\d+)?/?' . ')+' . ')' . ")\\1#", $content, $post_links ); $post_links = array_unique( array_map( static function ( $link ) { $link = html_entity_decode( $link ); return str_replace( ';', '', $link ); }, $post_links[2] ) ); return array_values( $post_links ); } function do_enclose( $content, $post ) { global $wpdb; require_once ABSPATH . WPINC . '/class-IXR.php'; $post = get_post( $post ); if ( ! $post ) { return false; } if ( null === $content ) { $content = $post->post_content; } $post_links = array(); $pung = get_enclosed( $post->ID ); $post_links_temp = wp_extract_urls( $content ); foreach ( $pung as $link_test ) { if ( ! in_array( $link_test, $post_links_temp, true ) ) { $mids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $link_test ) . '%' ) ); foreach ( $mids as $mid ) { delete_metadata_by_mid( 'post', $mid ); } } } foreach ( (array) $post_links_temp as $link_test ) { if ( ! in_array( $link_test, $pung, true ) ) { $test = parse_url( $link_test ); if ( false === $test ) { continue; } if ( isset( $test['query'] ) ) { $post_links[] = $link_test; } elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) { $post_links[] = $link_test; } } } $post_links = apply_filters( 'enclosure_links', $post_links, $post->ID ); foreach ( (array) $post_links as $url ) { $url = strip_fragment_from_url( $url ); if ( '' !== $url && ! $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $url ) . '%' ) ) ) { $headers = wp_get_http_headers( $url ); if ( $headers ) { $len = isset( $headers['Content-Length'] ) ? (int) $headers['Content-Length'] : 0; $type = isset( $headers['Content-Type'] ) ? $headers['Content-Type'] : ''; $allowed_types = array( 'video', 'audio' ); $url_parts = parse_url( $url ); if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) { $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION ); if ( ! empty( $extension ) ) { foreach ( wp_get_mime_types() as $exts => $mime ) { if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) { $type = $mime; break; } } } } if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types, true ) ) { add_post_meta( $post->ID, 'enclosure', "$url\n$len\n$mime\n" ); } } } } } function wp_get_http_headers( $url, $deprecated = false ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.7.0' ); } $response = wp_safe_remote_head( $url ); if ( is_wp_error( $response ) ) { return false; } return wp_remote_retrieve_headers( $response ); } function is_new_day() { global $currentday, $previousday; if ( $currentday !== $previousday ) { return 1; } else { return 0; } } function build_query( $data ) { return _http_build_query( $data, null, '&', '', false ); } function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) { $ret = array(); foreach ( (array) $data as $k => $v ) { if ( $urlencode ) { $k = urlencode( $k ); } if ( is_int( $k ) && null !== $prefix ) { $k = $prefix . $k; } if ( ! empty( $key ) ) { $k = $key . '%5B' . $k . '%5D'; } if ( null === $v ) { continue; } elseif ( false === $v ) { $v = '0'; } if ( is_array( $v ) || is_object( $v ) ) { array_push( $ret, _http_build_query( $v, '', $sep, $k, $urlencode ) ); } elseif ( $urlencode ) { array_push( $ret, $k . '=' . urlencode( $v ) ); } else { array_push( $ret, $k . '=' . $v ); } } if ( null === $sep ) { $sep = ini_get( 'arg_separator.output' ); } return implode( $sep, $ret ); } function add_query_arg( ...$args ) { if ( is_array( $args[0] ) ) { if ( count( $args ) < 2 || false === $args[1] ) { $uri = $_SERVER['REQUEST_URI']; } else { $uri = $args[1]; } } else { if ( count( $args ) < 3 || false === $args[2] ) { $uri = $_SERVER['REQUEST_URI']; } else { $uri = $args[2]; } } $frag = strstr( $uri, '#' ); if ( $frag ) { $uri = substr( $uri, 0, -strlen( $frag ) ); } else { $frag = ''; } if ( 0 === stripos( $uri, 'http://' ) ) { $protocol = 'http://'; $uri = substr( $uri, 7 ); } elseif ( 0 === stripos( $uri, 'https://' ) ) { $protocol = 'https://'; $uri = substr( $uri, 8 ); } else { $protocol = ''; } if ( str_contains( $uri, '?' ) ) { list( $base, $query ) = explode( '?', $uri, 2 ); $base .= '?'; } elseif ( $protocol || ! str_contains( $uri, '=' ) ) { $base = $uri . '?'; $query = ''; } else { $base = ''; $query = $uri; } wp_parse_str( $query, $qs ); $qs = urlencode_deep( $qs ); if ( is_array( $args[0] ) ) { foreach ( $args[0] as $k => $v ) { $qs[ $k ] = $v; } } else { $qs[ $args[0] ] = $args[1]; } foreach ( $qs as $k => $v ) { if ( false === $v ) { unset( $qs[ $k ] ); } } $ret = build_query( $qs ); $ret = trim( $ret, '?' ); $ret = preg_replace( '#=(&|$)#', '$1', $ret ); $ret = $protocol . $base . $ret . $frag; $ret = rtrim( $ret, '?' ); $ret = str_replace( '?#', '#', $ret ); return $ret; } function remove_query_arg( $key, $query = false ) { if ( is_array( $key ) ) { foreach ( $key as $k ) { $query = add_query_arg( $k, false, $query ); } return $query; } return add_query_arg( $key, false, $query ); } function wp_removable_query_args() { $removable_query_args = array( 'activate', 'activated', 'admin_email_remind_later', 'approved', 'core-major-auto-updates-saved', 'deactivate', 'delete_count', 'deleted', 'disabled', 'doing_wp_cron', 'enabled', 'error', 'hotkeys_highlight_first', 'hotkeys_highlight_last', 'ids', 'locked', 'message', 'same', 'saved', 'settings-updated', 'skipped', 'spammed', 'trashed', 'unspammed', 'untrashed', 'update', 'updated', 'wp-post-new-reload', ); return apply_filters( 'removable_query_args', $removable_query_args ); } function add_magic_quotes( $input_array ) { foreach ( (array) $input_array as $k => $v ) { if ( is_array( $v ) ) { $input_array[ $k ] = add_magic_quotes( $v ); } elseif ( is_string( $v ) ) { $input_array[ $k ] = addslashes( $v ); } } return $input_array; } function wp_remote_fopen( $uri ) { $parsed_url = parse_url( $uri ); if ( ! $parsed_url || ! is_array( $parsed_url ) ) { return false; } $options = array(); $options['timeout'] = 10; $response = wp_safe_remote_get( $uri, $options ); if ( is_wp_error( $response ) ) { return false; } return wp_remote_retrieve_body( $response ); } function wp( $query_vars = '' ) { global $wp, $wp_query, $wp_the_query; $wp->main( $query_vars ); if ( ! isset( $wp_the_query ) ) { $wp_the_query = $wp_query; } } function get_status_header_desc( $code ) { global $wp_header_to_desc; $code = absint( $code ); if ( ! isset( $wp_header_to_desc ) ) { $wp_header_to_desc = array( 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 103 => 'Early Hints', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', 226 => 'IM Used', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Reserved', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 421 => 'Misdirected Request', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Too Early', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 451 => 'Unavailable For Legal Reasons', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 510 => 'Not Extended', 511 => 'Network Authentication Required', ); } if ( isset( $wp_header_to_desc[ $code ] ) ) { return $wp_header_to_desc[ $code ]; } else { return ''; } } function status_header( $code, $description = '' ) { if ( ! $description ) { $description = get_status_header_desc( $code ); } if ( empty( $description ) ) { return; } $protocol = wp_get_server_protocol(); $status_header = "$protocol $code $description"; if ( function_exists( 'apply_filters' ) ) { $status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol ); } if ( ! headers_sent() ) { header( $status_header, true, $code ); } } function wp_get_nocache_headers() { $cache_control = 'no-cache, must-revalidate, max-age=0, no-store, private'; $headers = array( 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT', 'Cache-Control' => $cache_control, ); if ( function_exists( 'apply_filters' ) ) { $headers = (array) apply_filters( 'nocache_headers', $headers ); } $headers['Last-Modified'] = false; return $headers; } function nocache_headers() { if ( headers_sent() ) { return; } $headers = wp_get_nocache_headers(); unset( $headers['Last-Modified'] ); header_remove( 'Last-Modified' ); foreach ( $headers as $name => $field_value ) { header( "{$name}: {$field_value}" ); } } function cache_javascript_headers() { $expires_offset = 10 * DAY_IN_SECONDS; header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) ); header( 'Vary: Accept-Encoding' ); header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expires_offset ) . ' GMT' ); } function get_num_queries() { global $wpdb; return $wpdb->num_queries; } function bool_from_yn( $yn ) { return ( 'y' === strtolower( $yn ) ); } function do_feed() { global $wp_query; $feed = get_query_var( 'feed' ); $feed = preg_replace( '/^_+/', '', $feed ); if ( '' === $feed || 'feed' === $feed ) { $feed = get_default_feed(); } if ( ! has_action( "do_feed_{$feed}" ) ) { wp_die( __( '<strong>Error:</strong> This is not a valid feed template.' ), '', array( 'response' => 404 ) ); } do_action( "do_feed_{$feed}", $wp_query->is_comment_feed, $feed ); } function do_feed_rdf() { load_template( ABSPATH . WPINC . '/feed-rdf.php' ); } function do_feed_rss() { load_template( ABSPATH . WPINC . '/feed-rss.php' ); } function do_feed_rss2( $for_comments ) { if ( $for_comments ) { load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' ); } else { load_template( ABSPATH . WPINC . '/feed-rss2.php' ); } } function do_feed_atom( $for_comments ) { if ( $for_comments ) { load_template( ABSPATH . WPINC . '/feed-atom-comments.php' ); } else { load_template( ABSPATH . WPINC . '/feed-atom.php' ); } } function do_robots() { header( 'Content-Type: text/plain; charset=utf-8' ); do_action( 'do_robotstxt' ); $output = "User-agent: *\n"; $public = (bool) get_option( 'blog_public' ); $site_url = parse_url( site_url() ); $path = ( ! empty( $site_url['path'] ) ) ? $site_url['path'] : ''; $output .= "Disallow: $path/wp-admin/\n"; $output .= "Allow: $path/wp-admin/admin-ajax.php\n"; echo apply_filters( 'robots_txt', $output, $public ); } function do_favicon() { do_action( 'do_faviconico' ); wp_redirect( get_site_icon_url( 32, includes_url( 'images/w-logo-blue-white-bg.png' ) ) ); exit; } function is_blog_installed() { global $wpdb; if ( wp_cache_get( 'is_blog_installed' ) ) { return true; } $suppress = $wpdb->suppress_errors(); if ( ! wp_installing() ) { $alloptions = wp_load_alloptions(); } if ( ! isset( $alloptions['siteurl'] ) ) { $installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" ); } else { $installed = $alloptions['siteurl']; } $wpdb->suppress_errors( $suppress ); $installed = ! empty( $installed ); wp_cache_set( 'is_blog_installed', $installed ); if ( $installed ) { return true; } if ( defined( 'WP_REPAIRING' ) ) { return true; } $suppress = $wpdb->suppress_errors(); $wp_tables = $wpdb->tables(); foreach ( $wp_tables as $table ) { if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE === $table ) { continue; } if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE === $table ) { continue; } $described_table = $wpdb->get_results( "DESCRIBE $table;" ); if ( ( ! $described_table && empty( $wpdb->last_error ) ) || ( is_array( $described_table ) && 0 === count( $described_table ) ) ) { continue; } wp_load_translations_early(); $wpdb->error = sprintf( __( 'One or more database tables are unavailable. The database may need to be <a href="%s">repaired</a>.' ), 'maint/repair.php?referrer=is_blog_installed' ); dead_db(); } $wpdb->suppress_errors( $suppress ); wp_cache_set( 'is_blog_installed', false ); return false; } function wp_nonce_url( $actionurl, $action = -1, $name = '_wpnonce' ) { $actionurl = str_replace( '&', '&', $actionurl ); return esc_html( add_query_arg( $name, wp_create_nonce( $action ), $actionurl ) ); } function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $display = true ) { $name = esc_attr( $name ); $nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />'; if ( $referer ) { $nonce_field .= wp_referer_field( false ); } if ( $display ) { echo $nonce_field; } return $nonce_field; } function wp_referer_field( $display = true ) { $request_url = remove_query_arg( '_wp_http_referer' ); $referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_url( $request_url ) . '" />'; if ( $display ) { echo $referer_field; } return $referer_field; } function wp_original_referer_field( $display = true, $jump_back_to = 'current' ) { $ref = wp_get_original_referer(); if ( ! $ref ) { $ref = ( 'previous' === $jump_back_to ) ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] ); } $orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />'; if ( $display ) { echo $orig_referer_field; } return $orig_referer_field; } function wp_get_referer() { if ( ! function_exists( 'wp_validate_redirect' ) ) { return false; } $ref = wp_get_raw_referer(); if ( $ref && wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref && home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref ) { return wp_validate_redirect( $ref, false ); } return false; } function wp_get_raw_referer() { if ( ! empty( $_REQUEST['_wp_http_referer'] ) && is_string( $_REQUEST['_wp_http_referer'] ) ) { return wp_unslash( $_REQUEST['_wp_http_referer'] ); } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { return wp_unslash( $_SERVER['HTTP_REFERER'] ); } return false; } function wp_get_original_referer() { if ( ! function_exists( 'wp_validate_redirect' ) ) { return false; } if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) ) { return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false ); } return false; } function wp_mkdir_p( $target ) { $wrapper = null; if ( wp_is_stream( $target ) ) { list( $wrapper, $target ) = explode( '://', $target, 2 ); } $target = str_replace( '//', '/', $target ); if ( null !== $wrapper ) { $target = $wrapper . '://' . $target; } $target = rtrim( $target, '/' ); if ( empty( $target ) ) { $target = '/'; } if ( file_exists( $target ) ) { return @is_dir( $target ); } if ( str_contains( $target, '../' ) || str_contains( $target, '..' . DIRECTORY_SEPARATOR ) ) { return false; } $target_parent = dirname( $target ); while ( '.' !== $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) { $target_parent = dirname( $target_parent ); } $stat = @stat( $target_parent ); if ( $stat ) { $dir_perms = $stat['mode'] & 0007777; } else { $dir_perms = 0777; } if ( @mkdir( $target, $dir_perms, true ) ) { if ( ( $dir_perms & ~umask() ) !== $dir_perms ) { $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) ); for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) { chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms ); } } return true; } return false; } function path_is_absolute( $path ) { if ( wp_is_stream( $path ) && ( is_dir( $path ) || is_file( $path ) ) ) { return true; } if ( realpath( $path ) === $path ) { return true; } if ( strlen( $path ) === 0 || '.' === $path[0] ) { return false; } if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) { return true; } return ( '/' === $path[0] || '\\' === $path[0] ); } function path_join( $base, $path ) { if ( path_is_absolute( $path ) ) { return $path; } return rtrim( $base, '/' ) . '/' . $path; } function wp_normalize_path( $path ) { $wrapper = ''; if ( wp_is_stream( $path ) ) { list( $wrapper, $path ) = explode( '://', $path, 2 ); $wrapper .= '://'; } $path = str_replace( '\\', '/', $path ); $path = preg_replace( '|(?<=.)/+|', '/', $path ); if ( ':' === substr( $path, 1, 1 ) ) { $path = ucfirst( $path ); } return $wrapper . $path; } function get_temp_dir() { static $temp = ''; if ( defined( 'WP_TEMP_DIR' ) ) { return trailingslashit( WP_TEMP_DIR ); } if ( $temp ) { return trailingslashit( $temp ); } if ( function_exists( 'sys_get_temp_dir' ) ) { $temp = sys_get_temp_dir(); if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) { return trailingslashit( $temp ); } } $temp = ini_get( 'upload_tmp_dir' ); if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) { return trailingslashit( $temp ); } $temp = WP_CONTENT_DIR . '/'; if ( is_dir( $temp ) && wp_is_writable( $temp ) ) { return $temp; } return '/tmp/'; } function wp_is_writable( $path ) { if ( 'Windows' === PHP_OS_FAMILY ) { return win_is_writable( $path ); } return @is_writable( $path ); } function win_is_writable( $path ) { if ( '/' === $path[ strlen( $path ) - 1 ] ) { return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp' ); } elseif ( is_dir( $path ) ) { return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' ); } $should_delete_tmp_file = ! file_exists( $path ); $f = @fopen( $path, 'a' ); if ( false === $f ) { return false; } fclose( $f ); if ( $should_delete_tmp_file ) { unlink( $path ); } return true; } function wp_get_upload_dir() { return wp_upload_dir( null, false ); } function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) { static $cache = array(), $tested_paths = array(); $key = sprintf( '%d-%s', get_current_blog_id(), (string) $time ); if ( $refresh_cache || empty( $cache[ $key ] ) ) { $cache[ $key ] = _wp_upload_dir( $time ); } $uploads = apply_filters( 'upload_dir', $cache[ $key ] ); if ( $create_dir ) { $path = $uploads['path']; if ( array_key_exists( $path, $tested_paths ) ) { $uploads['error'] = $tested_paths[ $path ]; } else { if ( ! wp_mkdir_p( $path ) ) { if ( str_starts_with( $uploads['basedir'], ABSPATH ) ) { $error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir']; } else { $error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir']; } $uploads['error'] = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), esc_html( $error_path ) ); } $tested_paths[ $path ] = $uploads['error']; } } return $uploads; } function _wp_upload_dir( $time = null ) { $siteurl = get_option( 'siteurl' ); $upload_path = trim( get_option( 'upload_path' ) ); if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) { $dir = WP_CONTENT_DIR . '/uploads'; } elseif ( ! str_starts_with( $upload_path, ABSPATH ) ) { $dir = path_join( ABSPATH, $upload_path ); } else { $dir = $upload_path; } $url = get_option( 'upload_url_path' ); if ( ! $url ) { if ( empty( $upload_path ) || ( 'wp-content/uploads' === $upload_path ) || ( $upload_path === $dir ) ) { $url = WP_CONTENT_URL . '/uploads'; } else { $url = trailingslashit( $siteurl ) . $upload_path; } } if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) { $dir = ABSPATH . UPLOADS; $url = trailingslashit( $siteurl ) . UPLOADS; } if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) { if ( ! get_site_option( 'ms_files_rewriting' ) ) { if ( defined( 'MULTISITE' ) ) { $ms_dir = '/sites/' . get_current_blog_id(); } else { $ms_dir = '/' . get_current_blog_id(); } $dir .= $ms_dir; $url .= $ms_dir; } elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) { if ( defined( 'BLOGUPLOADDIR' ) ) { $dir = untrailingslashit( BLOGUPLOADDIR ); } else { $dir = ABSPATH . UPLOADS; } $url = trailingslashit( $siteurl ) . 'files'; } } $basedir = $dir; $baseurl = $url; $subdir = ''; if ( get_option( 'uploads_use_yearmonth_folders' ) ) { if ( ! $time ) { $time = current_time( 'mysql' ); } $y = substr( $time, 0, 4 ); $m = substr( $time, 5, 2 ); $subdir = "/$y/$m"; } $dir .= $subdir; $url .= $subdir; return array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $basedir, 'baseurl' => $baseurl, 'error' => false, ); } function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) { $filename = sanitize_file_name( $filename ); $ext2 = null; $number = ''; $alt_filenames = array(); $ext = pathinfo( $filename, PATHINFO_EXTENSION ); $name = pathinfo( $filename, PATHINFO_BASENAME ); if ( $ext ) { $ext = '.' . $ext; } if ( $name === $ext ) { $name = ''; } if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) { $filename = call_user_func( $unique_filename_callback, $dir, $name, $ext ); } else { $fname = pathinfo( $filename, PATHINFO_FILENAME ); if ( $fname && preg_match( '/-(?:\d+x\d+|scaled|rotated)$/', $fname ) ) { $number = 1; $filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename ); } $file_type = wp_check_filetype( $filename ); $mime_type = $file_type['type']; $is_image = ( ! empty( $mime_type ) && str_starts_with( $mime_type, 'image/' ) ); $upload_dir = wp_get_upload_dir(); $lc_filename = null; $lc_ext = strtolower( $ext ); $_dir = trailingslashit( $dir ); if ( $ext && $lc_ext !== $ext ) { $lc_filename = preg_replace( '|' . preg_quote( $ext ) . '$|', $lc_ext, $filename ); } while ( file_exists( $_dir . $filename ) || ( $lc_filename && file_exists( $_dir . $lc_filename ) ) ) { $new_number = (int) $number + 1; if ( $lc_filename ) { $lc_filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $lc_filename ); } if ( '' === "{$number}{$ext}" ) { $filename = "{$filename}-{$new_number}"; } else { $filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename ); } $number = $new_number; } if ( $lc_filename ) { $filename = $lc_filename; } $files = array(); $count = 10000; if ( $name && $ext && @is_dir( $dir ) && str_contains( $dir, $upload_dir['basedir'] ) ) { $files = apply_filters( 'pre_wp_unique_filename_file_list', null, $dir, $filename ); if ( null === $files ) { $files = @scandir( $dir ); } if ( ! empty( $files ) ) { $files = array_diff( $files, array( '.', '..' ) ); } if ( ! empty( $files ) ) { $count = count( $files ); $i = 0; while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) { $new_number = (int) $number + 1; $filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $filename ); $number = $new_number; ++$i; } } } if ( $is_image ) { $output_formats = wp_get_image_editor_output_format( $_dir . $filename, $mime_type ); $alt_types = array(); if ( ! empty( $output_formats[ $mime_type ] ) ) { $alt_mime_type = $output_formats[ $mime_type ]; $alt_types = array_keys( array_intersect( $output_formats, array( $mime_type, $alt_mime_type ) ) ); $alt_types[] = $alt_mime_type; } elseif ( ! empty( $output_formats ) ) { $alt_types = array_keys( array_intersect( $output_formats, array( $mime_type ) ) ); } $alt_types = array_unique( array_diff( $alt_types, array( $mime_type ) ) ); foreach ( $alt_types as $alt_type ) { $alt_ext = wp_get_default_extension_for_mime_type( $alt_type ); if ( ! $alt_ext ) { continue; } $alt_ext = ".{$alt_ext}"; $alt_filename = preg_replace( '|' . preg_quote( $lc_ext ) . '$|', $alt_ext, $filename ); $alt_filenames[ $alt_ext ] = $alt_filename; } if ( ! empty( $alt_filenames ) ) { $alt_filenames[ $lc_ext ] = $filename; $i = 0; while ( $i <= $count && _wp_check_alternate_file_names( $alt_filenames, $_dir, $files ) ) { $new_number = (int) $number + 1; foreach ( $alt_filenames as $alt_ext => $alt_filename ) { $alt_filenames[ $alt_ext ] = str_replace( array( "-{$number}{$alt_ext}", "{$number}{$alt_ext}" ), "-{$new_number}{$alt_ext}", $alt_filename ); } $filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $filename ); $number = $new_number; ++$i; } } } } return apply_filters( 'wp_unique_filename', $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number ); } function _wp_check_alternate_file_names( $filenames, $dir, $files ) { foreach ( $filenames as $filename ) { if ( file_exists( $dir . $filename ) ) { return true; } if ( ! empty( $files ) && _wp_check_existing_file_names( $filename, $files ) ) { return true; } } return false; } function _wp_check_existing_file_names( $filename, $files ) { $fname = pathinfo( $filename, PATHINFO_FILENAME ); $ext = pathinfo( $filename, PATHINFO_EXTENSION ); if ( empty( $fname ) ) { return false; } if ( $ext ) { $ext = ".$ext"; } $regex = '/^' . preg_quote( $fname ) . '-(?:\d+x\d+|scaled|rotated)' . preg_quote( $ext ) . '$/i'; foreach ( $files as $file ) { if ( preg_match( $regex, $file ) ) { return true; } } return false; } function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.0.0' ); } if ( empty( $name ) ) { return array( 'error' => __( 'Empty filename' ) ); } $wp_filetype = wp_check_filetype( $name ); if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) ) { return array( 'error' => __( 'Sorry, you are not allowed to upload this file type.' ) ); } $upload = wp_upload_dir( $time ); if ( false !== $upload['error'] ) { return $upload; } $upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time, ) ); if ( ! is_array( $upload_bits_error ) ) { $upload['error'] = $upload_bits_error; return $upload; } $filename = wp_unique_filename( $upload['path'], $name ); $new_file = $upload['path'] . "/$filename"; if ( ! wp_mkdir_p( dirname( $new_file ) ) ) { if ( str_starts_with( $upload['basedir'], ABSPATH ) ) { $error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir']; } else { $error_path = wp_basename( $upload['basedir'] ) . $upload['subdir']; } $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $error_path ); return array( 'error' => $message ); } $ifp = @fopen( $new_file, 'wb' ); if ( ! $ifp ) { return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ), ); } fwrite( $ifp, $bits ); fclose( $ifp ); clearstatcache(); $stat = @ stat( dirname( $new_file ) ); $perms = $stat['mode'] & 0007777; $perms = $perms & 0000666; chmod( $new_file, $perms ); clearstatcache(); $url = $upload['url'] . "/$filename"; if ( is_multisite() ) { clean_dirsize_cache( $new_file ); } return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $wp_filetype['type'], 'error' => false, ), 'sideload' ); } function wp_ext2type( $ext ) { $ext = strtolower( $ext ); $ext2type = wp_get_ext_types(); foreach ( $ext2type as $type => $exts ) { if ( in_array( $ext, $exts, true ) ) { return $type; } } } function wp_get_default_extension_for_mime_type( $mime_type ) { $extensions = explode( '|', array_search( $mime_type, wp_get_mime_types(), true ) ); if ( empty( $extensions[0] ) ) { return false; } return $extensions[0]; } function wp_check_filetype( $filename, $mimes = null ) { if ( empty( $mimes ) ) { $mimes = get_allowed_mime_types(); } $type = false; $ext = false; foreach ( $mimes as $ext_preg => $mime_match ) { $ext_preg = '!\.(' . $ext_preg . ')$!i'; if ( preg_match( $ext_preg, $filename, $ext_matches ) ) { $type = $mime_match; $ext = $ext_matches[1]; break; } } return compact( 'ext', 'type' ); } function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { $proper_filename = false; $wp_filetype = wp_check_filetype( $filename, $mimes ); $ext = $wp_filetype['ext']; $type = $wp_filetype['type']; if ( ! file_exists( $file ) ) { return compact( 'ext', 'type', 'proper_filename' ); } $real_mime = false; if ( $type && str_starts_with( $type, 'image/' ) ) { $real_mime = wp_get_image_mime( $file ); $heic_images_extensions = array( 'heif', 'heics', 'heifs', ); if ( $real_mime && ( $real_mime !== $type || in_array( $ext, $heic_images_extensions, true ) ) ) { $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array( 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/bmp' => 'bmp', 'image/tiff' => 'tif', 'image/webp' => 'webp', 'image/avif' => 'avif', 'image/heic' => 'heic', 'image/heif' => 'heic', 'image/heic-sequence' => 'heic', 'image/heif-sequence' => 'heic', ) ); if ( ! empty( $mime_to_ext[ $real_mime ] ) ) { $filename_parts = explode( '.', $filename ); array_pop( $filename_parts ); $filename_parts[] = $mime_to_ext[ $real_mime ]; $new_filename = implode( '.', $filename_parts ); if ( $new_filename !== $filename ) { $proper_filename = $new_filename; } $wp_filetype = wp_check_filetype( $new_filename, $mimes ); $ext = $wp_filetype['ext']; $type = $wp_filetype['type']; } else { $real_mime = false; } } } if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) { $finfo = finfo_open( FILEINFO_MIME_TYPE ); $real_mime = finfo_file( $finfo, $file ); if ( PHP_VERSION_ID < 80100 ) { finfo_close( $finfo ); } $google_docs_types = array( 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ); foreach ( $google_docs_types as $google_docs_type ) { if ( 2 === substr_count( $real_mime, $google_docs_type ) ) { $real_mime = $google_docs_type; } } $nonspecific_types = array( 'application/octet-stream', 'application/encrypted', 'application/CDFV2-encrypted', 'application/zip', ); if ( in_array( $real_mime, $nonspecific_types, true ) ) { if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ), true ) ) { $type = false; $ext = false; } } elseif ( str_starts_with( $real_mime, 'video/' ) || str_starts_with( $real_mime, 'audio/' ) ) { if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) { $type = false; $ext = false; } } elseif ( 'text/plain' === $real_mime ) { if ( ! in_array( $type, array( 'text/plain', 'text/csv', 'application/csv', 'text/richtext', 'text/tsv', 'text/vtt', ), true ) ) { $type = false; $ext = false; } } elseif ( 'application/csv' === $real_mime ) { if ( ! in_array( $type, array( 'text/csv', 'text/plain', 'application/csv', ), true ) ) { $type = false; $ext = false; } } elseif ( 'text/rtf' === $real_mime ) { if ( ! in_array( $type, array( 'text/rtf', 'text/plain', 'application/rtf', ), true ) ) { $type = false; $ext = false; } } else { if ( $type !== $real_mime ) { $type = false; $ext = false; } } } if ( $type ) { $allowed = get_allowed_mime_types(); if ( ! in_array( $type, $allowed, true ) ) { $type = false; $ext = false; } } return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime ); } function wp_get_image_mime( $file ) { try { if ( is_callable( 'exif_imagetype' ) ) { $imagetype = exif_imagetype( $file ); $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false; } elseif ( function_exists( 'getimagesize' ) ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) { $imagesize = getimagesize( $file ); } else { $imagesize = @getimagesize( $file ); } $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false; } else { $mime = false; } if ( false !== $mime ) { return $mime; } $magic = file_get_contents( $file, false, null, 0, 12 ); if ( false === $magic ) { return false; } $magic = bin2hex( $magic ); if ( ( str_starts_with( $magic, '52494646' ) ) && ( 16 === strpos( $magic, '57454250' ) ) ) { $mime = 'image/webp'; } $magic = str_split( $magic, 8 ); if ( isset( $magic[1] ) && isset( $magic[2] ) && 'ftyp' === hex2bin( $magic[1] ) ) { if ( 'avif' === hex2bin( $magic[2] ) || 'avis' === hex2bin( $magic[2] ) ) { $mime = 'image/avif'; } elseif ( 'heic' === hex2bin( $magic[2] ) ) { $mime = 'image/heic'; } elseif ( 'heif' === hex2bin( $magic[2] ) ) { $mime = 'image/heif'; } else { if ( extension_loaded( 'fileinfo' ) ) { $fileinfo = finfo_open( FILEINFO_MIME_TYPE ); $mime_type = finfo_file( $fileinfo, $file ); if ( PHP_VERSION_ID < 80100 ) { finfo_close( $fileinfo ); } if ( wp_is_heic_image_mime_type( $mime_type ) ) { $mime = $mime_type; } } } } } catch ( Exception $e ) { $mime = false; } return $mime; } function wp_get_mime_types() { return apply_filters( 'mime_types', array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'bmp' => 'image/bmp', 'tiff|tif' => 'image/tiff', 'webp' => 'image/webp', 'avif' => 'image/avif', 'ico' => 'image/x-icon', 'heic' => 'image/heic', 'heif' => 'image/heif', 'heics' => 'image/heic-sequence', 'heifs' => 'image/heif-sequence', 'asf|asx' => 'video/x-ms-asf', 'wmv' => 'video/x-ms-wmv', 'wmx' => 'video/x-ms-wmx', 'wm' => 'video/x-ms-wm', 'avi' => 'video/avi', 'divx' => 'video/divx', 'flv' => 'video/x-flv', 'mov|qt' => 'video/quicktime', 'mpeg|mpg|mpe' => 'video/mpeg', 'mp4|m4v' => 'video/mp4', 'ogv' => 'video/ogg', 'webm' => 'video/webm', 'mkv' => 'video/x-matroska', '3gp|3gpp' => 'video/3gpp', '3g2|3gp2' => 'video/3gpp2', 'txt|asc|c|cc|h|srt' => 'text/plain', 'csv' => 'text/csv', 'tsv' => 'text/tab-separated-values', 'ics' => 'text/calendar', 'rtx' => 'text/richtext', 'css' => 'text/css', 'htm|html' => 'text/html', 'vtt' => 'text/vtt', 'dfxp' => 'application/ttaf+xml', 'mp3|m4a|m4b' => 'audio/mpeg', 'aac' => 'audio/aac', 'ra|ram' => 'audio/x-realaudio', 'wav|x-wav' => 'audio/wav', 'ogg|oga' => 'audio/ogg', 'flac' => 'audio/flac', 'mid|midi' => 'audio/midi', 'wma' => 'audio/x-ms-wma', 'wax' => 'audio/x-ms-wax', 'mka' => 'audio/x-matroska', 'rtf' => 'application/rtf', 'js' => 'application/javascript', 'pdf' => 'application/pdf', 'swf' => 'application/x-shockwave-flash', 'class' => 'application/java', 'tar' => 'application/x-tar', 'zip' => 'application/zip', 'gz|gzip' => 'application/x-gzip', 'rar' => 'application/rar', '7z' => 'application/x-7z-compressed', 'exe' => 'application/x-msdownload', 'psd' => 'application/octet-stream', 'xcf' => 'application/octet-stream', 'doc' => 'application/msword', 'pot|pps|ppt' => 'application/vnd.ms-powerpoint', 'wri' => 'application/vnd.ms-write', 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel', 'mdb' => 'application/vnd.ms-access', 'mpp' => 'application/vnd.ms-project', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote', 'oxps' => 'application/oxps', 'xps' => 'application/vnd.ms-xpsdocument', 'odt' => 'application/vnd.oasis.opendocument.text', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'odc' => 'application/vnd.oasis.opendocument.chart', 'odb' => 'application/vnd.oasis.opendocument.database', 'odf' => 'application/vnd.oasis.opendocument.formula', 'wp|wpd' => 'application/wordperfect', 'key' => 'application/vnd.apple.keynote', 'numbers' => 'application/vnd.apple.numbers', 'pages' => 'application/vnd.apple.pages', ) ); } function wp_get_ext_types() { return apply_filters( 'ext2type', array( 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'heif', 'webp', 'avif' ), 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ), 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ), 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ), 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ), 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ), 'text' => array( 'asc', 'csv', 'tsv', 'txt' ), 'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ), 'code' => array( 'css', 'htm', 'html', 'php', 'js' ), ) ); } function wp_filesize( $path ) { $size = apply_filters( 'pre_wp_filesize', null, $path ); if ( is_int( $size ) ) { return $size; } $size = file_exists( $path ) ? (int) filesize( $path ) : 0; return (int) apply_filters( 'wp_filesize', $size, $path ); } function get_allowed_mime_types( $user = null ) { $t = wp_get_mime_types(); unset( $t['swf'], $t['exe'] ); if ( function_exists( 'current_user_can' ) ) { $unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' ); } if ( empty( $unfiltered ) ) { unset( $t['htm|html'], $t['js'] ); } return apply_filters( 'upload_mimes', $t, $user ); } function wp_nonce_ays( $action ) { $title = __( 'An error occurred.' ); $response_code = 403; if ( 'log-out' === $action ) { $title = sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'name' ) ); $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : ''; $html = $title; $html .= '</p><p>'; $html .= sprintf( __( 'Do you really want to <a href="%s">log out</a>?' ), wp_logout_url( $redirect_to ) ); } else { $html = __( 'The link you followed has expired.' ); if ( wp_get_referer() ) { $wp_http_referer = remove_query_arg( 'updated', wp_get_referer() ); $wp_http_referer = wp_validate_redirect( sanitize_url( $wp_http_referer ) ); $html .= '</p><p>'; $html .= sprintf( '<a href="%s">%s</a>', esc_url( $wp_http_referer ), __( 'Please try again.' ) ); } } wp_die( $html, $title, $response_code ); } function wp_die( $message = '', $title = '', $args = array() ) { global $wp_query; if ( is_int( $args ) ) { $args = array( 'response' => $args ); } elseif ( is_int( $title ) ) { $args = array( 'response' => $title ); $title = ''; } if ( wp_doing_ajax() ) { $callback = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' ); } elseif ( wp_is_json_request() ) { $callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' ); } elseif ( wp_is_serving_rest_request() && wp_is_jsonp_request() ) { $callback = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' ); } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { $callback = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' ); } elseif ( wp_is_xml_request() || isset( $wp_query ) && ( function_exists( 'is_feed' ) && is_feed() || function_exists( 'is_comment_feed' ) && is_comment_feed() || function_exists( 'is_trackback' ) && is_trackback() ) ) { $callback = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' ); } else { $callback = apply_filters( 'wp_die_handler', '_default_wp_die_handler' ); } call_user_func( $callback, $message, $title, $args ); } function _default_wp_die_handler( $message, $title = '', $args = array() ) { list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); if ( is_string( $message ) ) { if ( ! empty( $parsed_args['additional_errors'] ) ) { $message = array_merge( array( $message ), wp_list_pluck( $parsed_args['additional_errors'], 'message' ) ); $message = "<ul>\n\t\t<li>" . implode( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>"; } $message = sprintf( '<div class="wp-die-message">%s</div>', $message ); } $have_gettext = function_exists( '__' ); if ( ! empty( $parsed_args['link_url'] ) && ! empty( $parsed_args['link_text'] ) ) { $link_url = $parsed_args['link_url']; if ( function_exists( 'esc_url' ) ) { $link_url = esc_url( $link_url ); } $link_text = $parsed_args['link_text']; $message .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>"; } if ( isset( $parsed_args['back_link'] ) && $parsed_args['back_link'] ) { $back_text = $have_gettext ? __( '« Back' ) : '« Back'; $message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>"; } if ( ! did_action( 'admin_head' ) ) : if ( ! headers_sent() ) { header( "Content-Type: text/html; charset={$parsed_args['charset']}" ); status_header( $parsed_args['response'] ); nocache_headers(); } $text_direction = $parsed_args['text_direction']; $dir_attr = "dir='$text_direction'"; if ( empty( $args['text_direction'] ) && function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) { $dir_attr = get_language_attributes(); } ?>
<!DOCTYPE html>
<html <?php echo $dir_attr; ?>>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php
if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) { add_filter( 'wp_robots', 'wp_robots_no_robots' ); remove_filter( 'wp_robots', 'wp_robots_noindex_embeds' ); remove_filter( 'wp_robots', 'wp_robots_noindex_search' ); wp_robots(); } ?>
<title><?php echo $title; ?></title>
<style type="text/css">
html {
background: #f1f1f1;
}
body {
background: #fff;
border: 1px solid #ccd0d4;
color: #444;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
margin: 2em auto;
padding: 1em 2em;
max-width: 700px;
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .04);
box-shadow: 0 1px 1px rgba(0, 0, 0, .04);
}
h1 {
border-bottom: 1px solid #dadada;
clear: both;
color: #666;
font-size: 24px;
margin: 30px 0 0 0;
padding: 0;
padding-bottom: 7px;
}
#error-page {
margin-top: 50px;
}
#error-page p,
#error-page .wp-die-message {
font-size: 14px;
line-height: 1.5;
margin: 25px 0 20px;
}
#error-page code {
font-family: Consolas, Monaco, monospace;
}
ul li {
margin-bottom: 10px;
font-size: 14px ;
}
a {
color: #2271b1;
}
a:hover,
a:active {
color: #135e96;
}
a:focus {
color: #043959;
box-shadow: 0 0 0 2px #2271b1;
outline: 2px solid transparent;
}
.button {
background: #f3f5f6;
border: 1px solid #016087;
color: #016087;
display: inline-block;
text-decoration: none;
font-size: 13px;
line-height: 2;
height: 28px;
margin: 0;
padding: 0 10px 1px;
cursor: pointer;
-webkit-border-radius: 3px;
-webkit-appearance: none;
border-radius: 3px;
white-space: nowrap;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
vertical-align: top;
}
.button.button-large {
line-height: 2.30769231;
min-height: 32px;
padding: 0 12px;
}
.button:hover,
.button:focus {
background: #f1f1f1;
}
.button:focus {
background: #f3f5f6;
border-color: #007cba;
-webkit-box-shadow: 0 0 0 1px #007cba;
box-shadow: 0 0 0 1px #007cba;
color: #016087;
outline: 2px solid transparent;
outline-offset: 0;
}
.button:active {
background: #f3f5f6;
border-color: #7e8993;
-webkit-box-shadow: none;
box-shadow: none;
}
<?php
if ( 'rtl' === $text_direction ) { echo 'body { font-family: Tahoma, Arial; }'; } ?>
</style>
</head>
<body id="error-page">
<?php endif; ?>
<?php echo $message; ?>
</body>
</html>
<?php
if ( $parsed_args['exit'] ) { die(); } } function _ajax_wp_die_handler( $message, $title = '', $args = array() ) { $args = wp_parse_args( $args, array( 'response' => 200 ) ); list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); if ( ! headers_sent() ) { if ( null !== $args['response'] ) { status_header( $parsed_args['response'] ); } nocache_headers(); } if ( is_scalar( $message ) ) { $message = (string) $message; } else { $message = '0'; } if ( $parsed_args['exit'] ) { die( $message ); } echo $message; } function _json_wp_die_handler( $message, $title = '', $args = array() ) { list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); $data = array( 'code' => $parsed_args['code'], 'message' => $message, 'data' => array( 'status' => $parsed_args['response'], ), 'additional_errors' => $parsed_args['additional_errors'], ); if ( isset( $parsed_args['error_data'] ) ) { $data['data']['error'] = $parsed_args['error_data']; } if ( ! headers_sent() ) { header( "Content-Type: application/json; charset={$parsed_args['charset']}" ); if ( null !== $parsed_args['response'] ) { status_header( $parsed_args['response'] ); } nocache_headers(); } echo wp_json_encode( $data ); if ( $parsed_args['exit'] ) { die(); } } function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) { list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); $data = array( 'code' => $parsed_args['code'], 'message' => $message, 'data' => array( 'status' => $parsed_args['response'], ), 'additional_errors' => $parsed_args['additional_errors'], ); if ( isset( $parsed_args['error_data'] ) ) { $data['data']['error'] = $parsed_args['error_data']; } if ( ! headers_sent() ) { header( "Content-Type: application/javascript; charset={$parsed_args['charset']}" ); header( 'X-Content-Type-Options: nosniff' ); header( 'X-Robots-Tag: noindex' ); if ( null !== $parsed_args['response'] ) { status_header( $parsed_args['response'] ); } nocache_headers(); } $result = wp_json_encode( $data ); $jsonp_callback = $_GET['_jsonp']; echo '/**/' . $jsonp_callback . '(' . $result . ')'; if ( $parsed_args['exit'] ) { die(); } } function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) { global $wp_xmlrpc_server; list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); if ( ! headers_sent() ) { nocache_headers(); } if ( $wp_xmlrpc_server ) { $error = new IXR_Error( $parsed_args['response'], $message ); $wp_xmlrpc_server->output( $error->getXml() ); } if ( $parsed_args['exit'] ) { die(); } } function _xml_wp_die_handler( $message, $title = '', $args = array() ) { list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); $message = htmlspecialchars( $message ); $title = htmlspecialchars( $title ); $xml = <<<EOD
<error>
<code>{$parsed_args['code']}</code>
<title><![CDATA[{$title}]]></title>
<message><![CDATA[{$message}]]></message>
<data>
<status>{$parsed_args['response']}</status>
</data>
</error>
EOD;
if ( ! headers_sent() ) { header( "Content-Type: text/xml; charset={$parsed_args['charset']}" ); if ( null !== $parsed_args['response'] ) { status_header( $parsed_args['response'] ); } nocache_headers(); } echo $xml; if ( $parsed_args['exit'] ) { die(); } } function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) { list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args ); if ( $parsed_args['exit'] ) { if ( is_scalar( $message ) ) { die( (string) $message ); } die(); } if ( is_scalar( $message ) ) { echo (string) $message; } } function _wp_die_process_input( $message, $title = '', $args = array() ) { $defaults = array( 'response' => 0, 'code' => '', 'exit' => true, 'back_link' => false, 'link_url' => '', 'link_text' => '', 'text_direction' => '', 'charset' => 'utf-8', 'additional_errors' => array(), ); $args = wp_parse_args( $args, $defaults ); if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { if ( ! empty( $message->errors ) ) { $errors = array(); foreach ( (array) $message->errors as $error_code => $error_messages ) { foreach ( (array) $error_messages as $error_message ) { $errors[] = array( 'code' => $error_code, 'message' => $error_message, 'data' => $message->get_error_data( $error_code ), ); } } $message = $errors[0]['message']; if ( empty( $args['code'] ) ) { $args['code'] = $errors[0]['code']; } if ( empty( $args['response'] ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['status'] ) ) { $args['response'] = $errors[0]['data']['status']; } if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) { $title = $errors[0]['data']['title']; } if ( WP_DEBUG_DISPLAY && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['error'] ) ) { $args['error_data'] = $errors[0]['data']['error']; } unset( $errors[0] ); $args['additional_errors'] = array_values( $errors ); } else { $message = ''; } } $have_gettext = function_exists( '__' ); if ( empty( $args['code'] ) ) { $args['code'] = 'wp_die'; } if ( empty( $args['response'] ) ) { $args['response'] = 500; } if ( empty( $title ) ) { $title = $have_gettext ? __( 'WordPress › Error' ) : 'WordPress › Error'; } if ( empty( $args['text_direction'] ) || ! in_array( $args['text_direction'], array( 'ltr', 'rtl' ), true ) ) { $args['text_direction'] = 'ltr'; if ( function_exists( 'is_rtl' ) && is_rtl() ) { $args['text_direction'] = 'rtl'; } } if ( ! empty( $args['charset'] ) ) { $args['charset'] = _canonical_charset( $args['charset'] ); } return array( $message, $title, $args ); } function wp_json_encode( $value, $flags = 0, $depth = 512 ) { $json = json_encode( $value, $flags, $depth ); if ( false !== $json ) { return $json; } try { $value = _wp_json_sanity_check( $value, $depth ); } catch ( Exception $e ) { return false; } return json_encode( $value, $flags, $depth ); } function _wp_json_sanity_check( $value, $depth ) { if ( $depth < 0 ) { throw new Exception( 'Reached depth limit' ); } if ( is_array( $value ) ) { $output = array(); foreach ( $value as $id => $el ) { if ( is_string( $id ) ) { $clean_id = _wp_json_convert_string( $id ); } else { $clean_id = $id; } if ( is_array( $el ) || is_object( $el ) ) { $output[ $clean_id ] = _wp_json_sanity_check( $el, $depth - 1 ); } elseif ( is_string( $el ) ) { $output[ $clean_id ] = _wp_json_convert_string( $el ); } else { $output[ $clean_id ] = $el; } } } elseif ( is_object( $value ) ) { $output = new stdClass(); foreach ( $value as $id => $el ) { if ( is_string( $id ) ) { $clean_id = _wp_json_convert_string( $id ); } else { $clean_id = $id; } if ( is_array( $el ) || is_object( $el ) ) { $output->$clean_id = _wp_json_sanity_check( $el, $depth - 1 ); } elseif ( is_string( $el ) ) { $output->$clean_id = _wp_json_convert_string( $el ); } else { $output->$clean_id = $el; } } } elseif ( is_string( $value ) ) { return _wp_json_convert_string( $value ); } else { return $value; } return $output; } function _wp_json_convert_string( $input_string ) { static $use_mb = null; if ( is_null( $use_mb ) ) { $use_mb = function_exists( 'mb_convert_encoding' ); } if ( $use_mb ) { $encoding = mb_detect_encoding( $input_string, mb_detect_order(), true ); if ( $encoding ) { return mb_convert_encoding( $input_string, 'UTF-8', $encoding ); } else { return mb_convert_encoding( $input_string, 'UTF-8', 'UTF-8' ); } } else { return wp_check_invalid_utf8( $input_string, true ); } } function _wp_json_prepare_data( $value ) { _deprecated_function( __FUNCTION__, '5.3.0' ); return $value; } function wp_send_json( $response, $status_code = null, $flags = 0 ) { if ( wp_is_serving_rest_request() ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Return a %1$s or %2$s object from your callback when using the REST API.' ), 'WP_REST_Response', 'WP_Error' ), '5.5.0' ); } if ( ! headers_sent() ) { header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) ); if ( null !== $status_code ) { status_header( $status_code ); } } echo wp_json_encode( $response, $flags ); if ( wp_doing_ajax() ) { wp_die( '', '', array( 'response' => null, ) ); } else { die; } } function wp_send_json_success( $value = null, $status_code = null, $flags = 0 ) { $response = array( 'success' => true ); if ( isset( $value ) ) { $response['data'] = $value; } wp_send_json( $response, $status_code, $flags ); } function wp_send_json_error( $value = null, $status_code = null, $flags = 0 ) { $response = array( 'success' => false ); if ( isset( $value ) ) { if ( is_wp_error( $value ) ) { $result = array(); foreach ( $value->errors as $code => $messages ) { foreach ( $messages as $message ) { $result[] = array( 'code' => $code, 'message' => $message, ); } } $response['data'] = $result; } else { $response['data'] = $value; } } wp_send_json( $response, $status_code, $flags ); } function wp_check_jsonp_callback( $callback ) { if ( ! is_string( $callback ) ) { return false; } preg_replace( '/[^\w\.]/', '', $callback, -1, $illegal_char_count ); return 0 === $illegal_char_count; } function wp_json_file_decode( $filename, $options = array() ) { $result = null; $filename = wp_normalize_path( realpath( $filename ) ); if ( ! $filename ) { wp_trigger_error( __FUNCTION__, sprintf( __( "File %s doesn't exist!" ), $filename ) ); return $result; } $options = wp_parse_args( $options, array( 'associative' => false ) ); $decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] ); if ( JSON_ERROR_NONE !== json_last_error() ) { wp_trigger_error( __FUNCTION__, sprintf( __( 'Error when decoding a JSON file at path %1$s: %2$s' ), $filename, json_last_error_msg() ) ); return $result; } return $decoded_file; } function _config_wp_home( $url = '' ) { if ( defined( 'WP_HOME' ) ) { return untrailingslashit( WP_HOME ); } return $url; } function _config_wp_siteurl( $url = '' ) { if ( defined( 'WP_SITEURL' ) ) { return untrailingslashit( WP_SITEURL ); } return $url; } function _delete_option_fresh_site() { update_option( 'fresh_site', '0', false ); } function _mce_set_direction( $mce_init ) { if ( is_rtl() ) { $mce_init['directionality'] = 'rtl'; $mce_init['rtl_ui'] = true; if ( ! empty( $mce_init['plugins'] ) && ! str_contains( $mce_init['plugins'], 'directionality' ) ) { $mce_init['plugins'] .= ',directionality'; } if ( ! empty( $mce_init['toolbar1'] ) && ! preg_match( '/\bltr\b/', $mce_init['toolbar1'] ) ) { $mce_init['toolbar1'] .= ',ltr'; } } return $mce_init; } function wp_is_serving_rest_request() { return defined( 'REST_REQUEST' ) && REST_REQUEST; } function smilies_init() { global $wpsmiliestrans, $wp_smiliessearch; if ( ! get_option( 'use_smilies' ) ) { return; } if ( ! isset( $wpsmiliestrans ) ) { $wpsmiliestrans = array( ':mrgreen:' => 'mrgreen.png', ':neutral:' => "\xf0\x9f\x98\x90", ':twisted:' => "\xf0\x9f\x98\x88", ':arrow:' => "\xe2\x9e\xa1", ':shock:' => "\xf0\x9f\x98\xaf", ':smile:' => "\xf0\x9f\x99\x82", ':???:' => "\xf0\x9f\x98\x95", ':cool:' => "\xf0\x9f\x98\x8e", ':evil:' => "\xf0\x9f\x91\xbf", ':grin:' => "\xf0\x9f\x98\x80", ':idea:' => "\xf0\x9f\x92\xa1", ':oops:' => "\xf0\x9f\x98\xb3", ':razz:' => "\xf0\x9f\x98\x9b", ':roll:' => "\xf0\x9f\x99\x84", ':wink:' => "\xf0\x9f\x98\x89", ':cry:' => "\xf0\x9f\x98\xa5", ':eek:' => "\xf0\x9f\x98\xae", ':lol:' => "\xf0\x9f\x98\x86", ':mad:' => "\xf0\x9f\x98\xa1", ':sad:' => "\xf0\x9f\x99\x81", '8-)' => "\xf0\x9f\x98\x8e", '8-O' => "\xf0\x9f\x98\xaf", ':-(' => "\xf0\x9f\x99\x81", ':-)' => "\xf0\x9f\x99\x82", ':-?' => "\xf0\x9f\x98\x95", ':-D' => "\xf0\x9f\x98\x80", ':-P' => "\xf0\x9f\x98\x9b", ':-o' => "\xf0\x9f\x98\xae", ':-x' => "\xf0\x9f\x98\xa1", ':-|' => "\xf0\x9f\x98\x90", ';-)' => "\xf0\x9f\x98\x89", '8O' => "\xf0\x9f\x98\xaf", ':(' => "\xf0\x9f\x99\x81", ':)' => "\xf0\x9f\x99\x82", ':?' => "\xf0\x9f\x98\x95", ':D' => "\xf0\x9f\x98\x80", ':P' => "\xf0\x9f\x98\x9b", ':o' => "\xf0\x9f\x98\xae", ':x' => "\xf0\x9f\x98\xa1", ':|' => "\xf0\x9f\x98\x90", ';)' => "\xf0\x9f\x98\x89", ':!:' => "\xe2\x9d\x97", ':?:' => "\xe2\x9d\x93", ); } $wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans ); if ( count( $wpsmiliestrans ) === 0 ) { return; } krsort( $wpsmiliestrans ); $spaces = wp_spaces_regexp(); $wp_smiliessearch = '/(?<=' . $spaces . '|^)'; $subchar = ''; foreach ( (array) $wpsmiliestrans as $smiley => $img ) { $firstchar = substr( $smiley, 0, 1 ); $rest = substr( $smiley, 1 ); if ( $firstchar !== $subchar ) { if ( '' !== $subchar ) { $wp_smiliessearch .= ')(?=' . $spaces . '|$)'; $wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; } $subchar = $firstchar; $wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:'; } else { $wp_smiliessearch .= '|'; } $wp_smiliessearch .= preg_quote( $rest, '/' ); } $wp_smiliessearch .= ')(?=' . $spaces . '|$)/m'; } function wp_parse_args( $args, $defaults = array() ) { if ( is_object( $args ) ) { $parsed_args = get_object_vars( $args ); } elseif ( is_array( $args ) ) { $parsed_args =& $args; } else { wp_parse_str( $args, $parsed_args ); } if ( is_array( $defaults ) && $defaults ) { return array_merge( $defaults, $parsed_args ); } return $parsed_args; } function wp_parse_list( $input_list ) { if ( ! is_array( $input_list ) ) { return preg_split( '/[\s,]+/', $input_list, -1, PREG_SPLIT_NO_EMPTY ); } $input_list = array_filter( $input_list, 'is_scalar' ); return $input_list; } function wp_parse_id_list( $input_list ) { $input_list = wp_parse_list( $input_list ); return array_unique( array_map( 'absint', $input_list ) ); } function wp_parse_slug_list( $input_list ) { $input_list = wp_parse_list( $input_list ); return array_unique( array_map( 'sanitize_title', $input_list ) ); } function wp_array_slice_assoc( $input_array, $keys ) { $slice = array(); foreach ( $keys as $key ) { if ( isset( $input_array[ $key ] ) ) { $slice[ $key ] = $input_array[ $key ]; } } return $slice; } function wp_recursive_ksort( &$input_array ) { foreach ( $input_array as &$value ) { if ( is_array( $value ) ) { wp_recursive_ksort( $value ); } } ksort( $input_array ); } function _wp_array_get( $input_array, $path, $default_value = null ) { if ( ! is_array( $path ) || 0 === count( $path ) ) { return $default_value; } foreach ( $path as $path_element ) { if ( ! is_array( $input_array ) ) { return $default_value; } if ( is_string( $path_element ) || is_integer( $path_element ) || null === $path_element ) { if ( isset( $path_element, $input_array[ $path_element ] ) ) { $input_array = $input_array[ $path_element ]; continue; } if ( isset( $path_element ) && array_key_exists( $path_element, $input_array ) ) { $input_array = $input_array[ $path_element ]; continue; } } return $default_value; } return $input_array; } function _wp_array_set( &$input_array, $path, $value = null ) { if ( ! is_array( $input_array ) ) { return; } if ( ! is_array( $path ) ) { return; } $path_length = count( $path ); if ( 0 === $path_length ) { return; } foreach ( $path as $path_element ) { if ( ! is_string( $path_element ) && ! is_integer( $path_element ) && ! is_null( $path_element ) ) { return; } } for ( $i = 0; $i < $path_length - 1; ++$i ) { $path_element = $path[ $i ]; if ( ! array_key_exists( $path_element, $input_array ) || ! is_array( $input_array[ $path_element ] ) ) { $input_array[ $path_element ] = array(); } $input_array = &$input_array[ $path_element ]; } $input_array[ $path[ $i ] ] = $value; } function _wp_to_kebab_case( $input_string ) { $rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; $rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; $rsPunctuationRange = '\\x{2000}-\\x{206f}'; $rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; $rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; $rsBreakRange = $rsNonCharRange . $rsPunctuationRange . $rsSpaceRange; $rsBreak = '[' . $rsBreakRange . ']'; $rsDigits = '\\d+'; $rsLower = '[' . $rsLowerRange . ']'; $rsMisc = '[^' . $rsBreakRange . $rsDigits . $rsLowerRange . $rsUpperRange . ']'; $rsUpper = '[' . $rsUpperRange . ']'; $rsMiscLower = '(?:' . $rsLower . '|' . $rsMisc . ')'; $rsMiscUpper = '(?:' . $rsUpper . '|' . $rsMisc . ')'; $rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])'; $rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])'; $regexp = '/' . implode( '|', array( $rsUpper . '?' . $rsLower . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper, '$' ) ) . ')', $rsMiscUpper . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper . $rsMiscLower, '$' ) ) . ')', $rsUpper . '?' . $rsMiscLower . '+', $rsUpper . '+', $rsOrdUpper, $rsOrdLower, $rsDigits, ) ) . '/u'; preg_match_all( $regexp, str_replace( "'", '', $input_string ), $matches ); return strtolower( implode( '-', $matches[0] ) ); } function wp_is_numeric_array( $data ) { if ( ! is_array( $data ) ) { return false; } $keys = array_keys( $data ); $string_keys = array_filter( $keys, 'is_string' ); return count( $string_keys ) === 0; } function wp_filter_object_list( $input_list, $args = array(), $operator = 'and', $field = false ) { if ( ! is_array( $input_list ) ) { return array(); } $util = new WP_List_Util( $input_list ); $util->filter( $args, $operator ); if ( $field ) { $util->pluck( $field ); } return $util->get_output(); } function wp_list_filter( $input_list, $args = array(), $operator = 'AND' ) { return wp_filter_object_list( $input_list, $args, $operator ); } function wp_list_pluck( $input_list, $field, $index_key = null ) { if ( ! is_array( $input_list ) ) { return array(); } $util = new WP_List_Util( $input_list ); return $util->pluck( $field, $index_key ); } function wp_list_sort( $input_list, $orderby = array(), $order = 'ASC', $preserve_keys = false ) { if ( ! is_array( $input_list ) ) { return array(); } $util = new WP_List_Util( $input_list ); return $util->sort( $orderby, $order, $preserve_keys ); } function wp_maybe_load_widgets() { if ( ! apply_filters( 'load_default_widgets', true ) ) { return; } require_once ABSPATH . WPINC . '/default-widgets.php'; add_action( '_admin_menu', 'wp_widgets_add_menu' ); } function wp_widgets_add_menu() { global $submenu; if ( ! current_theme_supports( 'widgets' ) ) { return; } $menu_name = __( 'Widgets' ); if ( wp_is_block_theme() ) { $submenu['themes.php'][] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); } else { $submenu['themes.php'][8] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); } ksort( $submenu['themes.php'], SORT_NUMERIC ); } function wp_ob_end_flush_all() { $levels = ob_get_level(); for ( $i = 0; $i < $levels; $i++ ) { ob_end_flush(); } } function dead_db() { global $wpdb; wp_load_translations_early(); if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) { require_once WP_CONTENT_DIR . '/db-error.php'; die(); } if ( wp_installing() || defined( 'WP_ADMIN' ) ) { wp_die( $wpdb->error ); } wp_die( '<h1>' . __( 'Error establishing a database connection' ) . '</h1>', __( 'Database Error' ) ); } function _deprecated_function( $function_name, $version, $replacement = '' ) { do_action( 'deprecated_function_run', $function_name, $replacement, $version ); if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) { if ( function_exists( '__' ) ) { if ( $replacement ) { $message = sprintf( __( 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $function_name, $version, $replacement ); } else { $message = sprintf( __( 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function_name, $version ); } } else { if ( $replacement ) { $message = sprintf( 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $function_name, $version, $replacement ); } else { $message = sprintf( 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', $function_name, $version ); } } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _deprecated_constructor( $class_name, $version, $parent_class = '' ) { do_action( 'deprecated_constructor_run', $class_name, $version, $parent_class ); if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) { if ( function_exists( '__' ) ) { if ( $parent_class ) { $message = sprintf( __( 'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ), $class_name, $parent_class, $version, '<code>__construct()</code>' ); } else { $message = sprintf( __( 'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $class_name, $version, '<code>__construct()</code>' ); } } else { if ( $parent_class ) { $message = sprintf( 'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.', $class_name, $parent_class, $version, '<code>__construct()</code>' ); } else { $message = sprintf( 'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $class_name, $version, '<code>__construct()</code>' ); } } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _deprecated_class( $class_name, $version, $replacement = '' ) { do_action( 'deprecated_class_run', $class_name, $replacement, $version ); if ( WP_DEBUG && apply_filters( 'deprecated_class_trigger_error', true ) ) { if ( function_exists( '__' ) ) { if ( $replacement ) { $message = sprintf( __( 'Class %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $class_name, $version, $replacement ); } else { $message = sprintf( __( 'Class %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $class_name, $version ); } } else { if ( $replacement ) { $message = sprintf( 'Class %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $class_name, $version, $replacement ); } else { $message = sprintf( 'Class %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', $class_name, $version ); } } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _deprecated_file( $file, $version, $replacement = '', $message = '' ) { do_action( 'deprecated_file_included', $file, $replacement, $version, $message ); if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) { $message = empty( $message ) ? '' : ' ' . $message; if ( function_exists( '__' ) ) { if ( $replacement ) { $message = sprintf( __( 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $file, $version, $replacement ) . $message; } else { $message = sprintf( __( 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $file, $version ) . $message; } } else { if ( $replacement ) { $message = sprintf( 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $file, $version, $replacement ); } else { $message = sprintf( 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', $file, $version ) . $message; } } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _deprecated_argument( $function_name, $version, $message = '' ) { do_action( 'deprecated_argument_run', $function_name, $message, $version ); if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) { if ( function_exists( '__' ) ) { if ( $message ) { $message = sprintf( __( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), $function_name, $version, $message ); } else { $message = sprintf( __( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function_name, $version ); } } else { if ( $message ) { $message = sprintf( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', $function_name, $version, $message ); } else { $message = sprintf( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.', $function_name, $version ); } } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _deprecated_hook( $hook, $version, $replacement = '', $message = '' ) { do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message ); if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) { $message = empty( $message ) ? '' : ' ' . $message; if ( $replacement ) { $message = sprintf( __( 'Hook %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $hook, $version, $replacement ) . $message; } else { $message = sprintf( __( 'Hook %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $hook, $version ) . $message; } wp_trigger_error( '', $message, E_USER_DEPRECATED ); } } function _doing_it_wrong( $function_name, $message, $version ) { do_action( 'doing_it_wrong_run', $function_name, $message, $version ); if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function_name, $message, $version ) ) { if ( function_exists( '__' ) ) { if ( $version ) { $version = sprintf( __( '(This message was added in version %s.)' ), $version ); } $message .= ' ' . sprintf( __( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ), __( 'https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/' ) ); $message = sprintf( __( 'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function_name, $message, $version ); } else { if ( $version ) { $version = sprintf( '(This message was added in version %s.)', $version ); } $message .= sprintf( ' Please see <a href="%s">Debugging in WordPress</a> for more information.', 'https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/' ); $message = sprintf( 'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s', $function_name, $message, $version ); } wp_trigger_error( '', $message ); } } function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) { if ( ! WP_DEBUG ) { return; } do_action( 'wp_trigger_error_run', $function_name, $message, $error_level ); if ( ! empty( $function_name ) ) { $message = sprintf( '%s(): %s', $function_name, $message ); } $message = wp_kses( $message, array( 'a' => array( 'href' => true ), 'br' => array(), 'code' => array(), 'em' => array(), 'strong' => array(), ), array( 'http', 'https' ) ); if ( E_USER_ERROR === $error_level ) { throw new WP_Exception( $message ); } trigger_error( $message, $error_level ); } function is_lighttpd_before_150() { $server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' ); $server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : ''; return ( 'lighttpd' === $server_parts[0] && -1 === version_compare( $server_parts[1], '1.5.0' ) ); } function apache_mod_loaded( $mod, $default_value = false ) { global $is_apache; if ( ! $is_apache ) { return false; } $loaded_mods = array(); if ( function_exists( 'apache_get_modules' ) ) { $loaded_mods = apache_get_modules(); if ( in_array( $mod, $loaded_mods, true ) ) { return true; } } if ( empty( $loaded_mods ) && function_exists( 'phpinfo' ) && ! str_contains( ini_get( 'disable_functions' ), 'phpinfo' ) ) { ob_start(); phpinfo( INFO_MODULES ); $phpinfo = ob_get_clean(); if ( str_contains( $phpinfo, $mod ) ) { return true; } } return $default_value; } function iis7_supports_permalinks() { global $is_iis7; $supports_permalinks = false; if ( $is_iis7 ) { $supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( 'cgi-fcgi' === PHP_SAPI ); } return apply_filters( 'iis7_supports_permalinks', $supports_permalinks ); } function validate_file( $file, $allowed_files = array() ) { if ( ! is_scalar( $file ) || '' === $file ) { return 0; } $file = wp_normalize_path( $file ); $allowed_files = array_map( 'wp_normalize_path', $allowed_files ); if ( '../' === $file ) { return 1; } if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) { return 1; } if ( str_contains( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) { return 1; } if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files, true ) ) { return 3; } if ( ':' === substr( $file, 1, 1 ) ) { return 2; } return 0; } function force_ssl_admin( $force = null ) { static $forced = false; if ( ! is_null( $force ) ) { $old_forced = $forced; $forced = (bool) $force; return $old_forced; } return $forced; } function wp_guess_url() { if ( defined( 'WP_SITEURL' ) && '' !== WP_SITEURL ) { $url = WP_SITEURL; } else { $abspath_fix = str_replace( '\\', '/', ABSPATH ); $script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] ); if ( str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) || str_contains( $_SERVER['REQUEST_URI'], 'wp-login.php' ) ) { $path = preg_replace( '#/(wp-admin/?.*|wp-login\.php.*)#i', '', $_SERVER['REQUEST_URI'] ); } elseif ( $script_filename_dir . '/' === $abspath_fix ) { $path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] ); } else { if ( str_contains( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) { $directory = str_replace( ABSPATH, '', $script_filename_dir ); $path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ); } elseif ( str_contains( $abspath_fix, $script_filename_dir ) ) { $subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) ); $path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory; } else { $path = $_SERVER['REQUEST_URI']; } } $schema = is_ssl() ? 'https://' : 'http://'; $url = $schema . $_SERVER['HTTP_HOST'] . $path; } return rtrim( $url, '/' ); } function wp_suspend_cache_addition( $suspend = null ) { static $_suspend = false; if ( is_bool( $suspend ) ) { $_suspend = $suspend; } return $_suspend; } function wp_suspend_cache_invalidation( $suspend = true ) { global $_wp_suspend_cache_invalidation; $current_suspend = $_wp_suspend_cache_invalidation; $_wp_suspend_cache_invalidation = $suspend; return $current_suspend; } function is_main_site( $site_id = null, $network_id = null ) { if ( ! is_multisite() ) { return true; } if ( ! $site_id ) { $site_id = get_current_blog_id(); } $site_id = (int) $site_id; return get_main_site_id( $network_id ) === $site_id; } function get_main_site_id( $network_id = null ) { if ( ! is_multisite() ) { return get_current_blog_id(); } $network = get_network( $network_id ); if ( ! $network ) { return 0; } return $network->site_id; } function is_main_network( $network_id = null ) { if ( ! is_multisite() ) { return true; } if ( null === $network_id ) { $network_id = get_current_network_id(); } $network_id = (int) $network_id; return ( get_main_network_id() === $network_id ); } function get_main_network_id() { if ( ! is_multisite() ) { return 1; } $current_network = get_network(); if ( defined( 'PRIMARY_NETWORK_ID' ) ) { $main_network_id = PRIMARY_NETWORK_ID; } elseif ( isset( $current_network->id ) && 1 === (int) $current_network->id ) { $main_network_id = 1; } else { $_networks = get_networks( array( 'fields' => 'ids', 'number' => 1, ) ); $main_network_id = array_shift( $_networks ); } return (int) apply_filters( 'get_main_network_id', $main_network_id ); } function is_site_meta_supported() { global $wpdb; if ( ! is_multisite() ) { return false; } $network_id = get_main_network_id(); $supported = get_network_option( $network_id, 'site_meta_supported', false ); if ( false === $supported ) { $supported = $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->blogmeta}'" ) ? 1 : 0; update_network_option( $network_id, 'site_meta_supported', $supported ); } return (bool) $supported; } function wp_timezone_override_offset() { $timezone_string = get_option( 'timezone_string' ); if ( ! $timezone_string ) { return false; } $timezone_object = timezone_open( $timezone_string ); $datetime_object = date_create(); if ( false === $timezone_object || false === $datetime_object ) { return false; } return round( timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS, 2 ); } function _wp_timezone_choice_usort_callback( $a, $b ) { if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) { if ( str_starts_with( $a['city'], 'GMT+' ) && str_starts_with( $b['city'], 'GMT+' ) ) { return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) ); } if ( 'UTC' === $a['city'] ) { if ( str_starts_with( $b['city'], 'GMT+' ) ) { return 1; } return -1; } if ( 'UTC' === $b['city'] ) { if ( str_starts_with( $a['city'], 'GMT+' ) ) { return -1; } return 1; } return strnatcasecmp( $a['city'], $b['city'] ); } if ( $a['t_continent'] === $b['t_continent'] ) { if ( $a['t_city'] === $b['t_city'] ) { return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] ); } return strnatcasecmp( $a['t_city'], $b['t_city'] ); } else { if ( 'Etc' === $a['continent'] ) { return 1; } if ( 'Etc' === $b['continent'] ) { return -1; } return strnatcasecmp( $a['t_continent'], $b['t_continent'] ); } } function wp_timezone_choice( $selected_zone, $locale = null ) { static $mo_loaded = false, $locale_loaded = null; $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' ); if ( ! $mo_loaded || $locale !== $locale_loaded ) { $locale_loaded = $locale ? $locale : get_locale(); $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo'; unload_textdomain( 'continents-cities', true ); load_textdomain( 'continents-cities', $mofile, $locale_loaded ); $mo_loaded = true; } $tz_identifiers = timezone_identifiers_list(); $zonen = array(); foreach ( $tz_identifiers as $zone ) { $zone = explode( '/', $zone ); if ( ! in_array( $zone[0], $continents, true ) ) { continue; } $exists = array( 0 => ( isset( $zone[0] ) && $zone[0] ), 1 => ( isset( $zone[1] ) && $zone[1] ), 2 => ( isset( $zone[2] ) && $zone[2] ), ); $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] ); $exists[4] = ( $exists[1] && $exists[3] ); $exists[5] = ( $exists[2] && $exists[3] ); $zonen[] = array( 'continent' => ( $exists[0] ? $zone[0] : '' ), 'city' => ( $exists[1] ? $zone[1] : '' ), 'subcity' => ( $exists[2] ? $zone[2] : '' ), 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ), 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ), 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ), ); } usort( $zonen, '_wp_timezone_choice_usort_callback' ); $structure = array(); if ( empty( $selected_zone ) ) { $structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>'; } if ( in_array( $selected_zone, $tz_identifiers, true ) === false && in_array( $selected_zone, timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true ) ) { $structure[] = '<option selected="selected" value="' . esc_attr( $selected_zone ) . '">' . esc_html( $selected_zone ) . '</option>'; } foreach ( $zonen as $key => $zone ) { $value = array( $zone['continent'] ); if ( empty( $zone['city'] ) ) { $display = $zone['t_continent']; } else { if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) { $label = $zone['t_continent']; $structure[] = '<optgroup label="' . esc_attr( $label ) . '">'; } $value[] = $zone['city']; $display = $zone['t_city']; if ( ! empty( $zone['subcity'] ) ) { $value[] = $zone['subcity']; $display .= ' - ' . $zone['t_subcity']; } } $value = implode( '/', $value ); $selected = ''; if ( $value === $selected_zone ) { $selected = 'selected="selected" '; } $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . '</option>'; if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) { $structure[] = '</optgroup>'; } } $structure[] = '<optgroup label="' . esc_attr__( 'UTC' ) . '">'; $selected = ''; if ( 'UTC' === $selected_zone ) { $selected = 'selected="selected" '; } $structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC' ) . '</option>'; $structure[] = '</optgroup>'; $structure[] = '<optgroup label="' . esc_attr__( 'Manual Offsets' ) . '">'; $offset_range = array( -12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14, ); foreach ( $offset_range as $offset ) { if ( 0 <= $offset ) { $offset_name = '+' . $offset; } else { $offset_name = (string) $offset; } $offset_value = $offset_name; $offset_name = str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), $offset_name ); $offset_name = 'UTC' . $offset_name; $offset_value = 'UTC' . $offset_value; $selected = ''; if ( $offset_value === $selected_zone ) { $selected = 'selected="selected" '; } $structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . '</option>'; } $structure[] = '</optgroup>'; return implode( "\n", $structure ); } function _cleanup_header_comment( $str ) { return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) ); } function wp_scheduled_delete() { global $wpdb; $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS ); $posts_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp ), ARRAY_A ); foreach ( (array) $posts_to_delete as $post ) { $post_id = (int) $post['post_id']; if ( ! $post_id ) { continue; } $del_post = get_post( $post_id ); if ( ! $del_post || 'trash' !== $del_post->post_status ) { delete_post_meta( $post_id, '_wp_trash_meta_status' ); delete_post_meta( $post_id, '_wp_trash_meta_time' ); } else { wp_delete_post( $post_id ); } } $comments_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp ), ARRAY_A ); foreach ( (array) $comments_to_delete as $comment ) { $comment_id = (int) $comment['comment_id']; if ( ! $comment_id ) { continue; } $del_comment = get_comment( $comment_id ); if ( ! $del_comment || 'trash' !== $del_comment->comment_approved ) { delete_comment_meta( $comment_id, '_wp_trash_meta_time' ); delete_comment_meta( $comment_id, '_wp_trash_meta_status' ); } else { wp_delete_comment( $del_comment ); } } } function get_file_data( $file, $default_headers, $context = '' ) { $file_data = file_get_contents( $file, false, null, 0, 8 * KB_IN_BYTES ); if ( false === $file_data ) { $file_data = ''; } $file_data = str_replace( "\r", "\n", $file_data ); $extra_headers = $context ? apply_filters( "extra_{$context}_headers", array() ) : array(); if ( $extra_headers ) { $extra_headers = array_combine( $extra_headers, $extra_headers ); $all_headers = array_merge( $extra_headers, (array) $default_headers ); } else { $all_headers = $default_headers; } foreach ( $all_headers as $field => $regex ) { if ( preg_match( '/^(?:[ \t]*<\?php)?[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] ) { $all_headers[ $field ] = _cleanup_header_comment( $match[1] ); } else { $all_headers[ $field ] = ''; } } return $all_headers; } function __return_true() { return true; } function __return_false() { return false; } function __return_zero() { return 0; } function __return_empty_array() { return array(); } function __return_null() { return null; } function __return_empty_string() { return ''; } function send_nosniff_header() { header( 'X-Content-Type-Options: nosniff' ); } function _wp_mysql_week( $column ) { $start_of_week = (int) get_option( 'start_of_week' ); switch ( $start_of_week ) { case 1: return "WEEK( $column, 1 )"; case 2: case 3: case 4: case 5: case 6: return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )"; case 0: default: return "WEEK( $column, 0 )"; } } function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) { $override = is_null( $start_parent ) ? array() : array( $start => $start_parent ); $arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ); if ( ! $arbitrary_loop_member ) { return array(); } return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true ); } function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) { $tortoise = $start; $hare = $start; $evanescent_hare = $start; $return = array(); while ( $tortoise && ( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) ) && ( $hare = isset( $override[ $evanescent_hare ] ) ? $override[ $evanescent_hare ] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) ) ) { if ( $_return_loop ) { $return[ $tortoise ] = true; $return[ $evanescent_hare ] = true; $return[ $hare ] = true; } if ( $tortoise === $evanescent_hare || $tortoise === $hare ) { return $_return_loop ? $return : $tortoise; } $tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) ); } return false; } function send_frame_options_header() { if ( ! headers_sent() ) { header( 'X-Frame-Options: SAMEORIGIN' ); header( "Content-Security-Policy: frame-ancestors 'self';" ); } } function wp_admin_headers() { $policy = 'strict-origin-when-cross-origin'; $policy = apply_filters( 'admin_referrer_policy', $policy ); header( sprintf( 'Referrer-Policy: %s', $policy ) ); } function wp_allowed_protocols() { static $protocols = array(); if ( empty( $protocols ) ) { $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'irc6', 'ircs', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' ); } if ( ! did_action( 'wp_loaded' ) ) { $protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) ); } return $protocols; } function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) { static $truncate_paths; $trace = debug_backtrace( false ); $caller = array(); $check_class = ! is_null( $ignore_class ); ++$skip_frames; if ( ! isset( $truncate_paths ) ) { $truncate_paths = array( wp_normalize_path( WP_CONTENT_DIR ), wp_normalize_path( ABSPATH ), ); } foreach ( $trace as $call ) { if ( $skip_frames > 0 ) { --$skip_frames; } elseif ( isset( $call['class'] ) ) { if ( $check_class && $ignore_class === $call['class'] ) { continue; } $caller[] = "{$call['class']}{$call['type']}{$call['function']}"; } else { if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ), true ) ) { $caller[] = "{$call['function']}('{$call['args'][0]}')"; } elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ), true ) ) { $filename = isset( $call['args'][0] ) ? $call['args'][0] : ''; $caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')"; } else { $caller[] = $call['function']; } } } if ( $pretty ) { return implode( ', ', array_reverse( $caller ) ); } else { return $caller; } } function _get_non_cached_ids( $object_ids, $cache_group ) { $object_ids = array_filter( $object_ids, '_validate_cache_id' ); $object_ids = array_unique( array_map( 'intval', $object_ids ), SORT_NUMERIC ); if ( empty( $object_ids ) ) { return array(); } $non_cached_ids = array(); $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); foreach ( $cache_values as $id => $value ) { if ( false === $value ) { $non_cached_ids[] = (int) $id; } } return $non_cached_ids; } function _validate_cache_id( $object_id ) { if ( is_int( $object_id ) || ( is_string( $object_id ) && (string) (int) $object_id === $object_id ) ) { return true; } $message = sprintf( __( 'Object ID must be an integer, %s given.' ), gettype( $object_id ) ); _doing_it_wrong( '_get_non_cached_ids', $message, '6.3.0' ); return false; } function _device_can_upload() { if ( ! wp_is_mobile() ) { return true; } $ua = $_SERVER['HTTP_USER_AGENT']; if ( str_contains( $ua, 'iPhone' ) || str_contains( $ua, 'iPad' ) || str_contains( $ua, 'iPod' ) ) { return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' ); } return true; } function wp_is_stream( $path ) { $scheme_separator = strpos( $path, '://' ); if ( false === $scheme_separator ) { return false; } $stream = substr( $path, 0, $scheme_separator ); return in_array( $stream, stream_get_wrappers(), true ); } function wp_checkdate( $month, $day, $year, $source_date ) { $checkdate = false; if ( is_numeric( $month ) && is_numeric( $day ) && is_numeric( $year ) ) { $checkdate = checkdate( (int) $month, (int) $day, (int) $year ); } return apply_filters( 'wp_checkdate', $checkdate, $source_date ); } function wp_auth_check_load() { if ( ! is_admin() && ! is_user_logged_in() ) { return; } if ( defined( 'IFRAME_REQUEST' ) ) { return; } $screen = get_current_screen(); $hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' ); $show = ! in_array( $screen->id, $hidden, true ); if ( apply_filters( 'wp_auth_check_load', $show, $screen ) ) { wp_enqueue_style( 'wp-auth-check' ); wp_enqueue_script( 'wp-auth-check' ); add_action( 'admin_print_footer_scripts', 'wp_auth_check_html', 5 ); add_action( 'wp_print_footer_scripts', 'wp_auth_check_html', 5 ); } } function wp_auth_check_html() { $login_url = wp_login_url(); $current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST']; $same_domain = str_starts_with( $login_url, $current_domain ); $same_domain = apply_filters( 'wp_auth_check_same_domain', $same_domain ); $wrap_class = $same_domain ? 'hidden' : 'hidden fallback'; ?>
<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
<div id="wp-auth-check-bg"></div>
<div id="wp-auth-check">
<button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text">
<?php
_e( 'Close dialog' ); ?>
</span></button>
<?php
if ( $same_domain ) { $login_src = add_query_arg( array( 'interim-login' => '1', 'wp_lang' => get_user_locale(), ), $login_url ); ?>
<div id="wp-auth-check-form" class="loading" data-src="<?php echo esc_url( $login_src ); ?>"></div>
<?php
} ?>
<div class="wp-auth-fallback">
<p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e( 'Session expired' ); ?></b></p>
<p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e( 'Please log in again.' ); ?></a>
<?php _e( 'The login page will open in a new tab. After logging in you can close it and return to this page.' ); ?></p>
</div>
</div>
</div>
<?php
} function wp_auth_check( $response ) { $response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] ); return $response; } function get_tag_regex( $tag ) { if ( empty( $tag ) ) { return ''; } return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) ); } function is_utf8_charset( $blog_charset = null ) { return _is_utf8_charset( $blog_charset ?? get_option( 'blog_charset' ) ); } function _canonical_charset( $charset ) { if ( is_utf8_charset( $charset ) ) { return 'UTF-8'; } if ( ( 0 === strcasecmp( 'iso-8859-1', $charset ) ) || ( 0 === strcasecmp( 'iso8859-1', $charset ) ) ) { return 'ISO-8859-1'; } return $charset; } function mbstring_binary_safe_encoding( $reset = false ) { static $encodings = array(); static $overloaded = null; if ( is_null( $overloaded ) ) { if ( function_exists( 'mb_internal_encoding' ) && ( (int) ini_get( 'mbstring.func_overload' ) & 2 ) ) { $overloaded = true; } else { $overloaded = false; } } if ( false === $overloaded ) { return; } if ( ! $reset ) { $encoding = mb_internal_encoding(); array_push( $encodings, $encoding ); mb_internal_encoding( 'ISO-8859-1' ); } if ( $reset && $encodings ) { $encoding = array_pop( $encodings ); mb_internal_encoding( $encoding ); } } function reset_mbstring_encoding() { mbstring_binary_safe_encoding( true ); } function wp_validate_boolean( $value ) { if ( is_bool( $value ) ) { return $value; } if ( is_string( $value ) && 'false' === strtolower( $value ) ) { return false; } return (bool) $value; } function wp_delete_file( $file ) { $delete = apply_filters( 'wp_delete_file', $file ); if ( ! empty( $delete ) ) { return @unlink( $delete ); } return false; } function wp_delete_file_from_directory( $file, $directory ) { if ( wp_is_stream( $file ) ) { $real_file = $file; $real_directory = $directory; } else { $real_file = realpath( wp_normalize_path( $file ) ); $real_directory = realpath( wp_normalize_path( $directory ) ); } if ( false !== $real_file ) { $real_file = wp_normalize_path( $real_file ); } if ( false !== $real_directory ) { $real_directory = wp_normalize_path( $real_directory ); } if ( false === $real_file || false === $real_directory || ! str_starts_with( $real_file, trailingslashit( $real_directory ) ) ) { return false; } return wp_delete_file( $file ); } function wp_post_preview_js() { global $post; if ( ! is_preview() || empty( $post ) ) { return; } $name = 'wp-preview-' . (int) $post->ID; ob_start(); ?>
<script>
( function() {
var query = document.location.search;
if ( query && query.indexOf( 'preview=true' ) !== -1 ) {
window.name = '<?php echo $name; ?>';
}
if ( window.addEventListener ) {
window.addEventListener( 'pagehide', function() { window.name = ''; } );
}
}());
//# sourceURL=<?php echo rawurlencode( __FUNCTION__ ); ?>
</script>
<?php
wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) ); } function mysql_to_rfc3339( $date_string ) { return mysql2date( 'Y-m-d\TH:i:s', $date_string, false ); } function wp_raise_memory_limit( $context = 'admin' ) { if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) { return false; } $current_limit = ini_get( 'memory_limit' ); $current_limit_int = wp_convert_hr_to_bytes( $current_limit ); if ( -1 === $current_limit_int ) { return false; } $wp_max_limit = WP_MAX_MEMORY_LIMIT; $wp_max_limit_int = wp_convert_hr_to_bytes( $wp_max_limit ); $filtered_limit = $wp_max_limit; switch ( $context ) { case 'admin': $filtered_limit = apply_filters( 'admin_memory_limit', $filtered_limit ); break; case 'image': $filtered_limit = apply_filters( 'image_memory_limit', $filtered_limit ); break; case 'cron': $filtered_limit = apply_filters( 'cron_memory_limit', $filtered_limit ); break; default: $filtered_limit = apply_filters( "{$context}_memory_limit", $filtered_limit ); break; } $filtered_limit_int = wp_convert_hr_to_bytes( $filtered_limit ); if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) { if ( false !== ini_set( 'memory_limit', $filtered_limit ) ) { return $filtered_limit; } else { return false; } } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) { if ( false !== ini_set( 'memory_limit', $wp_max_limit ) ) { return $wp_max_limit; } else { return false; } } return false; } function wp_generate_uuid4() { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); } function wp_is_uuid( $uuid, $version = null ) { if ( ! is_string( $uuid ) ) { return false; } if ( is_numeric( $version ) ) { if ( 4 !== (int) $version ) { _doing_it_wrong( __FUNCTION__, __( 'Only UUID V4 is supported at this time.' ), '4.9.0' ); return false; } $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; } else { $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/'; } return (bool) preg_match( $regex, $uuid ); } function wp_unique_id( $prefix = '' ) { static $id_counter = 0; return $prefix . (string) ++$id_counter; } function wp_unique_prefixed_id( $prefix = '' ) { static $id_counters = array(); if ( ! is_string( $prefix ) ) { wp_trigger_error( __FUNCTION__, sprintf( 'The prefix must be a string. "%s" data type given.', gettype( $prefix ) ) ); $prefix = ''; } if ( ! isset( $id_counters[ $prefix ] ) ) { $id_counters[ $prefix ] = 0; } $id = ++$id_counters[ $prefix ]; return $prefix . (string) $id; } function wp_unique_id_from_values( array $data, string $prefix = '' ): string { if ( empty( $data ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s parameter must not be empty.' ), '$data' ), '6.8.0' ); } $serialized = wp_json_encode( $data ); $hash = substr( md5( $serialized ), 0, 8 ); return $prefix . $hash; } function wp_cache_get_last_changed( $group ) { $last_changed = wp_cache_get( 'last_changed', $group ); if ( $last_changed ) { return $last_changed; } return wp_cache_set_last_changed( $group ); } function wp_cache_set_last_changed( $group ) { $previous_time = wp_cache_get( 'last_changed', $group ); $time = microtime(); wp_cache_set( 'last_changed', $time, $group ); do_action( 'wp_cache_set_last_changed', $group, $time, $previous_time ); return $time; } function wp_site_admin_email_change_notification( $old_email, $new_email, $option_name ) { $send = true; if ( empty( $old_email ) || 'you@example.com' === $old_email ) { $send = false; } $send = apply_filters( 'send_site_admin_email_change_email', $send, $old_email, $new_email ); if ( ! $send ) { return; } $email_change_text = __( 'Hi,
This notice confirms that the admin email address was changed on ###SITENAME###.
The new admin email address is ###NEW_EMAIL###.
This email has been sent to ###OLD_EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $email_change_email = array( 'to' => $old_email, 'subject' => __( '[%s] Admin Email Changed' ), 'message' => $email_change_text, 'headers' => '', ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email ); $email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITENAME###', $site_name, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] ); wp_mail( $email_change_email['to'], sprintf( $email_change_email['subject'], $site_name ), $email_change_email['message'], $email_change_email['headers'] ); } function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) { if ( empty( $ip_addr ) ) { return '0.0.0.0'; } $ip_prefix = ''; $is_ipv6 = substr_count( $ip_addr, ':' ) > 1; $is_ipv4 = ( 3 === substr_count( $ip_addr, '.' ) ); if ( $is_ipv6 && $is_ipv4 ) { $ip_prefix = '::ffff:'; $ip_addr = preg_replace( '/^\[?[0-9a-f:]*:/i', '', $ip_addr ); $ip_addr = str_replace( ']', '', $ip_addr ); $is_ipv6 = false; } if ( $is_ipv6 ) { $left_bracket = strpos( $ip_addr, '[' ); $right_bracket = strpos( $ip_addr, ']' ); $percent = strpos( $ip_addr, '%' ); $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000'; if ( false !== $left_bracket && false !== $right_bracket ) { $ip_addr = substr( $ip_addr, $left_bracket + 1, $right_bracket - $left_bracket - 1 ); } elseif ( false !== $left_bracket || false !== $right_bracket ) { return '::'; } if ( false !== $percent ) { $ip_addr = substr( $ip_addr, 0, $percent ); } if ( preg_match( '/[^0-9a-f:]/i', $ip_addr ) ) { return '::'; } if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) { $ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) ); if ( false === $ip_addr ) { return '::'; } } elseif ( ! $ipv6_fallback ) { return '::'; } } elseif ( $is_ipv4 ) { $last_octet_position = strrpos( $ip_addr, '.' ); $ip_addr = substr( $ip_addr, 0, $last_octet_position ) . '.0'; } else { return '0.0.0.0'; } return $ip_prefix . $ip_addr; } function wp_privacy_anonymize_data( $type, $data = '' ) { switch ( $type ) { case 'email': $anonymous = 'deleted@site.invalid'; break; case 'url': $anonymous = 'https://site.invalid'; break; case 'ip': $anonymous = wp_privacy_anonymize_ip( $data ); break; case 'date': $anonymous = '0000-00-00 00:00:00'; break; case 'text': $anonymous = __( '[deleted]' ); break; case 'longtext': $anonymous = __( 'This content was deleted by the author.' ); break; default: $anonymous = ''; break; } return apply_filters( 'wp_privacy_anonymize_data', $anonymous, $type, $data ); } function wp_privacy_exports_dir() { $upload_dir = wp_upload_dir(); $exports_dir = trailingslashit( $upload_dir['basedir'] ) . 'wp-personal-data-exports/'; return apply_filters( 'wp_privacy_exports_dir', $exports_dir ); } function wp_privacy_exports_url() { $upload_dir = wp_upload_dir(); $exports_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-personal-data-exports/'; return apply_filters( 'wp_privacy_exports_url', $exports_url ); } function wp_schedule_delete_old_privacy_export_files() { if ( wp_installing() ) { return; } if ( ! wp_next_scheduled( 'wp_privacy_delete_old_export_files' ) ) { wp_schedule_event( time(), 'hourly', 'wp_privacy_delete_old_export_files' ); } } function wp_privacy_delete_old_export_files() { $exports_dir = wp_privacy_exports_dir(); if ( ! is_dir( $exports_dir ) ) { return; } require_once ABSPATH . 'wp-admin/includes/file.php'; $export_files = list_files( $exports_dir, 100, array( 'index.php' ) ); $expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS ); foreach ( (array) $export_files as $export_file ) { $file_age_in_seconds = time() - filemtime( $export_file ); if ( $expiration < $file_age_in_seconds ) { unlink( $export_file ); } } } function wp_get_update_php_url() { $default_url = wp_get_default_update_php_url(); $update_url = $default_url; if ( false !== getenv( 'WP_UPDATE_PHP_URL' ) ) { $update_url = getenv( 'WP_UPDATE_PHP_URL' ); } $update_url = apply_filters( 'wp_update_php_url', $update_url ); if ( empty( $update_url ) ) { $update_url = $default_url; } return $update_url; } function wp_get_default_update_php_url() { return _x( 'https://wordpress.org/support/update-php/', 'localized PHP upgrade information page' ); } function wp_update_php_annotation( $before = '<p class="description">', $after = '</p>', $display = true ) { $annotation = wp_get_update_php_annotation(); if ( $annotation ) { if ( $display ) { echo $before . $annotation . $after; } else { return $before . $annotation . $after; } } } function wp_get_update_php_annotation() { $update_url = wp_get_update_php_url(); $default_url = wp_get_default_update_php_url(); if ( $update_url === $default_url ) { return ''; } $annotation = sprintf( __( 'This resource is provided by your web host, and is specific to your site. For more information, <a href="%s" target="_blank">see the official WordPress documentation</a>.' ), esc_url( $default_url ) ); return $annotation; } function wp_get_direct_php_update_url() { $direct_update_url = ''; if ( false !== getenv( 'WP_DIRECT_UPDATE_PHP_URL' ) ) { $direct_update_url = getenv( 'WP_DIRECT_UPDATE_PHP_URL' ); } $direct_update_url = apply_filters( 'wp_direct_php_update_url', $direct_update_url ); return $direct_update_url; } function wp_direct_php_update_button() { $direct_update_url = wp_get_direct_php_update_url(); if ( empty( $direct_update_url ) ) { return; } echo '<p class="button-container">'; printf( '<a class="button button-primary" href="%1$s" target="_blank">%2$s<span class="screen-reader-text"> %3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>', esc_url( $direct_update_url ), __( 'Update PHP' ), __( '(opens in a new tab)' ) ); echo '</p>'; } function wp_get_update_https_url() { $default_url = wp_get_default_update_https_url(); $update_url = $default_url; if ( false !== getenv( 'WP_UPDATE_HTTPS_URL' ) ) { $update_url = getenv( 'WP_UPDATE_HTTPS_URL' ); } $update_url = apply_filters( 'wp_update_https_url', $update_url ); if ( empty( $update_url ) ) { $update_url = $default_url; } return $update_url; } function wp_get_default_update_https_url() { return __( 'https://developer.wordpress.org/advanced-administration/security/https/' ); } function wp_get_direct_update_https_url() { $direct_update_url = ''; if ( false !== getenv( 'WP_DIRECT_UPDATE_HTTPS_URL' ) ) { $direct_update_url = getenv( 'WP_DIRECT_UPDATE_HTTPS_URL' ); } $direct_update_url = apply_filters( 'wp_direct_update_https_url', $direct_update_url ); return $direct_update_url; } function get_dirsize( $directory, $max_execution_time = null ) { if ( is_multisite() && is_main_site() ) { $size = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time ); } else { $size = recurse_dirsize( $directory, null, $max_execution_time ); } return $size; } function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) { $directory = untrailingslashit( $directory ); $save_cache = false; if ( ! isset( $directory_cache ) ) { $directory_cache = get_transient( 'dirsize_cache' ); $save_cache = true; } if ( isset( $directory_cache[ $directory ] ) && is_int( $directory_cache[ $directory ] ) ) { return $directory_cache[ $directory ]; } if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) { return false; } if ( ( is_string( $exclude ) && $directory === $exclude ) || ( is_array( $exclude ) && in_array( $directory, $exclude, true ) ) ) { return false; } if ( null === $max_execution_time ) { if ( function_exists( 'ini_get' ) ) { $max_execution_time = ini_get( 'max_execution_time' ); } else { $max_execution_time = 0; } if ( $max_execution_time > 10 ) { $max_execution_time -= 1; } } $size = apply_filters( 'pre_recurse_dirsize', false, $directory, $exclude, $max_execution_time, $directory_cache ); if ( false === $size ) { $size = 0; $handle = opendir( $directory ); if ( $handle ) { while ( ( $file = readdir( $handle ) ) !== false ) { $path = $directory . '/' . $file; if ( '.' !== $file && '..' !== $file ) { if ( is_file( $path ) ) { $size += filesize( $path ); } elseif ( is_dir( $path ) ) { $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time, $directory_cache ); if ( $handlesize > 0 ) { $size += $handlesize; } } if ( $max_execution_time > 0 && ( microtime( true ) - WP_START_TIMESTAMP ) > $max_execution_time ) { $size = null; break; } } } closedir( $handle ); } } if ( ! is_array( $directory_cache ) ) { $directory_cache = array(); } $directory_cache[ $directory ] = $size; if ( $save_cache ) { $expiration = ( wp_using_ext_object_cache() ) ? 0 : 10 * YEAR_IN_SECONDS; set_transient( 'dirsize_cache', $directory_cache, $expiration ); } return $size; } function clean_dirsize_cache( $path ) { if ( ! is_string( $path ) || empty( $path ) ) { wp_trigger_error( '', sprintf( __( '%1$s only accepts a non-empty path string, received %2$s.' ), '<code>clean_dirsize_cache()</code>', '<code>' . gettype( $path ) . '</code>' ) ); return; } $directory_cache = get_transient( 'dirsize_cache' ); if ( empty( $directory_cache ) ) { return; } $expiration = ( wp_using_ext_object_cache() ) ? 0 : 10 * YEAR_IN_SECONDS; if ( ! str_contains( $path, '/' ) && ! str_contains( $path, '\\' ) ) { unset( $directory_cache[ $path ] ); set_transient( 'dirsize_cache', $directory_cache, $expiration ); return; } $last_path = null; $path = untrailingslashit( $path ); unset( $directory_cache[ $path ] ); while ( $last_path !== $path && DIRECTORY_SEPARATOR !== $path && '.' !== $path && '..' !== $path ) { $last_path = $path; $path = dirname( $path ); unset( $directory_cache[ $path ] ); } set_transient( 'dirsize_cache', $directory_cache, $expiration ); } function wp_get_wp_version() { static $wp_version; if ( ! isset( $wp_version ) ) { require ABSPATH . WPINC . '/version.php'; } return $wp_version; } function is_wp_version_compatible( $required ) { if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS && isset( $GLOBALS['_wp_tests_wp_version'] ) ) { $wp_version = $GLOBALS['_wp_tests_wp_version']; } else { $wp_version = wp_get_wp_version(); } list( $version ) = explode( '-', $wp_version ); if ( is_string( $required ) ) { $trimmed = trim( $required ); if ( substr_count( $trimmed, '.' ) > 1 && str_ends_with( $trimmed, '.0' ) ) { $required = substr( $trimmed, 0, -2 ); } } return empty( $required ) || version_compare( $version, $required, '>=' ); } function is_php_version_compatible( $required ) { return empty( $required ) || version_compare( PHP_VERSION, $required, '>=' ); } function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { return abs( (float) $expected - (float) $actual ) <= $precision; } function wp_get_admin_notice( $message, $args = array() ) { $defaults = array( 'type' => '', 'dismissible' => false, 'id' => '', 'additional_classes' => array(), 'attributes' => array(), 'paragraph_wrap' => true, ); $args = wp_parse_args( $args, $defaults ); $args = apply_filters( 'wp_admin_notice_args', $args, $message ); $id = ''; $classes = 'notice'; $attributes = ''; if ( is_string( $args['id'] ) ) { $trimmed_id = trim( $args['id'] ); if ( '' !== $trimmed_id ) { $id = 'id="' . $trimmed_id . '" '; } } if ( is_string( $args['type'] ) ) { $type = trim( $args['type'] ); if ( str_contains( $type, ' ' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s key must be a string without spaces.' ), '<code>type</code>' ), '6.4.0' ); } if ( '' !== $type ) { $classes .= ' notice-' . $type; } } if ( true === $args['dismissible'] ) { $classes .= ' is-dismissible'; } if ( is_array( $args['additional_classes'] ) && ! empty( $args['additional_classes'] ) ) { $classes .= ' ' . implode( ' ', $args['additional_classes'] ); } if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) { $attributes = ''; foreach ( $args['attributes'] as $attr => $val ) { if ( is_bool( $val ) ) { $attributes .= $val ? ' ' . $attr : ''; } elseif ( is_int( $attr ) ) { $attributes .= ' ' . esc_attr( trim( $val ) ); } elseif ( $val ) { $attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"'; } } } if ( false !== $args['paragraph_wrap'] ) { $message = "<p>$message</p>"; } $markup = sprintf( '<div %1$sclass="%2$s"%3$s>%4$s</div>', $id, $classes, $attributes, $message ); return apply_filters( 'wp_admin_notice_markup', $markup, $message, $args ); } function wp_admin_notice( $message, $args = array() ) { do_action( 'wp_admin_notice', $message, $args ); echo wp_kses_post( wp_get_admin_notice( $message, $args ) ); } function wp_is_heic_image_mime_type( $mime_type ) { $heic_mime_types = array( 'image/heic', 'image/heif', 'image/heic-sequence', 'image/heif-sequence', ); return in_array( $mime_type, $heic_mime_types, true ); } function wp_fast_hash( string $message ): string { $hashed = sodium_crypto_generichash( $message, 'wp_fast_hash_6.8+', 30 ); return '$generic$' . sodium_bin2base64( $hashed, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING ); } function wp_verify_fast_hash( string $message, string $hash ): bool { if ( ! str_starts_with( $hash, '$generic$' ) ) { require_once ABSPATH . WPINC . '/class-phpass.php'; return ( new PasswordHash( 8, true ) )->CheckPassword( $message, $hash ); } return hash_equals( $hash, wp_fast_hash( $message ) ); }
###require ABSPATH . WPINC . '/class-wp-meta-query.php';
class WP_Meta_Query { public $queries = array(); public $relation; public $meta_table; public $meta_id_column; public $primary_table; public $primary_id_column; protected $table_aliases = array(); protected $clauses = array(); protected $has_or_relation = false; public function __construct( $meta_query = array() ) { if ( ! $meta_query ) { return; } if ( isset( $meta_query['relation'] ) && 'OR' === strtoupper( $meta_query['relation'] ) ) { $this->relation = 'OR'; } else { $this->relation = 'AND'; } $this->queries = $this->sanitize_query( $meta_query ); } public function sanitize_query( $queries ) { $clean_queries = array(); if ( ! is_array( $queries ) ) { return $clean_queries; } foreach ( $queries as $key => $query ) { if ( 'relation' === $key ) { $relation = $query; } elseif ( ! is_array( $query ) ) { continue; } elseif ( $this->is_first_order_clause( $query ) ) { if ( isset( $query['value'] ) && array() === $query['value'] ) { unset( $query['value'] ); } $clean_queries[ $key ] = $query; } else { $cleaned_query = $this->sanitize_query( $query ); if ( ! empty( $cleaned_query ) ) { $clean_queries[ $key ] = $cleaned_query; } } } if ( empty( $clean_queries ) ) { return $clean_queries; } if ( isset( $relation ) && 'OR' === strtoupper( $relation ) ) { $clean_queries['relation'] = 'OR'; $this->has_or_relation = true; } elseif ( 1 === count( $clean_queries ) ) { $clean_queries['relation'] = 'OR'; } else { $clean_queries['relation'] = 'AND'; } return $clean_queries; } protected function is_first_order_clause( $query ) { return isset( $query['key'] ) || isset( $query['value'] ); } public function parse_query_vars( $qv ) { $meta_query = array(); $primary_meta_query = array(); foreach ( array( 'key', 'compare', 'type', 'compare_key', 'type_key' ) as $key ) { if ( ! empty( $qv[ "meta_$key" ] ) ) { $primary_meta_query[ $key ] = $qv[ "meta_$key" ]; } } if ( isset( $qv['meta_value'] ) && '' !== $qv['meta_value'] && ( ! is_array( $qv['meta_value'] ) || $qv['meta_value'] ) ) { $primary_meta_query['value'] = $qv['meta_value']; } $existing_meta_query = isset( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ? $qv['meta_query'] : array(); if ( ! empty( $primary_meta_query ) && ! empty( $existing_meta_query ) ) { $meta_query = array( 'relation' => 'AND', $primary_meta_query, $existing_meta_query, ); } elseif ( ! empty( $primary_meta_query ) ) { $meta_query = array( $primary_meta_query, ); } elseif ( ! empty( $existing_meta_query ) ) { $meta_query = $existing_meta_query; } $this->__construct( $meta_query ); } public function get_cast_for_type( $type = '' ) { if ( empty( $type ) ) { return 'CHAR'; } $meta_type = strtoupper( $type ); if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) ) { return 'CHAR'; } if ( 'NUMERIC' === $meta_type ) { $meta_type = 'SIGNED'; } return $meta_type; } public function get_sql( $type, $primary_table, $primary_id_column, $context = null ) { $meta_table = _get_meta_table( $type ); if ( ! $meta_table ) { return false; } $this->table_aliases = array(); $this->meta_table = $meta_table; $this->meta_id_column = sanitize_key( $type . '_id' ); $this->primary_table = $primary_table; $this->primary_id_column = $primary_id_column; $sql = $this->get_sql_clauses(); if ( str_contains( $sql['join'], 'LEFT JOIN' ) ) { $sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] ); } return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) ); } protected function get_sql_clauses() { $queries = $this->queries; $sql = $this->get_sql_for_query( $queries ); if ( ! empty( $sql['where'] ) ) { $sql['where'] = ' AND ' . $sql['where']; } return $sql; } protected function get_sql_for_query( &$query, $depth = 0 ) { $sql_chunks = array( 'join' => array(), 'where' => array(), ); $sql = array( 'join' => '', 'where' => '', ); $indent = ''; for ( $i = 0; $i < $depth; $i++ ) { $indent .= ' '; } foreach ( $query as $key => &$clause ) { if ( 'relation' === $key ) { $relation = $query['relation']; } elseif ( is_array( $clause ) ) { if ( $this->is_first_order_clause( $clause ) ) { $clause_sql = $this->get_sql_for_clause( $clause, $query, $key ); $where_count = count( $clause_sql['where'] ); if ( ! $where_count ) { $sql_chunks['where'][] = ''; } elseif ( 1 === $where_count ) { $sql_chunks['where'][] = $clause_sql['where'][0]; } else { $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; } $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); } else { $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); $sql_chunks['where'][] = $clause_sql['where']; $sql_chunks['join'][] = $clause_sql['join']; } } } $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); if ( empty( $relation ) ) { $relation = 'AND'; } if ( ! empty( $sql_chunks['join'] ) ) { $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); } if ( ! empty( $sql_chunks['where'] ) ) { $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; } return $sql; } public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) { global $wpdb; $sql_chunks = array( 'where' => array(), 'join' => array(), ); if ( isset( $clause['compare'] ) ) { $clause['compare'] = strtoupper( $clause['compare'] ); } else { $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '='; } $non_numeric_operators = array( '=', '!=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'EXISTS', 'NOT EXISTS', 'RLIKE', 'REGEXP', 'NOT REGEXP', ); $numeric_operators = array( '>', '>=', '<', '<=', 'BETWEEN', 'NOT BETWEEN', ); if ( ! in_array( $clause['compare'], $non_numeric_operators, true ) && ! in_array( $clause['compare'], $numeric_operators, true ) ) { $clause['compare'] = '='; } if ( isset( $clause['compare_key'] ) ) { $clause['compare_key'] = strtoupper( $clause['compare_key'] ); } else { $clause['compare_key'] = isset( $clause['key'] ) && is_array( $clause['key'] ) ? 'IN' : '='; } if ( ! in_array( $clause['compare_key'], $non_numeric_operators, true ) ) { $clause['compare_key'] = '='; } $meta_compare = $clause['compare']; $meta_compare_key = $clause['compare_key']; $join = ''; $alias = $this->find_compatible_table_alias( $clause, $parent_query ); if ( false === $alias ) { $i = count( $this->table_aliases ); $alias = $i ? 'mt' . $i : $this->meta_table; if ( 'NOT EXISTS' === $meta_compare ) { $join .= " LEFT JOIN $this->meta_table"; $join .= $i ? " AS $alias" : ''; if ( 'LIKE' === $meta_compare_key ) { $join .= $wpdb->prepare( " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key LIKE %s )", '%' . $wpdb->esc_like( $clause['key'] ) . '%' ); } else { $join .= $wpdb->prepare( " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key = %s )", $clause['key'] ); } } else { $join .= " INNER JOIN $this->meta_table"; $join .= $i ? " AS $alias" : ''; $join .= " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column )"; } $this->table_aliases[] = $alias; $sql_chunks['join'][] = $join; } $clause['alias'] = $alias; $_meta_type = isset( $clause['type'] ) ? $clause['type'] : ''; $meta_type = $this->get_cast_for_type( $_meta_type ); $clause['cast'] = $meta_type; if ( is_int( $clause_key ) || ! $clause_key ) { $clause_key = $clause['alias']; } $iterator = 1; $clause_key_base = $clause_key; while ( isset( $this->clauses[ $clause_key ] ) ) { $clause_key = $clause_key_base . '-' . $iterator; ++$iterator; } $this->clauses[ $clause_key ] =& $clause; if ( array_key_exists( 'key', $clause ) ) { if ( 'NOT EXISTS' === $meta_compare ) { $sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL'; } else { if ( in_array( $meta_compare_key, array( '!=', 'NOT IN', 'NOT LIKE', 'NOT EXISTS', 'NOT REGEXP' ), true ) ) { $i = count( $this->table_aliases ); $subquery_alias = $i ? 'mt' . $i : $this->meta_table; $this->table_aliases[] = $subquery_alias; $meta_compare_string_start = 'NOT EXISTS ('; $meta_compare_string_start .= "SELECT 1 FROM $wpdb->postmeta $subquery_alias "; $meta_compare_string_start .= "WHERE $subquery_alias.post_ID = $alias.post_ID "; $meta_compare_string_end = 'LIMIT 1'; $meta_compare_string_end .= ')'; } switch ( $meta_compare_key ) { case '=': case 'EXISTS': $where = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) ); break; case 'LIKE': $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%'; $where = $wpdb->prepare( "$alias.meta_key LIKE %s", $meta_compare_value ); break; case 'IN': $meta_compare_string = "$alias.meta_key IN (" . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ')'; $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); break; case 'RLIKE': case 'REGEXP': $operator = $meta_compare_key; if ( isset( $clause['type_key'] ) && 'BINARY' === strtoupper( $clause['type_key'] ) ) { $cast = 'BINARY'; $meta_key = "CAST($alias.meta_key AS BINARY)"; } else { $cast = ''; $meta_key = "$alias.meta_key"; } $where = $wpdb->prepare( "$meta_key $operator $cast %s", trim( $clause['key'] ) ); break; case '!=': case 'NOT EXISTS': $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key = %s " . $meta_compare_string_end; $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); break; case 'NOT LIKE': $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key LIKE %s " . $meta_compare_string_end; $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%'; $where = $wpdb->prepare( $meta_compare_string, $meta_compare_value ); break; case 'NOT IN': $array_subclause = '(' . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ') '; $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key IN " . $array_subclause . $meta_compare_string_end; $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); break; case 'NOT REGEXP': $operator = $meta_compare_key; if ( isset( $clause['type_key'] ) && 'BINARY' === strtoupper( $clause['type_key'] ) ) { $cast = 'BINARY'; $meta_key = "CAST($subquery_alias.meta_key AS BINARY)"; } else { $cast = ''; $meta_key = "$subquery_alias.meta_key"; } $meta_compare_string = $meta_compare_string_start . "AND $meta_key REGEXP $cast %s " . $meta_compare_string_end; $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); break; } $sql_chunks['where'][] = $where; } } if ( array_key_exists( 'value', $clause ) ) { $meta_value = $clause['value']; if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) { if ( ! is_array( $meta_value ) ) { $meta_value = preg_split( '/[,\s]+/', $meta_value ); } } elseif ( is_string( $meta_value ) ) { $meta_value = trim( $meta_value ); } switch ( $meta_compare ) { case 'IN': case 'NOT IN': $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')'; $where = $wpdb->prepare( $meta_compare_string, $meta_value ); break; case 'BETWEEN': case 'NOT BETWEEN': $where = $wpdb->prepare( '%s AND %s', $meta_value[0], $meta_value[1] ); break; case 'LIKE': case 'NOT LIKE': $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%'; $where = $wpdb->prepare( '%s', $meta_value ); break; case 'EXISTS': $meta_compare = '='; $where = $wpdb->prepare( '%s', $meta_value ); break; case 'NOT EXISTS': $where = ''; break; default: $where = $wpdb->prepare( '%s', $meta_value ); break; } if ( $where ) { if ( 'CHAR' === $meta_type ) { $sql_chunks['where'][] = "$alias.meta_value {$meta_compare} {$where}"; } else { $sql_chunks['where'][] = "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$where}"; } } } if ( 1 < count( $sql_chunks['where'] ) ) { $sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' ); } return $sql_chunks; } public function get_clauses() { return $this->clauses; } protected function find_compatible_table_alias( $clause, $parent_query ) { $alias = false; foreach ( $parent_query as $sibling ) { if ( empty( $sibling['alias'] ) ) { continue; } if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) { continue; } $compatible_compares = array(); if ( 'OR' === $parent_query['relation'] ) { $compatible_compares = array( '=', 'IN', 'BETWEEN', 'LIKE', 'REGEXP', 'RLIKE', '>', '>=', '<', '<=' ); } elseif ( isset( $sibling['key'] ) && isset( $clause['key'] ) && $sibling['key'] === $clause['key'] ) { $compatible_compares = array( '!=', 'NOT IN', 'NOT LIKE' ); } $clause_compare = strtoupper( $clause['compare'] ); $sibling_compare = strtoupper( $sibling['compare'] ); if ( in_array( $clause_compare, $compatible_compares, true ) && in_array( $sibling_compare, $compatible_compares, true ) ) { $alias = preg_replace( '/\W/', '_', $sibling['alias'] ); break; } } return apply_filters( 'meta_query_find_compatible_table_alias', $alias, $clause, $parent_query, $this ); } public function has_or_relation() { return $this->has_or_relation; } }
###require ABSPATH . WPINC . '/class-wp-matchesmapregex.php';
class WP_MatchesMapRegex { private $_matches; public $output; private $_subject; public $_pattern = '(\$matches\[[1-9]+[0-9]*\])'; public function __construct( $subject, $matches ) { $this->_subject = $subject; $this->_matches = $matches; $this->output = $this->_map(); } public static function apply( $subject, $matches ) { $result = new WP_MatchesMapRegex( $subject, $matches ); return $result->output; } private function _map() { $callback = array( $this, 'callback' ); return preg_replace_callback( $this->_pattern, $callback, $this->_subject ); } public function callback( $matches ) { $index = (int) substr( $matches[0], 9, -1 ); return ( isset( $this->_matches[ $index ] ) ? urlencode( $this->_matches[ $index ] ) : '' ); } }
###require ABSPATH . WPINC . '/class-wp.php';
class WP { public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'favicon', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' ); public $private_query_vars = array( 'offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in', 'post_parent', 'post_parent__in', 'post_parent__not_in', 'title', 'fields' ); public $extra_query_vars = array(); public $query_vars = array(); public $query_string = ''; public $request = ''; public $matched_rule = ''; public $matched_query = ''; public $did_permalink = false; public function add_query_var( $qv ) { if ( ! in_array( $qv, $this->public_query_vars, true ) ) { $this->public_query_vars[] = $qv; } } public function remove_query_var( $name ) { $this->public_query_vars = array_diff( $this->public_query_vars, array( $name ) ); } public function set_query_var( $key, $value ) { $this->query_vars[ $key ] = $value; } public function parse_request( $extra_query_vars = '' ) { global $wp_rewrite; if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) { return false; } $this->query_vars = array(); $post_type_query_vars = array(); if ( is_array( $extra_query_vars ) ) { $this->extra_query_vars = & $extra_query_vars; } elseif ( ! empty( $extra_query_vars ) ) { parse_str( $extra_query_vars, $this->extra_query_vars ); } $rewrite = $wp_rewrite->wp_rewrite_rules(); if ( ! empty( $rewrite ) ) { $error = '404'; $this->did_permalink = true; $pathinfo = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : ''; list( $pathinfo ) = explode( '?', $pathinfo ); $pathinfo = str_replace( '%', '%25', $pathinfo ); list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] ); $self = $_SERVER['PHP_SELF']; $home_path = parse_url( home_url(), PHP_URL_PATH ); $home_path_regex = ''; if ( is_string( $home_path ) && '' !== $home_path ) { $home_path = trim( $home_path, '/' ); $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) ); } $req_uri = str_replace( $pathinfo, '', $req_uri ); $req_uri = trim( $req_uri, '/' ); $pathinfo = trim( $pathinfo, '/' ); $self = trim( $self, '/' ); if ( ! empty( $home_path_regex ) ) { $req_uri = preg_replace( $home_path_regex, '', $req_uri ); $req_uri = trim( $req_uri, '/' ); $pathinfo = preg_replace( $home_path_regex, '', $pathinfo ); $pathinfo = trim( $pathinfo, '/' ); $self = preg_replace( $home_path_regex, '', $self ); $self = trim( $self, '/' ); } if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $wp_rewrite->index . '$|', $pathinfo ) ) { $requested_path = $pathinfo; } else { if ( $req_uri === $wp_rewrite->index ) { $req_uri = ''; } $requested_path = $req_uri; } $requested_file = $req_uri; $this->request = $requested_path; $request_match = $requested_path; if ( empty( $request_match ) ) { if ( isset( $rewrite['$'] ) ) { $this->matched_rule = '$'; $query = $rewrite['$']; $matches = array( '' ); } } else { foreach ( (array) $rewrite as $match => $query ) { if ( ! empty( $requested_file ) && str_starts_with( $match, $requested_file ) && $requested_file !== $requested_path ) { $request_match = $requested_file . '/' . $requested_path; } if ( preg_match( "#^$match#", $request_match, $matches ) || preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { $page = get_page_by_path( $matches[ $varmatch[1] ] ); if ( ! $page ) { continue; } $post_status_obj = get_post_status_object( $page->post_status ); if ( ! $post_status_obj->public && ! $post_status_obj->protected && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { continue; } } $this->matched_rule = $match; break; } } } if ( ! empty( $this->matched_rule ) ) { $query = preg_replace( '!^.+\?!', '', $query ); $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) ); $this->matched_query = $query; parse_str( $query, $perma_query_vars ); if ( '404' === $error ) { unset( $error, $_GET['error'] ); } } if ( empty( $requested_path ) || $requested_file === $self || str_contains( $_SERVER['PHP_SELF'], 'wp-admin/' ) ) { unset( $error, $_GET['error'] ); if ( isset( $perma_query_vars ) && str_contains( $_SERVER['PHP_SELF'], 'wp-admin/' ) ) { unset( $perma_query_vars ); } $this->did_permalink = false; } } $this->public_query_vars = apply_filters( 'query_vars', $this->public_query_vars ); foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) { if ( is_post_type_viewable( $t ) && $t->query_var ) { $post_type_query_vars[ $t->query_var ] = $post_type; } } foreach ( $this->public_query_vars as $wpvar ) { if ( isset( $this->extra_query_vars[ $wpvar ] ) ) { $this->query_vars[ $wpvar ] = $this->extra_query_vars[ $wpvar ]; } elseif ( isset( $_GET[ $wpvar ] ) && isset( $_POST[ $wpvar ] ) && $_GET[ $wpvar ] !== $_POST[ $wpvar ] ) { wp_die( __( 'A variable mismatch has been detected.' ), __( 'Sorry, you are not allowed to view this item.' ), 400 ); } elseif ( isset( $_POST[ $wpvar ] ) ) { $this->query_vars[ $wpvar ] = $_POST[ $wpvar ]; } elseif ( isset( $_GET[ $wpvar ] ) ) { $this->query_vars[ $wpvar ] = $_GET[ $wpvar ]; } elseif ( isset( $perma_query_vars[ $wpvar ] ) ) { $this->query_vars[ $wpvar ] = $perma_query_vars[ $wpvar ]; } if ( ! empty( $this->query_vars[ $wpvar ] ) ) { if ( ! is_array( $this->query_vars[ $wpvar ] ) ) { $this->query_vars[ $wpvar ] = (string) $this->query_vars[ $wpvar ]; } else { foreach ( $this->query_vars[ $wpvar ] as $vkey => $v ) { if ( is_scalar( $v ) ) { $this->query_vars[ $wpvar ][ $vkey ] = (string) $v; } } } if ( isset( $post_type_query_vars[ $wpvar ] ) ) { $this->query_vars['post_type'] = $post_type_query_vars[ $wpvar ]; $this->query_vars['name'] = $this->query_vars[ $wpvar ]; } } } foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) { if ( $t->query_var && isset( $this->query_vars[ $t->query_var ] ) ) { $this->query_vars[ $t->query_var ] = str_replace( ' ', '+', $this->query_vars[ $t->query_var ] ); } } if ( ! is_admin() ) { foreach ( get_taxonomies( array( 'publicly_queryable' => false ), 'objects' ) as $taxonomy => $t ) { if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) { unset( $this->query_vars['taxonomy'], $this->query_vars['term'] ); } } } if ( isset( $this->query_vars['post_type'] ) ) { $queryable_post_types = get_post_types( array( 'publicly_queryable' => true ) ); if ( ! is_array( $this->query_vars['post_type'] ) ) { if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types, true ) ) { unset( $this->query_vars['post_type'] ); } } else { $this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types ); } } $this->query_vars = wp_resolve_numeric_slug_conflicts( $this->query_vars ); foreach ( (array) $this->private_query_vars as $var ) { if ( isset( $this->extra_query_vars[ $var ] ) ) { $this->query_vars[ $var ] = $this->extra_query_vars[ $var ]; } } if ( isset( $error ) ) { $this->query_vars['error'] = $error; } $this->query_vars = apply_filters( 'request', $this->query_vars ); do_action_ref_array( 'parse_request', array( &$this ) ); return true; } public function send_headers() { global $wp_query; $headers = array(); $status = null; $exit_required = false; $date_format = 'D, d M Y H:i:s'; if ( is_user_logged_in() ) { $headers = array_merge( $headers, wp_get_nocache_headers() ); } elseif ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) { $expires = 10 * MINUTE_IN_SECONDS; $headers['Expires'] = gmdate( $date_format, time() + $expires ); $headers['Cache-Control'] = sprintf( 'max-age=%d, must-revalidate', $expires ); } if ( ! empty( $this->query_vars['error'] ) ) { $status = (int) $this->query_vars['error']; if ( 404 === $status ) { if ( ! is_user_logged_in() ) { $headers = array_merge( $headers, wp_get_nocache_headers() ); } $headers['Content-Type'] = get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ); } elseif ( in_array( $status, array( 403, 500, 502, 503 ), true ) ) { $exit_required = true; } } elseif ( empty( $this->query_vars['feed'] ) ) { $headers['Content-Type'] = get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ); } else { $type = $this->query_vars['feed']; if ( 'feed' === $this->query_vars['feed'] ) { $type = get_default_feed(); } $headers['Content-Type'] = feed_content_type( $type ) . '; charset=' . get_option( 'blog_charset' ); if ( ! empty( $this->query_vars['withcomments'] ) || str_contains( $this->query_vars['feed'], 'comments-' ) || ( empty( $this->query_vars['withoutcomments'] ) && ( ! empty( $this->query_vars['p'] ) || ! empty( $this->query_vars['name'] ) || ! empty( $this->query_vars['page_id'] ) || ! empty( $this->query_vars['pagename'] ) || ! empty( $this->query_vars['attachment'] ) || ! empty( $this->query_vars['attachment_id'] ) ) ) ) { $wp_last_modified_post = mysql2date( $date_format, get_lastpostmodified( 'GMT' ), false ); $wp_last_modified_comment = mysql2date( $date_format, get_lastcommentmodified( 'GMT' ), false ); if ( strtotime( $wp_last_modified_post ) > strtotime( $wp_last_modified_comment ) ) { $wp_last_modified = $wp_last_modified_post; } else { $wp_last_modified = $wp_last_modified_comment; } } else { $wp_last_modified = mysql2date( $date_format, get_lastpostmodified( 'GMT' ), false ); } if ( ! $wp_last_modified ) { $wp_last_modified = gmdate( $date_format ); } $wp_last_modified .= ' GMT'; $wp_etag = '"' . md5( $wp_last_modified ) . '"'; $headers['Last-Modified'] = $wp_last_modified; $headers['ETag'] = $wp_etag; if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) { $client_etag = wp_unslash( $_SERVER['HTTP_IF_NONE_MATCH'] ); } else { $client_etag = ''; } if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) { $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); } else { $client_last_modified = ''; } $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0; $wp_modified_timestamp = strtotime( $wp_last_modified ); if ( ( $client_last_modified && $client_etag ) ? ( ( $client_modified_timestamp >= $wp_modified_timestamp ) && ( $client_etag === $wp_etag ) ) : ( ( $client_modified_timestamp >= $wp_modified_timestamp ) || ( $client_etag === $wp_etag ) ) ) { $status = 304; $exit_required = true; } } if ( is_singular() ) { $post = isset( $wp_query->post ) ? $wp_query->post : null; if ( $post && pings_open( $post ) ) { $headers['X-Pingback'] = get_bloginfo( 'pingback_url', 'display' ); } if ( ! empty( $post->post_password ) ) { $headers = array_merge( $headers, wp_get_nocache_headers() ); } } $headers = apply_filters( 'wp_headers', $headers, $this ); if ( ! empty( $status ) ) { status_header( $status ); } if ( isset( $headers['Last-Modified'] ) && false === $headers['Last-Modified'] ) { unset( $headers['Last-Modified'] ); if ( ! headers_sent() ) { header_remove( 'Last-Modified' ); } } if ( ! headers_sent() ) { foreach ( (array) $headers as $name => $field_value ) { header( "{$name}: {$field_value}" ); } } if ( $exit_required ) { exit; } do_action_ref_array( 'send_headers', array( &$this ) ); } public function build_query_string() { $this->query_string = ''; foreach ( (array) array_keys( $this->query_vars ) as $wpvar ) { if ( '' !== $this->query_vars[ $wpvar ] ) { $this->query_string .= ( strlen( $this->query_string ) < 1 ) ? '' : '&'; if ( ! is_scalar( $this->query_vars[ $wpvar ] ) ) { continue; } $this->query_string .= $wpvar . '=' . rawurlencode( $this->query_vars[ $wpvar ] ); } } if ( has_filter( 'query_string' ) ) { $this->query_string = apply_filters_deprecated( 'query_string', array( $this->query_string ), '2.1.0', 'query_vars, request' ); parse_str( $this->query_string, $this->query_vars ); } } public function register_globals() { global $wp_query; foreach ( (array) $wp_query->query_vars as $key => $value ) { $GLOBALS[ $key ] = $value; } $GLOBALS['query_string'] = $this->query_string; $GLOBALS['posts'] = & $wp_query->posts; $GLOBALS['post'] = isset( $wp_query->post ) ? $wp_query->post : null; $GLOBALS['request'] = $wp_query->request; if ( $wp_query->is_single() || $wp_query->is_page() ) { $GLOBALS['more'] = 1; $GLOBALS['single'] = 1; } if ( $wp_query->is_author() ) { $GLOBALS['authordata'] = get_userdata( get_queried_object_id() ); } } public function init() { wp_get_current_user(); } public function query_posts() { global $wp_the_query; $this->build_query_string(); $wp_the_query->query( $this->query_vars ); } public function handle_404() { global $wp_query; if ( false !== apply_filters( 'pre_handle_404', false, $wp_query ) ) { return; } if ( is_404() ) { return; } $set_404 = true; if ( is_admin() || is_robots() || is_favicon() ) { $set_404 = false; } elseif ( $wp_query->posts ) { $content_found = true; if ( is_singular() ) { $post = isset( $wp_query->post ) ? $wp_query->post : null; $next = '<!--nextpage-->'; if ( $post && ! empty( $this->query_vars['page'] ) ) { if ( str_contains( $post->post_content, $next ) ) { $page = trim( $this->query_vars['page'], '/' ); $content_found = (int) $page <= ( substr_count( $post->post_content, $next ) + 1 ); } else { $content_found = false; } } } if ( $wp_query->is_posts_page && ! empty( $this->query_vars['page'] ) ) { $content_found = false; } if ( $content_found ) { $set_404 = false; } } elseif ( ! is_paged() ) { $author = get_query_var( 'author' ); if ( is_author() && is_numeric( $author ) && $author > 0 && is_user_member_of_blog( $author ) || ( is_tag() || is_category() || is_tax() || is_post_type_archive() ) && get_queried_object() || is_home() || is_search() || is_feed() ) { $set_404 = false; } } if ( $set_404 ) { $wp_query->set_404(); status_header( 404 ); nocache_headers(); } else { status_header( 200 ); } } public function main( $query_args = '' ) { $this->init(); $parsed = $this->parse_request( $query_args ); if ( $parsed ) { $this->query_posts(); $this->handle_404(); $this->register_globals(); } $this->send_headers(); do_action_ref_array( 'wp', array( &$this ) ); } }
###require ABSPATH . WPINC . '/class-wp-error.php';
class WP_Error { public $errors = array(); public $error_data = array(); protected $additional_data = array(); public function __construct( $code = '', $message = '', $data = '' ) { if ( empty( $code ) ) { return; } $this->add( $code, $message, $data ); } public function get_error_codes() { if ( ! $this->has_errors() ) { return array(); } return array_keys( $this->errors ); } public function get_error_code() { $codes = $this->get_error_codes(); if ( empty( $codes ) ) { return ''; } return $codes[0]; } public function get_error_messages( $code = '' ) { if ( empty( $code ) ) { $all_messages = array(); foreach ( (array) $this->errors as $code => $messages ) { $all_messages = array_merge( $all_messages, $messages ); } return $all_messages; } if ( isset( $this->errors[ $code ] ) ) { return $this->errors[ $code ]; } else { return array(); } } public function get_error_message( $code = '' ) { if ( empty( $code ) ) { $code = $this->get_error_code(); } $messages = $this->get_error_messages( $code ); if ( empty( $messages ) ) { return ''; } return $messages[0]; } public function get_error_data( $code = '' ) { if ( empty( $code ) ) { $code = $this->get_error_code(); } if ( isset( $this->error_data[ $code ] ) ) { return $this->error_data[ $code ]; } } public function has_errors() { if ( ! empty( $this->errors ) ) { return true; } return false; } public function add( $code, $message, $data = '' ) { $this->errors[ $code ][] = $message; if ( ! empty( $data ) ) { $this->add_data( $data, $code ); } do_action( 'wp_error_added', $code, $message, $data, $this ); } public function add_data( $data, $code = '' ) { if ( empty( $code ) ) { $code = $this->get_error_code(); } if ( isset( $this->error_data[ $code ] ) ) { $this->additional_data[ $code ][] = $this->error_data[ $code ]; } $this->error_data[ $code ] = $data; } public function get_all_error_data( $code = '' ) { if ( empty( $code ) ) { $code = $this->get_error_code(); } $data = array(); if ( isset( $this->additional_data[ $code ] ) ) { $data = $this->additional_data[ $code ]; } if ( isset( $this->error_data[ $code ] ) ) { $data[] = $this->error_data[ $code ]; } return $data; } public function remove( $code ) { unset( $this->errors[ $code ] ); unset( $this->error_data[ $code ] ); unset( $this->additional_data[ $code ] ); } public function merge_from( WP_Error $error ) { static::copy_errors( $error, $this ); } public function export_to( WP_Error $error ) { static::copy_errors( $this, $error ); } protected static function copy_errors( WP_Error $from, WP_Error $to ) { foreach ( $from->get_error_codes() as $code ) { foreach ( $from->get_error_messages( $code ) as $error_message ) { $to->add( $code, $error_message ); } foreach ( $from->get_all_error_data( $code ) as $data ) { $to->add_data( $data, $code ); } } } }
require ABSPATH . WPINC . '/pomo/mo.php';
###require ABSPATH . WPINC . '/l10n/class-wp-translation-controller.php';
final class WP_Translation_Controller { protected $current_locale = 'en_US'; protected $loaded_translations = array(); protected $loaded_files = array(); private static $instance = null; public static function get_instance(): WP_Translation_Controller { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } public function get_locale(): string { return $this->current_locale; } public function set_locale( string $locale ) { $this->current_locale = $locale; } public function load_file( string $translation_file, string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } $translation_file = realpath( $translation_file ); if ( false === $translation_file ) { return false; } if ( isset( $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] ) && false !== $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] ) { return null === $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ]->error(); } if ( isset( $this->loaded_files[ $translation_file ][ $locale ] ) && array() !== $this->loaded_files[ $translation_file ][ $locale ] ) { $moe = reset( $this->loaded_files[ $translation_file ][ $locale ] ); } else { $moe = WP_Translation_File::create( $translation_file ); if ( false === $moe || null !== $moe->error() ) { $moe = false; } } $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] = $moe; if ( ! $moe instanceof WP_Translation_File ) { return false; } if ( ! isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { $this->loaded_translations[ $locale ][ $textdomain ] = array(); } $this->loaded_translations[ $locale ][ $textdomain ][] = $moe; return true; } public function unload_file( $file, string $textdomain = 'default', ?string $locale = null ): bool { if ( is_string( $file ) ) { $file = realpath( $file ); } if ( null !== $locale ) { if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $i => $moe ) { if ( $file === $moe || $file === $moe->get_file() ) { unset( $this->loaded_translations[ $locale ][ $textdomain ][ $i ] ); unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); return true; } } } return true; } foreach ( $this->loaded_translations as $l => $domains ) { if ( ! isset( $domains[ $textdomain ] ) ) { continue; } foreach ( $domains[ $textdomain ] as $i => $moe ) { if ( $file === $moe || $file === $moe->get_file() ) { unset( $this->loaded_translations[ $l ][ $textdomain ][ $i ] ); unset( $this->loaded_files[ $moe->get_file() ][ $l ][ $textdomain ] ); return true; } } } return false; } public function unload_textdomain( string $textdomain = 'default', ?string $locale = null ): bool { $unloaded = false; if ( null !== $locale ) { if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { $unloaded = true; foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $moe ) { unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); } } unset( $this->loaded_translations[ $locale ][ $textdomain ] ); return $unloaded; } foreach ( $this->loaded_translations as $l => $domains ) { if ( ! isset( $domains[ $textdomain ] ) ) { continue; } $unloaded = true; foreach ( $domains[ $textdomain ] as $moe ) { unset( $this->loaded_files[ $moe->get_file() ][ $l ][ $textdomain ] ); } unset( $this->loaded_translations[ $l ][ $textdomain ] ); } return $unloaded; } public function is_textdomain_loaded( string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } return isset( $this->loaded_translations[ $locale ][ $textdomain ] ) && array() !== $this->loaded_translations[ $locale ][ $textdomain ]; } public function translate( string $text, string $context = '', string $textdomain = 'default', ?string $locale = null ) { if ( '' !== $context ) { $context .= "\4"; } $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { return false; } return $translation['entries'][0]; } public function translate_plural( array $plurals, int $number, string $context = '', string $textdomain = 'default', ?string $locale = null ) { if ( '' !== $context ) { $context .= "\4"; } $text = implode( "\0", $plurals ); $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { $text = $plurals[0]; $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { return false; } } $source = $translation['source']; $num = $source->get_plural_form( $number ); return $translation['entries'][ $num ] ?? $translation['entries'][0]; } public function get_headers( string $textdomain = 'default' ): array { if ( array() === $this->loaded_translations ) { return array(); } $headers = array(); foreach ( $this->get_files( $textdomain ) as $moe ) { foreach ( $moe->headers() as $header => $value ) { $headers[ $this->normalize_header( $header ) ] = $value; } } return $headers; } protected function normalize_header( string $header ): string { $parts = explode( '-', $header ); $parts = array_map( 'ucfirst', $parts ); return implode( '-', $parts ); } public function get_entries( string $textdomain = 'default' ): array { if ( array() === $this->loaded_translations ) { return array(); } $entries = array(); foreach ( $this->get_files( $textdomain ) as $moe ) { $entries = array_merge( $entries, $moe->entries() ); } return $entries; } protected function locate_translation( string $singular, string $textdomain = 'default', ?string $locale = null ) { if ( array() === $this->loaded_translations ) { return false; } foreach ( $this->get_files( $textdomain, $locale ) as $moe ) { $translation = $moe->translate( $singular ); if ( false !== $translation ) { return array( 'entries' => explode( "\0", $translation ), 'source' => $moe, ); } if ( null !== $moe->error() ) { $this->unload_file( $moe, $textdomain, $locale ); } } return false; } protected function get_files( string $textdomain = 'default', ?string $locale = null ): array { if ( null === $locale ) { $locale = $this->current_locale; } return $this->loaded_translations[ $locale ][ $textdomain ] ?? array(); } public function has_translation( string $singular, string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } return false !== $this->locate_translation( $singular, $textdomain, $locale ); } }
###require ABSPATH . WPINC . '/l10n/class-wp-translations.php';
class WP_Translations { protected $textdomain = 'default'; protected $controller; public function __construct( WP_Translation_Controller $controller, string $textdomain = 'default' ) { $this->controller = $controller; $this->textdomain = $textdomain; } public function __get( string $name ) { if ( 'entries' === $name ) { $entries = $this->controller->get_entries( $this->textdomain ); $result = array(); foreach ( $entries as $original => $translations ) { $result[] = $this->make_entry( $original, $translations ); } return $result; } if ( 'headers' === $name ) { return $this->controller->get_headers( $this->textdomain ); } return null; } private function make_entry( $original, $translations ): Translation_Entry { $entry = new Translation_Entry(); $parts = explode( "\4", $original ); if ( isset( $parts[1] ) ) { $original = $parts[1]; $entry->context = $parts[0]; } $entry->singular = $original; $entry->translations = explode( "\0", $translations ); $entry->is_plural = count( $entry->translations ) > 1; return $entry; } public function translate_plural( $singular, $plural, $count = 1, $context = '' ) { if ( null === $singular || null === $plural ) { return $singular; } $translation = $this->controller->translate_plural( array( $singular, $plural ), (int) $count, (string) $context, $this->textdomain ); if ( false !== $translation ) { return $translation; } return ( 1 === (int) $count ? $singular : $plural ); } public function translate( $singular, $context = '' ) { if ( null === $singular ) { return null; } $translation = $this->controller->translate( $singular, (string) $context, $this->textdomain ); if ( false !== $translation ) { return $translation; } return $singular; } }
###require ABSPATH . WPINC . '/l10n/class-wp-translation-file.php';
abstract class WP_Translation_File { protected $headers = array(); protected $parsed = false; protected $error; protected $file = ''; protected $entries = array(); protected $plural_forms = null; protected function __construct( string $file ) { $this->file = $file; } public static function create( string $file, ?string $filetype = null ) { if ( ! is_readable( $file ) ) { return false; } if ( null === $filetype ) { $pos = strrpos( $file, '.' ); if ( false !== $pos ) { $filetype = substr( $file, $pos + 1 ); } } switch ( $filetype ) { case 'mo': return new WP_Translation_File_MO( $file ); case 'php': return new WP_Translation_File_PHP( $file ); default: return false; } } public static function transform( string $file, string $filetype ) { $source = self::create( $file ); if ( false === $source ) { return false; } switch ( $filetype ) { case 'mo': $destination = new WP_Translation_File_MO( '' ); break; case 'php': $destination = new WP_Translation_File_PHP( '' ); break; default: return false; } $success = $destination->import( $source ); if ( ! $success ) { return false; } return $destination->export(); } public function headers(): array { if ( ! $this->parsed ) { $this->parse_file(); } return $this->headers; } public function entries(): array { if ( ! $this->parsed ) { $this->parse_file(); } return $this->entries; } public function error() { return $this->error; } public function get_file(): string { return $this->file; } public function translate( string $text ) { if ( ! $this->parsed ) { $this->parse_file(); } return $this->entries[ $text ] ?? false; } public function get_plural_form( int $number ): int { if ( ! $this->parsed ) { $this->parse_file(); } if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) { $expression = $this->get_plural_expression_from_header( $this->headers['plural-forms'] ); $this->plural_forms = $this->make_plural_form_function( $expression ); } if ( is_callable( $this->plural_forms ) ) { $result = call_user_func( $this->plural_forms, $number ); return $result; } return ( 1 === $number ? 0 : 1 ); } protected function get_plural_expression_from_header( string $header ): string { if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) { return trim( $matches[2] ); } return 'n != 1'; } protected function make_plural_form_function( string $expression ): callable { try { $handler = new Plural_Forms( rtrim( $expression, ';' ) ); return array( $handler, 'get' ); } catch ( Exception $e ) { return $this->make_plural_form_function( 'n != 1' ); } } protected function import( WP_Translation_File $source ): bool { if ( null !== $source->error() ) { return false; } $this->headers = $source->headers(); $this->entries = $source->entries(); $this->error = $source->error(); return null === $this->error; } abstract protected function parse_file(); abstract public function export(); }
###require ABSPATH . WPINC . '/l10n/class-wp-translation-file-mo.php';
class WP_Translation_File_MO extends WP_Translation_File { protected $uint32 = false; const MAGIC_MARKER = 0x950412de; protected function detect_endian_and_validate_file( string $header ) { $big = unpack( 'N', $header ); if ( false === $big ) { return false; } $big = reset( $big ); if ( false === $big ) { return false; } $little = unpack( 'V', $header ); if ( false === $little ) { return false; } $little = reset( $little ); if ( false === $little ) { return false; } if ( (int) self::MAGIC_MARKER === $big ) { return 'N'; } if ( (int) self::MAGIC_MARKER === $little ) { return 'V'; } $this->error = 'Magic marker does not exist'; return false; } protected function parse_file(): bool { $this->parsed = true; $file_contents = file_get_contents( $this->file ); if ( false === $file_contents ) { return false; } $file_length = strlen( $file_contents ); if ( $file_length < 24 ) { $this->error = 'Invalid data'; return false; } $this->uint32 = $this->detect_endian_and_validate_file( substr( $file_contents, 0, 4 ) ); if ( false === $this->uint32 ) { return false; } $offsets = substr( $file_contents, 4, 24 ); if ( false === $offsets ) { return false; } $offsets = unpack( "{$this->uint32}rev/{$this->uint32}total/{$this->uint32}originals_addr/{$this->uint32}translations_addr/{$this->uint32}hash_length/{$this->uint32}hash_addr", $offsets ); if ( false === $offsets ) { return false; } $offsets['originals_length'] = $offsets['translations_addr'] - $offsets['originals_addr']; $offsets['translations_length'] = $offsets['hash_addr'] - $offsets['translations_addr']; if ( $offsets['rev'] > 0 ) { $this->error = 'Unsupported revision'; return false; } if ( $offsets['translations_addr'] > $file_length || $offsets['originals_addr'] > $file_length ) { $this->error = 'Invalid data'; return false; } $original_data = str_split( substr( $file_contents, $offsets['originals_addr'], $offsets['originals_length'] ), 8 ); $translations_data = str_split( substr( $file_contents, $offsets['translations_addr'], $offsets['translations_length'] ), 8 ); foreach ( array_keys( $original_data ) as $i ) { $o = unpack( "{$this->uint32}length/{$this->uint32}pos", $original_data[ $i ] ); $t = unpack( "{$this->uint32}length/{$this->uint32}pos", $translations_data[ $i ] ); if ( false === $o || false === $t ) { continue; } $original = substr( $file_contents, $o['pos'], $o['length'] ); $translation = substr( $file_contents, $t['pos'], $t['length'] ); $translation = rtrim( $translation, "\0" ); if ( '' === $original ) { foreach ( explode( "\n", $translation ) as $meta_line ) { if ( '' === $meta_line || ! str_contains( $meta_line, ':' ) ) { continue; } list( $name, $value ) = array_map( 'trim', explode( ':', $meta_line, 2 ) ); $this->headers[ strtolower( $name ) ] = $value; } } else { $parts = explode( "\0", (string) $original ); $this->entries[ $parts[0] ] = $translation; } } return true; } public function export(): string { $headers_string = ''; foreach ( $this->headers as $header => $value ) { $headers_string .= "{$header}: $value\n"; } $entries = array_merge( array( '' => $headers_string ), $this->entries ); $entry_count = count( $entries ); if ( false === $this->uint32 ) { $this->uint32 = 'V'; } $bytes_for_entries = $entry_count * 4 * 2; $originals_addr = 28; $translations_addr = $originals_addr + $bytes_for_entries; $hash_addr = $translations_addr + $bytes_for_entries; $entry_offsets = $hash_addr; $file_header = pack( $this->uint32 . '*', (int) self::MAGIC_MARKER, 0, $entry_count, $originals_addr, $translations_addr, 0, $hash_addr ); $o_entries = ''; $t_entries = ''; $o_addr = ''; $t_addr = ''; foreach ( array_keys( $entries ) as $original ) { $o_addr .= pack( $this->uint32 . '*', strlen( $original ), $entry_offsets ); $entry_offsets += strlen( $original ) + 1; $o_entries .= $original . "\0"; } foreach ( $entries as $translations ) { $t_addr .= pack( $this->uint32 . '*', strlen( $translations ), $entry_offsets ); $entry_offsets += strlen( $translations ) + 1; $t_entries .= $translations . "\0"; } return $file_header . $o_addr . $t_addr . $o_entries . $t_entries; } }
###require ABSPATH . WPINC . '/l10n/class-wp-translation-file-php.php';
class WP_Translation_File_PHP extends WP_Translation_File { protected function parse_file() { $this->parsed = true; $result = include $this->file; if ( ! $result || ! is_array( $result ) ) { $this->error = 'Invalid data'; return; } if ( isset( $result['messages'] ) && is_array( $result['messages'] ) ) { foreach ( $result['messages'] as $original => $translation ) { $this->entries[ (string) $original ] = $translation; } unset( $result['messages'] ); } $this->headers = array_change_key_case( $result ); } public function export(): string { $data = array_merge( $this->headers, array( 'messages' => $this->entries ) ); return '<?php' . PHP_EOL . 'return ' . $this->var_export( $data ) . ';' . PHP_EOL; } private function var_export( $value ): string { if ( ! is_array( $value ) ) { return var_export( $value, true ); } $entries = array(); $is_list = array_is_list( $value ); foreach ( $value as $key => $val ) { $entries[] = $is_list ? $this->var_export( $val ) : var_export( $key, true ) . '=>' . $this->var_export( $val ); } return '[' . implode( ',', $entries ) . ']'; } }
global $wpdb;
require_wp_db();
$GLOBALS['table_prefix'] = $table_prefix;
wp_set_wpdb_vars();
wp_start_object_cache();
###require ABSPATH . WPINC . '/default-filters.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } foreach ( array( 'pre_term_name', 'pre_comment_author_name', 'pre_link_name', 'pre_link_target', 'pre_link_rel', 'pre_user_display_name', 'pre_user_first_name', 'pre_user_last_name', 'pre_user_nickname' ) as $filter ) { add_filter( $filter, 'sanitize_text_field' ); add_filter( $filter, 'wp_filter_kses' ); add_filter( $filter, '_wp_specialchars', 30 ); } foreach ( array( 'term_name', 'comment_author_name', 'link_name', 'link_target', 'link_rel', 'user_display_name', 'user_first_name', 'user_last_name', 'user_nickname' ) as $filter ) { if ( is_admin() ) { add_filter( $filter, 'sanitize_text_field' ); add_filter( $filter, 'wp_kses_data' ); } add_filter( $filter, '_wp_specialchars', 30 ); } foreach ( array( 'pre_term_description', 'pre_link_description', 'pre_link_notes', 'pre_user_description' ) as $filter ) { add_filter( $filter, 'wp_filter_kses' ); } if ( is_admin() ) { foreach ( array( 'term_description', 'link_description', 'link_notes', 'user_description' ) as $filter ) { add_filter( $filter, 'wp_kses_data' ); } add_filter( 'comment_text', 'wp_kses_post' ); } foreach ( array( 'pre_comment_author_email', 'pre_user_email' ) as $filter ) { add_filter( $filter, 'trim' ); add_filter( $filter, 'sanitize_email' ); add_filter( $filter, 'wp_filter_kses' ); } foreach ( array( 'comment_author_email', 'user_email' ) as $filter ) { add_filter( $filter, 'sanitize_email' ); if ( is_admin() ) { add_filter( $filter, 'wp_kses_data' ); } } foreach ( array( 'pre_comment_author_url', 'pre_user_url', 'pre_link_url', 'pre_link_image', 'pre_link_rss', 'pre_post_guid', ) as $filter ) { add_filter( $filter, 'wp_strip_all_tags' ); add_filter( $filter, 'sanitize_url' ); add_filter( $filter, 'wp_filter_kses' ); } foreach ( array( 'user_url', 'link_url', 'link_image', 'link_rss', 'comment_url', 'post_guid' ) as $filter ) { if ( is_admin() ) { add_filter( $filter, 'wp_strip_all_tags' ); } add_filter( $filter, 'esc_url' ); if ( is_admin() ) { add_filter( $filter, 'wp_kses_data' ); } } add_filter( 'pre_term_slug', 'sanitize_title' ); add_filter( 'wp_insert_post_data', '_wp_customize_changeset_filter_insert_post_data', 10, 2 ); foreach ( array( 'pre_post_type', 'pre_post_status', 'pre_post_comment_status', 'pre_post_ping_status' ) as $filter ) { add_filter( $filter, 'sanitize_key' ); } add_filter( 'pre_post_mime_type', 'sanitize_mime_type' ); add_filter( 'post_mime_type', 'sanitize_mime_type' ); add_filter( 'register_meta_args', '_wp_register_meta_args_allowed_list', 10, 2 ); add_action( 'admin_init', 'wp_schedule_update_user_counts' ); add_action( 'wp_update_user_counts', 'wp_schedule_update_user_counts', 10, 0 ); foreach ( array( 'user_register', 'deleted_user' ) as $action ) { add_action( $action, 'wp_maybe_update_user_counts', 10, 0 ); } add_action( 'added_post_meta', 'wp_cache_set_posts_last_changed' ); add_action( 'updated_post_meta', 'wp_cache_set_posts_last_changed' ); add_action( 'deleted_post_meta', 'wp_cache_set_posts_last_changed' ); add_action( 'added_user_meta', 'wp_cache_set_users_last_changed' ); add_action( 'updated_user_meta', 'wp_cache_set_users_last_changed' ); add_action( 'deleted_user_meta', 'wp_cache_set_users_last_changed' ); add_action( 'add_user_role', 'wp_cache_set_users_last_changed' ); add_action( 'set_user_role', 'wp_cache_set_users_last_changed' ); add_action( 'remove_user_role', 'wp_cache_set_users_last_changed' ); add_action( 'added_term_meta', 'wp_cache_set_terms_last_changed' ); add_action( 'updated_term_meta', 'wp_cache_set_terms_last_changed' ); add_action( 'deleted_term_meta', 'wp_cache_set_terms_last_changed' ); add_filter( 'get_term_metadata', 'wp_check_term_meta_support_prefilter' ); add_filter( 'add_term_metadata', 'wp_check_term_meta_support_prefilter' ); add_filter( 'update_term_metadata', 'wp_check_term_meta_support_prefilter' ); add_filter( 'delete_term_metadata', 'wp_check_term_meta_support_prefilter' ); add_filter( 'get_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' ); add_filter( 'update_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' ); add_filter( 'delete_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' ); add_filter( 'update_term_metadata_cache', 'wp_check_term_meta_support_prefilter' ); add_action( 'added_comment_meta', 'wp_cache_set_comments_last_changed' ); add_action( 'updated_comment_meta', 'wp_cache_set_comments_last_changed' ); add_action( 'deleted_comment_meta', 'wp_cache_set_comments_last_changed' ); add_action( 'init', 'wp_create_initial_comment_meta' ); foreach ( array( 'content_save_pre', 'excerpt_save_pre', 'comment_save_pre', 'pre_comment_content' ) as $filter ) { add_filter( $filter, 'convert_invalid_entities' ); add_filter( $filter, 'balanceTags', 50 ); } foreach ( array( 'comment_author', 'term_name', 'link_name', 'link_description', 'link_notes', 'bloginfo', 'wp_title', 'document_title', 'widget_title' ) as $filter ) { add_filter( $filter, 'wptexturize' ); add_filter( $filter, 'convert_chars' ); add_filter( $filter, 'esc_html' ); } foreach ( array( 'the_content', 'the_title', 'wp_title', 'document_title' ) as $filter ) { add_filter( $filter, 'capital_P_dangit', 11 ); } add_filter( 'comment_text', 'capital_P_dangit', 31 ); foreach ( array( 'single_post_title', 'single_cat_title', 'single_tag_title', 'single_month_title', 'nav_menu_attr_title', 'nav_menu_description' ) as $filter ) { add_filter( $filter, 'wptexturize' ); add_filter( $filter, 'strip_tags' ); } foreach ( array( 'term_description', 'get_the_post_type_description' ) as $filter ) { add_filter( $filter, 'wptexturize' ); add_filter( $filter, 'convert_chars' ); add_filter( $filter, 'wpautop' ); add_filter( $filter, 'shortcode_unautop' ); } add_filter( 'term_name_rss', 'convert_chars' ); add_filter( 'wp_insert_post_parent', 'wp_check_post_hierarchy_for_loops', 10, 2 ); add_filter( 'wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10, 3 ); add_filter( 'the_title', 'wptexturize' ); add_filter( 'the_title', 'convert_chars' ); add_filter( 'the_title', 'trim' ); add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', 8 ); add_filter( 'the_content', 'do_blocks', 9 ); add_filter( 'the_content', 'wptexturize' ); add_filter( 'the_content', 'convert_smilies', 20 ); add_filter( 'the_content', 'wpautop' ); add_filter( 'the_content', 'shortcode_unautop' ); add_filter( 'the_content', 'prepend_attachment' ); add_filter( 'the_content', 'wp_replace_insecure_home_url' ); add_filter( 'the_content', 'do_shortcode', 11 ); add_filter( 'the_content', 'wp_filter_content_tags', 12 ); add_filter( 'the_excerpt', 'wptexturize' ); add_filter( 'the_excerpt', 'convert_smilies' ); add_filter( 'the_excerpt', 'convert_chars' ); add_filter( 'the_excerpt', 'wpautop' ); add_filter( 'the_excerpt', 'shortcode_unautop' ); add_filter( 'the_excerpt', 'wp_replace_insecure_home_url' ); add_filter( 'the_excerpt', 'wp_filter_content_tags', 12 ); add_filter( 'get_the_excerpt', 'wp_trim_excerpt', 10, 2 ); add_filter( 'the_post_thumbnail_caption', 'wptexturize' ); add_filter( 'the_post_thumbnail_caption', 'convert_smilies' ); add_filter( 'the_post_thumbnail_caption', 'convert_chars' ); add_filter( 'comment_text', 'wptexturize' ); add_filter( 'comment_text', 'convert_chars' ); add_filter( 'comment_text', 'make_clickable', 9 ); add_filter( 'comment_text', 'force_balance_tags', 25 ); add_filter( 'comment_text', 'convert_smilies', 20 ); add_filter( 'comment_text', 'wpautop', 30 ); add_filter( 'comment_excerpt', 'convert_chars' ); add_filter( 'list_cats', 'wptexturize' ); add_filter( 'wp_sprintf', 'wp_sprintf_l', 10, 2 ); add_filter( 'widget_text', 'balanceTags' ); add_filter( 'widget_text_content', 'capital_P_dangit', 11 ); add_filter( 'widget_text_content', 'wptexturize' ); add_filter( 'widget_text_content', 'convert_smilies', 20 ); add_filter( 'widget_text_content', 'wpautop' ); add_filter( 'widget_text_content', 'shortcode_unautop' ); add_filter( 'widget_text_content', 'wp_replace_insecure_home_url' ); add_filter( 'widget_text_content', 'do_shortcode', 11 ); add_filter( 'widget_text_content', 'wp_filter_content_tags', 12 ); add_filter( 'widget_block_content', 'do_blocks', 9 ); add_filter( 'widget_block_content', 'do_shortcode', 11 ); add_filter( 'widget_block_content', 'wp_filter_content_tags', 12 ); add_filter( 'block_type_metadata', 'wp_migrate_old_typography_shape' ); add_filter( 'wp_get_custom_css', 'wp_replace_insecure_home_url' ); add_filter( 'the_title_rss', 'strip_tags' ); add_filter( 'the_title_rss', 'ent2ncr', 8 ); add_filter( 'the_title_rss', 'esc_html' ); add_filter( 'the_content_rss', 'ent2ncr', 8 ); add_filter( 'the_content_feed', 'wp_staticize_emoji' ); add_filter( 'the_content_feed', '_oembed_filter_feed_content' ); add_filter( 'the_excerpt_rss', 'convert_chars' ); add_filter( 'the_excerpt_rss', 'ent2ncr', 8 ); add_filter( 'comment_author_rss', 'ent2ncr', 8 ); add_filter( 'comment_text_rss', 'ent2ncr', 8 ); add_filter( 'comment_text_rss', 'esc_html' ); add_filter( 'comment_text_rss', 'wp_staticize_emoji' ); add_filter( 'bloginfo_rss', 'ent2ncr', 8 ); add_filter( 'the_author', 'ent2ncr', 8 ); add_filter( 'the_guid', 'esc_url' ); add_filter( 'wp_mail', 'wp_staticize_emoji_for_email' ); add_filter( 'wp_robots', 'wp_robots_noindex' ); add_filter( 'wp_robots', 'wp_robots_noindex_embeds' ); add_filter( 'wp_robots', 'wp_robots_noindex_search' ); add_filter( 'wp_robots', 'wp_robots_max_image_preview_large' ); foreach ( array( 'publish_post', 'publish_page', 'wp_ajax_save-widget', 'wp_ajax_widgets-order', 'customize_save_after', 'rest_after_save_widget', 'rest_delete_widget', 'rest_save_sidebar', ) as $action ) { add_action( $action, '_delete_option_fresh_site', 0 ); } add_filter( 'wp_default_autoload_value', 'wp_filter_default_autoload_value_via_option_size', 5, 4 ); add_filter( 'option_ping_sites', 'privacy_ping_filter' ); add_filter( 'option_blog_charset', '_wp_specialchars' ); add_filter( 'option_blog_charset', '_canonical_charset' ); add_filter( 'option_home', '_config_wp_home' ); add_filter( 'option_siteurl', '_config_wp_siteurl' ); add_filter( 'tiny_mce_before_init', '_mce_set_direction' ); add_filter( 'teeny_mce_before_init', '_mce_set_direction' ); add_filter( 'pre_kses', 'wp_pre_kses_less_than' ); add_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10, 3 ); add_filter( 'sanitize_title', 'sanitize_title_with_dashes', 10, 3 ); add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 ); add_filter( 'comment_flood_filter', 'wp_throttle_comment_flood', 10, 3 ); add_filter( 'pre_comment_content', 'wp_rel_ugc', 15 ); add_filter( 'comment_email', 'antispambot' ); add_filter( 'option_tag_base', '_wp_filter_taxonomy_base' ); add_filter( 'option_category_base', '_wp_filter_taxonomy_base' ); add_filter( 'the_posts', '_close_comments_for_old_posts', 10, 2 ); add_filter( 'comments_open', '_close_comments_for_old_post', 10, 2 ); add_filter( 'pings_open', '_close_comments_for_old_post', 10, 2 ); add_filter( 'editable_slug', 'urldecode' ); add_filter( 'editable_slug', 'esc_textarea' ); add_filter( 'pingback_ping_source_uri', 'pingback_ping_source_uri' ); add_filter( 'xmlrpc_pingback_error', 'xmlrpc_pingback_error' ); add_filter( 'title_save_pre', 'trim' ); add_action( 'transition_comment_status', '_clear_modified_cache_on_transition_comment_status', 10, 2 ); add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 ); add_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' ); add_action( 'wp_head', 'rest_output_link_wp_head', 10, 0 ); add_action( 'template_redirect', 'rest_output_link_header', 11, 0 ); add_action( 'auth_cookie_malformed', 'rest_cookie_collect_status' ); add_action( 'auth_cookie_expired', 'rest_cookie_collect_status' ); add_action( 'auth_cookie_bad_username', 'rest_cookie_collect_status' ); add_action( 'auth_cookie_bad_hash', 'rest_cookie_collect_status' ); add_action( 'auth_cookie_valid', 'rest_cookie_collect_status' ); add_action( 'application_password_failed_authentication', 'rest_application_password_collect_status' ); add_action( 'application_password_did_authenticate', 'rest_application_password_collect_status', 10, 2 ); add_filter( 'rest_authentication_errors', 'rest_application_password_check_errors', 90 ); add_filter( 'rest_authentication_errors', 'rest_cookie_check_errors', 100 ); add_action( 'wp_head', '_wp_render_title_tag', 1 ); add_action( 'wp_head', 'wp_enqueue_scripts', 1 ); add_action( 'wp_head', 'wp_resource_hints', 2 ); add_action( 'wp_head', 'wp_preload_resources', 1 ); add_action( 'wp_head', 'feed_links', 2 ); add_action( 'wp_head', 'feed_links_extra', 3 ); add_action( 'wp_head', 'rsd_link' ); add_action( 'wp_head', 'locale_stylesheet' ); add_action( 'publish_future_post', 'check_and_publish_future_post', 10, 1 ); add_action( 'wp_head', 'wp_robots', 1 ); add_action( 'wp_head', 'print_emoji_detection_script', 7 ); add_action( 'wp_head', 'wp_print_styles', 8 ); add_action( 'wp_head', 'wp_print_head_scripts', 9 ); add_action( 'wp_head', 'wp_generator' ); add_action( 'wp_head', 'rel_canonical' ); add_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 ); add_action( 'wp_head', 'wp_custom_css_cb', 101 ); add_action( 'wp_head', 'wp_site_icon', 99 ); add_action( 'wp_footer', 'wp_print_speculation_rules' ); add_action( 'wp_footer', 'wp_print_footer_scripts', 20 ); add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 ); add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); add_action( 'init', '_register_core_block_patterns_and_categories' ); add_action( 'init', 'check_theme_switched', 99 ); add_action( 'init', array( 'WP_Block_Supports', 'init' ), 22 ); add_action( 'switch_theme', 'wp_clean_theme_json_cache' ); add_action( 'start_previewing_theme', 'wp_clean_theme_json_cache' ); add_action( 'after_switch_theme', '_wp_menus_changed' ); add_action( 'after_switch_theme', '_wp_sidebars_changed' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_emoji_styles' ); add_action( 'wp_print_styles', 'print_emoji_styles' ); if ( isset( $_GET['replytocom'] ) || ( isset( $_GET['unapproved'] ) && isset( $_GET['moderation-hash'] ) ) ) { add_filter( 'wp_robots', 'wp_robots_no_robots' ); } add_action( 'login_head', 'wp_robots', 1 ); add_filter( 'login_head', 'wp_resource_hints', 8 ); add_action( 'login_head', 'wp_print_head_scripts', 9 ); add_action( 'login_head', 'print_admin_styles', 9 ); add_action( 'login_head', 'wp_site_icon', 99 ); add_action( 'login_footer', 'wp_print_footer_scripts', 20 ); add_action( 'login_init', 'send_frame_options_header', 10, 0 ); add_action( 'login_init', 'wp_admin_headers' ); foreach ( array( 'rss2_head', 'commentsrss2_head', 'rss_head', 'rdf_header', 'atom_head', 'comments_atom_head', 'opml_head', 'app_head' ) as $action ) { add_action( $action, 'the_generator' ); } add_action( 'atom_head', 'atom_site_icon' ); add_action( 'rss2_head', 'rss2_site_icon' ); if ( ! defined( 'DOING_CRON' ) ) { add_action( 'init', 'wp_cron' ); } add_action( 'update_option_home', 'wp_update_https_migration_required', 10, 2 ); add_action( 'do_feed_rdf', 'do_feed_rdf', 10, 0 ); add_action( 'do_feed_rss', 'do_feed_rss', 10, 0 ); add_action( 'do_feed_rss2', 'do_feed_rss2', 10, 1 ); add_action( 'do_feed_atom', 'do_feed_atom', 10, 1 ); add_action( 'do_pings', 'do_all_pings', 10, 0 ); add_action( 'do_all_pings', 'do_all_pingbacks', 10, 0 ); add_action( 'do_all_pings', 'do_all_enclosures', 10, 0 ); add_action( 'do_all_pings', 'do_all_trackbacks', 10, 0 ); add_action( 'do_all_pings', 'generic_ping', 10, 0 ); add_action( 'do_robots', 'do_robots' ); add_action( 'do_favicon', 'do_favicon' ); add_action( 'wp_before_include_template', 'wp_start_template_enhancement_output_buffer', 1000 ); add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 ); add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' ); add_action( 'init', 'smilies_init', 5 ); add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 ); add_action( 'plugins_loaded', 'wp_maybe_load_embeds', 0 ); add_action( 'shutdown', 'wp_ob_end_flush_all', 1 ); add_action( 'wp_after_insert_post', 'wp_save_post_revision_on_insert', 9, 3 ); add_action( 'post_updated', 'wp_save_post_revision', 10, 1 ); add_action( 'publish_post', '_publish_post_hook', 5, 1 ); add_action( 'transition_post_status', '_transition_post_status', 5, 3 ); add_action( 'transition_post_status', '_update_term_count_on_transition_post_status', 10, 3 ); add_action( 'comment_form', 'wp_comment_form_unfiltered_html_nonce' ); add_action( 'user_request_action_confirmed', '_wp_privacy_account_request_confirmed' ); add_action( 'user_request_action_confirmed', '_wp_privacy_send_request_confirmation_notification', 12 ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_comment_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_media_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_user_personal_data_exporter', 1 ); add_filter( 'wp_privacy_personal_data_erasers', 'wp_register_comment_personal_data_eraser' ); add_action( 'init', 'wp_schedule_delete_old_privacy_export_files' ); add_action( 'wp_privacy_delete_old_export_files', 'wp_privacy_delete_old_export_files' ); add_action( 'wp_scheduled_delete', 'wp_scheduled_delete' ); add_action( 'wp_scheduled_auto_draft_delete', 'wp_delete_auto_drafts' ); add_action( 'importer_scheduled_cleanup', 'wp_delete_attachment' ); add_action( 'upgrader_scheduled_cleanup', 'wp_delete_attachment' ); add_action( 'delete_expired_transients', 'delete_expired_transients' ); add_action( 'delete_post', '_wp_delete_post_menu_item' ); add_action( 'delete_term', '_wp_delete_tax_menu_item', 10, 3 ); add_action( 'transition_post_status', '_wp_auto_add_pages_to_menu', 10, 3 ); add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); add_action( 'begin_fetch_post_thumbnail_html', '_wp_post_thumbnail_class_filter_add' ); add_action( 'end_fetch_post_thumbnail_html', '_wp_post_thumbnail_class_filter_remove' ); add_action( 'begin_fetch_post_thumbnail_html', '_wp_post_thumbnail_context_filter_add' ); add_action( 'end_fetch_post_thumbnail_html', '_wp_post_thumbnail_context_filter_remove' ); add_action( 'template_redirect', 'wp_old_slug_redirect' ); add_action( 'post_updated', 'wp_check_for_changed_slugs', 12, 3 ); add_action( 'attachment_updated', 'wp_check_for_changed_slugs', 12, 3 ); add_action( 'post_updated', 'wp_check_for_changed_dates', 12, 3 ); add_action( 'attachment_updated', 'wp_check_for_changed_dates', 12, 3 ); add_action( 'init', '_show_post_preview' ); add_action( 'wp_head', 'wp_post_preview_js', 1 ); add_filter( 'pre_option_gmt_offset', 'wp_timezone_override_offset' ); add_filter( 'default_option_link_manager_enabled', '__return_true' ); add_filter( 'pre_option_embed_autourls', '__return_true' ); add_filter( 'heartbeat_settings', 'wp_heartbeat_settings' ); add_action( 'admin_enqueue_scripts', 'wp_auth_check_load' ); add_filter( 'heartbeat_send', 'wp_auth_check' ); add_filter( 'heartbeat_nopriv_send', 'wp_auth_check' ); add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_application_password', 20, 3 ); add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 ); add_filter( 'determine_current_user', 'wp_validate_auth_cookie' ); add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 ); add_filter( 'determine_current_user', 'wp_validate_application_password', 20 ); add_action( 'admin_init', '_wp_check_for_scheduled_split_terms' ); add_action( 'split_shared_term', '_wp_check_split_default_terms', 10, 4 ); add_action( 'split_shared_term', '_wp_check_split_terms_in_menus', 10, 4 ); add_action( 'split_shared_term', '_wp_check_split_nav_menu_terms', 10, 4 ); add_action( 'wp_split_shared_term_batch', '_wp_batch_split_terms' ); add_action( 'admin_init', '_wp_check_for_scheduled_update_comment_type' ); add_action( 'wp_update_comment_type_batch', '_wp_batch_update_comment_type' ); add_action( 'comment_post', 'wp_new_comment_notify_moderator' ); add_action( 'comment_post', 'wp_new_comment_notify_postauthor' ); add_action( 'rest_insert_comment', 'wp_new_comment_via_rest_notify_postauthor' ); add_action( 'after_password_reset', 'wp_password_change_notification' ); add_action( 'register_new_user', 'wp_send_new_user_notifications' ); add_action( 'edit_user_created_user', 'wp_send_new_user_notifications', 10, 2 ); add_action( 'init', 'rest_api_init' ); add_action( 'rest_api_init', 'rest_api_default_filters', 10, 1 ); add_action( 'rest_api_init', 'register_initial_settings', 10 ); add_action( 'rest_api_init', 'create_initial_rest_routes', 99 ); add_action( 'parse_request', 'rest_api_loaded' ); add_action( 'wp_abilities_api_categories_init', 'wp_register_core_ability_categories' ); add_action( 'wp_abilities_api_init', 'wp_register_core_abilities' ); add_action( 'init', 'wp_sitemaps_get_server' ); add_action( 'setup_theme', 'create_initial_theme_features', 0 ); add_action( 'after_setup_theme', '_add_default_theme_supports', 1 ); add_action( 'wp_loaded', '_custom_header_background_just_in_time' ); add_action( 'wp_head', '_custom_logo_header_styles' ); add_action( 'plugins_loaded', '_wp_customize_include' ); add_action( 'transition_post_status', '_wp_customize_publish_changeset', 10, 3 ); add_action( 'admin_enqueue_scripts', '_wp_customize_loader_settings' ); add_action( 'delete_attachment', '_delete_attachment_theme_mod' ); add_action( 'transition_post_status', '_wp_keep_alive_customize_changeset_dependent_auto_drafts', 20, 3 ); add_action( 'plugins_loaded', 'wp_initialize_theme_preview_hooks', 1 ); add_action( 'init', 'wp_initialize_site_preview_hooks', 1 ); add_action( 'save_post', 'delete_get_calendar_cache' ); add_action( 'delete_post', 'delete_get_calendar_cache' ); add_action( 'update_option_start_of_week', 'delete_get_calendar_cache' ); add_action( 'update_option_gmt_offset', 'delete_get_calendar_cache' ); add_action( 'transition_post_status', '__clear_multi_author_cache' ); add_action( 'init', 'create_initial_post_types', 0 ); add_action( 'admin_menu', '_add_post_type_submenus' ); add_action( 'before_delete_post', '_reset_front_page_settings_for_post' ); add_action( 'wp_trash_post', '_reset_front_page_settings_for_post' ); add_action( 'change_locale', 'create_initial_post_types' ); add_filter( 'request', '_post_format_request' ); add_filter( 'term_link', '_post_format_link', 10, 3 ); add_filter( 'get_post_format', '_post_format_get_term' ); add_filter( 'get_terms', '_post_format_get_terms', 10, 3 ); add_filter( 'wp_get_object_terms', '_post_format_wp_get_object_terms' ); add_action( 'init', 'kses_init' ); add_action( 'set_current_user', 'kses_init' ); add_action( 'wp_default_scripts', 'wp_default_scripts' ); add_action( 'wp_default_scripts', 'wp_default_packages' ); add_action( 'wp_default_scripts', 'wp_default_script_modules' ); add_action( 'wp_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 ); add_action( 'wp_enqueue_scripts', 'wp_common_block_scripts_and_styles' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_classic_theme_styles' ); add_action( 'admin_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 ); add_action( 'admin_enqueue_scripts', 'wp_common_block_scripts_and_styles' ); add_action( 'admin_enqueue_scripts', 'wp_enqueue_command_palette_assets' ); add_action( 'enqueue_block_assets', 'wp_enqueue_classic_theme_styles' ); add_action( 'enqueue_block_assets', 'wp_enqueue_registered_block_scripts_and_styles' ); add_action( 'enqueue_block_assets', 'enqueue_block_styles_assets', 30 ); add_action( 'init', 'wp_load_classic_theme_block_styles_on_demand', 8 ); add_action( 'enqueue_block_editor_assets', 'wp_enqueue_registered_block_scripts_and_styles' ); add_action( 'enqueue_block_editor_assets', 'enqueue_editor_block_styles_assets' ); add_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' ); add_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_format_library_assets' ); add_action( 'enqueue_block_editor_assets', 'wp_enqueue_global_styles_css_custom_properties' ); add_action( 'wp_print_scripts', 'wp_just_in_time_script_localization' ); add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' ); add_action( 'customize_controls_print_styles', 'wp_resource_hints', 1 ); add_action( 'admin_head', 'wp_check_widget_editor_deps' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles' ); add_action( 'wp_footer', 'wp_enqueue_global_styles', 1 ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_stored_styles' ); add_action( 'wp_footer', 'wp_enqueue_stored_styles', 1 ); add_action( 'wp_default_styles', 'wp_default_styles' ); add_filter( 'style_loader_src', 'wp_style_loader_src', 10, 2 ); add_action( 'wp_head', 'wp_enqueue_img_auto_sizes_contain_css_fix', 0 ); add_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 ); add_action( 'wp_head', 'wp_maybe_inline_styles', 1 ); add_action( 'wp_footer', 'wp_maybe_inline_styles', 1 ); add_action( 'init', '_wp_footnotes_kses_init' ); add_action( 'set_current_user', '_wp_footnotes_kses_init' ); add_filter( 'force_filtered_html_on_import', '_wp_footnotes_force_filtered_html_on_import_filter', 999 ); add_filter( 'theme_wp_navigation_templates', '__return_empty_array' ); add_action( 'init', 'create_initial_taxonomies', 0 ); add_action( 'change_locale', 'create_initial_taxonomies' ); add_action( 'template_redirect', 'redirect_canonical' ); add_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 ); add_action( 'wp_playlist_scripts', 'wp_playlist_scripts' ); add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' ); add_action( 'plugins_loaded', '_wp_add_additional_image_sizes', 0 ); add_filter( 'plupload_default_settings', 'wp_show_heic_upload_error' ); add_filter( 'nav_menu_item_id', '_nav_menu_item_id_use_once', 10, 2 ); add_filter( 'nav_menu_css_class', 'wp_nav_menu_remove_menu_item_has_children_class', 10, 4 ); add_action( 'after_setup_theme', 'wp_setup_widgets_block_editor', 1 ); add_action( 'init', 'wp_widgets_init', 1 ); add_action( 'change_locale', array( 'WP_Widget_Media', 'reset_default_labels' ) ); add_action( 'widgets_init', '_wp_block_theme_register_classic_sidebars', 1 ); add_action( 'template_redirect', '_wp_admin_bar_init', 0 ); add_action( 'admin_init', '_wp_admin_bar_init' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_admin_bar_bump_styles' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_admin_bar_header_styles' ); add_action( 'admin_enqueue_scripts', 'wp_enqueue_admin_bar_header_styles' ); add_action( 'before_signup_header', '_wp_admin_bar_init' ); add_action( 'activate_header', '_wp_admin_bar_init' ); add_action( 'wp_body_open', 'wp_admin_bar_render', 0 ); add_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); add_action( 'in_admin_header', 'wp_admin_bar_render', 0 ); add_action( 'media_buttons', 'media_buttons' ); add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); add_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 ); add_action( 'rest_api_init', 'wp_oembed_register_route' ); add_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 ); add_action( 'wp_head', 'wp_oembed_add_discovery_links', 4 ); add_action( 'wp_head', 'wp_oembed_add_discovery_links' ); add_action( 'wp_head', 'wp_oembed_add_host_js' ); add_filter( 'embed_oembed_html', 'wp_maybe_enqueue_oembed_host_js' ); add_action( 'embed_head', 'enqueue_embed_scripts', 1 ); add_action( 'embed_head', 'print_emoji_detection_script' ); add_action( 'embed_head', 'wp_enqueue_embed_styles', 9 ); add_action( 'embed_head', 'print_embed_styles' ); add_action( 'embed_head', 'wp_print_head_scripts', 20 ); add_action( 'embed_head', 'wp_print_styles', 20 ); add_action( 'embed_head', 'wp_robots' ); add_action( 'embed_head', 'rel_canonical' ); add_action( 'embed_head', 'locale_stylesheet', 30 ); add_action( 'enqueue_embed_scripts', 'wp_enqueue_emoji_styles' ); add_action( 'embed_content_meta', 'print_embed_comments_button' ); add_action( 'embed_content_meta', 'print_embed_sharing_button' ); add_action( 'embed_footer', 'print_embed_sharing_dialog' ); add_action( 'embed_footer', 'print_embed_scripts' ); add_action( 'embed_footer', 'wp_print_footer_scripts', 20 ); add_filter( 'excerpt_more', 'wp_embed_excerpt_more', 20 ); add_filter( 'the_excerpt_embed', 'wptexturize' ); add_filter( 'the_excerpt_embed', 'convert_chars' ); add_filter( 'the_excerpt_embed', 'wpautop' ); add_filter( 'the_excerpt_embed', 'shortcode_unautop' ); add_filter( 'the_excerpt_embed', 'wp_embed_excerpt_attachment' ); add_filter( 'oembed_dataparse', 'wp_filter_oembed_iframe_title_attribute', 5, 3 ); add_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10, 3 ); add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 ); add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 ); add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 ); add_filter( 'user_has_cap', 'wp_maybe_grant_resume_extensions_caps', 1 ); add_filter( 'user_has_cap', 'wp_maybe_grant_site_health_caps', 1, 4 ); add_filter( 'render_block_context', '_block_template_render_without_post_block_context' ); add_filter( 'pre_wp_unique_post_slug', 'wp_filter_wp_template_unique_post_slug', 10, 5 ); add_action( 'save_post_wp_template_part', 'wp_set_unique_slug_on_create_template_part' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_template_skip_link' ); add_action( 'wp_footer', 'the_block_template_skip_link' ); add_action( 'after_setup_theme', 'wp_enable_block_templates', 1 ); add_action( 'wp_loaded', '_add_template_loader_filters' ); add_filter( 'rest_wp_navigation_item_schema', array( 'WP_Navigation_Fallback', 'update_wp_navigation_post_schema' ) ); add_filter( 'render_block', 'wp_render_typography_support', 10, 2 ); add_action( 'init', 'wp_register_persisted_preferences_meta' ); add_action( 'init', 'wp_create_initial_post_meta' ); add_filter( 'wp_save_post_revision_post_has_changed', 'wp_check_revisioned_meta_fields_have_changed', 10, 3 ); add_action( '_wp_put_post_revision', 'wp_save_revisioned_meta_fields', 10, 2 ); add_action( 'wp_creating_autosave', 'wp_autosave_post_revisioned_meta_fields' ); add_action( 'wp_restore_post_revision', 'wp_restore_post_revision_meta', 10, 2 ); add_action( 'wp_head', 'wp_print_font_faces', 50 ); add_action( 'deleted_post', '_wp_after_delete_font_family', 10, 2 ); add_action( 'before_delete_post', '_wp_before_delete_font_face', 10, 2 ); add_action( 'init', '_wp_register_default_font_collections' ); add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' ); add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); add_filter( 'rest_pre_insert_page', 'update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_pre_insert_post', 'update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_pre_insert_wp_block', 'update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_pre_insert_wp_navigation', 'update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_prepare_page', 'insert_hooked_blocks_into_rest_response', 10, 2 ); add_filter( 'rest_prepare_post', 'insert_hooked_blocks_into_rest_response', 10, 2 ); add_filter( 'rest_prepare_wp_block', 'insert_hooked_blocks_into_rest_response', 10, 2 ); add_filter( 'rest_prepare_wp_navigation', 'insert_hooked_blocks_into_rest_response', 10, 2 ); unset( $filter, $action );
if ( is_multisite() ) {
### require ABSPATH . WPINC . '/class-wp-site-query.php';
class WP_Site_Query { public $request; protected $sql_clauses = array( 'select' => '', 'from' => '', 'where' => array(), 'groupby' => '', 'orderby' => '', 'limits' => '', ); public $meta_query = false; protected $meta_query_clauses; public $date_query = false; public $query_vars; public $query_var_defaults; public $sites; public $found_sites = 0; public $max_num_pages = 0; public function __construct( $query = '' ) { $this->query_var_defaults = array( 'fields' => '', 'ID' => '', 'site__in' => '', 'site__not_in' => '', 'number' => 100, 'offset' => '', 'no_found_rows' => true, 'orderby' => 'id', 'order' => 'ASC', 'network_id' => 0, 'network__in' => '', 'network__not_in' => '', 'domain' => '', 'domain__in' => '', 'domain__not_in' => '', 'path' => '', 'path__in' => '', 'path__not_in' => '', 'public' => null, 'archived' => null, 'mature' => null, 'spam' => null, 'deleted' => null, 'lang_id' => null, 'lang__in' => '', 'lang__not_in' => '', 'search' => '', 'search_columns' => array(), 'count' => false, 'date_query' => null, 'update_site_cache' => true, 'update_site_meta_cache' => true, 'meta_query' => '', 'meta_key' => '', 'meta_value' => '', 'meta_type' => '', 'meta_compare' => '', ); if ( ! empty( $query ) ) { $this->query( $query ); } } public function parse_query( $query = '' ) { if ( empty( $query ) ) { $query = $this->query_vars; } $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); do_action_ref_array( 'parse_site_query', array( &$this ) ); } public function query( $query ) { $this->query_vars = wp_parse_args( $query ); return $this->get_sites(); } public function get_sites() { global $wpdb; $this->parse_query(); $this->meta_query = new WP_Meta_Query(); $this->meta_query->parse_query_vars( $this->query_vars ); do_action_ref_array( 'pre_get_sites', array( &$this ) ); $this->meta_query->parse_query_vars( $this->query_vars ); if ( ! empty( $this->meta_query->queries ) ) { $this->meta_query_clauses = $this->meta_query->get_sql( 'blog', $wpdb->blogs, 'blog_id', $this ); } $site_data = null; $site_data = apply_filters_ref_array( 'sites_pre_query', array( $site_data, &$this ) ); if ( null !== $site_data ) { if ( is_array( $site_data ) && ! $this->query_vars['count'] ) { $this->sites = $site_data; } return $site_data; } $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); unset( $_args['fields'], $_args['update_site_cache'], $_args['update_site_meta_cache'] ); $key = md5( serialize( $_args ) ); $last_changed = wp_cache_get_last_changed( 'sites' ); $cache_key = "get_sites:$key"; $cache_value = wp_cache_get_salted( $cache_key, 'site-queries', $last_changed ); if ( false === $cache_value ) { $site_ids = $this->get_site_ids(); if ( $site_ids ) { $this->set_found_sites(); } $cache_value = array( 'site_ids' => $site_ids, 'found_sites' => $this->found_sites, ); wp_cache_set_salted( $cache_key, $cache_value, 'site-queries', $last_changed ); } else { $site_ids = $cache_value['site_ids']; $this->found_sites = $cache_value['found_sites']; } if ( $this->found_sites && $this->query_vars['number'] ) { $this->max_num_pages = (int) ceil( $this->found_sites / $this->query_vars['number'] ); } if ( $this->query_vars['count'] ) { return (int) $site_ids; } $site_ids = array_map( 'intval', $site_ids ); if ( $this->query_vars['update_site_meta_cache'] ) { wp_lazyload_site_meta( $site_ids ); } if ( 'ids' === $this->query_vars['fields'] ) { $this->sites = $site_ids; return $this->sites; } if ( $this->query_vars['update_site_cache'] ) { _prime_site_caches( $site_ids, false ); } $_sites = array(); foreach ( $site_ids as $site_id ) { $_site = get_site( $site_id ); if ( $_site ) { $_sites[] = $_site; } } $_sites = apply_filters_ref_array( 'the_sites', array( $_sites, &$this ) ); $this->sites = array_map( 'get_site', $_sites ); return $this->sites; } protected function get_site_ids() { global $wpdb; $order = $this->parse_order( $this->query_vars['order'] ); if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) { $orderby = ''; } elseif ( ! empty( $this->query_vars['orderby'] ) ) { $ordersby = is_array( $this->query_vars['orderby'] ) ? $this->query_vars['orderby'] : preg_split( '/[,\s]/', $this->query_vars['orderby'] ); $orderby_array = array(); foreach ( $ordersby as $_key => $_value ) { if ( ! $_value ) { continue; } if ( is_int( $_key ) ) { $_orderby = $_value; $_order = $order; } else { $_orderby = $_key; $_order = $_value; } $parsed = $this->parse_orderby( $_orderby ); if ( ! $parsed ) { continue; } if ( 'site__in' === $_orderby || 'network__in' === $_orderby ) { $orderby_array[] = $parsed; continue; } $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); } $orderby = implode( ', ', $orderby_array ); } else { $orderby = "{$wpdb->blogs}.blog_id $order"; } $number = absint( $this->query_vars['number'] ); $offset = absint( $this->query_vars['offset'] ); $limits = ''; if ( ! empty( $number ) ) { if ( $offset ) { $limits = 'LIMIT ' . $offset . ',' . $number; } else { $limits = 'LIMIT ' . $number; } } if ( $this->query_vars['count'] ) { $fields = 'COUNT(*)'; } else { $fields = "{$wpdb->blogs}.blog_id"; } $site_id = absint( $this->query_vars['ID'] ); if ( ! empty( $site_id ) ) { $this->sql_clauses['where']['ID'] = $wpdb->prepare( "{$wpdb->blogs}.blog_id = %d", $site_id ); } if ( ! empty( $this->query_vars['site__in'] ) ) { $this->sql_clauses['where']['site__in'] = "{$wpdb->blogs}.blog_id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['site__not_in'] ) ) { $this->sql_clauses['where']['site__not_in'] = "{$wpdb->blogs}.blog_id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['site__not_in'] ) ) . ' )'; } $network_id = absint( $this->query_vars['network_id'] ); if ( ! empty( $network_id ) ) { $this->sql_clauses['where']['network_id'] = $wpdb->prepare( 'site_id = %d', $network_id ); } if ( ! empty( $this->query_vars['network__in'] ) ) { $this->sql_clauses['where']['network__in'] = 'site_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['network__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['network__not_in'] ) ) { $this->sql_clauses['where']['network__not_in'] = 'site_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['network__not_in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['domain'] ) ) { $this->sql_clauses['where']['domain'] = $wpdb->prepare( 'domain = %s', $this->query_vars['domain'] ); } if ( is_array( $this->query_vars['domain__in'] ) ) { $this->sql_clauses['where']['domain__in'] = "domain IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__in'] ) ) . "' )"; } if ( is_array( $this->query_vars['domain__not_in'] ) ) { $this->sql_clauses['where']['domain__not_in'] = "domain NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__not_in'] ) ) . "' )"; } if ( ! empty( $this->query_vars['path'] ) ) { $this->sql_clauses['where']['path'] = $wpdb->prepare( 'path = %s', $this->query_vars['path'] ); } if ( is_array( $this->query_vars['path__in'] ) ) { $this->sql_clauses['where']['path__in'] = "path IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__in'] ) ) . "' )"; } if ( is_array( $this->query_vars['path__not_in'] ) ) { $this->sql_clauses['where']['path__not_in'] = "path NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__not_in'] ) ) . "' )"; } if ( is_numeric( $this->query_vars['archived'] ) ) { $archived = absint( $this->query_vars['archived'] ); $this->sql_clauses['where']['archived'] = $wpdb->prepare( 'archived = %s ', absint( $archived ) ); } if ( is_numeric( $this->query_vars['mature'] ) ) { $mature = absint( $this->query_vars['mature'] ); $this->sql_clauses['where']['mature'] = $wpdb->prepare( 'mature = %d ', $mature ); } if ( is_numeric( $this->query_vars['spam'] ) ) { $spam = absint( $this->query_vars['spam'] ); $this->sql_clauses['where']['spam'] = $wpdb->prepare( 'spam = %d ', $spam ); } if ( is_numeric( $this->query_vars['deleted'] ) ) { $deleted = absint( $this->query_vars['deleted'] ); $this->sql_clauses['where']['deleted'] = $wpdb->prepare( 'deleted = %d ', $deleted ); } if ( is_numeric( $this->query_vars['public'] ) ) { $public = absint( $this->query_vars['public'] ); $this->sql_clauses['where']['public'] = $wpdb->prepare( 'public = %d ', $public ); } if ( is_numeric( $this->query_vars['lang_id'] ) ) { $lang_id = absint( $this->query_vars['lang_id'] ); $this->sql_clauses['where']['lang_id'] = $wpdb->prepare( 'lang_id = %d ', $lang_id ); } if ( ! empty( $this->query_vars['lang__in'] ) ) { $this->sql_clauses['where']['lang__in'] = 'lang_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['lang__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['lang__not_in'] ) ) { $this->sql_clauses['where']['lang__not_in'] = 'lang_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['lang__not_in'] ) ) . ' )'; } if ( strlen( $this->query_vars['search'] ) ) { $search_columns = array(); if ( $this->query_vars['search_columns'] ) { $search_columns = array_intersect( $this->query_vars['search_columns'], array( 'domain', 'path' ) ); } if ( ! $search_columns ) { $search_columns = array( 'domain', 'path' ); } $search_columns = apply_filters( 'site_search_columns', $search_columns, $this->query_vars['search'], $this ); $this->sql_clauses['where']['search'] = $this->get_search_sql( $this->query_vars['search'], $search_columns ); } $date_query = $this->query_vars['date_query']; if ( ! empty( $date_query ) && is_array( $date_query ) ) { $this->date_query = new WP_Date_Query( $date_query, 'registered' ); $this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() ); } $join = ''; $groupby = ''; if ( ! empty( $this->meta_query_clauses ) ) { $join .= $this->meta_query_clauses['join']; $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] ); if ( ! $this->query_vars['count'] ) { $groupby = "{$wpdb->blogs}.blog_id"; } } $where = implode( ' AND ', $this->sql_clauses['where'] ); $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); $clauses = apply_filters_ref_array( 'sites_clauses', array( compact( $pieces ), &$this ) ); $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; if ( $where ) { $where = 'WHERE ' . $where; } if ( $groupby ) { $groupby = 'GROUP BY ' . $groupby; } if ( $orderby ) { $orderby = "ORDER BY $orderby"; } $found_rows = ''; if ( ! $this->query_vars['no_found_rows'] ) { $found_rows = 'SQL_CALC_FOUND_ROWS'; } $this->sql_clauses['select'] = "SELECT $found_rows $fields"; $this->sql_clauses['from'] = "FROM $wpdb->blogs $join"; $this->sql_clauses['groupby'] = $groupby; $this->sql_clauses['orderby'] = $orderby; $this->sql_clauses['limits'] = $limits; $this->request = "{$this->sql_clauses['select']}
{$this->sql_clauses['from']}
{$where}
{$this->sql_clauses['groupby']}
{$this->sql_clauses['orderby']}
{$this->sql_clauses['limits']}"; if ( $this->query_vars['count'] ) { return (int) $wpdb->get_var( $this->request ); } $site_ids = $wpdb->get_col( $this->request ); return array_map( 'intval', $site_ids ); } private function set_found_sites() { global $wpdb; if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) { $found_sites_query = apply_filters( 'found_sites_query', 'SELECT FOUND_ROWS()', $this ); $this->found_sites = (int) $wpdb->get_var( $found_sites_query ); } } protected function get_search_sql( $search, $columns ) { global $wpdb; if ( str_contains( $search, '*' ) ) { $like = '%' . implode( '%', array_map( array( $wpdb, 'esc_like' ), explode( '*', $search ) ) ) . '%'; } else { $like = '%' . $wpdb->esc_like( $search ) . '%'; } $searches = array(); foreach ( $columns as $column ) { $searches[] = $wpdb->prepare( "$column LIKE %s", $like ); } return '(' . implode( ' OR ', $searches ) . ')'; } protected function parse_orderby( $orderby ) { global $wpdb; $parsed = false; switch ( $orderby ) { case 'site__in': $site__in = implode( ',', array_map( 'absint', $this->query_vars['site__in'] ) ); $parsed = "FIELD( {$wpdb->blogs}.blog_id, $site__in )"; break; case 'network__in': $network__in = implode( ',', array_map( 'absint', $this->query_vars['network__in'] ) ); $parsed = "FIELD( {$wpdb->blogs}.site_id, $network__in )"; break; case 'domain': case 'last_updated': case 'path': case 'registered': case 'deleted': case 'spam': case 'mature': case 'archived': case 'public': $parsed = $orderby; break; case 'network_id': $parsed = 'site_id'; break; case 'domain_length': $parsed = 'CHAR_LENGTH(domain)'; break; case 'path_length': $parsed = 'CHAR_LENGTH(path)'; break; case 'id': $parsed = "{$wpdb->blogs}.blog_id"; break; } if ( ! empty( $parsed ) || empty( $this->meta_query_clauses ) ) { return $parsed; } $meta_clauses = $this->meta_query->get_clauses(); if ( empty( $meta_clauses ) ) { return $parsed; } $primary_meta_query = reset( $meta_clauses ); if ( ! empty( $primary_meta_query['key'] ) && $primary_meta_query['key'] === $orderby ) { $orderby = 'meta_value'; } switch ( $orderby ) { case 'meta_value': if ( ! empty( $primary_meta_query['type'] ) ) { $parsed = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})"; } else { $parsed = "{$primary_meta_query['alias']}.meta_value"; } break; case 'meta_value_num': $parsed = "{$primary_meta_query['alias']}.meta_value+0"; break; default: if ( isset( $meta_clauses[ $orderby ] ) ) { $meta_clause = $meta_clauses[ $orderby ]; $parsed = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})"; } } return $parsed; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'ASC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } }
### require ABSPATH . WPINC . '/class-wp-network-query.php';
class WP_Network_Query { public $request; protected $sql_clauses = array( 'select' => '', 'from' => '', 'where' => array(), 'groupby' => '', 'orderby' => '', 'limits' => '', ); public $query_vars; public $query_var_defaults; public $networks; public $found_networks = 0; public $max_num_pages = 0; public function __construct( $query = '' ) { $this->query_var_defaults = array( 'network__in' => '', 'network__not_in' => '', 'count' => false, 'fields' => '', 'number' => '', 'offset' => '', 'no_found_rows' => true, 'orderby' => 'id', 'order' => 'ASC', 'domain' => '', 'domain__in' => '', 'domain__not_in' => '', 'path' => '', 'path__in' => '', 'path__not_in' => '', 'search' => '', 'update_network_cache' => true, ); if ( ! empty( $query ) ) { $this->query( $query ); } } public function parse_query( $query = '' ) { if ( empty( $query ) ) { $query = $this->query_vars; } $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); do_action_ref_array( 'parse_network_query', array( &$this ) ); } public function query( $query ) { $this->query_vars = wp_parse_args( $query ); return $this->get_networks(); } public function get_networks() { $this->parse_query(); do_action_ref_array( 'pre_get_networks', array( &$this ) ); $network_data = null; $network_data = apply_filters_ref_array( 'networks_pre_query', array( $network_data, &$this ) ); if ( null !== $network_data ) { if ( is_array( $network_data ) && ! $this->query_vars['count'] ) { $this->networks = $network_data; } return $network_data; } $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); unset( $_args['fields'], $_args['update_network_cache'] ); $key = md5( serialize( $_args ) ); $last_changed = wp_cache_get_last_changed( 'networks' ); $cache_key = "get_network_ids:$key"; $cache_value = wp_cache_get_salted( $cache_key, 'network-queries', $last_changed ); if ( false === $cache_value ) { $network_ids = $this->get_network_ids(); if ( $network_ids ) { $this->set_found_networks(); } $cache_value = array( 'network_ids' => $network_ids, 'found_networks' => $this->found_networks, ); wp_cache_set_salted( $cache_key, $cache_value, 'network-queries', $last_changed ); } else { $network_ids = $cache_value['network_ids']; $this->found_networks = $cache_value['found_networks']; } if ( $this->found_networks && $this->query_vars['number'] ) { $this->max_num_pages = (int) ceil( $this->found_networks / $this->query_vars['number'] ); } if ( $this->query_vars['count'] ) { return (int) $network_ids; } $network_ids = array_map( 'intval', $network_ids ); if ( 'ids' === $this->query_vars['fields'] ) { $this->networks = $network_ids; return $this->networks; } if ( $this->query_vars['update_network_cache'] ) { _prime_network_caches( $network_ids ); } $_networks = array(); foreach ( $network_ids as $network_id ) { $_network = get_network( $network_id ); if ( $_network ) { $_networks[] = $_network; } } $_networks = apply_filters_ref_array( 'the_networks', array( $_networks, &$this ) ); $this->networks = array_map( 'get_network', $_networks ); return $this->networks; } protected function get_network_ids() { global $wpdb; $order = $this->parse_order( $this->query_vars['order'] ); if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) { $orderby = ''; } elseif ( ! empty( $this->query_vars['orderby'] ) ) { $ordersby = is_array( $this->query_vars['orderby'] ) ? $this->query_vars['orderby'] : preg_split( '/[,\s]/', $this->query_vars['orderby'] ); $orderby_array = array(); foreach ( $ordersby as $_key => $_value ) { if ( ! $_value ) { continue; } if ( is_int( $_key ) ) { $_orderby = $_value; $_order = $order; } else { $_orderby = $_key; $_order = $_value; } $parsed = $this->parse_orderby( $_orderby ); if ( ! $parsed ) { continue; } if ( 'network__in' === $_orderby ) { $orderby_array[] = $parsed; continue; } $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); } $orderby = implode( ', ', $orderby_array ); } else { $orderby = "$wpdb->site.id $order"; } $number = absint( $this->query_vars['number'] ); $offset = absint( $this->query_vars['offset'] ); $limits = ''; if ( ! empty( $number ) ) { if ( $offset ) { $limits = 'LIMIT ' . $offset . ',' . $number; } else { $limits = 'LIMIT ' . $number; } } if ( $this->query_vars['count'] ) { $fields = 'COUNT(*)'; } else { $fields = "$wpdb->site.id"; } if ( ! empty( $this->query_vars['network__in'] ) ) { $this->sql_clauses['where']['network__in'] = "$wpdb->site.id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['network__not_in'] ) ) { $this->sql_clauses['where']['network__not_in'] = "$wpdb->site.id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__not_in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['domain'] ) ) { $this->sql_clauses['where']['domain'] = $wpdb->prepare( "$wpdb->site.domain = %s", $this->query_vars['domain'] ); } if ( is_array( $this->query_vars['domain__in'] ) ) { $this->sql_clauses['where']['domain__in'] = "$wpdb->site.domain IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__in'] ) ) . "' )"; } if ( is_array( $this->query_vars['domain__not_in'] ) ) { $this->sql_clauses['where']['domain__not_in'] = "$wpdb->site.domain NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__not_in'] ) ) . "' )"; } if ( ! empty( $this->query_vars['path'] ) ) { $this->sql_clauses['where']['path'] = $wpdb->prepare( "$wpdb->site.path = %s", $this->query_vars['path'] ); } if ( is_array( $this->query_vars['path__in'] ) ) { $this->sql_clauses['where']['path__in'] = "$wpdb->site.path IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__in'] ) ) . "' )"; } if ( is_array( $this->query_vars['path__not_in'] ) ) { $this->sql_clauses['where']['path__not_in'] = "$wpdb->site.path NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__not_in'] ) ) . "' )"; } if ( strlen( $this->query_vars['search'] ) ) { $this->sql_clauses['where']['search'] = $this->get_search_sql( $this->query_vars['search'], array( "$wpdb->site.domain", "$wpdb->site.path" ) ); } $join = ''; $where = implode( ' AND ', $this->sql_clauses['where'] ); $groupby = ''; $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); $clauses = apply_filters_ref_array( 'networks_clauses', array( compact( $pieces ), &$this ) ); $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; if ( $where ) { $where = 'WHERE ' . $where; } if ( $groupby ) { $groupby = 'GROUP BY ' . $groupby; } if ( $orderby ) { $orderby = "ORDER BY $orderby"; } $found_rows = ''; if ( ! $this->query_vars['no_found_rows'] ) { $found_rows = 'SQL_CALC_FOUND_ROWS'; } $this->sql_clauses['select'] = "SELECT $found_rows $fields"; $this->sql_clauses['from'] = "FROM $wpdb->site $join"; $this->sql_clauses['groupby'] = $groupby; $this->sql_clauses['orderby'] = $orderby; $this->sql_clauses['limits'] = $limits; $this->request = "{$this->sql_clauses['select']}
{$this->sql_clauses['from']}
{$where}
{$this->sql_clauses['groupby']}
{$this->sql_clauses['orderby']}
{$this->sql_clauses['limits']}"; if ( $this->query_vars['count'] ) { return (int) $wpdb->get_var( $this->request ); } $network_ids = $wpdb->get_col( $this->request ); return array_map( 'intval', $network_ids ); } private function set_found_networks() { global $wpdb; if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) { $found_networks_query = apply_filters( 'found_networks_query', 'SELECT FOUND_ROWS()', $this ); $this->found_networks = (int) $wpdb->get_var( $found_networks_query ); } } protected function get_search_sql( $search, $columns ) { global $wpdb; $like = '%' . $wpdb->esc_like( $search ) . '%'; $searches = array(); foreach ( $columns as $column ) { $searches[] = $wpdb->prepare( "$column LIKE %s", $like ); } return '(' . implode( ' OR ', $searches ) . ')'; } protected function parse_orderby( $orderby ) { global $wpdb; $allowed_keys = array( 'id', 'domain', 'path', ); $parsed = false; if ( 'network__in' === $orderby ) { $network__in = implode( ',', array_map( 'absint', $this->query_vars['network__in'] ) ); $parsed = "FIELD( {$wpdb->site}.id, $network__in )"; } elseif ( 'domain_length' === $orderby || 'path_length' === $orderby ) { $field = substr( $orderby, 0, -7 ); $parsed = "CHAR_LENGTH($wpdb->site.$field)"; } elseif ( in_array( $orderby, $allowed_keys, true ) ) { $parsed = "$wpdb->site.$orderby"; } return $parsed; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'ASC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } }
### require ABSPATH . WPINC . '/ms-blogs.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } require_once ABSPATH . WPINC . '/ms-site.php'; require_once ABSPATH . WPINC . '/ms-network.php'; function wpmu_update_blogs_date() { $site_id = get_current_blog_id(); update_blog_details( $site_id, array( 'last_updated' => current_time( 'mysql', true ) ) ); do_action( 'wpmu_blog_updated', $site_id ); } function get_blogaddress_by_id( $blog_id ) { $bloginfo = get_site( (int) $blog_id ); if ( empty( $bloginfo ) ) { return ''; } $scheme = parse_url( $bloginfo->home, PHP_URL_SCHEME ); $scheme = empty( $scheme ) ? 'http' : $scheme; return esc_url( $scheme . '://' . $bloginfo->domain . $bloginfo->path ); } function get_blogaddress_by_name( $blogname ) { if ( is_subdomain_install() ) { if ( 'main' === $blogname ) { $blogname = 'www'; } $url = rtrim( network_home_url(), '/' ); if ( ! empty( $blogname ) ) { $url = preg_replace( '|^([^\.]+://)|', '${1}' . $blogname . '.', $url ); } } else { $url = network_home_url( $blogname ); } return esc_url( $url . '/' ); } function get_id_from_blogname( $slug ) { $current_network = get_network(); $slug = trim( $slug, '/' ); if ( is_subdomain_install() ) { $domain = $slug . '.' . preg_replace( '|^www\.|', '', $current_network->domain ); $path = $current_network->path; } else { $domain = $current_network->domain; $path = $current_network->path . $slug . '/'; } $site_ids = get_sites( array( 'number' => 1, 'fields' => 'ids', 'domain' => $domain, 'path' => $path, 'update_site_meta_cache' => false, ) ); if ( empty( $site_ids ) ) { return null; } return array_shift( $site_ids ); } function get_blog_details( $fields = null, $get_all = true ) { global $wpdb; if ( is_array( $fields ) ) { if ( isset( $fields['blog_id'] ) ) { $blog_id = $fields['blog_id']; } elseif ( isset( $fields['domain'] ) && isset( $fields['path'] ) ) { $key = md5( $fields['domain'] . $fields['path'] ); $blog = wp_cache_get( $key, 'blog-lookup' ); if ( false !== $blog ) { return $blog; } if ( str_starts_with( $fields['domain'], 'www.' ) ) { $nowww = substr( $fields['domain'], 4 ); $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) AND path = %s ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'], $fields['path'] ) ); } else { $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $fields['domain'], $fields['path'] ) ); } if ( $blog ) { wp_cache_set( $blog->blog_id . 'short', $blog, 'blog-details' ); $blog_id = $blog->blog_id; } else { return false; } } elseif ( isset( $fields['domain'] ) && is_subdomain_install() ) { $key = md5( $fields['domain'] ); $blog = wp_cache_get( $key, 'blog-lookup' ); if ( false !== $blog ) { return $blog; } if ( str_starts_with( $fields['domain'], 'www.' ) ) { $nowww = substr( $fields['domain'], 4 ); $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'] ) ); } else { $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $fields['domain'] ) ); } if ( $blog ) { wp_cache_set( $blog->blog_id . 'short', $blog, 'blog-details' ); $blog_id = $blog->blog_id; } else { return false; } } else { return false; } } else { if ( ! $fields ) { $blog_id = get_current_blog_id(); } elseif ( ! is_numeric( $fields ) ) { $blog_id = get_id_from_blogname( $fields ); } else { $blog_id = $fields; } } $blog_id = (int) $blog_id; $all = $get_all ? '' : 'short'; $details = wp_cache_get( $blog_id . $all, 'blog-details' ); if ( $details ) { if ( ! is_object( $details ) ) { if ( -1 === $details ) { return false; } else { wp_cache_delete( $blog_id . $all, 'blog-details' ); unset( $details ); } } else { return $details; } } if ( $get_all ) { $details = wp_cache_get( $blog_id . 'short', 'blog-details' ); } else { $details = wp_cache_get( $blog_id, 'blog-details' ); if ( $details ) { if ( ! is_object( $details ) ) { if ( -1 === $details ) { return false; } else { wp_cache_delete( $blog_id, 'blog-details' ); unset( $details ); } } else { return $details; } } } if ( empty( $details ) ) { $details = WP_Site::get_instance( $blog_id ); if ( ! $details ) { wp_cache_set( $blog_id, -1, 'blog-details' ); return false; } } if ( ! $details instanceof WP_Site ) { $details = new WP_Site( $details ); } if ( ! $get_all ) { wp_cache_set( $blog_id . $all, $details, 'blog-details' ); return $details; } $switched_blog = false; if ( get_current_blog_id() !== $blog_id ) { switch_to_blog( $blog_id ); $switched_blog = true; } $details->blogname = get_option( 'blogname' ); $details->siteurl = get_option( 'siteurl' ); $details->post_count = get_option( 'post_count' ); $details->home = get_option( 'home' ); if ( $switched_blog ) { restore_current_blog(); } $details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' ); wp_cache_set( $blog_id . $all, $details, 'blog-details' ); $key = md5( $details->domain . $details->path ); wp_cache_set( $key, $details, 'blog-lookup' ); return $details; } function refresh_blog_details( $blog_id = 0 ) { $blog_id = (int) $blog_id; if ( ! $blog_id ) { $blog_id = get_current_blog_id(); } clean_blog_cache( $blog_id ); } function update_blog_details( $blog_id, $details = array() ) { if ( empty( $details ) ) { return false; } if ( is_object( $details ) ) { $details = get_object_vars( $details ); } $site = wp_update_site( $blog_id, $details ); if ( is_wp_error( $site ) ) { return false; } return true; } function clean_site_details_cache( $site_id = 0 ) { $site_id = (int) $site_id; if ( ! $site_id ) { $site_id = get_current_blog_id(); } wp_cache_delete( $site_id, 'site-details' ); wp_cache_delete( $site_id, 'blog-details' ); } function get_blog_option( $id, $option, $default_value = false ) { $id = (int) $id; if ( empty( $id ) ) { $id = get_current_blog_id(); } if ( get_current_blog_id() === $id ) { return get_option( $option, $default_value ); } switch_to_blog( $id ); $value = get_option( $option, $default_value ); restore_current_blog(); return apply_filters( "blog_option_{$option}", $value, $id ); } function add_blog_option( $id, $option, $value ) { $id = (int) $id; if ( empty( $id ) ) { $id = get_current_blog_id(); } if ( get_current_blog_id() === $id ) { return add_option( $option, $value ); } switch_to_blog( $id ); $return = add_option( $option, $value ); restore_current_blog(); return $return; } function delete_blog_option( $id, $option ) { $id = (int) $id; if ( empty( $id ) ) { $id = get_current_blog_id(); } if ( get_current_blog_id() === $id ) { return delete_option( $option ); } switch_to_blog( $id ); $return = delete_option( $option ); restore_current_blog(); return $return; } function update_blog_option( $id, $option, $value, $deprecated = null ) { $id = (int) $id; if ( null !== $deprecated ) { _deprecated_argument( __FUNCTION__, '3.1.0' ); } if ( get_current_blog_id() === $id ) { return update_option( $option, $value ); } switch_to_blog( $id ); $return = update_option( $option, $value ); restore_current_blog(); return $return; } function switch_to_blog( $new_blog_id, $deprecated = null ) { global $wpdb; $prev_blog_id = get_current_blog_id(); if ( empty( $new_blog_id ) ) { $new_blog_id = $prev_blog_id; } $GLOBALS['_wp_switched_stack'][] = $prev_blog_id; if ( $new_blog_id === $prev_blog_id ) { do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' ); $GLOBALS['switched'] = true; return true; } $wpdb->set_blog_id( $new_blog_id ); $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix(); $GLOBALS['blog_id'] = $new_blog_id; if ( function_exists( 'wp_cache_switch_to_blog' ) ) { wp_cache_switch_to_blog( $new_blog_id ); } else { global $wp_object_cache; if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) { $global_groups = $wp_object_cache->global_groups; } else { $global_groups = false; } wp_cache_init(); if ( function_exists( 'wp_cache_add_global_groups' ) ) { if ( is_array( $global_groups ) ) { wp_cache_add_global_groups( $global_groups ); } else { wp_cache_add_global_groups( array( 'blog-details', 'blog-id-cache', 'blog-lookup', 'blog_meta', 'global-posts', 'image_editor', 'networks', 'network-queries', 'sites', 'site-details', 'site-options', 'site-queries', 'site-transient', 'theme_files', 'rss', 'users', 'user-queries', 'user_meta', 'useremail', 'userlogins', 'userslugs', ) ); } wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } } do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' ); $GLOBALS['switched'] = true; return true; } function restore_current_blog() { global $wpdb; if ( empty( $GLOBALS['_wp_switched_stack'] ) ) { return false; } $new_blog_id = array_pop( $GLOBALS['_wp_switched_stack'] ); $prev_blog_id = get_current_blog_id(); if ( $new_blog_id === $prev_blog_id ) { do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'restore' ); $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] ); return true; } $wpdb->set_blog_id( $new_blog_id ); $GLOBALS['blog_id'] = $new_blog_id; $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix(); if ( function_exists( 'wp_cache_switch_to_blog' ) ) { wp_cache_switch_to_blog( $new_blog_id ); } else { global $wp_object_cache; if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) { $global_groups = $wp_object_cache->global_groups; } else { $global_groups = false; } wp_cache_init(); if ( function_exists( 'wp_cache_add_global_groups' ) ) { if ( is_array( $global_groups ) ) { wp_cache_add_global_groups( $global_groups ); } else { wp_cache_add_global_groups( array( 'blog-details', 'blog-id-cache', 'blog-lookup', 'blog_meta', 'global-posts', 'image_editor', 'networks', 'network-queries', 'sites', 'site-details', 'site-options', 'site-queries', 'site-transient', 'theme_files', 'rss', 'users', 'user-queries', 'user_meta', 'useremail', 'userlogins', 'userslugs', ) ); } wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } } do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'restore' ); $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] ); return true; } function wp_switch_roles_and_user( $new_site_id, $old_site_id ) { if ( $new_site_id === $old_site_id ) { return; } if ( ! did_action( 'init' ) ) { return; } wp_roles()->for_site( $new_site_id ); wp_get_current_user()->for_site( $new_site_id ); } function ms_is_switched() { return ! empty( $GLOBALS['_wp_switched_stack'] ); } function is_archived( $id ) { return get_blog_status( $id, 'archived' ); } function update_archived( $id, $archived ) { update_blog_status( $id, 'archived', $archived ); return $archived; } function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) { global $wpdb; if ( null !== $deprecated ) { _deprecated_argument( __FUNCTION__, '3.1.0' ); } $allowed_field_names = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); if ( ! in_array( $pref, $allowed_field_names, true ) ) { return $value; } $result = wp_update_site( $blog_id, array( $pref => $value, ) ); if ( is_wp_error( $result ) ) { return false; } return $value; } function get_blog_status( $id, $pref ) { global $wpdb; $details = get_site( $id ); if ( $details ) { return $details->$pref; } return $wpdb->get_var( $wpdb->prepare( "SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id ) ); } function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) { global $wpdb; if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, 'MU' ); } return $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", get_current_network_id(), $start, $quantity ), ARRAY_A ); } function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) { $post_type_obj = get_post_type_object( $post->post_type ); if ( ! $post_type_obj || ! $post_type_obj->public ) { return; } if ( 'publish' !== $new_status && 'publish' !== $old_status ) { return; } wpmu_update_blogs_date(); } function _update_blog_date_on_post_delete( $post_id ) { $post = get_post( $post_id ); $post_type_obj = get_post_type_object( $post->post_type ); if ( ! $post_type_obj || ! $post_type_obj->public ) { return; } if ( 'publish' !== $post->post_status ) { return; } wpmu_update_blogs_date(); } function _update_posts_count_on_delete( $post_id, $post ) { if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) { return; } update_posts_count(); } function _update_posts_count_on_transition_post_status( $new_status, $old_status, $post = null ) { if ( $new_status === $old_status ) { return; } if ( 'post' !== get_post_type( $post ) ) { return; } if ( 'publish' !== $new_status && 'publish' !== $old_status ) { return; } update_posts_count(); } function wp_count_sites( $network_id = null ) { if ( empty( $network_id ) ) { $network_id = get_current_network_id(); } $counts = array(); $args = array( 'network_id' => $network_id, 'number' => 1, 'fields' => 'ids', 'no_found_rows' => false, ); $q = new WP_Site_Query( $args ); $counts['all'] = $q->found_sites; $_args = $args; $statuses = array( 'public', 'archived', 'mature', 'spam', 'deleted' ); foreach ( $statuses as $status ) { $_args = $args; $_args[ $status ] = 1; $q = new WP_Site_Query( $_args ); $counts[ $status ] = $q->found_sites; } return $counts; }
### require ABSPATH . WPINC . '/ms-settings.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } global $current_site, $current_blog, $domain, $path, $site_id, $public; require_once ABSPATH . WPINC . '/class-wp-network.php'; require_once ABSPATH . WPINC . '/class-wp-site.php'; require_once ABSPATH . WPINC . '/ms-load.php'; require_once ABSPATH . WPINC . '/ms-default-constants.php'; if ( defined( 'SUNRISE' ) ) { include_once WP_CONTENT_DIR . '/sunrise.php'; } ms_subdomain_constants(); if ( ! isset( $current_site ) || ! isset( $current_blog ) ) { $domain = strtolower( stripslashes( $_SERVER['HTTP_HOST'] ?? '' ) ); if ( str_ends_with( $domain, ':80' ) ) { $domain = substr( $domain, 0, -3 ); $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 ); } elseif ( str_ends_with( $domain, ':443' ) ) { $domain = substr( $domain, 0, -4 ); $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 ); } $path = stripslashes( $_SERVER['REQUEST_URI'] ); if ( is_admin() ) { $path = preg_replace( '#(.*)/wp-admin/.*#', '$1/', $path ); } list( $path ) = explode( '?', $path ); $bootstrap_result = ms_load_current_site_and_network( $domain, $path, is_subdomain_install() ); if ( true === $bootstrap_result ) { } elseif ( false === $bootstrap_result ) { ms_not_installed( $domain, $path ); } else { header( 'Location: ' . $bootstrap_result ); exit; } unset( $bootstrap_result ); $blog_id = $current_blog->blog_id; $public = $current_blog->public; if ( empty( $current_blog->site_id ) ) { $current_blog->site_id = 1; } $site_id = $current_blog->site_id; wp_load_core_site_options( $site_id ); } $wpdb->set_prefix( $table_prefix, false ); $wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id ); $table_prefix = $wpdb->get_blog_prefix(); $_wp_switched_stack = array(); $switched = false; wp_start_object_cache(); if ( ! $current_site instanceof WP_Network ) { $current_site = new WP_Network( $current_site ); } if ( ! $current_blog instanceof WP_Site ) { $current_blog = new WP_Site( $current_blog ); } ms_upload_constants(); do_action( 'ms_loaded' );
} elseif ( ! defined( 'MULTISITE' ) ) {
define( 'MULTISITE', false );
}
register_shutdown_function( 'shutdown_action_hook' );
if ( SHORTINIT ) {
return false;
}
###require_once ABSPATH . WPINC . '/l10n.php';
function get_locale() { global $locale, $wp_local_package; if ( isset( $locale ) ) { return apply_filters( 'locale', $locale ); } if ( isset( $wp_local_package ) ) { $locale = $wp_local_package; } if ( defined( 'WPLANG' ) ) { $locale = WPLANG; } if ( is_multisite() ) { if ( wp_installing() ) { $ms_locale = get_site_option( 'WPLANG' ); } else { $ms_locale = get_option( 'WPLANG' ); if ( false === $ms_locale ) { $ms_locale = get_site_option( 'WPLANG' ); } } if ( false !== $ms_locale ) { $locale = $ms_locale; } } else { $db_locale = get_option( 'WPLANG' ); if ( false !== $db_locale ) { $locale = $db_locale; } } if ( empty( $locale ) ) { $locale = 'en_US'; } return apply_filters( 'locale', $locale ); } function get_user_locale( $user = 0 ) { $user_object = false; if ( 0 === $user && function_exists( 'wp_get_current_user' ) ) { $user_object = wp_get_current_user(); } elseif ( $user instanceof WP_User ) { $user_object = $user; } elseif ( $user && is_numeric( $user ) ) { $user_object = get_user_by( 'id', $user ); } if ( ! $user_object ) { return get_locale(); } $locale = $user_object->locale; return $locale ? $locale : get_locale(); } function determine_locale() { $determined_locale = apply_filters( 'pre_determine_locale', null ); if ( $determined_locale && is_string( $determined_locale ) ) { return $determined_locale; } if ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] && ( ! empty( $_GET['wp_lang'] ) || ! empty( $_COOKIE['wp_lang'] ) ) ) { if ( ! empty( $_GET['wp_lang'] ) ) { $determined_locale = sanitize_locale_name( $_GET['wp_lang'] ); } else { $determined_locale = sanitize_locale_name( $_COOKIE['wp_lang'] ); } } elseif ( is_admin() || ( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() ) ) { $determined_locale = get_user_locale(); } elseif ( ( ! empty( $_REQUEST['language'] ) || isset( $GLOBALS['wp_local_package'] ) ) && wp_installing() ) { if ( ! empty( $_REQUEST['language'] ) ) { $determined_locale = sanitize_locale_name( $_REQUEST['language'] ); } else { $determined_locale = $GLOBALS['wp_local_package']; } } if ( ! $determined_locale ) { $determined_locale = get_locale(); } return apply_filters( 'determine_locale', $determined_locale ); } function translate( $text, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); $translation = $translations->translate( $text ); $translation = apply_filters( 'gettext', $translation, $text, $domain ); $translation = apply_filters( "gettext_{$domain}", $translation, $text, $domain ); return $translation; } function before_last_bar( $text ) { $last_bar = strrpos( $text, '|' ); if ( false === $last_bar ) { return $text; } else { return substr( $text, 0, $last_bar ); } } function translate_with_gettext_context( $text, $context, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); $translation = $translations->translate( $text, $context ); $translation = apply_filters( 'gettext_with_context', $translation, $text, $context, $domain ); $translation = apply_filters( "gettext_with_context_{$domain}", $translation, $text, $context, $domain ); return $translation; } function __( $text, $domain = 'default' ) { return translate( $text, $domain ); } function esc_attr__( $text, $domain = 'default' ) { return esc_attr( translate( $text, $domain ) ); } function esc_html__( $text, $domain = 'default' ) { return esc_html( translate( $text, $domain ) ); } function _e( $text, $domain = 'default' ) { echo translate( $text, $domain ); } function esc_attr_e( $text, $domain = 'default' ) { echo esc_attr( translate( $text, $domain ) ); } function esc_html_e( $text, $domain = 'default' ) { echo esc_html( translate( $text, $domain ) ); } function _x( $text, $context, $domain = 'default' ) { return translate_with_gettext_context( $text, $context, $domain ); } function _ex( $text, $context, $domain = 'default' ) { echo _x( $text, $context, $domain ); } function esc_attr_x( $text, $context, $domain = 'default' ) { return esc_attr( translate_with_gettext_context( $text, $context, $domain ) ); } function esc_html_x( $text, $context, $domain = 'default' ) { return esc_html( translate_with_gettext_context( $text, $context, $domain ) ); } function _n( $single, $plural, $number, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); $translation = $translations->translate_plural( $single, $plural, $number ); $translation = apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); $translation = apply_filters( "ngettext_{$domain}", $translation, $single, $plural, $number, $domain ); return $translation; } function _nx( $single, $plural, $number, $context, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); $translation = $translations->translate_plural( $single, $plural, $number, $context ); $translation = apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); $translation = apply_filters( "ngettext_with_context_{$domain}", $translation, $single, $plural, $number, $context, $domain ); return $translation; } function _n_noop( $singular, $plural, $domain = null ) { return array( 0 => $singular, 1 => $plural, 'singular' => $singular, 'plural' => $plural, 'context' => null, 'domain' => $domain, ); } function _nx_noop( $singular, $plural, $context, $domain = null ) { return array( 0 => $singular, 1 => $plural, 2 => $context, 'singular' => $singular, 'plural' => $plural, 'context' => $context, 'domain' => $domain, ); } function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) { if ( $nooped_plural['domain'] ) { $domain = $nooped_plural['domain']; } if ( $nooped_plural['context'] ) { return _nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain ); } else { return _n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain ); } } function load_textdomain( $domain, $mofile, $locale = null ) { global $l10n, $l10n_unloaded, $wp_textdomain_registry; $l10n_unloaded = (array) $l10n_unloaded; if ( ! is_string( $domain ) ) { return false; } $loaded = apply_filters( 'pre_load_textdomain', null, $domain, $mofile, $locale ); if ( null !== $loaded ) { if ( true === $loaded ) { unset( $l10n_unloaded[ $domain ] ); } return $loaded; } $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile, $locale ); if ( true === (bool) $plugin_override ) { unset( $l10n_unloaded[ $domain ] ); return true; } do_action( 'load_textdomain', $domain, $mofile ); $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain ); if ( ! $locale ) { $locale = determine_locale(); } $i18n_controller = WP_Translation_Controller::get_instance(); $i18n_controller->set_locale( $locale ); $preferred_format = apply_filters( 'translation_file_format', 'php', $domain ); if ( ! in_array( $preferred_format, array( 'php', 'mo' ), true ) ) { $preferred_format = 'php'; } $translation_files = array(); if ( 'mo' !== $preferred_format ) { $translation_files[] = substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) ); } $translation_files[] = $mofile; foreach ( $translation_files as $file ) { $file = (string) apply_filters( 'load_translation_file', $file, $domain, $locale ); $success = $i18n_controller->load_file( $file, $domain, $locale ); if ( $success ) { if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof MO ) { $i18n_controller->load_file( $l10n[ $domain ]->get_filename(), $domain, $locale ); } unset( $l10n[ $domain ] ); $l10n[ $domain ] = new WP_Translations( $i18n_controller, $domain ); $wp_textdomain_registry->set( $domain, $locale, dirname( $file ) ); return true; } } return false; } function unload_textdomain( $domain, $reloadable = false ) { global $l10n, $l10n_unloaded; $l10n_unloaded = (array) $l10n_unloaded; $plugin_override = apply_filters( 'override_unload_textdomain', false, $domain, $reloadable ); if ( $plugin_override ) { if ( ! $reloadable ) { $l10n_unloaded[ $domain ] = true; } return true; } do_action( 'unload_textdomain', $domain, $reloadable ); if ( ! $reloadable ) { WP_Translation_Controller::get_instance()->unload_textdomain( $domain ); } if ( isset( $l10n[ $domain ] ) ) { if ( $l10n[ $domain ] instanceof NOOP_Translations ) { unset( $l10n[ $domain ] ); return false; } unset( $l10n[ $domain ] ); if ( ! $reloadable ) { $l10n_unloaded[ $domain ] = true; } return true; } return false; } function load_default_textdomain( $locale = null ) { if ( null === $locale ) { $locale = determine_locale(); } unload_textdomain( 'default', true ); $return = load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo", $locale ); if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) { load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo", $locale ); return $return; } if ( is_admin() || wp_installing() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) || doing_action( 'wp_maybe_auto_update' ) ) { load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo", $locale ); } if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) { load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo", $locale ); } return $return; } function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) { global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; } if ( false !== $plugin_rel_path ) { $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' ); } elseif ( false !== $deprecated ) { _deprecated_argument( __FUNCTION__, '2.7.0' ); $path = ABSPATH . trim( $deprecated, '/' ); } else { $path = WP_PLUGIN_DIR; } $wp_textdomain_registry->set_custom_path( $domain, $path ); if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { unset( $l10n[ $domain ] ); } return true; } function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; } $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' ); $wp_textdomain_registry->set_custom_path( $domain, $path ); if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { unset( $l10n[ $domain ] ); } return true; } function load_theme_textdomain( $domain, $path = false ) { global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; } if ( ! $path ) { $path = get_template_directory(); } $wp_textdomain_registry->set_custom_path( $domain, $path ); if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { unset( $l10n[ $domain ] ); } return true; } function load_child_theme_textdomain( $domain, $path = false ) { if ( ! $path ) { $path = get_stylesheet_directory(); } return load_theme_textdomain( $domain, $path ); } function load_script_textdomain( $handle, $domain = 'default', $path = '' ) { global $wp_textdomain_registry; $wp_scripts = wp_scripts(); if ( ! isset( $wp_scripts->registered[ $handle ] ) ) { return false; } $locale = determine_locale(); if ( ! $path ) { $path = $wp_textdomain_registry->get( $domain, $locale ); } $path = untrailingslashit( $path ); $file_base = 'default' === $domain ? $locale : $domain . '-' . $locale; $handle_filename = $file_base . '-' . $handle . '.json'; if ( $path ) { $translations = load_script_translations( $path . '/' . $handle_filename, $handle, $domain ); if ( $translations ) { return $translations; } } $src = $wp_scripts->registered[ $handle ]->src; if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && str_starts_with( $src, $wp_scripts->content_url ) ) ) { $src = $wp_scripts->base_url . $src; } $relative = false; $languages_path = WP_LANG_DIR; $src_url = wp_parse_url( $src ); $content_url = wp_parse_url( content_url() ); $plugins_url = wp_parse_url( plugins_url() ); $site_url = wp_parse_url( site_url() ); $theme_root = get_theme_root(); if ( ( ! isset( $content_url['path'] ) || str_starts_with( $src_url['path'], $content_url['path'] ) ) && ( ! isset( $src_url['host'] ) || ! isset( $content_url['host'] ) || $src_url['host'] === $content_url['host'] ) ) { if ( isset( $content_url['path'] ) ) { $relative = substr( $src_url['path'], strlen( $content_url['path'] ) ); } else { $relative = $src_url['path']; } $relative = trim( $relative, '/' ); $relative = explode( '/', $relative ); $theme_dir = array_slice( explode( '/', $theme_root ), -1 ); $dirname = $theme_dir[0] === $relative[0] ? 'themes' : 'plugins'; $languages_path = WP_LANG_DIR . '/' . $dirname; $relative = array_slice( $relative, 2 ); $relative = implode( '/', $relative ); } elseif ( ( ! isset( $plugins_url['path'] ) || str_starts_with( $src_url['path'], $plugins_url['path'] ) ) && ( ! isset( $src_url['host'] ) || ! isset( $plugins_url['host'] ) || $src_url['host'] === $plugins_url['host'] ) ) { if ( isset( $plugins_url['path'] ) ) { $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) ); } else { $relative = $src_url['path']; } $relative = trim( $relative, '/' ); $relative = explode( '/', $relative ); $languages_path = WP_LANG_DIR . '/plugins'; $relative = array_slice( $relative, 1 ); $relative = implode( '/', $relative ); } elseif ( ! isset( $src_url['host'] ) || ! isset( $site_url['host'] ) || $src_url['host'] === $site_url['host'] ) { if ( ! isset( $site_url['path'] ) ) { $relative = trim( $src_url['path'], '/' ); } elseif ( str_starts_with( $src_url['path'], trailingslashit( $site_url['path'] ) ) ) { $relative = substr( $src_url['path'], strlen( $site_url['path'] ) ); $relative = trim( $relative, '/' ); } } $relative = apply_filters( 'load_script_textdomain_relative_path', $relative, $src ); if ( false === $relative ) { return load_script_translations( false, $handle, $domain ); } if ( str_ends_with( $relative, '.min.js' ) ) { $relative = substr( $relative, 0, -7 ) . '.js'; } $md5_filename = $file_base . '-' . md5( $relative ) . '.json'; if ( $path ) { $translations = load_script_translations( $path . '/' . $md5_filename, $handle, $domain ); if ( $translations ) { return $translations; } } $translations = load_script_translations( $languages_path . '/' . $md5_filename, $handle, $domain ); if ( $translations ) { return $translations; } return load_script_translations( false, $handle, $domain ); } function load_script_translations( $file, $handle, $domain ) { $translations = apply_filters( 'pre_load_script_translations', null, $file, $handle, $domain ); if ( null !== $translations ) { return $translations; } $file = apply_filters( 'load_script_translation_file', $file, $handle, $domain ); if ( ! $file || ! is_readable( $file ) ) { return false; } $translations = file_get_contents( $file ); return apply_filters( 'load_script_translations', $translations, $file, $handle, $domain ); } function _load_textdomain_just_in_time( $domain ) { global $l10n_unloaded, $wp_textdomain_registry; $l10n_unloaded = (array) $l10n_unloaded; if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) { return false; } if ( ! $wp_textdomain_registry->has( $domain ) ) { return false; } $locale = determine_locale(); $path = $wp_textdomain_registry->get( $domain, $locale ); if ( ! $path ) { return false; } if ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Translation loading for the %1$s domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the %2$s action or later.' ), '<code>' . $domain . '</code>', '<code>init</code>' ), '6.7.0' ); } $template_directory = trailingslashit( get_template_directory() ); $stylesheet_directory = trailingslashit( get_stylesheet_directory() ); if ( str_starts_with( $path, $template_directory ) || str_starts_with( $path, $stylesheet_directory ) ) { $mofile = "{$path}{$locale}.mo"; } else { $mofile = "{$path}{$domain}-{$locale}.mo"; } return load_textdomain( $domain, $mofile, $locale ); } function get_translations_for_domain( $domain ) { global $l10n; if ( isset( $l10n[ $domain ] ) || ( _load_textdomain_just_in_time( $domain ) && isset( $l10n[ $domain ] ) ) ) { return $l10n[ $domain ]; } static $noop_translations = null; if ( null === $noop_translations ) { $noop_translations = new NOOP_Translations(); } $l10n[ $domain ] = &$noop_translations; return $noop_translations; } function is_textdomain_loaded( $domain ) { global $l10n; return isset( $l10n[ $domain ] ) && ! $l10n[ $domain ] instanceof NOOP_Translations; } function translate_user_role( $name, $domain = 'default' ) { return translate_with_gettext_context( before_last_bar( $name ), 'User role', $domain ); } function get_available_languages( $dir = null ) { global $wp_textdomain_registry; $languages = array(); $path = is_null( $dir ) ? WP_LANG_DIR : $dir; $lang_files = $wp_textdomain_registry->get_language_files_from_path( $path ); if ( $lang_files ) { foreach ( $lang_files as $lang_file ) { $lang_file = basename( $lang_file, '.mo' ); $lang_file = basename( $lang_file, '.l10n.php' ); if ( ! str_starts_with( $lang_file, 'continents-cities' ) && ! str_starts_with( $lang_file, 'ms-' ) && ! str_starts_with( $lang_file, 'admin-' ) ) { $languages[] = $lang_file; } } } return apply_filters( 'get_available_languages', array_unique( $languages ), $dir ); } function wp_get_installed_translations( $type ) { global $wp_textdomain_registry; if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) { return array(); } $dir = 'core' === $type ? WP_LANG_DIR : WP_LANG_DIR . "/$type"; if ( ! is_dir( $dir ) ) { return array(); } $files = $wp_textdomain_registry->get_language_files_from_path( $dir ); if ( ! $files ) { return array(); } $language_data = array(); foreach ( $files as $file ) { if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?)\.(?:mo|l10n\.php)/', basename( $file ), $match ) ) { continue; } list( , $textdomain, $language ) = $match; if ( '' === $textdomain ) { $textdomain = 'default'; } if ( str_ends_with( $file, '.mo' ) ) { $pofile = substr_replace( $file, '.po', - strlen( '.mo' ) ); if ( ! file_exists( $pofile ) ) { continue; } $language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( $pofile ); } else { $pofile = substr_replace( $file, '.po', - strlen( '.l10n.php' ) ); if ( file_exists( $pofile ) ) { continue; } $language_data[ $textdomain ][ $language ] = wp_get_l10n_php_file_data( $file ); } } return $language_data; } function wp_get_pomo_file_data( $po_file ) { $headers = get_file_data( $po_file, array( 'POT-Creation-Date' => '"POT-Creation-Date', 'PO-Revision-Date' => '"PO-Revision-Date', 'Project-Id-Version' => '"Project-Id-Version', 'X-Generator' => '"X-Generator', ) ); foreach ( $headers as $header => $value ) { $headers[ $header ] = preg_replace( '~(\\\n)?"$~', '', $value ); } return $headers; } function wp_get_l10n_php_file_data( $php_file ) { $data = (array) include $php_file; unset( $data['messages'] ); $headers = array( 'POT-Creation-Date' => 'pot-creation-date', 'PO-Revision-Date' => 'po-revision-date', 'Project-Id-Version' => 'project-id-version', 'X-Generator' => 'x-generator', ); $result = array( 'POT-Creation-Date' => '', 'PO-Revision-Date' => '', 'Project-Id-Version' => '', 'X-Generator' => '', ); foreach ( $headers as $po_header => $php_header ) { if ( isset( $data[ $php_header ] ) ) { $result[ $po_header ] = $data[ $php_header ]; } } return $result; } function wp_dropdown_languages( $args = array() ) { $parsed_args = wp_parse_args( $args, array( 'id' => 'locale', 'name' => 'locale', 'languages' => array(), 'translations' => array(), 'selected' => '', 'echo' => 1, 'show_available_translations' => true, 'show_option_site_default' => false, 'show_option_en_us' => true, 'explicit_option_en_us' => false, ) ); if ( ! $parsed_args['id'] || ! $parsed_args['name'] ) { return; } if ( 'en_US' === $parsed_args['selected'] && ! $parsed_args['explicit_option_en_us'] ) { $parsed_args['selected'] = ''; } $translations = $parsed_args['translations']; if ( empty( $translations ) ) { require_once ABSPATH . 'wp-admin/includes/translation-install.php'; $translations = wp_get_available_translations(); } $languages = array(); foreach ( $parsed_args['languages'] as $locale ) { if ( isset( $translations[ $locale ] ) ) { $translation = $translations[ $locale ]; $languages[] = array( 'language' => $translation['language'], 'native_name' => $translation['native_name'], 'lang' => current( $translation['iso'] ), ); unset( $translations[ $locale ] ); } else { $languages[] = array( 'language' => $locale, 'native_name' => $locale, 'lang' => '', ); } } $translations_available = ( ! empty( $translations ) && $parsed_args['show_available_translations'] ); $structure = array(); if ( $translations_available ) { $structure[] = '<optgroup label="' . esc_attr_x( 'Installed', 'translations' ) . '">'; } if ( $parsed_args['show_option_site_default'] ) { $structure[] = sprintf( '<option value="site-default" data-installed="1"%s>%s</option>', selected( 'site-default', $parsed_args['selected'], false ), _x( 'Site Default', 'default site language' ) ); } if ( $parsed_args['show_option_en_us'] ) { $value = ( $parsed_args['explicit_option_en_us'] ) ? 'en_US' : ''; $structure[] = sprintf( '<option value="%s" lang="en" data-installed="1"%s>English (United States)</option>', esc_attr( $value ), selected( '', $parsed_args['selected'], false ) ); } foreach ( $languages as $language ) { $structure[] = sprintf( '<option value="%s" lang="%s"%s data-installed="1">%s</option>', esc_attr( $language['language'] ), esc_attr( $language['lang'] ), selected( $language['language'], $parsed_args['selected'], false ), esc_html( $language['native_name'] ) ); } if ( $translations_available ) { $structure[] = '</optgroup>'; } if ( $translations_available ) { $structure[] = '<optgroup label="' . esc_attr_x( 'Available', 'translations' ) . '">'; foreach ( $translations as $translation ) { $structure[] = sprintf( '<option value="%s" lang="%s"%s>%s</option>', esc_attr( $translation['language'] ), esc_attr( current( $translation['iso'] ) ), selected( $translation['language'], $parsed_args['selected'], false ), esc_html( $translation['native_name'] ) ); } $structure[] = '</optgroup>'; } $output = sprintf( '<select name="%s" id="%s">', esc_attr( $parsed_args['name'] ), esc_attr( $parsed_args['id'] ) ); $output .= implode( "\n", $structure ); $output .= '</select>'; if ( $parsed_args['echo'] ) { echo $output; } return $output; } function is_rtl() { global $wp_locale; if ( ! ( $wp_locale instanceof WP_Locale ) ) { return false; } return $wp_locale->is_rtl(); } function switch_to_locale( $locale ) { global $wp_locale_switcher; if ( ! $wp_locale_switcher ) { return false; } return $wp_locale_switcher->switch_to_locale( $locale ); } function switch_to_user_locale( $user_id ) { global $wp_locale_switcher; if ( ! $wp_locale_switcher ) { return false; } return $wp_locale_switcher->switch_to_user_locale( $user_id ); } function restore_previous_locale() { global $wp_locale_switcher; if ( ! $wp_locale_switcher ) { return false; } return $wp_locale_switcher->restore_previous_locale(); } function restore_current_locale() { global $wp_locale_switcher; if ( ! $wp_locale_switcher ) { return false; } return $wp_locale_switcher->restore_current_locale(); } function is_locale_switched() { global $wp_locale_switcher; return $wp_locale_switcher->is_switched(); } function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdomain ) { if ( empty( $i18n_schema ) || empty( $settings ) || empty( $textdomain ) ) { return $settings; } if ( is_string( $i18n_schema ) && is_string( $settings ) ) { return translate_with_gettext_context( $settings, $i18n_schema, $textdomain ); } if ( is_array( $i18n_schema ) && is_array( $settings ) ) { $translated_settings = array(); foreach ( $settings as $value ) { $translated_settings[] = translate_settings_using_i18n_schema( $i18n_schema[0], $value, $textdomain ); } return $translated_settings; } if ( is_object( $i18n_schema ) && is_array( $settings ) ) { $group_key = '*'; $translated_settings = array(); foreach ( $settings as $key => $value ) { if ( isset( $i18n_schema->$key ) ) { $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); } elseif ( isset( $i18n_schema->$group_key ) ) { $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$group_key, $value, $textdomain ); } else { $translated_settings[ $key ] = $value; } } return $translated_settings; } return $settings; } function wp_get_list_item_separator() { global $wp_locale; if ( ! ( $wp_locale instanceof WP_Locale ) ) { return __( ', ' ); } return $wp_locale->get_list_item_separator(); } function wp_get_word_count_type() { global $wp_locale; if ( ! ( $wp_locale instanceof WP_Locale ) ) { return 'words'; } return $wp_locale->get_word_count_type(); } function has_translation( string $singular, string $textdomain = 'default', ?string $locale = null ): bool { return WP_Translation_Controller::get_instance()->has_translation( $singular, $textdomain, $locale ); }
###require_once ABSPATH . WPINC . '/class-wp-textdomain-registry.php';
class WP_Textdomain_Registry { protected $all = array(); protected $current = array(); protected $custom_paths = array(); protected $cached_mo_files = array(); protected $domains_with_translations = array(); public function init() { add_action( 'upgrader_process_complete', array( $this, 'invalidate_mo_files_cache' ), 10, 2 ); } public function get( $domain, $locale ) { $path = $this->all[ $domain ][ $locale ] ?? $this->get_path_from_lang_dir( $domain, $locale ); return apply_filters( 'lang_dir_for_domain', $path, $domain, $locale ); } public function has( $domain ) { return ( isset( $this->current[ $domain ] ) || empty( $this->all[ $domain ] ) || in_array( $domain, $this->domains_with_translations, true ) ); } public function set( $domain, $locale, $path ) { $this->all[ $domain ][ $locale ] = $path ? rtrim( $path, '/' ) . '/' : false; $this->current[ $domain ] = $this->all[ $domain ][ $locale ]; } public function set_custom_path( $domain, $path ) { if ( isset( $this->all[ $domain ] ) ) { $this->all[ $domain ] = array_filter( $this->all[ $domain ] ); } if ( empty( $this->current[ $domain ] ) ) { unset( $this->current[ $domain ] ); } $this->custom_paths[ $domain ] = rtrim( $path, '/' ); } public function get_language_files_from_path( $path ) { $path = rtrim( $path, '/' ) . '/'; $files = apply_filters( 'pre_get_language_files_from_path', null, $path ); if ( null !== $files ) { return $files; } $cache_key = md5( $path ); $files = wp_cache_get( $cache_key, 'translation_files' ); if ( false === $files ) { $files = glob( $path . '*.mo' ); if ( false === $files ) { $files = array(); } $php_files = glob( $path . '*.l10n.php' ); if ( is_array( $php_files ) ) { $files = array_merge( $files, $php_files ); } wp_cache_set( $cache_key, $files, 'translation_files', HOUR_IN_SECONDS ); } return $files; } public function invalidate_mo_files_cache( $upgrader, $hook_extra ) { if ( ! isset( $hook_extra['type'] ) || 'translation' !== $hook_extra['type'] || array() === $hook_extra['translations'] ) { return; } $translation_types = array_unique( wp_list_pluck( $hook_extra['translations'], 'type' ) ); foreach ( $translation_types as $type ) { switch ( $type ) { case 'plugin': wp_cache_delete( md5( WP_LANG_DIR . '/plugins/' ), 'translation_files' ); break; case 'theme': wp_cache_delete( md5( WP_LANG_DIR . '/themes/' ), 'translation_files' ); break; default: wp_cache_delete( md5( WP_LANG_DIR . '/' ), 'translation_files' ); break; } } } private function get_paths_for_domain( $domain ) { $locations = array( WP_LANG_DIR . '/plugins', WP_LANG_DIR . '/themes', ); if ( isset( $this->custom_paths[ $domain ] ) ) { $locations[] = $this->custom_paths[ $domain ]; } return $locations; } private function get_path_from_lang_dir( $domain, $locale ) { $locations = $this->get_paths_for_domain( $domain ); $found_location = false; foreach ( $locations as $location ) { $files = $this->get_language_files_from_path( $location ); $mo_path = "$location/$domain-$locale.mo"; $php_path = "$location/$domain-$locale.l10n.php"; foreach ( $files as $file_path ) { if ( ! in_array( $domain, $this->domains_with_translations, true ) && str_starts_with( str_replace( "$location/", '', $file_path ), "$domain-" ) ) { $this->domains_with_translations[] = $domain; } if ( $file_path === $mo_path || $file_path === $php_path ) { $found_location = rtrim( $location, '/' ) . '/'; break 2; } } } if ( $found_location ) { $this->set( $domain, $locale, $found_location ); return $found_location; } if ( isset( $this->custom_paths[ $domain ] ) ) { $fallback_location = rtrim( $this->custom_paths[ $domain ], '/' ) . '/'; $this->set( $domain, $locale, $fallback_location ); return $fallback_location; } $this->set( $domain, $locale, false ); return false; } }
###require_once ABSPATH . WPINC . '/class-wp-locale.php';
class WP_Locale { public $weekday = array(); public $weekday_initial = array(); public $weekday_abbrev = array(); public $month = array(); public $month_genitive = array(); public $month_abbrev = array(); public $meridiem = array(); public $text_direction = 'ltr'; public $number_format = array(); public $list_item_separator; public $word_count_type; public function __construct() { $this->init(); $this->register_globals(); } public function init() { $this->weekday[0] = __( 'Sunday' ); $this->weekday[1] = __( 'Monday' ); $this->weekday[2] = __( 'Tuesday' ); $this->weekday[3] = __( 'Wednesday' ); $this->weekday[4] = __( 'Thursday' ); $this->weekday[5] = __( 'Friday' ); $this->weekday[6] = __( 'Saturday' ); $this->weekday_initial[ $this->weekday[0] ] = _x( 'S', 'Sunday initial' ); $this->weekday_initial[ $this->weekday[1] ] = _x( 'M', 'Monday initial' ); $this->weekday_initial[ $this->weekday[2] ] = _x( 'T', 'Tuesday initial' ); $this->weekday_initial[ $this->weekday[3] ] = _x( 'W', 'Wednesday initial' ); $this->weekday_initial[ $this->weekday[4] ] = _x( 'T', 'Thursday initial' ); $this->weekday_initial[ $this->weekday[5] ] = _x( 'F', 'Friday initial' ); $this->weekday_initial[ $this->weekday[6] ] = _x( 'S', 'Saturday initial' ); $this->weekday_abbrev[ $this->weekday[0] ] = __( 'Sun' ); $this->weekday_abbrev[ $this->weekday[1] ] = __( 'Mon' ); $this->weekday_abbrev[ $this->weekday[2] ] = __( 'Tue' ); $this->weekday_abbrev[ $this->weekday[3] ] = __( 'Wed' ); $this->weekday_abbrev[ $this->weekday[4] ] = __( 'Thu' ); $this->weekday_abbrev[ $this->weekday[5] ] = __( 'Fri' ); $this->weekday_abbrev[ $this->weekday[6] ] = __( 'Sat' ); $this->month['01'] = __( 'January' ); $this->month['02'] = __( 'February' ); $this->month['03'] = __( 'March' ); $this->month['04'] = __( 'April' ); $this->month['05'] = __( 'May' ); $this->month['06'] = __( 'June' ); $this->month['07'] = __( 'July' ); $this->month['08'] = __( 'August' ); $this->month['09'] = __( 'September' ); $this->month['10'] = __( 'October' ); $this->month['11'] = __( 'November' ); $this->month['12'] = __( 'December' ); $this->month_genitive['01'] = _x( 'January', 'genitive' ); $this->month_genitive['02'] = _x( 'February', 'genitive' ); $this->month_genitive['03'] = _x( 'March', 'genitive' ); $this->month_genitive['04'] = _x( 'April', 'genitive' ); $this->month_genitive['05'] = _x( 'May', 'genitive' ); $this->month_genitive['06'] = _x( 'June', 'genitive' ); $this->month_genitive['07'] = _x( 'July', 'genitive' ); $this->month_genitive['08'] = _x( 'August', 'genitive' ); $this->month_genitive['09'] = _x( 'September', 'genitive' ); $this->month_genitive['10'] = _x( 'October', 'genitive' ); $this->month_genitive['11'] = _x( 'November', 'genitive' ); $this->month_genitive['12'] = _x( 'December', 'genitive' ); $this->month_abbrev[ $this->month['01'] ] = _x( 'Jan', 'January abbreviation' ); $this->month_abbrev[ $this->month['02'] ] = _x( 'Feb', 'February abbreviation' ); $this->month_abbrev[ $this->month['03'] ] = _x( 'Mar', 'March abbreviation' ); $this->month_abbrev[ $this->month['04'] ] = _x( 'Apr', 'April abbreviation' ); $this->month_abbrev[ $this->month['05'] ] = _x( 'May', 'May abbreviation' ); $this->month_abbrev[ $this->month['06'] ] = _x( 'Jun', 'June abbreviation' ); $this->month_abbrev[ $this->month['07'] ] = _x( 'Jul', 'July abbreviation' ); $this->month_abbrev[ $this->month['08'] ] = _x( 'Aug', 'August abbreviation' ); $this->month_abbrev[ $this->month['09'] ] = _x( 'Sep', 'September abbreviation' ); $this->month_abbrev[ $this->month['10'] ] = _x( 'Oct', 'October abbreviation' ); $this->month_abbrev[ $this->month['11'] ] = _x( 'Nov', 'November abbreviation' ); $this->month_abbrev[ $this->month['12'] ] = _x( 'Dec', 'December abbreviation' ); $this->meridiem['am'] = __( 'am' ); $this->meridiem['pm'] = __( 'pm' ); $this->meridiem['AM'] = __( 'AM' ); $this->meridiem['PM'] = __( 'PM' ); $thousands_sep = __( 'number_format_thousands_sep' ); $thousands_sep = str_replace( ' ', ' ', $thousands_sep ); $this->number_format['thousands_sep'] = ( 'number_format_thousands_sep' === $thousands_sep ) ? ',' : $thousands_sep; $decimal_point = __( 'number_format_decimal_point' ); $this->number_format['decimal_point'] = ( 'number_format_decimal_point' === $decimal_point ) ? '.' : $decimal_point; $this->list_item_separator = __( ', ' ); if ( isset( $GLOBALS['text_direction'] ) ) { $this->text_direction = $GLOBALS['text_direction']; } elseif ( 'rtl' === _x( 'ltr', 'text direction' ) ) { $this->text_direction = 'rtl'; } $this->word_count_type = $this->get_word_count_type(); } public function get_weekday( $weekday_number ) { return $this->weekday[ $weekday_number ]; } public function get_weekday_initial( $weekday_name ) { return $this->weekday_initial[ $weekday_name ]; } public function get_weekday_abbrev( $weekday_name ) { return $this->weekday_abbrev[ $weekday_name ]; } public function get_month( $month_number ) { $month_number = zeroise( $month_number, 2 ); if ( ! isset( $this->month[ $month_number ] ) ) { return ''; } return $this->month[ $month_number ]; } public function get_month_abbrev( $month_name ) { return $this->month_abbrev[ $month_name ]; } public function get_month_genitive( $month_number ) { return $this->month_genitive[ zeroise( $month_number, 2 ) ]; } public function get_meridiem( $meridiem ) { return $this->meridiem[ $meridiem ]; } public function register_globals() { $GLOBALS['weekday'] = $this->weekday; $GLOBALS['weekday_initial'] = $this->weekday_initial; $GLOBALS['weekday_abbrev'] = $this->weekday_abbrev; $GLOBALS['month'] = $this->month; $GLOBALS['month_abbrev'] = $this->month_abbrev; } public function is_rtl() { return 'rtl' === $this->text_direction; } public function _strings_for_pot() { __( 'F j, Y' ); __( 'g:i a' ); __( 'F j, Y g:i a' ); } public function get_list_item_separator() { return $this->list_item_separator; } public function get_word_count_type() { $word_count_type = is_null( $this->word_count_type ) ? _x( 'words', 'Word count type. Do not translate!' ) : $this->word_count_type; if ( 'characters_excluding_spaces' !== $word_count_type && 'characters_including_spaces' !== $word_count_type ) { $word_count_type = 'words'; } return $word_count_type; } }
###require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php';
class WP_Locale_Switcher { private $stack = array(); private $original_locale; private $available_languages; public function __construct() { $this->original_locale = determine_locale(); $this->available_languages = array_merge( array( 'en_US' ), get_available_languages() ); } public function init() { add_filter( 'locale', array( $this, 'filter_locale' ) ); add_filter( 'determine_locale', array( $this, 'filter_locale' ) ); } public function switch_to_locale( $locale, $user_id = false ) { $current_locale = determine_locale(); if ( $current_locale === $locale ) { return false; } if ( ! in_array( $locale, $this->available_languages, true ) ) { return false; } $this->stack[] = array( $locale, $user_id ); $this->change_locale( $locale ); do_action( 'switch_locale', $locale, $user_id ); return true; } public function switch_to_user_locale( $user_id ) { $locale = get_user_locale( $user_id ); return $this->switch_to_locale( $locale, $user_id ); } public function restore_previous_locale() { $previous_locale = array_pop( $this->stack ); if ( null === $previous_locale ) { return false; } $entry = end( $this->stack ); $locale = is_array( $entry ) ? $entry[0] : false; if ( ! $locale ) { $locale = $this->original_locale; } $this->change_locale( $locale ); do_action( 'restore_previous_locale', $locale, $previous_locale[0] ); return $locale; } public function restore_current_locale() { if ( empty( $this->stack ) ) { return false; } $this->stack = array( array( $this->original_locale, false ) ); return $this->restore_previous_locale(); } public function is_switched() { return ! empty( $this->stack ); } public function get_switched_locale() { $entry = end( $this->stack ); if ( $entry ) { return $entry[0]; } return false; } public function get_switched_user_id() { $entry = end( $this->stack ); if ( $entry ) { return $entry[1]; } return false; } public function filter_locale( $locale ) { $switched_locale = $this->get_switched_locale(); if ( $switched_locale ) { return $switched_locale; } return $locale; } private function load_translations( $locale ) { global $l10n; $domains = $l10n ? array_keys( $l10n ) : array(); load_default_textdomain( $locale ); foreach ( $domains as $domain ) { if ( 'default' === $domain ) { continue; } unload_textdomain( $domain, true ); get_translations_for_domain( $domain ); } } private function change_locale( $locale ) { global $wp_locale, $phpmailer; $this->load_translations( $locale ); $wp_locale = new WP_Locale(); WP_Translation_Controller::get_instance()->set_locale( $locale ); if ( $phpmailer instanceof WP_PHPMailer ) { $phpmailer->setLanguage(); } do_action( 'change_locale', $locale ); } }
wp_not_installed();
###require ABSPATH . WPINC . '/class-wp-walker.php';
class Walker { public $tree_type; public $db_fields; public $max_pages = 1; public $has_children; public function start_lvl( &$output, $depth = 0, $args = array() ) {} public function end_lvl( &$output, $depth = 0, $args = array() ) {} public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) {} public function end_el( &$output, $data_object, $depth = 0, $args = array() ) {} public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { if ( ! $element ) { return; } $max_depth = (int) $max_depth; $depth = (int) $depth; $id_field = $this->db_fields['id']; $id = $element->$id_field; $this->has_children = ! empty( $children_elements[ $id ] ); if ( isset( $args[0] ) && is_array( $args[0] ) ) { $args[0]['has_children'] = $this->has_children; } $this->start_el( $output, $element, $depth, ...array_values( $args ) ); if ( ( 0 === $max_depth || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) { foreach ( $children_elements[ $id ] as $child ) { if ( ! isset( $newlevel ) ) { $newlevel = true; $this->start_lvl( $output, $depth, ...array_values( $args ) ); } $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output ); } unset( $children_elements[ $id ] ); } if ( isset( $newlevel ) && $newlevel ) { $this->end_lvl( $output, $depth, ...array_values( $args ) ); } $this->end_el( $output, $element, $depth, ...array_values( $args ) ); } public function walk( $elements, $max_depth, ...$args ) { $output = ''; $max_depth = (int) $max_depth; if ( $max_depth < -1 || empty( $elements ) ) { return $output; } $parent_field = $this->db_fields['parent']; if ( -1 === $max_depth ) { $empty_array = array(); foreach ( $elements as $e ) { $this->display_element( $e, $empty_array, 1, 0, $args, $output ); } return $output; } $top_level_elements = array(); $children_elements = array(); foreach ( $elements as $e ) { if ( empty( $e->$parent_field ) ) { $top_level_elements[] = $e; } else { $children_elements[ $e->$parent_field ][] = $e; } } if ( empty( $top_level_elements ) ) { $first = array_slice( $elements, 0, 1 ); $root = $first[0]; $top_level_elements = array(); $children_elements = array(); foreach ( $elements as $e ) { if ( $root->$parent_field === $e->$parent_field ) { $top_level_elements[] = $e; } else { $children_elements[ $e->$parent_field ][] = $e; } } } foreach ( $top_level_elements as $e ) { $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); } if ( ( 0 === $max_depth ) && count( $children_elements ) > 0 ) { $empty_array = array(); foreach ( $children_elements as $orphans ) { foreach ( $orphans as $op ) { $this->display_element( $op, $empty_array, 1, 0, $args, $output ); } } } return $output; } public function paged_walk( $elements, $max_depth, $page_num, $per_page, ...$args ) { $output = ''; $max_depth = (int) $max_depth; if ( empty( $elements ) || $max_depth < -1 ) { return $output; } $parent_field = $this->db_fields['parent']; $count = -1; if ( -1 === $max_depth ) { $total_top = count( $elements ); } if ( $page_num < 1 || $per_page < 0 ) { $paging = false; $start = 0; if ( -1 === $max_depth ) { $end = $total_top; } $this->max_pages = 1; } else { $paging = true; $start = ( (int) $page_num - 1 ) * (int) $per_page; $end = $start + $per_page; if ( -1 === $max_depth ) { $this->max_pages = (int) ceil( $total_top / $per_page ); } } if ( -1 === $max_depth ) { if ( ! empty( $args[0]['reverse_top_level'] ) ) { $elements = array_reverse( $elements ); $oldstart = $start; $start = $total_top - $end; $end = $total_top - $oldstart; } $empty_array = array(); foreach ( $elements as $e ) { ++$count; if ( $count < $start ) { continue; } if ( $count >= $end ) { break; } $this->display_element( $e, $empty_array, 1, 0, $args, $output ); } return $output; } $top_level_elements = array(); $children_elements = array(); foreach ( $elements as $e ) { if ( empty( $e->$parent_field ) ) { $top_level_elements[] = $e; } else { $children_elements[ $e->$parent_field ][] = $e; } } $total_top = count( $top_level_elements ); if ( $paging ) { $this->max_pages = (int) ceil( $total_top / $per_page ); } else { $end = $total_top; } if ( ! empty( $args[0]['reverse_top_level'] ) ) { $top_level_elements = array_reverse( $top_level_elements ); $oldstart = $start; $start = $total_top - $end; $end = $total_top - $oldstart; } if ( ! empty( $args[0]['reverse_children'] ) ) { foreach ( $children_elements as $parent => $children ) { $children_elements[ $parent ] = array_reverse( $children ); } } foreach ( $top_level_elements as $e ) { ++$count; if ( $end >= $total_top && $count < $start ) { $this->unset_children( $e, $children_elements ); } if ( $count < $start ) { continue; } if ( $count >= $end ) { break; } $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); } if ( $end >= $total_top && count( $children_elements ) > 0 ) { $empty_array = array(); foreach ( $children_elements as $orphans ) { foreach ( $orphans as $op ) { $this->display_element( $op, $empty_array, 1, 0, $args, $output ); } } } return $output; } public function get_number_of_root_elements( $elements ) { $num = 0; $parent_field = $this->db_fields['parent']; foreach ( $elements as $e ) { if ( empty( $e->$parent_field ) ) { ++$num; } } return $num; } public function unset_children( $element, &$children_elements ) { if ( ! $element || ! $children_elements ) { return; } $id_field = $this->db_fields['id']; $id = $element->$id_field; if ( ! empty( $children_elements[ $id ] ) && is_array( $children_elements[ $id ] ) ) { foreach ( (array) $children_elements[ $id ] as $child ) { $this->unset_children( $child, $children_elements ); } } unset( $children_elements[ $id ] ); } }
###require ABSPATH . WPINC . '/class-wp-ajax-response.php';
class WP_Ajax_Response { public $responses = array(); public function __construct( $args = '' ) { if ( ! empty( $args ) ) { $this->add( $args ); } } public function add( $args = '' ) { $defaults = array( 'what' => 'object', 'action' => false, 'id' => '0', 'old_id' => false, 'position' => 1, 'data' => '', 'supplemental' => array(), ); $parsed_args = wp_parse_args( $args, $defaults ); $position = preg_replace( '/[^a-z0-9:_-]/i', '', $parsed_args['position'] ); $id = $parsed_args['id']; $what = $parsed_args['what']; $action = $parsed_args['action']; $old_id = $parsed_args['old_id']; $data = $parsed_args['data']; if ( is_wp_error( $id ) ) { $data = $id; $id = 0; } $response = ''; if ( is_wp_error( $data ) ) { foreach ( (array) $data->get_error_codes() as $code ) { $response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message( $code ) . ']]></wp_error>'; $error_data = $data->get_error_data( $code ); if ( ! $error_data ) { continue; } $class = ''; if ( is_object( $error_data ) ) { $class = ' class="' . get_class( $error_data ) . '"'; $error_data = get_object_vars( $error_data ); } $response .= "<wp_error_data code='$code'$class>"; if ( is_scalar( $error_data ) ) { $response .= "<![CDATA[$error_data]]>"; } elseif ( is_array( $error_data ) ) { foreach ( $error_data as $k => $v ) { $response .= "<$k><![CDATA[$v]]></$k>"; } } $response .= '</wp_error_data>'; } } else { $response = "<response_data><![CDATA[$data]]></response_data>"; } $s = ''; if ( is_array( $parsed_args['supplemental'] ) ) { foreach ( $parsed_args['supplemental'] as $k => $v ) { $s .= "<$k><![CDATA[$v]]></$k>"; } $s = "<supplemental>$s</supplemental>"; } if ( false === $action ) { $action = $_POST['action']; } $x = ''; $x .= "<response action='{$action}_$id'>"; $x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>"; $x .= $response; $x .= $s; $x .= "</$what>"; $x .= '</response>'; $this->responses[] = $x; return $x; } public function send() { header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) ); echo "<?xml version='1.0' encoding='" . get_option( 'blog_charset' ) . "' standalone='yes'?><wp_ajax>"; foreach ( (array) $this->responses as $response ) { echo $response; } echo '</wp_ajax>'; if ( wp_doing_ajax() ) { wp_die(); } else { die(); } } }
require ABSPATH . WPINC . '/capabilities.php';
###require ABSPATH . WPINC . '/class-wp-roles.php';
class WP_Roles { public $roles; public $role_objects = array(); public $role_names = array(); public $role_key; public $use_db = true; protected $site_id = 0; public function __construct( $site_id = null ) { global $wp_user_roles; $this->use_db = empty( $wp_user_roles ); $this->for_site( $site_id ); } public function __call( $name, $arguments ) { if ( '_init' === $name ) { return $this->_init( ...$arguments ); } return false; } protected function _init() { _deprecated_function( __METHOD__, '4.9.0', 'WP_Roles::for_site()' ); $this->for_site(); } public function reinit() { _deprecated_function( __METHOD__, '4.7.0', 'WP_Roles::for_site()' ); $this->for_site(); } public function add_role( $role, $display_name, $capabilities = array() ) { if ( empty( $role ) || isset( $this->roles[ $role ] ) ) { return; } if ( wp_is_numeric_array( $capabilities ) ) { $capabilities = array_fill_keys( $capabilities, true ); } $this->roles[ $role ] = array( 'name' => $display_name, 'capabilities' => $capabilities, ); if ( $this->use_db ) { update_option( $this->role_key, $this->roles, true ); } $this->role_objects[ $role ] = new WP_Role( $role, $capabilities ); $this->role_names[ $role ] = $display_name; return $this->role_objects[ $role ]; } public function remove_role( $role ) { if ( ! isset( $this->role_objects[ $role ] ) ) { return; } unset( $this->role_objects[ $role ] ); unset( $this->role_names[ $role ] ); unset( $this->roles[ $role ] ); if ( $this->use_db ) { update_option( $this->role_key, $this->roles ); } if ( get_option( 'default_role' ) === $role ) { update_option( 'default_role', 'subscriber' ); } } public function add_cap( $role, $cap, $grant = true ) { if ( ! isset( $this->roles[ $role ] ) ) { return; } $this->roles[ $role ]['capabilities'][ $cap ] = $grant; if ( $this->use_db ) { update_option( $this->role_key, $this->roles ); } } public function remove_cap( $role, $cap ) { if ( ! isset( $this->roles[ $role ] ) ) { return; } unset( $this->roles[ $role ]['capabilities'][ $cap ] ); if ( $this->use_db ) { update_option( $this->role_key, $this->roles ); } } public function get_role( $role ) { if ( isset( $this->role_objects[ $role ] ) ) { return $this->role_objects[ $role ]; } else { return null; } } public function get_names() { return $this->role_names; } public function is_role( $role ) { return isset( $this->role_names[ $role ] ); } public function init_roles() { if ( empty( $this->roles ) ) { return; } $this->role_objects = array(); $this->role_names = array(); foreach ( array_keys( $this->roles ) as $role ) { $this->role_objects[ $role ] = new WP_Role( $role, $this->roles[ $role ]['capabilities'] ); $this->role_names[ $role ] = $this->roles[ $role ]['name']; } do_action( 'wp_roles_init', $this ); } public function for_site( $site_id = null ) { global $wpdb; if ( ! empty( $site_id ) ) { $this->site_id = absint( $site_id ); } else { $this->site_id = get_current_blog_id(); } $this->role_key = $wpdb->get_blog_prefix( $this->site_id ) . 'user_roles'; if ( ! empty( $this->roles ) && ! $this->use_db ) { return; } $this->roles = $this->get_roles_data(); $this->init_roles(); } public function get_site_id() { return $this->site_id; } protected function get_roles_data() { global $wp_user_roles; if ( ! empty( $wp_user_roles ) ) { return $wp_user_roles; } if ( is_multisite() && get_current_blog_id() !== $this->site_id ) { remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 ); $roles = get_blog_option( $this->site_id, $this->role_key, array() ); add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 ); return $roles; } return get_option( $this->role_key, array() ); } }
###require ABSPATH . WPINC . '/class-wp-role.php';
class WP_Role { public $name; public $capabilities; public function __construct( $role, $capabilities ) { $this->name = $role; $this->capabilities = $capabilities; } public function add_cap( $cap, $grant = true ) { $this->capabilities[ $cap ] = $grant; wp_roles()->add_cap( $this->name, $cap, $grant ); } public function remove_cap( $cap ) { unset( $this->capabilities[ $cap ] ); wp_roles()->remove_cap( $this->name, $cap ); } public function has_cap( $cap ) { $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); if ( ! empty( $capabilities[ $cap ] ) ) { return $capabilities[ $cap ]; } else { return false; } } }
###require ABSPATH . WPINC . '/class-wp-user.php';
class WP_User { public $data; public $ID = 0; public $caps = array(); public $cap_key; public $roles = array(); public $allcaps = array(); public $filter = null; private $site_id = 0; private static $back_compat_keys; public function __construct( $id = 0, $name = '', $site_id = 0 ) { global $wpdb; if ( ! isset( self::$back_compat_keys ) ) { $prefix = $wpdb->prefix; self::$back_compat_keys = array( 'user_firstname' => 'first_name', 'user_lastname' => 'last_name', 'user_description' => 'description', 'user_level' => $prefix . 'user_level', $prefix . 'usersettings' => $prefix . 'user-settings', $prefix . 'usersettingstime' => $prefix . 'user-settings-time', ); } if ( $id instanceof WP_User ) { $this->init( $id->data, $site_id ); return; } elseif ( is_object( $id ) ) { $this->init( $id, $site_id ); return; } if ( ! empty( $id ) && ! is_numeric( $id ) ) { $name = $id; $id = 0; } if ( $id ) { $data = self::get_data_by( 'id', $id ); } else { $data = self::get_data_by( 'login', $name ); } if ( $data ) { $this->init( $data, $site_id ); } else { $this->data = new stdClass(); } } public function init( $data, $site_id = 0 ) { if ( ! isset( $data->ID ) ) { $data->ID = 0; } $this->data = $data; $this->ID = (int) $data->ID; $this->for_site( $site_id ); } public static function get_data_by( $field, $value ) { global $wpdb; if ( 'ID' === $field ) { $field = 'id'; } if ( 'id' === $field ) { if ( ! is_numeric( $value ) ) { return false; } $value = (int) $value; if ( $value < 1 ) { return false; } } else { $value = trim( $value ); } if ( ! $value ) { return false; } switch ( $field ) { case 'id': $user_id = $value; $db_field = 'ID'; break; case 'slug': $user_id = wp_cache_get( $value, 'userslugs' ); $db_field = 'user_nicename'; break; case 'email': $user_id = wp_cache_get( $value, 'useremail' ); $db_field = 'user_email'; break; case 'login': $value = sanitize_user( $value ); $user_id = wp_cache_get( $value, 'userlogins' ); $db_field = 'user_login'; break; default: return false; } if ( false !== $user_id ) { $user = wp_cache_get( $user_id, 'users' ); if ( $user ) { return $user; } } $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE $db_field = %s LIMIT 1", $value ) ); if ( ! $user ) { return false; } update_user_caches( $user ); return $user; } public function __isset( $key ) { if ( 'id' === $key ) { _deprecated_argument( 'WP_User->id', '2.1.0', sprintf( __( 'Use %s instead.' ), '<code>WP_User->ID</code>' ) ); $key = 'ID'; } if ( isset( $this->data->$key ) ) { return true; } if ( isset( self::$back_compat_keys[ $key ] ) ) { $key = self::$back_compat_keys[ $key ]; } return metadata_exists( 'user', $this->ID, $key ); } public function __get( $key ) { if ( 'id' === $key ) { _deprecated_argument( 'WP_User->id', '2.1.0', sprintf( __( 'Use %s instead.' ), '<code>WP_User->ID</code>' ) ); return $this->ID; } if ( isset( $this->data->$key ) ) { $value = $this->data->$key; } else { if ( isset( self::$back_compat_keys[ $key ] ) ) { $key = self::$back_compat_keys[ $key ]; } $value = get_user_meta( $this->ID, $key, true ); } if ( $this->filter ) { $value = sanitize_user_field( $key, $value, $this->ID, $this->filter ); } return $value; } public function __set( $key, $value ) { if ( 'id' === $key ) { _deprecated_argument( 'WP_User->id', '2.1.0', sprintf( __( 'Use %s instead.' ), '<code>WP_User->ID</code>' ) ); $this->ID = $value; return; } $this->data->$key = $value; } public function __unset( $key ) { if ( 'id' === $key ) { _deprecated_argument( 'WP_User->id', '2.1.0', sprintf( __( 'Use %s instead.' ), '<code>WP_User->ID</code>' ) ); } if ( isset( $this->data->$key ) ) { unset( $this->data->$key ); } if ( isset( self::$back_compat_keys[ $key ] ) ) { unset( self::$back_compat_keys[ $key ] ); } } public function exists() { return ! empty( $this->ID ); } public function get( $key ) { return $this->__get( $key ); } public function has_prop( $key ) { return $this->__isset( $key ); } public function to_array() { return get_object_vars( $this->data ); } public function __call( $name, $arguments ) { if ( '_init_caps' === $name ) { return $this->_init_caps( ...$arguments ); } return false; } protected function _init_caps( $cap_key = '' ) { global $wpdb; _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' ); if ( empty( $cap_key ) ) { $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities'; } else { $this->cap_key = $cap_key; } $this->caps = $this->get_caps_data(); $this->get_role_caps(); } public function get_role_caps() { $switch_site = false; if ( is_multisite() && get_current_blog_id() !== $this->site_id ) { $switch_site = true; switch_to_blog( $this->site_id ); } $wp_roles = wp_roles(); if ( is_array( $this->caps ) ) { $this->roles = array(); foreach ( $this->caps as $key => $value ) { if ( $wp_roles->is_role( $key ) ) { $this->roles[] = $key; } } } $this->allcaps = array(); foreach ( (array) $this->roles as $role ) { $the_role = $wp_roles->get_role( $role ); $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); } $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); if ( $switch_site ) { restore_current_blog(); } return $this->allcaps; } public function add_role( $role ) { if ( empty( $role ) ) { return; } if ( in_array( $role, $this->roles, true ) ) { return; } $this->caps[ $role ] = true; update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); do_action( 'add_user_role', $this->ID, $role ); } public function remove_role( $role ) { if ( ! in_array( $role, $this->roles, true ) ) { return; } unset( $this->caps[ $role ] ); update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); do_action( 'remove_user_role', $this->ID, $role ); } public function set_role( $role ) { if ( 1 === count( $this->roles ) && current( $this->roles ) === $role ) { return; } foreach ( (array) $this->roles as $oldrole ) { unset( $this->caps[ $oldrole ] ); } $old_roles = $this->roles; if ( ! empty( $role ) ) { $this->caps[ $role ] = true; $this->roles = array( $role => true ); } else { $this->roles = array(); } update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); foreach ( $old_roles as $old_role ) { if ( ! $old_role || $old_role === $role ) { continue; } do_action( 'remove_user_role', $this->ID, $old_role ); } if ( $role && ! in_array( $role, $old_roles, true ) ) { do_action( 'add_user_role', $this->ID, $role ); } do_action( 'set_user_role', $this->ID, $role, $old_roles ); } public function level_reduction( $max, $item ) { if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { $level = (int) $matches[1]; return max( $max, $level ); } else { return $max; } } public function update_user_level_from_caps() { global $wpdb; $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); } public function add_cap( $cap, $grant = true ) { $this->caps[ $cap ] = $grant; update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); } public function remove_cap( $cap ) { if ( ! isset( $this->caps[ $cap ] ) ) { return; } unset( $this->caps[ $cap ] ); update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); } public function remove_all_caps() { global $wpdb; $this->caps = array(); delete_user_meta( $this->ID, $this->cap_key ); delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); $this->get_role_caps(); } public function has_cap( $cap, ...$args ) { if ( is_numeric( $cap ) ) { _deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) ); $cap = $this->translate_level_to_cap( $cap ); } $caps = map_meta_cap( $cap, $this->ID, ...$args ); if ( is_multisite() && is_super_admin( $this->ID ) ) { if ( in_array( 'do_not_allow', $caps, true ) ) { return false; } return true; } $args = array_merge( array( $cap, $this->ID ), $args ); $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); $capabilities['exist'] = true; unset( $capabilities['do_not_allow'] ); foreach ( (array) $caps as $cap ) { if ( empty( $capabilities[ $cap ] ) ) { return false; } } return true; } public function translate_level_to_cap( $level ) { return 'level_' . $level; } public function for_blog( $blog_id = 0 ) { _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' ); $this->for_site( $blog_id ); } public function for_site( $site_id = 0 ) { global $wpdb; if ( ! empty( $site_id ) ) { $this->site_id = absint( $site_id ); } else { $this->site_id = get_current_blog_id(); } $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities'; $this->caps = $this->get_caps_data(); $this->get_role_caps(); } public function get_site_id() { return $this->site_id; } private function get_caps_data() { $caps = get_user_meta( $this->ID, $this->cap_key, true ); if ( ! is_array( $caps ) ) { return array(); } return $caps; } }
###require ABSPATH . WPINC . '/class-wp-query.php';
class WP_Query { public $query; public $query_vars = array(); public $tax_query; public $meta_query = false; public $date_query = false; public $queried_object; public $queried_object_id; public $request; public $posts; public $post_count = 0; public $current_post = -1; public $before_loop = true; public $in_the_loop = false; public $post; public $comments; public $comment_count = 0; public $current_comment = -1; public $comment; public $found_posts = 0; public $max_num_pages = 0; public $max_num_comment_pages = 0; public $is_single = false; public $is_preview = false; public $is_page = false; public $is_archive = false; public $is_date = false; public $is_year = false; public $is_month = false; public $is_day = false; public $is_time = false; public $is_author = false; public $is_category = false; public $is_tag = false; public $is_tax = false; public $is_search = false; public $is_feed = false; public $is_comment_feed = false; public $is_trackback = false; public $is_home = false; public $is_privacy_policy = false; public $is_404 = false; public $is_embed = false; public $is_paged = false; public $is_admin = false; public $is_attachment = false; public $is_singular = false; public $is_robots = false; public $is_favicon = false; public $is_posts_page = false; public $is_post_type_archive = false; private $query_vars_hash = false; private $query_vars_changed = true; public $thumbnails_cached = false; protected $allow_query_attachment_by_filename = false; private $stopwords; private $compat_fields = array( 'query_vars_hash', 'query_vars_changed' ); private $compat_methods = array( 'init_query_flags', 'parse_tax_query' ); private $query_cache_key = ''; private function init_query_flags() { $this->is_single = false; $this->is_preview = false; $this->is_page = false; $this->is_archive = false; $this->is_date = false; $this->is_year = false; $this->is_month = false; $this->is_day = false; $this->is_time = false; $this->is_author = false; $this->is_category = false; $this->is_tag = false; $this->is_tax = false; $this->is_search = false; $this->is_feed = false; $this->is_comment_feed = false; $this->is_trackback = false; $this->is_home = false; $this->is_privacy_policy = false; $this->is_404 = false; $this->is_paged = false; $this->is_admin = false; $this->is_attachment = false; $this->is_singular = false; $this->is_robots = false; $this->is_favicon = false; $this->is_posts_page = false; $this->is_post_type_archive = false; } public function init() { unset( $this->posts ); unset( $this->query ); $this->query_vars = array(); unset( $this->queried_object ); unset( $this->queried_object_id ); $this->post_count = 0; $this->current_post = -1; $this->in_the_loop = false; $this->before_loop = true; unset( $this->request ); unset( $this->post ); unset( $this->comments ); unset( $this->comment ); $this->comment_count = 0; $this->current_comment = -1; $this->found_posts = 0; $this->max_num_pages = 0; $this->max_num_comment_pages = 0; $this->init_query_flags(); } public function parse_query_vars() { $this->parse_query(); } public function fill_query_vars( $query_vars ) { $keys = array( 'error', 'm', 'p', 'post_parent', 'subpost', 'subpost_id', 'attachment', 'attachment_id', 'name', 'pagename', 'page_id', 'second', 'minute', 'hour', 'day', 'monthnum', 'year', 'w', 'category_name', 'tag', 'cat', 'tag_id', 'author', 'author_name', 'feed', 'tb', 'paged', 'meta_key', 'meta_value', 'preview', 's', 'sentence', 'title', 'fields', 'menu_order', 'embed', ); foreach ( $keys as $key ) { if ( ! isset( $query_vars[ $key ] ) ) { $query_vars[ $key ] = ''; } } $array_keys = array( 'category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', 'post_name__in', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in', 'author__in', 'author__not_in', 'search_columns', ); foreach ( $array_keys as $key ) { if ( ! isset( $query_vars[ $key ] ) ) { $query_vars[ $key ] = array(); } } return $query_vars; } public function parse_query( $query = '' ) { if ( ! empty( $query ) ) { $this->init(); $this->query = wp_parse_args( $query ); $this->query_vars = $this->query; } elseif ( ! isset( $this->query ) ) { $this->query = $this->query_vars; } $this->query_vars = $this->fill_query_vars( $this->query_vars ); $query_vars = &$this->query_vars; $this->query_vars_changed = true; if ( ! empty( $query_vars['robots'] ) ) { $this->is_robots = true; } elseif ( ! empty( $query_vars['favicon'] ) ) { $this->is_favicon = true; } if ( ! is_scalar( $query_vars['p'] ) || (int) $query_vars['p'] < 0 ) { $query_vars['p'] = 0; $query_vars['error'] = '404'; } else { $query_vars['p'] = (int) $query_vars['p']; } $query_vars['page_id'] = is_scalar( $query_vars['page_id'] ) ? absint( $query_vars['page_id'] ) : 0; $query_vars['year'] = is_scalar( $query_vars['year'] ) ? absint( $query_vars['year'] ) : 0; $query_vars['monthnum'] = is_scalar( $query_vars['monthnum'] ) ? absint( $query_vars['monthnum'] ) : 0; $query_vars['day'] = is_scalar( $query_vars['day'] ) ? absint( $query_vars['day'] ) : 0; $query_vars['w'] = is_scalar( $query_vars['w'] ) ? absint( $query_vars['w'] ) : 0; $query_vars['m'] = is_scalar( $query_vars['m'] ) ? preg_replace( '|[^0-9]|', '', $query_vars['m'] ) : ''; $query_vars['paged'] = is_scalar( $query_vars['paged'] ) ? absint( $query_vars['paged'] ) : 0; $query_vars['cat'] = preg_replace( '|[^0-9,-]|', '', $query_vars['cat'] ); $query_vars['author'] = is_scalar( $query_vars['author'] ) ? preg_replace( '|[^0-9,-]|', '', $query_vars['author'] ) : ''; $query_vars['pagename'] = is_scalar( $query_vars['pagename'] ) ? trim( $query_vars['pagename'] ) : ''; $query_vars['name'] = is_scalar( $query_vars['name'] ) ? trim( $query_vars['name'] ) : ''; $query_vars['title'] = is_scalar( $query_vars['title'] ) ? trim( $query_vars['title'] ) : ''; if ( is_scalar( $query_vars['hour'] ) && '' !== $query_vars['hour'] ) { $query_vars['hour'] = absint( $query_vars['hour'] ); } else { $query_vars['hour'] = ''; } if ( is_scalar( $query_vars['minute'] ) && '' !== $query_vars['minute'] ) { $query_vars['minute'] = absint( $query_vars['minute'] ); } else { $query_vars['minute'] = ''; } if ( is_scalar( $query_vars['second'] ) && '' !== $query_vars['second'] ) { $query_vars['second'] = absint( $query_vars['second'] ); } else { $query_vars['second'] = ''; } if ( is_scalar( $query_vars['menu_order'] ) && '' !== $query_vars['menu_order'] ) { $query_vars['menu_order'] = absint( $query_vars['menu_order'] ); } else { $query_vars['menu_order'] = ''; } if ( ! is_scalar( $query_vars['s'] ) || ( ! empty( $query_vars['s'] ) && strlen( $query_vars['s'] ) > 1600 ) ) { $query_vars['s'] = ''; } if ( is_scalar( $query_vars['subpost'] ) && '' != $query_vars['subpost'] ) { $query_vars['attachment'] = $query_vars['subpost']; } if ( is_scalar( $query_vars['subpost_id'] ) && '' != $query_vars['subpost_id'] ) { $query_vars['attachment_id'] = $query_vars['subpost_id']; } $query_vars['attachment_id'] = is_scalar( $query_vars['attachment_id'] ) ? absint( $query_vars['attachment_id'] ) : 0; if ( ( '' !== $query_vars['attachment'] ) || ! empty( $query_vars['attachment_id'] ) ) { $this->is_single = true; $this->is_attachment = true; } elseif ( '' !== $query_vars['name'] ) { $this->is_single = true; } elseif ( $query_vars['p'] ) { $this->is_single = true; } elseif ( '' !== $query_vars['pagename'] || ! empty( $query_vars['page_id'] ) ) { $this->is_page = true; $this->is_single = false; } else { if ( isset( $this->query['s'] ) ) { $this->is_search = true; } if ( '' !== $query_vars['second'] ) { $this->is_time = true; $this->is_date = true; } if ( '' !== $query_vars['minute'] ) { $this->is_time = true; $this->is_date = true; } if ( '' !== $query_vars['hour'] ) { $this->is_time = true; $this->is_date = true; } if ( $query_vars['day'] ) { if ( ! $this->is_date ) { $date = sprintf( '%04d-%02d-%02d', $query_vars['year'], $query_vars['monthnum'], $query_vars['day'] ); if ( $query_vars['monthnum'] && $query_vars['year'] && ! wp_checkdate( $query_vars['monthnum'], $query_vars['day'], $query_vars['year'], $date ) ) { $query_vars['error'] = '404'; } else { $this->is_day = true; $this->is_date = true; } } } if ( $query_vars['monthnum'] ) { if ( ! $this->is_date ) { if ( 12 < $query_vars['monthnum'] ) { $query_vars['error'] = '404'; } else { $this->is_month = true; $this->is_date = true; } } } if ( $query_vars['year'] ) { if ( ! $this->is_date ) { $this->is_year = true; $this->is_date = true; } } if ( $query_vars['m'] ) { $this->is_date = true; if ( strlen( $query_vars['m'] ) > 9 ) { $this->is_time = true; } elseif ( strlen( $query_vars['m'] ) > 7 ) { $this->is_day = true; } elseif ( strlen( $query_vars['m'] ) > 5 ) { $this->is_month = true; } else { $this->is_year = true; } } if ( $query_vars['w'] ) { $this->is_date = true; } $this->query_vars_hash = false; $this->parse_tax_query( $query_vars ); foreach ( $this->tax_query->queries as $tax_query ) { if ( ! is_array( $tax_query ) ) { continue; } if ( isset( $tax_query['operator'] ) && 'NOT IN' !== $tax_query['operator'] ) { switch ( $tax_query['taxonomy'] ) { case 'category': $this->is_category = true; break; case 'post_tag': $this->is_tag = true; break; default: $this->is_tax = true; } } } unset( $tax_query ); if ( empty( $query_vars['author'] ) || ( '0' == $query_vars['author'] ) ) { $this->is_author = false; } else { $this->is_author = true; } if ( '' !== $query_vars['author_name'] ) { $this->is_author = true; } if ( ! empty( $query_vars['post_type'] ) && ! is_array( $query_vars['post_type'] ) ) { $post_type_obj = get_post_type_object( $query_vars['post_type'] ); if ( ! empty( $post_type_obj->has_archive ) ) { $this->is_post_type_archive = true; } } if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax ) { $this->is_archive = true; } } if ( '' != $query_vars['feed'] ) { $this->is_feed = true; } if ( '' != $query_vars['embed'] ) { $this->is_embed = true; } if ( '' != $query_vars['tb'] ) { $this->is_trackback = true; } if ( '' != $query_vars['paged'] && ( (int) $query_vars['paged'] > 1 ) ) { $this->is_paged = true; } if ( '' != $query_vars['preview'] ) { $this->is_preview = true; } if ( is_admin() ) { $this->is_admin = true; } if ( str_contains( $query_vars['feed'], 'comments-' ) ) { $query_vars['feed'] = str_replace( 'comments-', '', $query_vars['feed'] ); $query_vars['withcomments'] = 1; } $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; if ( $this->is_feed && ( ! empty( $query_vars['withcomments'] ) || ( empty( $query_vars['withoutcomments'] ) && $this->is_singular ) ) ) { $this->is_comment_feed = true; } if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( wp_is_serving_rest_request() && $this->is_main_query() ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) { $this->is_home = true; } if ( $this->is_home && 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) { $_query = wp_parse_args( $this->query ); if ( isset( $_query['pagename'] ) && '' === $_query['pagename'] ) { unset( $_query['pagename'] ); } unset( $_query['embed'] ); if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage' ) ) ) { $this->is_page = true; $this->is_home = false; $query_vars['page_id'] = get_option( 'page_on_front' ); if ( ! empty( $query_vars['paged'] ) ) { $query_vars['page'] = $query_vars['paged']; unset( $query_vars['paged'] ); } } } if ( '' !== $query_vars['pagename'] ) { $this->queried_object = get_page_by_path( $query_vars['pagename'] ); if ( $this->queried_object && 'attachment' === $this->queried_object->post_type ) { if ( preg_match( '/^[^%]*%(?:postname)%/', get_option( 'permalink_structure' ) ) ) { $post = get_page_by_path( $query_vars['pagename'], OBJECT, 'post' ); if ( $post ) { $this->queried_object = $post; $this->is_page = false; $this->is_single = true; } } } if ( ! empty( $this->queried_object ) ) { $this->queried_object_id = (int) $this->queried_object->ID; } else { unset( $this->queried_object ); } if ( 'page' === get_option( 'show_on_front' ) && isset( $this->queried_object_id ) && get_option( 'page_for_posts' ) == $this->queried_object_id ) { $this->is_page = false; $this->is_home = true; $this->is_posts_page = true; } if ( isset( $this->queried_object_id ) && get_option( 'wp_page_for_privacy_policy' ) == $this->queried_object_id ) { $this->is_privacy_policy = true; } } if ( $query_vars['page_id'] ) { if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) == $query_vars['page_id'] ) { $this->is_page = false; $this->is_home = true; $this->is_posts_page = true; } if ( get_option( 'wp_page_for_privacy_policy' ) == $query_vars['page_id'] ) { $this->is_privacy_policy = true; } } if ( ! empty( $query_vars['post_type'] ) ) { if ( is_array( $query_vars['post_type'] ) ) { $query_vars['post_type'] = array_map( 'sanitize_key', array_unique( $query_vars['post_type'] ) ); sort( $query_vars['post_type'] ); } else { $query_vars['post_type'] = sanitize_key( $query_vars['post_type'] ); } } if ( ! empty( $query_vars['post_status'] ) ) { if ( is_array( $query_vars['post_status'] ) ) { $query_vars['post_status'] = array_map( 'sanitize_key', array_unique( $query_vars['post_status'] ) ); sort( $query_vars['post_status'] ); } else { $query_vars['post_status'] = preg_replace( '|[^a-z0-9_,-]|', '', $query_vars['post_status'] ); } } if ( $this->is_posts_page && ( ! isset( $query_vars['withcomments'] ) || ! $query_vars['withcomments'] ) ) { $this->is_comment_feed = false; } $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; if ( '404' == $query_vars['error'] ) { $this->set_404(); } $this->is_embed = $this->is_embed && ( $this->is_singular || $this->is_404 ); $this->query_vars_hash = md5( serialize( $this->query_vars ) ); $this->query_vars_changed = false; do_action_ref_array( 'parse_query', array( &$this ) ); } public function parse_tax_query( &$query_vars ) { if ( ! empty( $query_vars['tax_query'] ) && is_array( $query_vars['tax_query'] ) ) { $tax_query = $query_vars['tax_query']; } else { $tax_query = array(); } if ( ! empty( $query_vars['taxonomy'] ) && ! empty( $query_vars['term'] ) ) { $tax_query[] = array( 'taxonomy' => $query_vars['taxonomy'], 'terms' => array( $query_vars['term'] ), 'field' => 'slug', ); } foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) { if ( 'post_tag' === $taxonomy ) { continue; } if ( $t->query_var && ! empty( $query_vars[ $t->query_var ] ) ) { $tax_query_defaults = array( 'taxonomy' => $taxonomy, 'field' => 'slug', ); if ( ! empty( $t->rewrite['hierarchical'] ) ) { $query_vars[ $t->query_var ] = wp_basename( $query_vars[ $t->query_var ] ); } $term = $query_vars[ $t->query_var ]; if ( ! is_array( $term ) ) { $term = explode( ',', $term ); $term = array_map( 'trim', $term ); } sort( $term ); $term = implode( ',', $term ); if ( str_contains( $term, '+' ) ) { $terms = preg_split( '/[+]+/', $term ); foreach ( $terms as $term ) { $tax_query[] = array_merge( $tax_query_defaults, array( 'terms' => array( $term ), ) ); } } else { $tax_query[] = array_merge( $tax_query_defaults, array( 'terms' => preg_split( '/[,]+/', $term ), ) ); } } } if ( is_array( $query_vars['cat'] ) ) { $query_vars['cat'] = implode( ',', $query_vars['cat'] ); } if ( ! empty( $query_vars['cat'] ) && ! $this->is_singular ) { $cat_in = array(); $cat_not_in = array(); $cat_array = preg_split( '/[,\s]+/', urldecode( $query_vars['cat'] ) ); $cat_array = array_map( 'intval', $cat_array ); sort( $cat_array ); $query_vars['cat'] = implode( ',', $cat_array ); foreach ( $cat_array as $cat ) { if ( $cat > 0 ) { $cat_in[] = $cat; } elseif ( $cat < 0 ) { $cat_not_in[] = abs( $cat ); } } if ( ! empty( $cat_in ) ) { $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $cat_in, 'field' => 'term_id', 'include_children' => true, ); } if ( ! empty( $cat_not_in ) ) { $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $cat_not_in, 'field' => 'term_id', 'operator' => 'NOT IN', 'include_children' => true, ); } unset( $cat_array, $cat_in, $cat_not_in ); } if ( ! empty( $query_vars['category__and'] ) && 1 === count( (array) $query_vars['category__and'] ) ) { $query_vars['category__and'] = (array) $query_vars['category__and']; if ( ! isset( $query_vars['category__in'] ) ) { $query_vars['category__in'] = array(); } $query_vars['category__in'][] = absint( reset( $query_vars['category__and'] ) ); unset( $query_vars['category__and'] ); } if ( ! empty( $query_vars['category__in'] ) ) { $query_vars['category__in'] = array_map( 'absint', array_unique( (array) $query_vars['category__in'] ) ); sort( $query_vars['category__in'] ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $query_vars['category__in'], 'field' => 'term_id', 'include_children' => false, ); } if ( ! empty( $query_vars['category__not_in'] ) ) { $query_vars['category__not_in'] = array_map( 'absint', array_unique( (array) $query_vars['category__not_in'] ) ); sort( $query_vars['category__not_in'] ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $query_vars['category__not_in'], 'operator' => 'NOT IN', 'include_children' => false, ); } if ( ! empty( $query_vars['category__and'] ) ) { $query_vars['category__and'] = array_map( 'absint', array_unique( (array) $query_vars['category__and'] ) ); sort( $query_vars['category__and'] ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $query_vars['category__and'], 'field' => 'term_id', 'operator' => 'AND', 'include_children' => false, ); } if ( is_array( $query_vars['tag'] ) ) { $query_vars['tag'] = implode( ',', $query_vars['tag'] ); } if ( '' !== $query_vars['tag'] && ! $this->is_singular && $this->query_vars_changed ) { if ( str_contains( $query_vars['tag'], ',' ) ) { $tags = preg_split( '/[,\r\n\t ]+/', $query_vars['tag'] ); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' ); $query_vars['tag_slug__in'][] = $tag; sort( $query_vars['tag_slug__in'] ); } } elseif ( preg_match( '/[+\r\n\t ]+/', $query_vars['tag'] ) || ! empty( $query_vars['cat'] ) ) { $tags = preg_split( '/[+\r\n\t ]+/', $query_vars['tag'] ); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' ); $query_vars['tag_slug__and'][] = $tag; } } else { $query_vars['tag'] = sanitize_term_field( 'slug', $query_vars['tag'], 0, 'post_tag', 'db' ); $query_vars['tag_slug__in'][] = $query_vars['tag']; sort( $query_vars['tag_slug__in'] ); } } if ( ! empty( $query_vars['tag_id'] ) ) { $query_vars['tag_id'] = absint( $query_vars['tag_id'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag_id'], ); } if ( ! empty( $query_vars['tag__in'] ) ) { $query_vars['tag__in'] = array_map( 'absint', array_unique( (array) $query_vars['tag__in'] ) ); sort( $query_vars['tag__in'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag__in'], ); } if ( ! empty( $query_vars['tag__not_in'] ) ) { $query_vars['tag__not_in'] = array_map( 'absint', array_unique( (array) $query_vars['tag__not_in'] ) ); sort( $query_vars['tag__not_in'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag__not_in'], 'operator' => 'NOT IN', ); } if ( ! empty( $query_vars['tag__and'] ) ) { $query_vars['tag__and'] = array_map( 'absint', array_unique( (array) $query_vars['tag__and'] ) ); sort( $query_vars['tag__and'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag__and'], 'operator' => 'AND', ); } if ( ! empty( $query_vars['tag_slug__in'] ) ) { $query_vars['tag_slug__in'] = array_map( 'sanitize_title_for_query', array_unique( (array) $query_vars['tag_slug__in'] ) ); sort( $query_vars['tag_slug__in'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag_slug__in'], 'field' => 'slug', ); } if ( ! empty( $query_vars['tag_slug__and'] ) ) { $query_vars['tag_slug__and'] = array_map( 'sanitize_title_for_query', array_unique( (array) $query_vars['tag_slug__and'] ) ); sort( $query_vars['tag_slug__and'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $query_vars['tag_slug__and'], 'field' => 'slug', 'operator' => 'AND', ); } $this->tax_query = new WP_Tax_Query( $tax_query ); do_action( 'parse_tax_query', $this ); } protected function parse_search( &$query_vars ) { global $wpdb; $search = ''; $query_vars['s'] = stripslashes( $query_vars['s'] ); if ( empty( $_GET['s'] ) && $this->is_main_query() ) { $query_vars['s'] = urldecode( $query_vars['s'] ); } $query_vars['s'] = str_replace( array( "\r", "\n" ), '', $query_vars['s'] ); $query_vars['search_terms_count'] = 1; if ( ! empty( $query_vars['sentence'] ) ) { $query_vars['search_terms'] = array( $query_vars['s'] ); } else { if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $query_vars['s'], $matches ) ) { $query_vars['search_terms_count'] = count( $matches[0] ); $query_vars['search_terms'] = $this->parse_search_terms( $matches[0] ); if ( empty( $query_vars['search_terms'] ) || count( $query_vars['search_terms'] ) > 9 ) { $query_vars['search_terms'] = array( $query_vars['s'] ); } } else { $query_vars['search_terms'] = array( $query_vars['s'] ); } } $n = ! empty( $query_vars['exact'] ) ? '' : '%'; $searchand = ''; $query_vars['search_orderby_title'] = array(); $default_search_columns = array( 'post_title', 'post_excerpt', 'post_content' ); $search_columns = ! empty( $query_vars['search_columns'] ) ? $query_vars['search_columns'] : $default_search_columns; if ( ! is_array( $search_columns ) ) { $search_columns = array( $search_columns ); } $search_columns = (array) apply_filters( 'post_search_columns', $search_columns, $query_vars['s'], $this ); $search_columns = array_intersect( $search_columns, $default_search_columns ); if ( empty( $search_columns ) ) { $search_columns = $default_search_columns; } $exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' ); foreach ( $query_vars['search_terms'] as $term ) { $exclude = $exclusion_prefix && str_starts_with( $term, $exclusion_prefix ); if ( $exclude ) { $like_op = 'NOT LIKE'; $andor_op = 'AND'; $term = substr( $term, 1 ); } else { $like_op = 'LIKE'; $andor_op = 'OR'; } if ( $n && ! $exclude ) { $like = '%' . $wpdb->esc_like( $term ) . '%'; $query_vars['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like ); } $like = $n . $wpdb->esc_like( $term ) . $n; $search_columns_parts = array(); foreach ( $search_columns as $search_column ) { $search_columns_parts[ $search_column ] = $wpdb->prepare( "({$wpdb->posts}.$search_column $like_op %s)", $like ); } if ( ! empty( $this->allow_query_attachment_by_filename ) ) { $search_columns_parts['attachment'] = $wpdb->prepare( "(sq1.meta_value $like_op %s)", $like ); } $search .= "$searchand(" . implode( " $andor_op ", $search_columns_parts ) . ')'; $searchand = ' AND '; } if ( ! empty( $search ) ) { $search = " AND ({$search}) "; if ( ! is_user_logged_in() ) { $search .= " AND ({$wpdb->posts}.post_password = '') "; } } return $search; } protected function parse_search_terms( $terms ) { $strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower'; $checked = array(); $stopwords = $this->get_search_stopwords(); foreach ( $terms as $term ) { if ( preg_match( '/^".+"$/', $term ) ) { $term = trim( $term, "\"'" ); } else { $term = trim( $term, "\"' " ); } if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) ) { continue; } if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) ) { continue; } $checked[] = $term; } return $checked; } protected function get_search_stopwords() { if ( isset( $this->stopwords ) ) { return $this->stopwords; } $words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www', 'Comma-separated list of search stopwords in your language' ) ); $stopwords = array(); foreach ( $words as $word ) { $word = trim( $word, "\r\n\t " ); if ( $word ) { $stopwords[] = $word; } } $this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords ); return $this->stopwords; } protected function parse_search_order( &$query_vars ) { global $wpdb; if ( $query_vars['search_terms_count'] > 1 ) { $num_terms = count( $query_vars['search_orderby_title'] ); $like = ''; if ( ! preg_match( '/(?:\s|^)\-/', $query_vars['s'] ) ) { $like = '%' . $wpdb->esc_like( $query_vars['s'] ) . '%'; } $search_orderby = ''; if ( $like ) { $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like ); } if ( $num_terms < 7 ) { $search_orderby .= 'WHEN ' . implode( ' AND ', $query_vars['search_orderby_title'] ) . ' THEN 2 '; if ( $num_terms > 1 ) { $search_orderby .= 'WHEN ' . implode( ' OR ', $query_vars['search_orderby_title'] ) . ' THEN 3 '; } } if ( $like ) { $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_excerpt LIKE %s THEN 4 ", $like ); $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_content LIKE %s THEN 5 ", $like ); } if ( $search_orderby ) { $search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)'; } } else { $search_orderby = reset( $query_vars['search_orderby_title'] ) . ' DESC'; } return $search_orderby; } protected function parse_orderby( $orderby ) { global $wpdb; $allowed_keys = array( 'post_name', 'post_author', 'post_date', 'post_title', 'post_modified', 'post_parent', 'post_type', 'name', 'author', 'date', 'title', 'modified', 'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand', 'post__in', 'post_parent__in', 'post_name__in', ); $primary_meta_key = ''; $primary_meta_query = false; $meta_clauses = $this->meta_query->get_clauses(); if ( ! empty( $meta_clauses ) ) { $primary_meta_query = reset( $meta_clauses ); if ( ! empty( $primary_meta_query['key'] ) ) { $primary_meta_key = $primary_meta_query['key']; $allowed_keys[] = $primary_meta_key; } $allowed_keys[] = 'meta_value'; $allowed_keys[] = 'meta_value_num'; $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_clauses ) ); } $rand_with_seed = false; if ( preg_match( '/RAND\(([0-9]+)\)/i', $orderby, $matches ) ) { $orderby = sprintf( 'RAND(%s)', (int) $matches[1] ); $allowed_keys[] = $orderby; $rand_with_seed = true; } if ( ! in_array( $orderby, $allowed_keys, true ) ) { return false; } $orderby_clause = ''; switch ( $orderby ) { case 'post_name': case 'post_author': case 'post_date': case 'post_title': case 'post_modified': case 'post_parent': case 'post_type': case 'ID': case 'menu_order': case 'comment_count': $orderby_clause = "{$wpdb->posts}.{$orderby}"; break; case 'rand': $orderby_clause = 'RAND()'; break; case $primary_meta_key: case 'meta_value': if ( ! empty( $primary_meta_query['type'] ) ) { $orderby_clause = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})"; } else { $orderby_clause = "{$primary_meta_query['alias']}.meta_value"; } break; case 'meta_value_num': $orderby_clause = "{$primary_meta_query['alias']}.meta_value+0"; break; case 'post__in': if ( ! empty( $this->query_vars['post__in'] ) ) { $orderby_clause = "FIELD({$wpdb->posts}.ID," . implode( ',', array_map( 'absint', $this->query_vars['post__in'] ) ) . ')'; } break; case 'post_parent__in': if ( ! empty( $this->query_vars['post_parent__in'] ) ) { $orderby_clause = "FIELD( {$wpdb->posts}.post_parent," . implode( ', ', array_map( 'absint', $this->query_vars['post_parent__in'] ) ) . ' )'; } break; case 'post_name__in': if ( ! empty( $this->query_vars['post_name__in'] ) ) { $post_name__in = array_map( 'sanitize_title_for_query', $this->query_vars['post_name__in'] ); $post_name__in_string = "'" . implode( "','", $post_name__in ) . "'"; $orderby_clause = "FIELD( {$wpdb->posts}.post_name," . $post_name__in_string . ' )'; } break; default: if ( array_key_exists( $orderby, $meta_clauses ) ) { $meta_clause = $meta_clauses[ $orderby ]; $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})"; } elseif ( $rand_with_seed ) { $orderby_clause = $orderby; } else { $orderby_clause = "{$wpdb->posts}.post_" . sanitize_key( $orderby ); } break; } return $orderby_clause; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'DESC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } public function set_404() { $is_feed = $this->is_feed; $this->init_query_flags(); $this->is_404 = true; $this->is_feed = $is_feed; do_action_ref_array( 'set_404', array( $this ) ); } public function get( $query_var, $default_value = '' ) { if ( isset( $this->query_vars[ $query_var ] ) ) { return $this->query_vars[ $query_var ]; } return $default_value; } public function set( $query_var, $value ) { $this->query_vars[ $query_var ] = $value; } public function get_posts() { global $wpdb; $this->parse_query(); do_action_ref_array( 'pre_get_posts', array( &$this ) ); $query_vars = &$this->query_vars; $query_vars = $this->fill_query_vars( $query_vars ); $this->allow_query_attachment_by_filename = apply_filters( 'wp_allow_query_attachment_by_filename', false ); remove_all_filters( 'wp_allow_query_attachment_by_filename' ); $this->meta_query = new WP_Meta_Query(); $this->meta_query->parse_query_vars( $query_vars ); $hash = md5( serialize( $this->query_vars ) ); if ( $hash !== $this->query_vars_hash ) { $this->query_vars_changed = true; $this->query_vars_hash = $hash; } unset( $hash ); $distinct = ''; $whichauthor = ''; $whichmimetype = ''; $where = ''; $limits = ''; $join = ''; $search = ''; $groupby = ''; $post_status_join = false; $page = 1; if ( isset( $query_vars['caller_get_posts'] ) ) { _deprecated_argument( 'WP_Query', '3.1.0', sprintf( __( '%1$s is deprecated. Use %2$s instead.' ), '<code>caller_get_posts</code>', '<code>ignore_sticky_posts</code>' ) ); if ( ! isset( $query_vars['ignore_sticky_posts'] ) ) { $query_vars['ignore_sticky_posts'] = $query_vars['caller_get_posts']; } } if ( ! isset( $query_vars['ignore_sticky_posts'] ) ) { $query_vars['ignore_sticky_posts'] = false; } if ( ! isset( $query_vars['suppress_filters'] ) ) { $query_vars['suppress_filters'] = false; } if ( ! isset( $query_vars['cache_results'] ) ) { $query_vars['cache_results'] = true; } if ( ! isset( $query_vars['update_post_term_cache'] ) ) { $query_vars['update_post_term_cache'] = true; } if ( ! isset( $query_vars['update_menu_item_cache'] ) ) { $query_vars['update_menu_item_cache'] = false; } if ( ! isset( $query_vars['lazy_load_term_meta'] ) ) { $query_vars['lazy_load_term_meta'] = $query_vars['update_post_term_cache']; } elseif ( $query_vars['lazy_load_term_meta'] ) { $query_vars['update_post_term_cache'] = true; } if ( ! isset( $query_vars['update_post_meta_cache'] ) ) { $query_vars['update_post_meta_cache'] = true; } if ( ! isset( $query_vars['post_type'] ) ) { if ( $this->is_search ) { $query_vars['post_type'] = 'any'; } else { $query_vars['post_type'] = ''; } } $post_type = $query_vars['post_type']; if ( empty( $query_vars['posts_per_page'] ) ) { $query_vars['posts_per_page'] = get_option( 'posts_per_page' ); } if ( isset( $query_vars['showposts'] ) && $query_vars['showposts'] ) { $query_vars['showposts'] = (int) $query_vars['showposts']; $query_vars['posts_per_page'] = $query_vars['showposts']; } if ( ( isset( $query_vars['posts_per_archive_page'] ) && 0 != $query_vars['posts_per_archive_page'] ) && ( $this->is_archive || $this->is_search ) ) { $query_vars['posts_per_page'] = $query_vars['posts_per_archive_page']; } if ( ! isset( $query_vars['nopaging'] ) ) { if ( -1 == $query_vars['posts_per_page'] ) { $query_vars['nopaging'] = true; } else { $query_vars['nopaging'] = false; } } if ( $this->is_feed ) { if ( ! empty( $query_vars['posts_per_rss'] ) ) { $query_vars['posts_per_page'] = $query_vars['posts_per_rss']; } else { $query_vars['posts_per_page'] = get_option( 'posts_per_rss' ); } $query_vars['nopaging'] = false; } $query_vars['posts_per_page'] = (int) $query_vars['posts_per_page']; if ( $query_vars['posts_per_page'] < -1 ) { $query_vars['posts_per_page'] = abs( $query_vars['posts_per_page'] ); } elseif ( 0 === $query_vars['posts_per_page'] ) { $query_vars['posts_per_page'] = 1; } if ( ! isset( $query_vars['comments_per_page'] ) || 0 == $query_vars['comments_per_page'] ) { $query_vars['comments_per_page'] = get_option( 'comments_per_page' ); } if ( $this->is_home && ( empty( $this->query ) || 'true' === $query_vars['preview'] ) && ( 'page' === get_option( 'show_on_front' ) ) && get_option( 'page_on_front' ) ) { $this->is_page = true; $this->is_home = false; $query_vars['page_id'] = get_option( 'page_on_front' ); } if ( isset( $query_vars['page'] ) ) { $query_vars['page'] = is_scalar( $query_vars['page'] ) ? absint( trim( $query_vars['page'], '/' ) ) : 0; } if ( isset( $query_vars['no_found_rows'] ) ) { $query_vars['no_found_rows'] = (bool) $query_vars['no_found_rows']; } else { $query_vars['no_found_rows'] = false; } switch ( $query_vars['fields'] ) { case 'ids': $fields = "{$wpdb->posts}.ID"; break; case 'id=>parent': $fields = "{$wpdb->posts}.ID, {$wpdb->posts}.post_parent"; break; case '': $query_vars['fields'] = 'all'; default: $fields = "{$wpdb->posts}.*"; } if ( '' !== $query_vars['menu_order'] ) { $where .= " AND {$wpdb->posts}.menu_order = " . $query_vars['menu_order']; } if ( $query_vars['m'] ) { $where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 0, 4 ); if ( strlen( $query_vars['m'] ) > 5 ) { $where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 4, 2 ); } if ( strlen( $query_vars['m'] ) > 7 ) { $where .= " AND DAYOFMONTH({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 6, 2 ); } if ( strlen( $query_vars['m'] ) > 9 ) { $where .= " AND HOUR({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 8, 2 ); } if ( strlen( $query_vars['m'] ) > 11 ) { $where .= " AND MINUTE({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 10, 2 ); } if ( strlen( $query_vars['m'] ) > 13 ) { $where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr( $query_vars['m'], 12, 2 ); } } $date_parameters = array(); if ( '' !== $query_vars['hour'] ) { $date_parameters['hour'] = $query_vars['hour']; } if ( '' !== $query_vars['minute'] ) { $date_parameters['minute'] = $query_vars['minute']; } if ( '' !== $query_vars['second'] ) { $date_parameters['second'] = $query_vars['second']; } if ( $query_vars['year'] ) { $date_parameters['year'] = $query_vars['year']; } if ( $query_vars['monthnum'] ) { $date_parameters['monthnum'] = $query_vars['monthnum']; } if ( $query_vars['w'] ) { $date_parameters['week'] = $query_vars['w']; } if ( $query_vars['day'] ) { $date_parameters['day'] = $query_vars['day']; } if ( $date_parameters ) { $date_query = new WP_Date_Query( array( $date_parameters ) ); $where .= $date_query->get_sql(); } unset( $date_parameters, $date_query ); if ( ! empty( $query_vars['date_query'] ) ) { $this->date_query = new WP_Date_Query( $query_vars['date_query'] ); $where .= $this->date_query->get_sql(); } if ( ! empty( $query_vars['post_type'] ) && 'any' !== $query_vars['post_type'] ) { foreach ( (array) $query_vars['post_type'] as $_post_type ) { $ptype_obj = get_post_type_object( $_post_type ); if ( ! $ptype_obj || ! $ptype_obj->query_var || empty( $query_vars[ $ptype_obj->query_var ] ) ) { continue; } if ( ! $ptype_obj->hierarchical ) { $query_vars['name'] = $query_vars[ $ptype_obj->query_var ]; } else { $query_vars['pagename'] = $query_vars[ $ptype_obj->query_var ]; $query_vars['name'] = ''; } break; } unset( $ptype_obj ); } if ( '' !== $query_vars['title'] ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $query_vars['title'] ) ); } if ( '' !== $query_vars['name'] ) { $query_vars['name'] = sanitize_title_for_query( $query_vars['name'] ); $where .= " AND {$wpdb->posts}.post_name = '" . $query_vars['name'] . "'"; } elseif ( '' !== $query_vars['pagename'] ) { if ( isset( $this->queried_object_id ) ) { $reqpage = $this->queried_object_id; } else { if ( 'page' !== $query_vars['post_type'] ) { foreach ( (array) $query_vars['post_type'] as $_post_type ) { $ptype_obj = get_post_type_object( $_post_type ); if ( ! $ptype_obj || ! $ptype_obj->hierarchical ) { continue; } $reqpage = get_page_by_path( $query_vars['pagename'], OBJECT, $_post_type ); if ( $reqpage ) { break; } } unset( $ptype_obj ); } else { $reqpage = get_page_by_path( $query_vars['pagename'] ); } if ( ! empty( $reqpage ) ) { $reqpage = $reqpage->ID; } else { $reqpage = 0; } } $page_for_posts = get_option( 'page_for_posts' ); if ( ( 'page' !== get_option( 'show_on_front' ) ) || empty( $page_for_posts ) || ( $reqpage != $page_for_posts ) ) { $query_vars['pagename'] = sanitize_title_for_query( wp_basename( $query_vars['pagename'] ) ); $query_vars['name'] = $query_vars['pagename']; $where .= " AND ({$wpdb->posts}.ID = '$reqpage')"; $reqpage_obj = get_post( $reqpage ); if ( is_object( $reqpage_obj ) && 'attachment' === $reqpage_obj->post_type ) { $this->is_attachment = true; $post_type = 'attachment'; $query_vars['post_type'] = 'attachment'; $this->is_page = true; $query_vars['attachment_id'] = $reqpage; } } } elseif ( '' !== $query_vars['attachment'] ) { $query_vars['attachment'] = sanitize_title_for_query( wp_basename( $query_vars['attachment'] ) ); $query_vars['name'] = $query_vars['attachment']; $where .= " AND {$wpdb->posts}.post_name = '" . $query_vars['attachment'] . "'"; } elseif ( is_array( $query_vars['post_name__in'] ) && ! empty( $query_vars['post_name__in'] ) ) { $query_vars['post_name__in'] = array_map( 'sanitize_title_for_query', $query_vars['post_name__in'] ); $post_name__in_for_where = array_unique( $query_vars['post_name__in'] ); sort( $post_name__in_for_where ); $post_name__in = "'" . implode( "','", $post_name__in_for_where ) . "'"; $where .= " AND {$wpdb->posts}.post_name IN ($post_name__in)"; } if ( $query_vars['attachment_id'] ) { $query_vars['p'] = absint( $query_vars['attachment_id'] ); } if ( $query_vars['p'] ) { $where .= " AND {$wpdb->posts}.ID = " . $query_vars['p']; } elseif ( $query_vars['post__in'] ) { $post__in_for_where = $query_vars['post__in']; $post__in_for_where = array_unique( array_map( 'absint', $post__in_for_where ) ); sort( $post__in_for_where ); $post__in = implode( ',', array_map( 'absint', $post__in_for_where ) ); $where .= " AND {$wpdb->posts}.ID IN ($post__in)"; } elseif ( $query_vars['post__not_in'] ) { sort( $query_vars['post__not_in'] ); $post__not_in = implode( ',', array_map( 'absint', $query_vars['post__not_in'] ) ); $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)"; } if ( is_numeric( $query_vars['post_parent'] ) ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_parent = %d ", $query_vars['post_parent'] ); } elseif ( $query_vars['post_parent__in'] ) { $post_parent__in_for_where = $query_vars['post_parent__in']; $post_parent__in_for_where = array_unique( array_map( 'absint', $post_parent__in_for_where ) ); sort( $post_parent__in_for_where ); $post_parent__in = implode( ',', array_map( 'absint', $post_parent__in_for_where ) ); $where .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)"; } elseif ( $query_vars['post_parent__not_in'] ) { sort( $query_vars['post_parent__not_in'] ); $post_parent__not_in = implode( ',', array_map( 'absint', $query_vars['post_parent__not_in'] ) ); $where .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)"; } if ( $query_vars['page_id'] ) { if ( ( 'page' !== get_option( 'show_on_front' ) ) || ( get_option( 'page_for_posts' ) != $query_vars['page_id'] ) ) { $query_vars['p'] = $query_vars['page_id']; $where = " AND {$wpdb->posts}.ID = " . $query_vars['page_id']; } } if ( strlen( $query_vars['s'] ) ) { $search = $this->parse_search( $query_vars ); } if ( ! $query_vars['suppress_filters'] ) { $search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) ); } if ( ! $this->is_singular ) { $this->parse_tax_query( $query_vars ); $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' ); $join .= $clauses['join']; $where .= $clauses['where']; } if ( $this->is_tax ) { if ( empty( $post_type ) ) { $post_type = array(); $taxonomies = array_keys( $this->tax_query->queried_terms ); foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) { $object_taxonomies = 'attachment' === $pt ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt ); if ( array_intersect( $taxonomies, $object_taxonomies ) ) { $post_type[] = $pt; } } if ( ! $post_type ) { $post_type = 'any'; } elseif ( count( $post_type ) === 1 ) { $post_type = $post_type[0]; } else { sort( $post_type ); } $post_status_join = true; } elseif ( in_array( 'attachment', (array) $post_type, true ) ) { $post_status_join = true; } } if ( ! empty( $this->tax_query->queried_terms ) ) { if ( ! isset( $query_vars['taxonomy'] ) ) { foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) { if ( empty( $queried_items['terms'][0] ) ) { continue; } if ( ! in_array( $queried_taxonomy, array( 'category', 'post_tag' ), true ) ) { $query_vars['taxonomy'] = $queried_taxonomy; if ( 'slug' === $queried_items['field'] ) { $query_vars['term'] = $queried_items['terms'][0]; } else { $query_vars['term_id'] = $queried_items['terms'][0]; } break; } } } foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) { if ( empty( $queried_items['terms'][0] ) ) { continue; } if ( 'category' === $queried_taxonomy ) { $the_cat = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'category' ); if ( $the_cat ) { $this->set( 'cat', $the_cat->term_id ); $this->set( 'category_name', $the_cat->slug ); } unset( $the_cat ); } if ( 'post_tag' === $queried_taxonomy ) { $the_tag = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'post_tag' ); if ( $the_tag ) { $this->set( 'tag_id', $the_tag->term_id ); } unset( $the_tag ); } } } if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) || ! empty( $this->allow_query_attachment_by_filename ) ) { $groupby = "{$wpdb->posts}.ID"; } if ( ! empty( $query_vars['author'] ) && '0' != $query_vars['author'] ) { $query_vars['author'] = addslashes_gpc( '' . urldecode( $query_vars['author'] ) ); $authors = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $query_vars['author'] ) ) ); sort( $authors ); foreach ( $authors as $author ) { $key = $author > 0 ? 'author__in' : 'author__not_in'; $query_vars[ $key ][] = abs( $author ); } $query_vars['author'] = implode( ',', $authors ); } if ( ! empty( $query_vars['author__not_in'] ) ) { if ( is_array( $query_vars['author__not_in'] ) ) { $query_vars['author__not_in'] = array_unique( array_map( 'absint', $query_vars['author__not_in'] ) ); sort( $query_vars['author__not_in'] ); } $author__not_in = implode( ',', (array) $query_vars['author__not_in'] ); $where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) "; } elseif ( ! empty( $query_vars['author__in'] ) ) { if ( is_array( $query_vars['author__in'] ) ) { $query_vars['author__in'] = array_unique( array_map( 'absint', $query_vars['author__in'] ) ); sort( $query_vars['author__in'] ); } $author__in = implode( ',', array_map( 'absint', array_unique( (array) $query_vars['author__in'] ) ) ); $where .= " AND {$wpdb->posts}.post_author IN ($author__in) "; } if ( '' !== $query_vars['author_name'] ) { if ( str_contains( $query_vars['author_name'], '/' ) ) { $query_vars['author_name'] = explode( '/', $query_vars['author_name'] ); if ( $query_vars['author_name'][ count( $query_vars['author_name'] ) - 1 ] ) { $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 1 ]; } else { $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 2 ]; } } $query_vars['author_name'] = sanitize_title_for_query( $query_vars['author_name'] ); $query_vars['author'] = get_user_by( 'slug', $query_vars['author_name'] ); if ( $query_vars['author'] ) { $query_vars['author'] = $query_vars['author']->ID; } $whichauthor .= " AND ({$wpdb->posts}.post_author = " . absint( $query_vars['author'] ) . ')'; } if ( isset( $query_vars['comment_count'] ) ) { if ( is_numeric( $query_vars['comment_count'] ) ) { $query_vars['comment_count'] = array( 'value' => (int) $query_vars['comment_count'], ); } if ( isset( $query_vars['comment_count']['value'] ) ) { $query_vars['comment_count'] = array_merge( array( 'compare' => '=', ), $query_vars['comment_count'] ); $compare_operators = array( '=', '!=', '>', '>=', '<', '<=' ); if ( ! in_array( $query_vars['comment_count']['compare'], $compare_operators, true ) ) { $query_vars['comment_count']['compare'] = '='; } $where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_count {$query_vars['comment_count']['compare']} %d", $query_vars['comment_count']['value'] ); } } if ( isset( $query_vars['post_mime_type'] ) && '' !== $query_vars['post_mime_type'] ) { $whichmimetype = wp_post_mime_type_where( $query_vars['post_mime_type'], $wpdb->posts ); } $where .= $search . $whichauthor . $whichmimetype; if ( ! empty( $this->allow_query_attachment_by_filename ) ) { $join .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )"; } if ( ! empty( $this->meta_query->queries ) ) { $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this ); $join .= $clauses['join']; $where .= $clauses['where']; } $rand = ( isset( $query_vars['orderby'] ) && 'rand' === $query_vars['orderby'] ); if ( ! isset( $query_vars['order'] ) ) { $query_vars['order'] = $rand ? '' : 'DESC'; } else { $query_vars['order'] = $rand ? '' : $this->parse_order( $query_vars['order'] ); } $force_asc = array( 'post__in', 'post_name__in', 'post_parent__in' ); if ( isset( $query_vars['orderby'] ) && in_array( $query_vars['orderby'], $force_asc, true ) ) { $query_vars['order'] = ''; } if ( empty( $query_vars['orderby'] ) ) { if ( isset( $query_vars['orderby'] ) && ( is_array( $query_vars['orderby'] ) || false === $query_vars['orderby'] ) ) { $orderby = ''; } else { $orderby = "{$wpdb->posts}.post_date " . $query_vars['order']; } } elseif ( 'none' === $query_vars['orderby'] ) { $orderby = ''; } else { $orderby_array = array(); if ( is_array( $query_vars['orderby'] ) ) { foreach ( $query_vars['orderby'] as $_orderby => $order ) { $orderby = addslashes_gpc( urldecode( $_orderby ) ); $parsed = $this->parse_orderby( $orderby ); if ( ! $parsed ) { continue; } $orderby_array[] = $parsed . ' ' . $this->parse_order( $order ); } $orderby = implode( ', ', $orderby_array ); } else { $query_vars['orderby'] = urldecode( $query_vars['orderby'] ); $query_vars['orderby'] = addslashes_gpc( $query_vars['orderby'] ); foreach ( explode( ' ', $query_vars['orderby'] ) as $i => $orderby ) { $parsed = $this->parse_orderby( $orderby ); if ( ! $parsed ) { continue; } $orderby_array[] = $parsed; } $orderby = implode( ' ' . $query_vars['order'] . ', ', $orderby_array ); if ( empty( $orderby ) ) { $orderby = "{$wpdb->posts}.post_date " . $query_vars['order']; } elseif ( ! empty( $query_vars['order'] ) ) { $orderby .= " {$query_vars['order']}"; } } } if ( ! empty( $query_vars['s'] ) ) { $search_orderby = ''; if ( ! empty( $query_vars['search_orderby_title'] ) && ( empty( $query_vars['orderby'] ) && ! $this->is_feed ) || ( isset( $query_vars['orderby'] ) && 'relevance' === $query_vars['orderby'] ) ) { $search_orderby = $this->parse_search_order( $query_vars ); } if ( ! $query_vars['suppress_filters'] ) { $search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this ); } if ( $search_orderby ) { $orderby = $orderby ? $search_orderby . ', ' . $orderby : $search_orderby; } } if ( is_array( $post_type ) && count( $post_type ) > 1 ) { $post_type_cap = 'multiple_post_type'; } else { if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $post_type_object = get_post_type_object( $post_type ); if ( empty( $post_type_object ) ) { $post_type_cap = $post_type; } } if ( isset( $query_vars['post_password'] ) ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_password = %s", $query_vars['post_password'] ); if ( empty( $query_vars['perm'] ) ) { $query_vars['perm'] = 'readable'; } } elseif ( isset( $query_vars['has_password'] ) ) { $where .= sprintf( " AND {$wpdb->posts}.post_password %s ''", $query_vars['has_password'] ? '!=' : '=' ); } if ( ! empty( $query_vars['comment_status'] ) ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_status = %s ", $query_vars['comment_status'] ); } if ( ! empty( $query_vars['ping_status'] ) ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $query_vars['ping_status'] ); } $skip_post_status = false; if ( 'any' === $post_type ) { $in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) ); if ( empty( $in_search_post_types ) ) { $post_type_where = ' AND 1=0 '; $skip_post_status = true; } else { $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')"; } } elseif ( ! empty( $post_type ) && is_array( $post_type ) ) { sort( $post_type ); $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( $post_type ) ) . "')"; } elseif ( ! empty( $post_type ) ) { $post_type_where = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type ); $post_type_object = get_post_type_object( $post_type ); } elseif ( $this->is_attachment ) { $post_type_where = " AND {$wpdb->posts}.post_type = 'attachment'"; $post_type_object = get_post_type_object( 'attachment' ); } elseif ( $this->is_page ) { $post_type_where = " AND {$wpdb->posts}.post_type = 'page'"; $post_type_object = get_post_type_object( 'page' ); } else { $post_type_where = " AND {$wpdb->posts}.post_type = 'post'"; $post_type_object = get_post_type_object( 'post' ); } $edit_cap = 'edit_post'; $read_cap = 'read_post'; if ( ! empty( $post_type_object ) ) { $edit_others_cap = $post_type_object->cap->edit_others_posts; $read_private_cap = $post_type_object->cap->read_private_posts; } else { $edit_others_cap = 'edit_others_' . $post_type_cap . 's'; $read_private_cap = 'read_private_' . $post_type_cap . 's'; } $user_id = get_current_user_id(); $q_status = array(); if ( $skip_post_status ) { $where .= $post_type_where; } elseif ( ! empty( $query_vars['post_status'] ) ) { $where .= $post_type_where; $statuswheres = array(); $q_status = $query_vars['post_status']; if ( ! is_array( $q_status ) ) { $q_status = explode( ',', $q_status ); } sort( $q_status ); $r_status = array(); $p_status = array(); $e_status = array(); if ( in_array( 'any', $q_status, true ) ) { foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) { if ( ! in_array( $status, $q_status, true ) ) { $e_status[] = "{$wpdb->posts}.post_status <> '$status'"; } } } else { foreach ( get_post_stati() as $status ) { if ( in_array( $status, $q_status, true ) ) { if ( 'private' === $status ) { $p_status[] = "{$wpdb->posts}.post_status = '$status'"; } else { $r_status[] = "{$wpdb->posts}.post_status = '$status'"; } } } } if ( empty( $query_vars['perm'] ) || 'readable' !== $query_vars['perm'] ) { $r_status = array_merge( $r_status, $p_status ); unset( $p_status ); } if ( ! empty( $e_status ) ) { $statuswheres[] = '(' . implode( ' AND ', $e_status ) . ')'; } if ( ! empty( $r_status ) ) { if ( ! empty( $query_vars['perm'] ) && 'editable' === $query_vars['perm'] && ! current_user_can( $edit_others_cap ) ) { $statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . implode( ' OR ', $r_status ) . '))'; } else { $statuswheres[] = '(' . implode( ' OR ', $r_status ) . ')'; } } if ( ! empty( $p_status ) ) { if ( ! empty( $query_vars['perm'] ) && 'readable' === $query_vars['perm'] && ! current_user_can( $read_private_cap ) ) { $statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . implode( ' OR ', $p_status ) . '))'; } else { $statuswheres[] = '(' . implode( ' OR ', $p_status ) . ')'; } } if ( $post_status_join ) { $join .= " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) "; foreach ( $statuswheres as $index => $statuswhere ) { $statuswheres[ $index ] = "($statuswhere OR ({$wpdb->posts}.post_status = 'inherit' AND " . str_replace( $wpdb->posts, 'p2', $statuswhere ) . '))'; } } $where_status = implode( ' OR ', $statuswheres ); if ( ! empty( $where_status ) ) { $where .= " AND ($where_status)"; } } elseif ( ! $this->is_singular ) { if ( 'any' === $post_type ) { $queried_post_types = get_post_types( array( 'exclude_from_search' => false ) ); } elseif ( is_array( $post_type ) ) { $queried_post_types = $post_type; } elseif ( ! empty( $post_type ) ) { $queried_post_types = array( $post_type ); } else { $queried_post_types = array( 'post' ); } if ( ! empty( $queried_post_types ) ) { sort( $queried_post_types ); $status_type_clauses = array(); foreach ( $queried_post_types as $queried_post_type ) { $queried_post_type_object = get_post_type_object( $queried_post_type ); $type_where = '(' . $wpdb->prepare( "{$wpdb->posts}.post_type = %s AND (", $queried_post_type ); $public_statuses = get_post_stati( array( 'public' => true ) ); $status_clauses = array(); foreach ( $public_statuses as $public_status ) { $status_clauses[] = "{$wpdb->posts}.post_status = '$public_status'"; } $type_where .= implode( ' OR ', $status_clauses ); if ( $this->is_admin ) { $admin_all_statuses = get_post_stati( array( 'protected' => true, 'show_in_admin_all_list' => true, ) ); foreach ( $admin_all_statuses as $admin_all_status ) { $type_where .= " OR {$wpdb->posts}.post_status = '$admin_all_status'"; } } if ( is_user_logged_in() && $queried_post_type_object instanceof WP_Post_Type ) { $read_private_cap = $queried_post_type_object->cap->read_private_posts; $private_statuses = get_post_stati( array( 'private' => true ) ); foreach ( $private_statuses as $private_status ) { $type_where .= current_user_can( $read_private_cap ) ? " \nOR {$wpdb->posts}.post_status = '$private_status'" : " \nOR ({$wpdb->posts}.post_author = $user_id AND {$wpdb->posts}.post_status = '$private_status')"; } } $type_where .= '))'; $status_type_clauses[] = $type_where; } if ( ! empty( $status_type_clauses ) ) { $where .= ' AND (' . implode( ' OR ', $status_type_clauses ) . ')'; } } else { $where .= ' AND 1=0 '; } } else { $where .= $post_type_where; } if ( ! $query_vars['suppress_filters'] ) { $where = apply_filters_ref_array( 'posts_where', array( $where, &$this ) ); $join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) ); } if ( empty( $query_vars['nopaging'] ) && ! $this->is_singular ) { $page = absint( $query_vars['paged'] ); if ( ! $page ) { $page = 1; } if ( isset( $query_vars['offset'] ) && is_numeric( $query_vars['offset'] ) ) { $query_vars['offset'] = absint( $query_vars['offset'] ); $pgstrt = $query_vars['offset'] . ', '; } else { $pgstrt = absint( ( $page - 1 ) * $query_vars['posts_per_page'] ) . ', '; } $limits = 'LIMIT ' . $pgstrt . $query_vars['posts_per_page']; } if ( $this->is_comment_feed && ! $this->is_singular ) { if ( $this->is_archive || $this->is_search ) { $cjoin = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID ) $join "; $cwhere = "WHERE comment_approved = '1' $where"; $cgroupby = "{$wpdb->comments}.comment_id"; } else { $cjoin = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )"; $cwhere = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'"; $cgroupby = ''; } if ( ! $query_vars['suppress_filters'] ) { $cjoin = apply_filters_ref_array( 'comment_feed_join', array( $cjoin, &$this ) ); $cwhere = apply_filters_ref_array( 'comment_feed_where', array( $cwhere, &$this ) ); $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( $cgroupby, &$this ) ); $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) ); } $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; $climits = ( ! empty( $climits ) ) ? $climits : ''; $comments_request = "SELECT $distinct {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits"; $key = md5( $comments_request ); $last_changed = array( wp_cache_get_last_changed( 'comment' ), wp_cache_get_last_changed( 'posts' ), ); $cache_key = "comment_feed:$key"; $comment_ids = wp_cache_get_salted( $cache_key, 'comment-queries', $last_changed ); if ( false === $comment_ids ) { $comment_ids = $wpdb->get_col( $comments_request ); wp_cache_set_salted( $cache_key, $comment_ids, 'comment-queries', $last_changed ); } _prime_comment_caches( $comment_ids ); $this->comments = array_map( 'get_comment', $comment_ids ); $this->comment_count = count( $this->comments ); $post_ids = array(); foreach ( $this->comments as $comment ) { $post_ids[] = (int) $comment->comment_post_ID; } $post_ids = implode( ',', $post_ids ); $join = ''; if ( $post_ids ) { $where = "AND {$wpdb->posts}.ID IN ($post_ids) "; } else { $where = 'AND 0'; } } $pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' ); if ( ! $query_vars['suppress_filters'] ) { $where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) ); $groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) ); $join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) ); $orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) ); $distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) ); $limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) ); $fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) ); $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) ); $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : ''; $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; } do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join ); if ( ! $query_vars['suppress_filters'] ) { $where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) ); $groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) ); $join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) ); $orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) ); $distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) ); $fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) ); $limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) ); $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : ''; $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; } if ( ! empty( $groupby ) ) { $groupby = 'GROUP BY ' . $groupby; } if ( ! empty( $orderby ) ) { $orderby = 'ORDER BY ' . $orderby; } $found_rows = ''; if ( ! $query_vars['no_found_rows'] && ! empty( $limits ) ) { $found_rows = 'SQL_CALC_FOUND_ROWS'; } $old_request = "SELECT $found_rows $distinct $fields
FROM {$wpdb->posts} $join
WHERE 1=1 $where
$groupby
$orderby
$limits"; $this->request = $old_request; if ( ! $query_vars['suppress_filters'] ) { $this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) ); } $this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) ); $id_query_is_cacheable = ! str_contains( strtoupper( $orderby ), ' RAND(' ); $cacheable_field_values = array( "{$wpdb->posts}.*", "{$wpdb->posts}.ID, {$wpdb->posts}.post_parent", "{$wpdb->posts}.ID", ); if ( ! in_array( $fields, $cacheable_field_values, true ) ) { $id_query_is_cacheable = false; } $last_changed = (array) wp_cache_get_last_changed( 'posts' ); if ( ! empty( $this->tax_query->queries ) ) { $last_changed[] = wp_cache_get_last_changed( 'terms' ); } if ( $query_vars['cache_results'] && $id_query_is_cacheable ) { $new_request = str_replace( $fields, "{$wpdb->posts}.*", $this->request ); $cache_key = $this->generate_cache_key( $query_vars, $new_request ); $cache_found = false; if ( null === $this->posts ) { $cached_results = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( $cached_results ) { $cache_found = true; $post_ids = array_map( 'intval', $cached_results['posts'] ); $this->post_count = count( $post_ids ); $this->found_posts = $cached_results['found_posts']; $this->max_num_pages = $cached_results['max_num_pages']; if ( 'ids' === $query_vars['fields'] ) { $this->posts = $post_ids; return $this->posts; } elseif ( 'id=>parent' === $query_vars['fields'] ) { _prime_post_parent_id_caches( $post_ids ); $post_parent_cache_keys = array(); foreach ( $post_ids as $post_id ) { $post_parent_cache_keys[] = 'post_parent:' . (string) $post_id; } $post_parents = wp_cache_get_multiple( $post_parent_cache_keys, 'posts' ); foreach ( $post_parents as $cache_key => $post_parent ) { $obj = new stdClass(); $obj->ID = (int) str_replace( 'post_parent:', '', $cache_key ); $obj->post_parent = (int) $post_parent; $this->posts[] = $obj; } return $post_parents; } else { _prime_post_caches( $post_ids, $query_vars['update_post_term_cache'], $query_vars['update_post_meta_cache'] ); $this->posts = array_map( 'get_post', $post_ids ); } } } } if ( 'ids' === $query_vars['fields'] ) { if ( null === $this->posts ) { $this->posts = $wpdb->get_col( $this->request ); } $this->posts = array_map( 'intval', $this->posts ); $this->post_count = count( $this->posts ); $this->set_found_posts( $query_vars, $limits ); if ( $query_vars['cache_results'] && $id_query_is_cacheable ) { $cache_value = array( 'posts' => $this->posts, 'found_posts' => $this->found_posts, 'max_num_pages' => $this->max_num_pages, ); wp_cache_set_salted( $cache_key, $cache_value, 'post-queries', $last_changed ); } return $this->posts; } if ( 'id=>parent' === $query_vars['fields'] ) { if ( null === $this->posts ) { $this->posts = $wpdb->get_results( $this->request ); } $this->post_count = count( $this->posts ); $this->set_found_posts( $query_vars, $limits ); $post_parents = array(); $post_ids = array(); $post_parents_cache = array(); foreach ( $this->posts as $key => $post ) { $this->posts[ $key ]->ID = (int) $post->ID; $this->posts[ $key ]->post_parent = (int) $post->post_parent; $post_parents[ (int) $post->ID ] = (int) $post->post_parent; $post_ids[] = (int) $post->ID; $post_parents_cache[ 'post_parent:' . (string) $post->ID ] = (int) $post->post_parent; } wp_cache_add_multiple( $post_parents_cache, 'posts' ); if ( $query_vars['cache_results'] && $id_query_is_cacheable ) { $cache_value = array( 'posts' => $post_ids, 'found_posts' => $this->found_posts, 'max_num_pages' => $this->max_num_pages, ); wp_cache_set_salted( $cache_key, $cache_value, 'post-queries', $last_changed ); } return $post_parents; } $is_unfiltered_query = $old_request === $this->request && "{$wpdb->posts}.*" === $fields; if ( null === $this->posts ) { $split_the_query = ( $is_unfiltered_query && ( wp_using_ext_object_cache() || ( ! empty( $limits ) && $query_vars['posts_per_page'] < 500 ) ) ); $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this, $old_request, compact( $pieces ) ); if ( $split_the_query ) { $this->request = "SELECT $found_rows $distinct {$wpdb->posts}.ID
FROM {$wpdb->posts} $join
WHERE 1=1 $where
$groupby
$orderby
$limits"; $this->request = apply_filters( 'posts_request_ids', $this->request, $this ); $post_ids = $wpdb->get_col( $this->request ); if ( $post_ids ) { $this->posts = $post_ids; $this->set_found_posts( $query_vars, $limits ); _prime_post_caches( $post_ids, $query_vars['update_post_term_cache'], $query_vars['update_post_meta_cache'] ); } else { $this->posts = array(); } } else { $this->posts = $wpdb->get_results( $this->request ); $this->set_found_posts( $query_vars, $limits ); } } if ( $this->posts ) { $this->posts = array_map( 'get_post', $this->posts ); } $unfiltered_posts = $this->posts; if ( $query_vars['cache_results'] && $id_query_is_cacheable && ! $cache_found ) { $post_ids = wp_list_pluck( $this->posts, 'ID' ); $cache_value = array( 'posts' => $post_ids, 'found_posts' => $this->found_posts, 'max_num_pages' => $this->max_num_pages, ); wp_cache_set_salted( $cache_key, $cache_value, 'post-queries', $last_changed ); } if ( ! $query_vars['suppress_filters'] ) { $this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) ); } if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) { $cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) ); $cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) ); $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) ); $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) ); $comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits"; $comment_key = md5( $comments_request ); $comment_last_changed = wp_cache_get_last_changed( 'comment' ); $comment_cache_key = "comment_feed:$comment_key"; $comment_ids = wp_cache_get_salted( $comment_cache_key, 'comment-queries', $comment_last_changed ); if ( false === $comment_ids ) { $comment_ids = $wpdb->get_col( $comments_request ); wp_cache_set_salted( $comment_cache_key, $comment_ids, 'comment-queries', $comment_last_changed ); } _prime_comment_caches( $comment_ids ); $this->comments = array_map( 'get_comment', $comment_ids ); $this->comment_count = count( $this->comments ); } if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) { $status = get_post_status( $this->posts[0] ); if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) { $this->is_page = false; $this->is_single = true; $this->is_attachment = true; } if ( ! in_array( $status, $q_status, true ) ) { $post_status_obj = get_post_status_object( $status ); if ( $post_status_obj && ! $post_status_obj->public ) { if ( ! is_user_logged_in() ) { $this->posts = array(); } else { if ( $post_status_obj->protected ) { if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) { $this->posts = array(); } else { $this->is_preview = true; if ( 'future' !== $status ) { $this->posts[0]->post_date = current_time( 'mysql' ); } } } elseif ( $post_status_obj->private ) { if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) { $this->posts = array(); } } else { $this->posts = array(); } } } elseif ( ! $post_status_obj ) { if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) { $this->posts = array(); } } } if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) ) { $this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) ); } } $sticky_posts = get_option( 'sticky_posts' ); if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $query_vars['ignore_sticky_posts'] ) { $num_posts = count( $this->posts ); $sticky_offset = 0; for ( $i = 0; $i < $num_posts; $i++ ) { if ( in_array( $this->posts[ $i ]->ID, $sticky_posts, true ) ) { $sticky_post = $this->posts[ $i ]; array_splice( $this->posts, $i, 1 ); array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) ); ++$sticky_offset; $offset = array_search( $sticky_post->ID, $sticky_posts, true ); unset( $sticky_posts[ $offset ] ); } } if ( ! empty( $sticky_posts ) && ! empty( $query_vars['post__not_in'] ) ) { $sticky_posts = array_diff( $sticky_posts, $query_vars['post__not_in'] ); } if ( ! empty( $sticky_posts ) ) { $stickies = get_posts( array( 'post__in' => $sticky_posts, 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => count( $sticky_posts ), 'suppress_filters' => $query_vars['suppress_filters'], 'cache_results' => $query_vars['cache_results'], 'update_post_meta_cache' => $query_vars['update_post_meta_cache'], 'update_post_term_cache' => $query_vars['update_post_term_cache'], 'lazy_load_term_meta' => $query_vars['lazy_load_term_meta'], ) ); foreach ( $stickies as $sticky_post ) { array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) ); ++$sticky_offset; } } } if ( ! $query_vars['suppress_filters'] ) { $this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) ); } if ( $this->posts ) { $this->post_count = count( $this->posts ); $this->posts = array_map( 'get_post', $this->posts ); if ( $query_vars['cache_results'] ) { if ( $is_unfiltered_query && $unfiltered_posts === $this->posts ) { update_post_caches( $this->posts, $post_type, $query_vars['update_post_term_cache'], $query_vars['update_post_meta_cache'] ); } else { $post_ids = wp_list_pluck( $this->posts, 'ID' ); _prime_post_caches( $post_ids, $query_vars['update_post_term_cache'], $query_vars['update_post_meta_cache'] ); } } $this->post = reset( $this->posts ); } else { $this->post_count = 0; $this->posts = array(); } if ( ! empty( $this->posts ) && $query_vars['update_menu_item_cache'] ) { update_menu_item_cache( $this->posts ); } if ( $query_vars['lazy_load_term_meta'] ) { wp_queue_posts_for_term_meta_lazyload( $this->posts ); } return $this->posts; } private function set_found_posts( $query_vars, $limits ) { global $wpdb; if ( $query_vars['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) ) { return; } if ( ! empty( $limits ) ) { $found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ); $this->found_posts = (int) $wpdb->get_var( $found_posts_query ); } else { if ( is_array( $this->posts ) ) { $this->found_posts = count( $this->posts ); } else { if ( null === $this->posts ) { $this->found_posts = 0; } else { $this->found_posts = 1; } } } $this->found_posts = (int) apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) ); if ( ! empty( $limits ) ) { $this->max_num_pages = (int) ceil( $this->found_posts / $query_vars['posts_per_page'] ); } } public function next_post() { ++$this->current_post; $this->post = $this->posts[ $this->current_post ]; return $this->post; } public function the_post() { global $post; if ( ! $this->in_the_loop ) { if ( 'all' === $this->query_vars['fields'] ) { $post_objects = $this->posts; } else { if ( 'ids' === $this->query_vars['fields'] ) { $post_ids = $this->posts; } else { $post_ids = array_reduce( $this->posts, function ( $carry, $post ) { if ( isset( $post->ID ) ) { $carry[] = $post->ID; } return $carry; }, array() ); } _prime_post_caches( $post_ids, $this->query_vars['update_post_term_cache'], $this->query_vars['update_post_meta_cache'] ); $post_objects = array_map( 'get_post', $post_ids ); } update_post_author_caches( $post_objects ); } $this->in_the_loop = true; $this->before_loop = false; if ( -1 === $this->current_post ) { do_action_ref_array( 'loop_start', array( &$this ) ); } $post = $this->next_post(); if ( 'all' !== $this->query_vars['fields'] ) { if ( 'ids' === $this->query_vars['fields'] ) { $post = get_post( $post ); } elseif ( isset( $post->ID ) ) { $post = get_post( $post->ID ); } } $this->setup_postdata( $post ); } public function have_posts() { if ( $this->current_post + 1 < $this->post_count ) { return true; } elseif ( $this->current_post + 1 === $this->post_count && $this->post_count > 0 ) { do_action_ref_array( 'loop_end', array( &$this ) ); $this->rewind_posts(); } elseif ( 0 === $this->post_count ) { $this->before_loop = false; do_action( 'loop_no_results', $this ); } $this->in_the_loop = false; return false; } public function rewind_posts() { $this->current_post = -1; if ( $this->post_count > 0 ) { $this->post = $this->posts[0]; } } public function next_comment() { ++$this->current_comment; $this->comment = $this->comments[ $this->current_comment ]; return $this->comment; } public function the_comment() { global $comment; $comment = $this->next_comment(); if ( 0 === $this->current_comment ) { do_action( 'comment_loop_start' ); } } public function have_comments() { if ( $this->current_comment + 1 < $this->comment_count ) { return true; } elseif ( $this->current_comment + 1 === $this->comment_count ) { $this->rewind_comments(); } return false; } public function rewind_comments() { $this->current_comment = -1; if ( $this->comment_count > 0 ) { $this->comment = $this->comments[0]; } } public function query( $query ) { $this->init(); $this->query = wp_parse_args( $query ); $this->query_vars = $this->query; return $this->get_posts(); } public function get_queried_object() { if ( isset( $this->queried_object ) ) { return $this->queried_object; } $this->queried_object = null; $this->queried_object_id = null; if ( $this->is_category || $this->is_tag || $this->is_tax ) { if ( $this->is_category ) { $cat = $this->get( 'cat' ); $category_name = $this->get( 'category_name' ); if ( $cat ) { $term = get_term( $cat, 'category' ); } elseif ( $category_name ) { $term = get_term_by( 'slug', $category_name, 'category' ); } } elseif ( $this->is_tag ) { $tag_id = $this->get( 'tag_id' ); $tag = $this->get( 'tag' ); if ( $tag_id ) { $term = get_term( $tag_id, 'post_tag' ); } elseif ( $tag ) { $term = get_term_by( 'slug', $tag, 'post_tag' ); } } else { if ( ! empty( $this->tax_query->queried_terms ) ) { $queried_taxonomies = array_keys( $this->tax_query->queried_terms ); $matched_taxonomy = reset( $queried_taxonomies ); $query = $this->tax_query->queried_terms[ $matched_taxonomy ]; if ( ! empty( $query['terms'] ) ) { if ( 'term_id' === $query['field'] ) { $term = get_term( reset( $query['terms'] ), $matched_taxonomy ); } else { $term = get_term_by( $query['field'], reset( $query['terms'] ), $matched_taxonomy ); } } } } if ( ! empty( $term ) && ! is_wp_error( $term ) ) { $this->queried_object = $term; $this->queried_object_id = (int) $term->term_id; if ( $this->is_category && 'category' === $this->queried_object->taxonomy ) { _make_cat_compat( $this->queried_object ); } } } elseif ( $this->is_post_type_archive ) { $post_type = $this->get( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $this->queried_object = get_post_type_object( $post_type ); } elseif ( $this->is_posts_page ) { $page_for_posts = get_option( 'page_for_posts' ); $this->queried_object = get_post( $page_for_posts ); $this->queried_object_id = (int) $this->queried_object->ID; } elseif ( $this->is_singular && ! empty( $this->post ) ) { $this->queried_object = $this->post; $this->queried_object_id = (int) $this->post->ID; } elseif ( $this->is_author ) { $author = (int) $this->get( 'author' ); $author_name = $this->get( 'author_name' ); if ( $author ) { $this->queried_object_id = $author; } elseif ( $author_name ) { $user = get_user_by( 'slug', $author_name ); if ( $user ) { $this->queried_object_id = $user->ID; } } $this->queried_object = get_userdata( $this->queried_object_id ); } return $this->queried_object; } public function get_queried_object_id() { $this->get_queried_object(); if ( isset( $this->queried_object_id ) ) { return $this->queried_object_id; } return 0; } public function __construct( $query = '' ) { if ( ! empty( $query ) ) { $this->query( $query ); } } public function __get( $name ) { if ( in_array( $name, $this->compat_fields, true ) ) { return $this->$name; } } public function __isset( $name ) { if ( in_array( $name, $this->compat_fields, true ) ) { return isset( $this->$name ); } return false; } public function __call( $name, $arguments ) { if ( in_array( $name, $this->compat_methods, true ) ) { return $this->$name( ...$arguments ); } return false; } public function is_archive() { return (bool) $this->is_archive; } public function is_post_type_archive( $post_types = '' ) { if ( empty( $post_types ) || ! $this->is_post_type_archive ) { return (bool) $this->is_post_type_archive; } $post_type = $this->get( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $post_type_object = get_post_type_object( $post_type ); if ( ! $post_type_object ) { return false; } return in_array( $post_type_object->name, (array) $post_types, true ); } public function is_attachment( $attachment = '' ) { if ( ! $this->is_attachment ) { return false; } if ( empty( $attachment ) ) { return true; } $attachment = array_map( 'strval', (array) $attachment ); $post_obj = $this->get_queried_object(); if ( ! $post_obj ) { return false; } if ( in_array( (string) $post_obj->ID, $attachment, true ) ) { return true; } elseif ( in_array( $post_obj->post_title, $attachment, true ) ) { return true; } elseif ( in_array( $post_obj->post_name, $attachment, true ) ) { return true; } return false; } public function is_author( $author = '' ) { if ( ! $this->is_author ) { return false; } if ( empty( $author ) ) { return true; } $author_obj = $this->get_queried_object(); if ( ! $author_obj ) { return false; } $author = array_map( 'strval', (array) $author ); if ( in_array( (string) $author_obj->ID, $author, true ) ) { return true; } elseif ( in_array( $author_obj->nickname, $author, true ) ) { return true; } elseif ( in_array( $author_obj->user_nicename, $author, true ) ) { return true; } return false; } public function is_category( $category = '' ) { if ( ! $this->is_category ) { return false; } if ( empty( $category ) ) { return true; } $cat_obj = $this->get_queried_object(); if ( ! $cat_obj ) { return false; } $category = array_map( 'strval', (array) $category ); if ( in_array( (string) $cat_obj->term_id, $category, true ) ) { return true; } elseif ( in_array( $cat_obj->name, $category, true ) ) { return true; } elseif ( in_array( $cat_obj->slug, $category, true ) ) { return true; } return false; } public function is_tag( $tag = '' ) { if ( ! $this->is_tag ) { return false; } if ( empty( $tag ) ) { return true; } $tag_obj = $this->get_queried_object(); if ( ! $tag_obj ) { return false; } $tag = array_map( 'strval', (array) $tag ); if ( in_array( (string) $tag_obj->term_id, $tag, true ) ) { return true; } elseif ( in_array( $tag_obj->name, $tag, true ) ) { return true; } elseif ( in_array( $tag_obj->slug, $tag, true ) ) { return true; } return false; } public function is_tax( $taxonomy = '', $term = '' ) { global $wp_taxonomies; if ( ! $this->is_tax ) { return false; } if ( empty( $taxonomy ) ) { return true; } $queried_object = $this->get_queried_object(); $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy ); $term_array = (array) $term; if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array, true ) ) ) { return false; } if ( empty( $term ) ) { return true; } return isset( $queried_object->term_id ) && count( array_intersect( array( $queried_object->term_id, $queried_object->name, $queried_object->slug ), $term_array ) ); } public function is_comments_popup() { _deprecated_function( __FUNCTION__, '4.5.0' ); return false; } public function is_date() { return (bool) $this->is_date; } public function is_day() { return (bool) $this->is_day; } public function is_feed( $feeds = '' ) { if ( empty( $feeds ) || ! $this->is_feed ) { return (bool) $this->is_feed; } $query_var = $this->get( 'feed' ); if ( 'feed' === $query_var ) { $query_var = get_default_feed(); } return in_array( $query_var, (array) $feeds, true ); } public function is_comment_feed() { return (bool) $this->is_comment_feed; } public function is_front_page() { if ( 'posts' === get_option( 'show_on_front' ) && $this->is_home() ) { return true; } elseif ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) ) { return true; } else { return false; } } public function is_home() { return (bool) $this->is_home; } public function is_privacy_policy() { if ( get_option( 'wp_page_for_privacy_policy' ) && $this->is_page( get_option( 'wp_page_for_privacy_policy' ) ) ) { return true; } else { return false; } } public function is_month() { return (bool) $this->is_month; } public function is_page( $page = '' ) { if ( ! $this->is_page ) { return false; } if ( empty( $page ) ) { return true; } $page_obj = $this->get_queried_object(); if ( ! $page_obj ) { return false; } $page = array_map( 'strval', (array) $page ); if ( in_array( (string) $page_obj->ID, $page, true ) ) { return true; } elseif ( in_array( $page_obj->post_title, $page, true ) ) { return true; } elseif ( in_array( $page_obj->post_name, $page, true ) ) { return true; } else { foreach ( $page as $pagepath ) { if ( ! strpos( $pagepath, '/' ) ) { continue; } $pagepath_obj = get_page_by_path( $pagepath ); if ( $pagepath_obj && ( $pagepath_obj->ID === $page_obj->ID ) ) { return true; } } } return false; } public function is_paged() { return (bool) $this->is_paged; } public function is_preview() { return (bool) $this->is_preview; } public function is_robots() { return (bool) $this->is_robots; } public function is_favicon() { return (bool) $this->is_favicon; } public function is_search() { return (bool) $this->is_search; } public function is_single( $post = '' ) { if ( ! $this->is_single ) { return false; } if ( empty( $post ) ) { return true; } $post_obj = $this->get_queried_object(); if ( ! $post_obj ) { return false; } $post = array_map( 'strval', (array) $post ); if ( in_array( (string) $post_obj->ID, $post, true ) ) { return true; } elseif ( in_array( $post_obj->post_title, $post, true ) ) { return true; } elseif ( in_array( $post_obj->post_name, $post, true ) ) { return true; } else { foreach ( $post as $postpath ) { if ( ! strpos( $postpath, '/' ) ) { continue; } $postpath_obj = get_page_by_path( $postpath, OBJECT, $post_obj->post_type ); if ( $postpath_obj && ( $postpath_obj->ID === $post_obj->ID ) ) { return true; } } } return false; } public function is_singular( $post_types = '' ) { if ( empty( $post_types ) || ! $this->is_singular ) { return (bool) $this->is_singular; } $post_obj = $this->get_queried_object(); if ( ! $post_obj ) { return false; } return in_array( $post_obj->post_type, (array) $post_types, true ); } public function is_time() { return (bool) $this->is_time; } public function is_trackback() { return (bool) $this->is_trackback; } public function is_year() { return (bool) $this->is_year; } public function is_404() { return (bool) $this->is_404; } public function is_embed() { return (bool) $this->is_embed; } public function is_main_query() { global $wp_the_query; return $wp_the_query === $this; } public function setup_postdata( $post ) { global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages; if ( ! ( $post instanceof WP_Post ) ) { $post = get_post( $post ); } if ( ! $post ) { return; } $elements = $this->generate_postdata( $post ); if ( false === $elements ) { return; } $id = $elements['id']; $authordata = $elements['authordata']; $currentday = $elements['currentday']; $currentmonth = $elements['currentmonth']; $page = $elements['page']; $pages = $elements['pages']; $multipage = $elements['multipage']; $more = $elements['more']; $numpages = $elements['numpages']; do_action_ref_array( 'the_post', array( &$post, &$this ) ); return true; } public function generate_postdata( $post ) { if ( ! ( $post instanceof WP_Post ) ) { $post = get_post( $post ); } if ( ! $post ) { return false; } $id = (int) $post->ID; $authordata = get_userdata( $post->post_author ); $currentday = false; $currentmonth = false; $post_date = $post->post_date; if ( ! empty( $post_date ) && '0000-00-00 00:00:00' !== $post_date ) { $currentmonth = substr( $post_date, 5, 2 ); $day = substr( $post_date, 8, 2 ); $year = substr( $post_date, 2, 2 ); $currentday = sprintf( '%s.%s.%s', $day, $currentmonth, $year ); } $numpages = 1; $multipage = 0; $page = $this->get( 'page' ); if ( ! $page ) { $page = 1; } if ( get_queried_object_id() === $post->ID && ( $this->is_page() || $this->is_single() ) ) { $more = 1; } elseif ( $this->is_feed() ) { $more = 1; } else { $more = 0; } $content = $post->post_content; if ( str_contains( $content, '<!--nextpage-->' ) ) { $content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content ); $content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content ); $content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content ); $content = str_replace( '<!-- wp:nextpage -->', '', $content ); $content = str_replace( '<!-- /wp:nextpage -->', '', $content ); if ( str_starts_with( $content, '<!--nextpage-->' ) ) { $content = substr( $content, 15 ); } $pages = explode( '<!--nextpage-->', $content ); } else { $pages = array( $post->post_content ); } $pages = apply_filters( 'content_pagination', $pages, $post ); $numpages = count( $pages ); if ( $numpages > 1 ) { if ( $page > 1 ) { $more = 1; } $multipage = 1; } else { $multipage = 0; } $elements = compact( 'id', 'authordata', 'currentday', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages' ); return $elements; } protected function generate_cache_key( array $args, $sql ) { global $wpdb; unset( $args['cache_results'], $args['fields'], $args['lazy_load_term_meta'], $args['update_post_meta_cache'], $args['update_post_term_cache'], $args['update_menu_item_cache'], $args['suppress_filters'] ); if ( empty( $args['post_type'] ) ) { if ( $this->is_attachment ) { $args['post_type'] = 'attachment'; } elseif ( $this->is_page ) { $args['post_type'] = 'page'; } else { $args['post_type'] = 'post'; } } elseif ( 'any' === $args['post_type'] ) { $args['post_type'] = array_values( get_post_types( array( 'exclude_from_search' => false ) ) ); } $args['post_type'] = (array) $args['post_type']; sort( $args['post_type'] ); $sortable_arrays_with_int_values = array( 'post__in', 'post_parent__in', ); foreach ( $sortable_arrays_with_int_values as $key ) { if ( isset( $args[ $key ] ) && is_array( $args[ $key ] ) ) { $args[ $key ] = array_unique( array_map( 'absint', $args[ $key ] ) ); sort( $args[ $key ] ); } } if ( isset( $args['post_name__in'] ) && is_array( $args['post_name__in'] ) ) { $args['post_name__in'] = array_unique( $args['post_name__in'] ); sort( $args['post_name__in'] ); } if ( isset( $args['post_status'] ) ) { $args['post_status'] = (array) $args['post_status']; sort( $args['post_status'] ); } if ( ! isset( $args['orderby'] ) ) { $args['orderby'] = 'date'; } $placeholder = $wpdb->placeholder_escape(); array_walk_recursive( $args, static function ( &$value ) use ( $wpdb, $placeholder ) { if ( is_string( $value ) && str_contains( $value, $placeholder ) ) { $value = $wpdb->remove_placeholder_escape( $value ); } } ); ksort( $args ); $sql = $wpdb->remove_placeholder_escape( $sql ); $key = md5( serialize( $args ) . $sql ); $this->query_cache_key = "wp_query:$key"; return $this->query_cache_key; } public function reset_postdata() { if ( ! empty( $this->post ) ) { $GLOBALS['post'] = $this->post; $this->setup_postdata( $this->post ); } } public function lazyload_term_meta( $check, $term_id ) { _deprecated_function( __METHOD__, '4.5.0' ); return $check; } public function lazyload_comment_meta( $check, $comment_id ) { _deprecated_function( __METHOD__, '4.5.0' ); return $check; } }
###require ABSPATH . WPINC . '/query.php';
function get_query_var( $query_var, $default_value = '' ) { global $wp_query; return $wp_query->get( $query_var, $default_value ); } function get_queried_object() { global $wp_query; return $wp_query->get_queried_object(); } function get_queried_object_id() { global $wp_query; return $wp_query->get_queried_object_id(); } function set_query_var( $query_var, $value ) { global $wp_query; $wp_query->set( $query_var, $value ); } function query_posts( $query ) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query( $query ); } function wp_reset_query() { $GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; wp_reset_postdata(); } function wp_reset_postdata() { global $wp_query; if ( isset( $wp_query ) ) { $wp_query->reset_postdata(); } } function is_archive() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_archive(); } function is_post_type_archive( $post_types = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_post_type_archive( $post_types ); } function is_attachment( $attachment = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_attachment( $attachment ); } function is_author( $author = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_author( $author ); } function is_category( $category = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_category( $category ); } function is_tag( $tag = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_tag( $tag ); } function is_tax( $taxonomy = '', $term = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_tax( $taxonomy, $term ); } function is_date() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_date(); } function is_day() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_day(); } function is_feed( $feeds = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_feed( $feeds ); } function is_comment_feed() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_comment_feed(); } function is_front_page() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_front_page(); } function is_home() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_home(); } function is_privacy_policy() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_privacy_policy(); } function is_month() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_month(); } function is_page( $page = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_page( $page ); } function is_paged() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_paged(); } function is_preview() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_preview(); } function is_robots() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_robots(); } function is_favicon() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_favicon(); } function is_search() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_search(); } function is_single( $post = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_single( $post ); } function is_singular( $post_types = '' ) { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_singular( $post_types ); } function is_time() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_time(); } function is_trackback() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_trackback(); } function is_year() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_year(); } function is_404() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_404(); } function is_embed() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' ); return false; } return $wp_query->is_embed(); } function is_main_query() { global $wp_query; if ( ! isset( $wp_query ) ) { _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '6.1.0' ); return false; } if ( 'pre_get_posts' === current_filter() ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'In %1$s, use the %2$s method, not the %3$s function. See %4$s.' ), '<code>pre_get_posts</code>', '<code>WP_Query->is_main_query()</code>', '<code>is_main_query()</code>', __( 'https://developer.wordpress.org/reference/functions/is_main_query/' ) ), '3.7.0' ); } return $wp_query->is_main_query(); } function have_posts() { global $wp_query; if ( ! isset( $wp_query ) ) { return false; } return $wp_query->have_posts(); } function in_the_loop() { global $wp_query; if ( ! isset( $wp_query ) ) { return false; } return $wp_query->in_the_loop; } function rewind_posts() { global $wp_query; if ( ! isset( $wp_query ) ) { return; } $wp_query->rewind_posts(); } function the_post() { global $wp_query; if ( ! isset( $wp_query ) ) { return; } $wp_query->the_post(); } function have_comments() { global $wp_query; if ( ! isset( $wp_query ) ) { return false; } return $wp_query->have_comments(); } function the_comment() { global $wp_query; if ( ! isset( $wp_query ) ) { return; } $wp_query->the_comment(); } function wp_old_slug_redirect() { if ( is_404() && '' !== get_query_var( 'name' ) ) { if ( get_query_var( 'post_type' ) ) { $post_type = get_query_var( 'post_type' ); } elseif ( get_query_var( 'attachment' ) ) { $post_type = 'attachment'; } elseif ( get_query_var( 'pagename' ) ) { $post_type = 'page'; } else { $post_type = 'post'; } if ( is_array( $post_type ) ) { if ( count( $post_type ) > 1 ) { return; } $post_type = reset( $post_type ); } if ( is_post_type_hierarchical( $post_type ) ) { return; } $id = _find_post_by_old_slug( $post_type ); if ( ! $id ) { $id = _find_post_by_old_date( $post_type ); } $id = apply_filters( 'old_slug_redirect_post_id', $id ); if ( ! $id ) { return; } $link = get_permalink( $id ); if ( get_query_var( 'paged' ) > 1 ) { $link = user_trailingslashit( trailingslashit( $link ) . 'page/' . get_query_var( 'paged' ) ); } elseif ( is_embed() ) { $link = user_trailingslashit( trailingslashit( $link ) . 'embed' ); } $link = apply_filters( 'old_slug_redirect_url', $link ); if ( ! $link ) { return; } wp_redirect( $link, 301 ); exit; } } function _find_post_by_old_slug( $post_type ) { global $wpdb; $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, get_query_var( 'name' ) ); if ( get_query_var( 'year' ) ) { $query .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) ); } if ( get_query_var( 'monthnum' ) ) { $query .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) ); } if ( get_query_var( 'day' ) ) { $query .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) ); } $key = md5( $query ); $last_changed = wp_cache_get_last_changed( 'posts' ); $cache_key = "find_post_by_old_slug:$key"; $cache = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( false !== $cache ) { $id = $cache; } else { $id = (int) $wpdb->get_var( $query ); wp_cache_set_salted( $cache_key, $id, 'post-queries', $last_changed ); } return $id; } function _find_post_by_old_date( $post_type ) { global $wpdb; $date_query = ''; if ( get_query_var( 'year' ) ) { $date_query .= $wpdb->prepare( ' AND YEAR(pm_date.meta_value) = %d', get_query_var( 'year' ) ); } if ( get_query_var( 'monthnum' ) ) { $date_query .= $wpdb->prepare( ' AND MONTH(pm_date.meta_value) = %d', get_query_var( 'monthnum' ) ); } if ( get_query_var( 'day' ) ) { $date_query .= $wpdb->prepare( ' AND DAYOFMONTH(pm_date.meta_value) = %d', get_query_var( 'day' ) ); } $id = 0; if ( $date_query ) { $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta AS pm_date, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_date' AND post_name = %s" . $date_query, $post_type, get_query_var( 'name' ) ); $key = md5( $query ); $last_changed = wp_cache_get_last_changed( 'posts' ); $cache_key = "find_post_by_old_date:$key"; $cache = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( false !== $cache ) { $id = $cache; } else { $id = (int) $wpdb->get_var( $query ); if ( ! $id ) { $id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts, $wpdb->postmeta AS pm_slug, $wpdb->postmeta AS pm_date WHERE ID = pm_slug.post_id AND ID = pm_date.post_id AND post_type = %s AND pm_slug.meta_key = '_wp_old_slug' AND pm_slug.meta_value = %s AND pm_date.meta_key = '_wp_old_date'" . $date_query, $post_type, get_query_var( 'name' ) ) ); } wp_cache_set_salted( $cache_key, $id, 'post-queries', $last_changed ); } } return $id; } function setup_postdata( $post ) { global $wp_query; if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) { return $wp_query->setup_postdata( $post ); } return false; } function generate_postdata( $post ) { global $wp_query; if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) { return $wp_query->generate_postdata( $post ); } return false; }
###require ABSPATH . WPINC . '/class-wp-date-query.php';
class WP_Date_Query { public $queries = array(); public $relation = 'AND'; public $column = 'post_date'; public $compare = '='; public $time_keys = array( 'after', 'before', 'year', 'month', 'monthnum', 'week', 'w', 'dayofyear', 'day', 'dayofweek', 'dayofweek_iso', 'hour', 'minute', 'second' ); public function __construct( $date_query, $default_column = 'post_date' ) { if ( empty( $date_query ) || ! is_array( $date_query ) ) { return; } if ( isset( $date_query['relation'] ) ) { $this->relation = $this->sanitize_relation( $date_query['relation'] ); } else { $this->relation = 'AND'; } if ( ! isset( $date_query[0] ) ) { $date_query = array( $date_query ); } if ( ! empty( $date_query['column'] ) ) { $date_query['column'] = esc_sql( $date_query['column'] ); } else { $date_query['column'] = esc_sql( $default_column ); } $this->column = $this->validate_column( $this->column ); $this->compare = $this->get_compare( $date_query ); $this->queries = $this->sanitize_query( $date_query ); } public function sanitize_query( $queries, $parent_query = null ) { $cleaned_query = array(); $defaults = array( 'column' => 'post_date', 'compare' => '=', 'relation' => 'AND', ); foreach ( $queries as $qkey => $qvalue ) { if ( is_numeric( $qkey ) && ! is_array( $qvalue ) ) { unset( $queries[ $qkey ] ); } } foreach ( $defaults as $dkey => $dvalue ) { if ( isset( $queries[ $dkey ] ) ) { continue; } if ( isset( $parent_query[ $dkey ] ) ) { $queries[ $dkey ] = $parent_query[ $dkey ]; } else { $queries[ $dkey ] = $dvalue; } } if ( $this->is_first_order_clause( $queries ) ) { $this->validate_date_values( $queries ); } $queries['relation'] = $this->sanitize_relation( $queries['relation'] ); foreach ( $queries as $key => $q ) { if ( ! is_array( $q ) || in_array( $key, $this->time_keys, true ) ) { $cleaned_query[ $key ] = $q; } else { $cleaned_query[] = $this->sanitize_query( $q, $queries ); } } return $cleaned_query; } protected function is_first_order_clause( $query ) { $time_keys = array_intersect( $this->time_keys, array_keys( $query ) ); return ! empty( $time_keys ); } public function get_compare( $query ) { if ( ! empty( $query['compare'] ) && in_array( $query['compare'], array( '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) { return strtoupper( $query['compare'] ); } return $this->compare; } public function validate_date_values( $date_query = array() ) { if ( empty( $date_query ) ) { return false; } $valid = true; if ( array_key_exists( 'before', $date_query ) && is_array( $date_query['before'] ) ) { $valid = $this->validate_date_values( $date_query['before'] ); } if ( array_key_exists( 'after', $date_query ) && is_array( $date_query['after'] ) ) { $valid = $this->validate_date_values( $date_query['after'] ); } $min_max_checks = array(); if ( array_key_exists( 'year', $date_query ) ) { if ( is_array( $date_query['year'] ) ) { $_year = reset( $date_query['year'] ); } else { $_year = $date_query['year']; } $max_days_of_year = (int) gmdate( 'z', mktime( 0, 0, 0, 12, 31, $_year ) ) + 1; } else { $max_days_of_year = 366; } $min_max_checks['dayofyear'] = array( 'min' => 1, 'max' => $max_days_of_year, ); $min_max_checks['dayofweek'] = array( 'min' => 1, 'max' => 7, ); $min_max_checks['dayofweek_iso'] = array( 'min' => 1, 'max' => 7, ); $min_max_checks['month'] = array( 'min' => 1, 'max' => 12, ); if ( isset( $_year ) ) { $week_count = gmdate( 'W', mktime( 0, 0, 0, 12, 28, $_year ) ); } else { $week_count = 53; } $min_max_checks['week'] = array( 'min' => 1, 'max' => $week_count, ); $min_max_checks['day'] = array( 'min' => 1, 'max' => 31, ); $min_max_checks['hour'] = array( 'min' => 0, 'max' => 23, ); $min_max_checks['minute'] = array( 'min' => 0, 'max' => 59, ); $min_max_checks['second'] = array( 'min' => 0, 'max' => 59, ); foreach ( $min_max_checks as $key => $check ) { if ( ! array_key_exists( $key, $date_query ) ) { continue; } foreach ( (array) $date_query[ $key ] as $_value ) { $is_between = $_value >= $check['min'] && $_value <= $check['max']; if ( ! is_numeric( $_value ) || ! $is_between ) { $error = sprintf( __( 'Invalid value %1$s for %2$s. Expected value should be between %3$s and %4$s.' ), '<code>' . esc_html( $_value ) . '</code>', '<code>' . esc_html( $key ) . '</code>', '<code>' . esc_html( $check['min'] ) . '</code>', '<code>' . esc_html( $check['max'] ) . '</code>' ); _doing_it_wrong( __CLASS__, $error, '4.1.0' ); $valid = false; } } } if ( ! $valid ) { return $valid; } $day_month_year_error_msg = ''; $day_exists = array_key_exists( 'day', $date_query ) && is_numeric( $date_query['day'] ); $month_exists = array_key_exists( 'month', $date_query ) && is_numeric( $date_query['month'] ); $year_exists = array_key_exists( 'year', $date_query ) && is_numeric( $date_query['year'] ); if ( $day_exists && $month_exists && $year_exists ) { if ( ! wp_checkdate( $date_query['month'], $date_query['day'], $date_query['year'], sprintf( '%s-%s-%s', $date_query['year'], $date_query['month'], $date_query['day'] ) ) ) { $day_month_year_error_msg = sprintf( __( 'The following values do not describe a valid date: year %1$s, month %2$s, day %3$s.' ), '<code>' . esc_html( $date_query['year'] ) . '</code>', '<code>' . esc_html( $date_query['month'] ) . '</code>', '<code>' . esc_html( $date_query['day'] ) . '</code>' ); $valid = false; } } elseif ( $day_exists && $month_exists ) { if ( ! wp_checkdate( $date_query['month'], $date_query['day'], 2012, sprintf( '2012-%s-%s', $date_query['month'], $date_query['day'] ) ) ) { $day_month_year_error_msg = sprintf( __( 'The following values do not describe a valid date: month %1$s, day %2$s.' ), '<code>' . esc_html( $date_query['month'] ) . '</code>', '<code>' . esc_html( $date_query['day'] ) . '</code>' ); $valid = false; } } if ( ! empty( $day_month_year_error_msg ) ) { _doing_it_wrong( __CLASS__, $day_month_year_error_msg, '4.1.0' ); } return $valid; } public function validate_column( $column ) { global $wpdb; $valid_columns = array( 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt', 'comment_date', 'comment_date_gmt', 'user_registered', ); if ( is_multisite() ) { $valid_columns = array_merge( $valid_columns, array( 'registered', 'last_updated', ) ); } if ( ! str_contains( $column, '.' ) ) { if ( ! in_array( $column, apply_filters( 'date_query_valid_columns', $valid_columns ), true ) ) { $column = 'post_date'; } $known_columns = array( $wpdb->posts => array( 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt', ), $wpdb->comments => array( 'comment_date', 'comment_date_gmt', ), $wpdb->users => array( 'user_registered', ), ); if ( is_multisite() ) { $known_columns[ $wpdb->blogs ] = array( 'registered', 'last_updated', ); } foreach ( $known_columns as $table_name => $table_columns ) { if ( in_array( $column, $table_columns, true ) ) { $column = $table_name . '.' . $column; break; } } } return preg_replace( '/[^a-zA-Z0-9_$\.]/', '', $column ); } public function get_sql() { $sql = $this->get_sql_clauses(); $where = $sql['where']; return apply_filters( 'get_date_sql', $where, $this ); } protected function get_sql_clauses() { $sql = $this->get_sql_for_query( $this->queries ); if ( ! empty( $sql['where'] ) ) { $sql['where'] = ' AND ' . $sql['where']; } return $sql; } protected function get_sql_for_query( $query, $depth = 0 ) { $sql_chunks = array( 'join' => array(), 'where' => array(), ); $sql = array( 'join' => '', 'where' => '', ); $indent = ''; for ( $i = 0; $i < $depth; $i++ ) { $indent .= ' '; } foreach ( $query as $key => $clause ) { if ( 'relation' === $key ) { $relation = $query['relation']; } elseif ( is_array( $clause ) ) { if ( $this->is_first_order_clause( $clause ) ) { $clause_sql = $this->get_sql_for_clause( $clause, $query ); $where_count = count( $clause_sql['where'] ); if ( ! $where_count ) { $sql_chunks['where'][] = ''; } elseif ( 1 === $where_count ) { $sql_chunks['where'][] = $clause_sql['where'][0]; } else { $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; } $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); } else { $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); $sql_chunks['where'][] = $clause_sql['where']; $sql_chunks['join'][] = $clause_sql['join']; } } } $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); if ( empty( $relation ) ) { $relation = 'AND'; } if ( ! empty( $sql_chunks['join'] ) ) { $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); } if ( ! empty( $sql_chunks['where'] ) ) { $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; } return $sql; } protected function get_sql_for_subquery( $query ) { return $this->get_sql_for_clause( $query, '' ); } protected function get_sql_for_clause( $query, $parent_query ) { global $wpdb; $where_parts = array(); $column = ( ! empty( $query['column'] ) ) ? esc_sql( $query['column'] ) : $this->column; $column = $this->validate_column( $column ); $compare = $this->get_compare( $query ); $inclusive = ! empty( $query['inclusive'] ); $lt = '<'; $gt = '>'; if ( $inclusive ) { $lt .= '='; $gt .= '='; } if ( ! empty( $query['after'] ) ) { $where_parts[] = $wpdb->prepare( "$column $gt %s", $this->build_mysql_datetime( $query['after'], ! $inclusive ) ); } if ( ! empty( $query['before'] ) ) { $where_parts[] = $wpdb->prepare( "$column $lt %s", $this->build_mysql_datetime( $query['before'], $inclusive ) ); } $date_units = array( 'YEAR' => array( 'year' ), 'MONTH' => array( 'month', 'monthnum' ), '_wp_mysql_week' => array( 'week', 'w' ), 'DAYOFYEAR' => array( 'dayofyear' ), 'DAYOFMONTH' => array( 'day' ), 'DAYOFWEEK' => array( 'dayofweek' ), 'WEEKDAY' => array( 'dayofweek_iso' ), ); foreach ( $date_units as $sql_part => $query_parts ) { foreach ( $query_parts as $query_part ) { if ( isset( $query[ $query_part ] ) ) { $value = $this->build_value( $compare, $query[ $query_part ] ); if ( $value ) { switch ( $sql_part ) { case '_wp_mysql_week': $where_parts[] = _wp_mysql_week( $column ) . " $compare $value"; break; case 'WEEKDAY': $where_parts[] = "$sql_part( $column ) + 1 $compare $value"; break; default: $where_parts[] = "$sql_part( $column ) $compare $value"; } break; } } } } if ( isset( $query['hour'] ) || isset( $query['minute'] ) || isset( $query['second'] ) ) { foreach ( array( 'hour', 'minute', 'second' ) as $unit ) { if ( ! isset( $query[ $unit ] ) ) { $query[ $unit ] = null; } } $time_query = $this->build_time_query( $column, $compare, $query['hour'], $query['minute'], $query['second'] ); if ( $time_query ) { $where_parts[] = $time_query; } } return array( 'where' => $where_parts, 'join' => array(), ); } public function build_value( $compare, $value ) { if ( ! isset( $value ) ) { return false; } switch ( $compare ) { case 'IN': case 'NOT IN': $value = (array) $value; $value = array_filter( $value, 'is_numeric' ); if ( empty( $value ) ) { return false; } return '(' . implode( ',', array_map( 'intval', $value ) ) . ')'; case 'BETWEEN': case 'NOT BETWEEN': if ( ! is_array( $value ) || 2 !== count( $value ) ) { $value = array( $value, $value ); } else { $value = array_values( $value ); } foreach ( $value as $v ) { if ( ! is_numeric( $v ) ) { return false; } } $value = array_map( 'intval', $value ); return $value[0] . ' AND ' . $value[1]; default: if ( ! is_numeric( $value ) ) { return false; } return (int) $value; } } public function build_mysql_datetime( $datetime, $default_to_max = false ) { if ( ! is_array( $datetime ) ) { if ( preg_match( '/^(\d{4})$/', $datetime, $matches ) ) { $datetime = array( 'year' => (int) $matches[1], ); } elseif ( preg_match( '/^(\d{4})\-(\d{2})$/', $datetime, $matches ) ) { $datetime = array( 'year' => (int) $matches[1], 'month' => (int) $matches[2], ); } elseif ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2})$/', $datetime, $matches ) ) { $datetime = array( 'year' => (int) $matches[1], 'month' => (int) $matches[2], 'day' => (int) $matches[3], ); } elseif ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})$/', $datetime, $matches ) ) { $datetime = array( 'year' => (int) $matches[1], 'month' => (int) $matches[2], 'day' => (int) $matches[3], 'hour' => (int) $matches[4], 'minute' => (int) $matches[5], ); } if ( ! is_array( $datetime ) ) { $wp_timezone = wp_timezone(); $dt = date_create( $datetime, $wp_timezone ); if ( false === $dt ) { return gmdate( 'Y-m-d H:i:s', false ); } return $dt->setTimezone( $wp_timezone )->format( 'Y-m-d H:i:s' ); } } $datetime = array_map( 'absint', $datetime ); if ( ! isset( $datetime['year'] ) ) { $datetime['year'] = current_time( 'Y' ); } if ( ! isset( $datetime['month'] ) ) { $datetime['month'] = ( $default_to_max ) ? 12 : 1; } if ( ! isset( $datetime['day'] ) ) { $datetime['day'] = ( $default_to_max ) ? (int) gmdate( 't', mktime( 0, 0, 0, $datetime['month'], 1, $datetime['year'] ) ) : 1; } if ( ! isset( $datetime['hour'] ) ) { $datetime['hour'] = ( $default_to_max ) ? 23 : 0; } if ( ! isset( $datetime['minute'] ) ) { $datetime['minute'] = ( $default_to_max ) ? 59 : 0; } if ( ! isset( $datetime['second'] ) ) { $datetime['second'] = ( $default_to_max ) ? 59 : 0; } return sprintf( '%04d-%02d-%02d %02d:%02d:%02d', $datetime['year'], $datetime['month'], $datetime['day'], $datetime['hour'], $datetime['minute'], $datetime['second'] ); } public function build_time_query( $column, $compare, $hour = null, $minute = null, $second = null ) { global $wpdb; if ( ! isset( $hour ) && ! isset( $minute ) && ! isset( $second ) ) { return false; } if ( in_array( $compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) { $return = array(); $value = $this->build_value( $compare, $hour ); if ( false !== $value ) { $return[] = "HOUR( $column ) $compare $value"; } $value = $this->build_value( $compare, $minute ); if ( false !== $value ) { $return[] = "MINUTE( $column ) $compare $value"; } $value = $this->build_value( $compare, $second ); if ( false !== $value ) { $return[] = "SECOND( $column ) $compare $value"; } return implode( ' AND ', $return ); } if ( isset( $hour ) && ! isset( $minute ) && ! isset( $second ) ) { $value = $this->build_value( $compare, $hour ); if ( false !== $value ) { return "HOUR( $column ) $compare $value"; } } elseif ( ! isset( $hour ) && isset( $minute ) && ! isset( $second ) ) { $value = $this->build_value( $compare, $minute ); if ( false !== $value ) { return "MINUTE( $column ) $compare $value"; } } elseif ( ! isset( $hour ) && ! isset( $minute ) && isset( $second ) ) { $value = $this->build_value( $compare, $second ); if ( false !== $value ) { return "SECOND( $column ) $compare $value"; } } if ( ! isset( $minute ) ) { return false; } $format = ''; $time = ''; if ( null !== $hour ) { $format .= '%H.'; $time .= sprintf( '%02d', $hour ) . '.'; } else { $format .= '0.'; $time .= '0.'; } $format .= '%i'; $time .= sprintf( '%02d', $minute ); if ( isset( $second ) ) { $format .= '%s'; $time .= sprintf( '%02d', $second ); } return $wpdb->prepare( "DATE_FORMAT( $column, %s ) $compare %f", $format, $time ); } public function sanitize_relation( $relation ) { if ( 'OR' === strtoupper( $relation ) ) { return 'OR'; } else { return 'AND'; } } }
###require ABSPATH . WPINC . '/theme.php';
function wp_get_themes( $args = array() ) { global $wp_theme_directories; $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0, ); $args = wp_parse_args( $args, $defaults ); $theme_directories = search_theme_directories(); if ( is_array( $wp_theme_directories ) && count( $wp_theme_directories ) > 1 ) { $current_theme = get_stylesheet(); if ( isset( $theme_directories[ $current_theme ] ) ) { $root_of_current_theme = get_raw_theme_root( $current_theme ); if ( ! in_array( $root_of_current_theme, $wp_theme_directories, true ) ) { $root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme; } $theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme; } } if ( empty( $theme_directories ) ) { return array(); } if ( is_multisite() && null !== $args['allowed'] ) { $allowed = $args['allowed']; if ( 'network' === $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_network() ); } elseif ( 'site' === $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_site( $args['blog_id'] ) ); } elseif ( $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) ); } else { $theme_directories = array_diff_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) ); } } $themes = array(); static $_themes = array(); foreach ( $theme_directories as $theme => $theme_root ) { if ( isset( $_themes[ $theme_root['theme_root'] . '/' . $theme ] ) ) { $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ]; } else { $themes[ $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] ); $_themes[ $theme_root['theme_root'] . '/' . $theme ] = $themes[ $theme ]; } } if ( null !== $args['errors'] ) { foreach ( $themes as $theme => $wp_theme ) { if ( (bool) $wp_theme->errors() !== $args['errors'] ) { unset( $themes[ $theme ] ); } } } return $themes; } function wp_get_theme( $stylesheet = '', $theme_root = '' ) { global $wp_theme_directories; if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } if ( empty( $theme_root ) ) { $theme_root = get_raw_theme_root( $stylesheet ); if ( false === $theme_root ) { $theme_root = WP_CONTENT_DIR . '/themes'; } elseif ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { $theme_root = WP_CONTENT_DIR . $theme_root; } } return new WP_Theme( $stylesheet, $theme_root ); } function wp_clean_themes_cache( $clear_update_cache = true ) { if ( $clear_update_cache ) { delete_site_transient( 'update_themes' ); } search_theme_directories( true ); foreach ( wp_get_themes( array( 'errors' => null ) ) as $theme ) { $theme->cache_delete(); } } function is_child_theme() { global $wp_stylesheet_path, $wp_template_path; return $wp_stylesheet_path !== $wp_template_path; } function get_stylesheet() { return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); } function get_stylesheet_directory() { $stylesheet = get_stylesheet(); $theme_root = get_theme_root( $stylesheet ); $stylesheet_dir = "$theme_root/$stylesheet"; return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); } function get_stylesheet_directory_uri() { $stylesheet = str_replace( '%2F', '/', rawurlencode( get_stylesheet() ) ); $theme_root_uri = get_theme_root_uri( $stylesheet ); $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); } function get_stylesheet_uri() { $stylesheet_dir_uri = get_stylesheet_directory_uri(); $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; return apply_filters( 'stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } function get_locale_stylesheet_uri() { global $wp_locale; $stylesheet_dir_uri = get_stylesheet_directory_uri(); $dir = get_stylesheet_directory(); $locale = get_locale(); if ( file_exists( "$dir/$locale.css" ) ) { $stylesheet_uri = "$stylesheet_dir_uri/$locale.css"; } elseif ( ! empty( $wp_locale->text_direction ) && file_exists( "$dir/{$wp_locale->text_direction}.css" ) ) { $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css"; } else { $stylesheet_uri = ''; } return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } function get_template() { return apply_filters( 'template', get_option( 'template' ) ); } function get_template_directory() { $template = get_template(); $theme_root = get_theme_root( $template ); $template_dir = "$theme_root/$template"; return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); } function get_template_directory_uri() { $template = str_replace( '%2F', '/', rawurlencode( get_template() ) ); $theme_root_uri = get_theme_root_uri( $template ); $template_dir_uri = "$theme_root_uri/$template"; return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); } function get_theme_roots() { global $wp_theme_directories; if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { return '/themes'; } $theme_roots = get_site_transient( 'theme_roots' ); if ( false === $theme_roots ) { search_theme_directories( true ); $theme_roots = get_site_transient( 'theme_roots' ); } return $theme_roots; } function register_theme_directory( $directory ) { global $wp_theme_directories; if ( ! file_exists( $directory ) ) { $directory = WP_CONTENT_DIR . '/' . $directory; if ( ! file_exists( $directory ) ) { return false; } } if ( ! is_array( $wp_theme_directories ) ) { $wp_theme_directories = array(); } $untrailed = untrailingslashit( $directory ); if ( ! empty( $untrailed ) && ! in_array( $untrailed, $wp_theme_directories, true ) ) { $wp_theme_directories[] = $untrailed; } return true; } function search_theme_directories( $force = false ) { global $wp_theme_directories; static $found_themes = null; if ( empty( $wp_theme_directories ) ) { return false; } if ( ! $force && isset( $found_themes ) ) { return $found_themes; } $found_themes = array(); $wp_theme_directories = (array) $wp_theme_directories; $relative_theme_roots = array(); foreach ( $wp_theme_directories as $theme_root ) { if ( str_starts_with( $theme_root, WP_CONTENT_DIR ) ) { $relative_theme_roots[ str_replace( WP_CONTENT_DIR, '', $theme_root ) ] = $theme_root; } else { $relative_theme_roots[ $theme_root ] = $theme_root; } } $cache_expiration = apply_filters( 'wp_cache_themes_persistently', false, 'search_theme_directories' ); if ( $cache_expiration ) { $cached_roots = get_site_transient( 'theme_roots' ); if ( is_array( $cached_roots ) ) { foreach ( $cached_roots as $theme_dir => $theme_root ) { if ( ! isset( $relative_theme_roots[ $theme_root ] ) ) { continue; } $found_themes[ $theme_dir ] = array( 'theme_file' => $theme_dir . '/style.css', 'theme_root' => $relative_theme_roots[ $theme_root ], ); } return $found_themes; } if ( ! is_int( $cache_expiration ) ) { $cache_expiration = 30 * MINUTE_IN_SECONDS; } } else { $cache_expiration = 30 * MINUTE_IN_SECONDS; } foreach ( $wp_theme_directories as $theme_root ) { $dirs = @ scandir( $theme_root ); if ( ! $dirs ) { wp_trigger_error( __FUNCTION__, "$theme_root is not readable" ); continue; } foreach ( $dirs as $dir ) { if ( ! is_dir( $theme_root . '/' . $dir ) || '.' === $dir[0] || 'CVS' === $dir ) { continue; } if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } else { $found_theme = false; $sub_dirs = @ scandir( $theme_root . '/' . $dir ); if ( ! $sub_dirs ) { wp_trigger_error( __FUNCTION__, "$theme_root/$dir is not readable" ); continue; } foreach ( $sub_dirs as $sub_dir ) { if ( ! is_dir( $theme_root . '/' . $dir . '/' . $sub_dir ) || '.' === $dir[0] || 'CVS' === $dir ) { continue; } if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) { continue; } $found_themes[ $dir . '/' . $sub_dir ] = array( 'theme_file' => $dir . '/' . $sub_dir . '/style.css', 'theme_root' => $theme_root, ); $found_theme = true; } if ( ! $found_theme ) { $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } } } } asort( $found_themes ); $theme_roots = array(); $relative_theme_roots = array_flip( $relative_theme_roots ); foreach ( $found_themes as $theme_dir => $theme_data ) { $theme_roots[ $theme_dir ] = $relative_theme_roots[ $theme_data['theme_root'] ]; } if ( get_site_transient( 'theme_roots' ) !== $theme_roots ) { set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); } return $found_themes; } function get_theme_root( $stylesheet_or_template = '' ) { global $wp_theme_directories; $theme_root = ''; if ( $stylesheet_or_template ) { $theme_root = get_raw_theme_root( $stylesheet_or_template ); if ( $theme_root ) { if ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { $theme_root = WP_CONTENT_DIR . $theme_root; } } } if ( ! $theme_root ) { $theme_root = WP_CONTENT_DIR . '/themes'; } return apply_filters( 'theme_root', $theme_root ); } function get_theme_root_uri( $stylesheet_or_template = '', $theme_root = '' ) { global $wp_theme_directories; if ( $stylesheet_or_template && ! $theme_root ) { $theme_root = get_raw_theme_root( $stylesheet_or_template ); } if ( $stylesheet_or_template && $theme_root ) { if ( in_array( $theme_root, (array) $wp_theme_directories, true ) ) { if ( str_starts_with( $theme_root, WP_CONTENT_DIR ) ) { $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); } elseif ( str_starts_with( $theme_root, ABSPATH ) ) { $theme_root_uri = site_url( str_replace( ABSPATH, '', $theme_root ) ); } elseif ( str_starts_with( $theme_root, WP_PLUGIN_DIR ) || str_starts_with( $theme_root, WPMU_PLUGIN_DIR ) ) { $theme_root_uri = plugins_url( basename( $theme_root ), $theme_root ); } else { $theme_root_uri = $theme_root; } } else { $theme_root_uri = content_url( $theme_root ); } } else { $theme_root_uri = content_url( 'themes' ); } return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); } function get_raw_theme_root( $stylesheet_or_template, $skip_cache = false ) { global $wp_theme_directories; if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { return '/themes'; } $theme_root = false; if ( ! $skip_cache ) { if ( get_option( 'stylesheet' ) === $stylesheet_or_template ) { $theme_root = get_option( 'stylesheet_root' ); } elseif ( get_option( 'template' ) === $stylesheet_or_template ) { $theme_root = get_option( 'template_root' ); } } if ( empty( $theme_root ) ) { $theme_roots = get_theme_roots(); if ( ! empty( $theme_roots[ $stylesheet_or_template ] ) ) { $theme_root = $theme_roots[ $stylesheet_or_template ]; } } return $theme_root; } function locale_stylesheet() { $stylesheet = get_locale_stylesheet_uri(); if ( empty( $stylesheet ) ) { return; } $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; printf( '<link rel="stylesheet" href="%s"%s media="screen" />', $stylesheet, $type_attr ); } function switch_theme( $stylesheet ) { global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars; $requirements = validate_theme_requirements( $stylesheet ); if ( is_wp_error( $requirements ) ) { wp_die( $requirements ); } $_sidebars_widgets = null; if ( 'wp_ajax_customize_save' === current_action() ) { $old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' ); if ( $old_sidebars_widgets_data_setting ) { $_sidebars_widgets = $wp_customize->post_value( $old_sidebars_widgets_data_setting ); } } elseif ( is_array( $sidebars_widgets ) ) { $_sidebars_widgets = $sidebars_widgets; } if ( is_array( $_sidebars_widgets ) ) { set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets, ) ); } $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); update_option( 'theme_switch_menu_locations', $nav_menu_locations, true ); if ( func_num_args() > 1 ) { $stylesheet = func_get_arg( 1 ); } $old_theme = wp_get_theme(); $new_theme = wp_get_theme( $stylesheet ); $template = $new_theme->get_template(); if ( wp_is_recovery_mode() ) { $paused_themes = wp_paused_themes(); $paused_themes->delete( $old_theme->get_stylesheet() ); $paused_themes->delete( $old_theme->get_template() ); } update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); if ( count( $wp_theme_directories ) > 1 ) { update_option( 'template_root', get_raw_theme_root( $template, true ) ); update_option( 'stylesheet_root', get_raw_theme_root( $stylesheet, true ) ); } else { delete_option( 'template_root' ); delete_option( 'stylesheet_root' ); } $new_name = $new_theme->get( 'Name' ); update_option( 'current_theme', $new_name ); if ( is_admin() && false === get_option( 'theme_mods_' . $stylesheet ) ) { $default_theme_mods = (array) get_option( 'mods_' . $new_name ); if ( ! empty( $nav_menu_locations ) && empty( $default_theme_mods['nav_menu_locations'] ) ) { $default_theme_mods['nav_menu_locations'] = $nav_menu_locations; } add_option( "theme_mods_$stylesheet", $default_theme_mods ); } else { if ( 'wp_ajax_customize_save' === current_action() ) { remove_theme_mod( 'sidebars_widgets' ); } } if ( $new_theme->is_block_theme() ) { set_theme_mod( 'wp_classic_sidebars', $wp_registered_sidebars ); } update_option( 'theme_switched', $old_theme->get_stylesheet() ); if ( ! is_multisite() || ! ms_is_switched() ) { wp_set_template_globals(); } if ( ! is_multisite() ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); } $theme_mods_options = array( 'theme_mods_' . $stylesheet => 'yes', 'theme_mods_' . $old_theme->get_stylesheet() => 'no', ); wp_set_option_autoload_values( $theme_mods_options ); do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } function validate_current_theme() { if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) { return true; } if ( ! file_exists( get_template_directory() . '/templates/index.html' ) && ! file_exists( get_template_directory() . '/block-templates/index.html' ) && ! file_exists( get_template_directory() . '/index.php' ) ) { } elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) { } elseif ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { } else { return true; } $default = wp_get_theme( WP_DEFAULT_THEME ); if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } $default = WP_Theme::get_core_default_theme(); if ( false === $default || get_stylesheet() === $default->get_stylesheet() ) { return true; } switch_theme( $default->get_stylesheet() ); return false; } function validate_theme_requirements( $stylesheet ) { $theme = wp_get_theme( $stylesheet ); $requirements = array( 'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '', 'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '', ); $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); if ( ! $compatible_wp && ! $compatible_php ) { return new WP_Error( 'theme_wp_php_incompatible', sprintf( _x( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } elseif ( ! $compatible_php ) { return new WP_Error( 'theme_php_incompatible', sprintf( _x( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } elseif ( ! $compatible_wp ) { return new WP_Error( 'theme_wp_incompatible', sprintf( _x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } return apply_filters( 'validate_theme_requirements', true, $stylesheet ); } function get_theme_mods() { $theme_slug = get_option( 'stylesheet' ); $mods = get_option( "theme_mods_$theme_slug" ); if ( false === $mods ) { $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } $mods = get_option( "mods_$theme_name" ); if ( is_admin() && false !== $mods ) { update_option( "theme_mods_$theme_slug", $mods ); delete_option( "mods_$theme_name" ); } } if ( ! is_array( $mods ) ) { $mods = array(); } return $mods; } function get_theme_mod( $name, $default_value = false ) { $mods = get_theme_mods(); if ( isset( $mods[ $name ] ) ) { return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); } if ( is_string( $default_value ) ) { if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default_value ) ) { $default_value = preg_replace( '#(?<!%)%$#', '', $default_value ); $default_value = sprintf( $default_value, get_template_directory_uri(), get_stylesheet_directory_uri() ); } } return apply_filters( "theme_mod_{$name}", $default_value ); } function set_theme_mod( $name, $value ) { $mods = get_theme_mods(); $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); $theme = get_option( 'stylesheet' ); return update_option( "theme_mods_$theme", $mods ); } function remove_theme_mod( $name ) { $mods = get_theme_mods(); if ( ! isset( $mods[ $name ] ) ) { return; } unset( $mods[ $name ] ); if ( empty( $mods ) ) { remove_theme_mods(); return; } $theme = get_option( 'stylesheet' ); update_option( "theme_mods_$theme", $mods ); } function remove_theme_mods() { delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } delete_option( 'mods_' . $theme_name ); } function get_header_textcolor() { return get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } function header_textcolor() { echo get_header_textcolor(); } function display_header_text() { if ( ! current_theme_supports( 'custom-header', 'header-text' ) ) { return false; } $text_color = get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); return 'blank' !== $text_color; } function has_header_image() { return (bool) get_header_image(); } function get_header_image() { $url = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); if ( 'remove-header' === $url ) { return false; } if ( is_random_header_image() ) { $url = get_random_header_image(); } $url = apply_filters( 'get_header_image', $url ); if ( ! is_string( $url ) ) { return false; } $url = trim( $url ); return sanitize_url( set_url_scheme( $url ) ); } function get_header_image_tag( $attr = array() ) { $header = get_custom_header(); $header->url = get_header_image(); if ( ! $header->url ) { return ''; } $width = absint( $header->width ); $height = absint( $header->height ); $alt = ''; if ( ! empty( $header->attachment_id ) ) { $image_alt = get_post_meta( $header->attachment_id, '_wp_attachment_image_alt', true ); if ( is_string( $image_alt ) ) { $alt = $image_alt; } } $attr = wp_parse_args( $attr, array( 'src' => $header->url, 'width' => $width, 'height' => $height, 'alt' => $alt, ) ); if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) ) { $image_meta = get_post_meta( $header->attachment_id, '_wp_attachment_metadata', true ); $size_array = array( $width, $height ); if ( is_array( $image_meta ) ) { $srcset = wp_calculate_image_srcset( $size_array, $header->url, $image_meta, $header->attachment_id ); if ( ! empty( $attr['sizes'] ) ) { $sizes = $attr['sizes']; } else { $sizes = wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id ); } if ( $srcset && $sizes ) { $attr['srcset'] = $srcset; $attr['sizes'] = $sizes; } } } $attr = array_merge( $attr, wp_get_loading_optimization_attributes( 'img', $attr, 'get_header_image_tag' ) ); if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } if ( isset( $attr['decoding'] ) && ! $attr['decoding'] ) { unset( $attr['decoding'] ); } $attr = apply_filters( 'get_header_image_tag_attributes', $attr, $header ); $attr = array_map( 'esc_attr', $attr ); $html = '<img'; foreach ( $attr as $name => $value ) { $html .= ' ' . $name . '="' . $value . '"'; } $html .= ' />'; return apply_filters( 'get_header_image_tag', $html, $header, $attr ); } function the_header_image_tag( $attr = array() ) { echo get_header_image_tag( $attr ); } function _get_random_header_data() { global $_wp_default_headers; static $_wp_random_header = null; if ( empty( $_wp_random_header ) ) { $header_image_mod = get_theme_mod( 'header_image', '' ); $headers = array(); if ( 'random-uploaded-image' === $header_image_mod ) { $headers = get_uploaded_header_images(); } elseif ( ! empty( $_wp_default_headers ) ) { if ( 'random-default-image' === $header_image_mod ) { $headers = $_wp_default_headers; } else { if ( current_theme_supports( 'custom-header', 'random-default' ) ) { $headers = $_wp_default_headers; } } } if ( empty( $headers ) ) { return new stdClass(); } $_wp_random_header = (object) $headers[ array_rand( $headers ) ]; $_wp_random_header->url = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() ); $_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() ); } return $_wp_random_header; } function get_random_header_image() { $random_image = _get_random_header_data(); if ( empty( $random_image->url ) ) { return ''; } return $random_image->url; } function is_random_header_image( $type = 'any' ) { $header_image_mod = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); if ( 'any' === $type ) { if ( 'random-default-image' === $header_image_mod || 'random-uploaded-image' === $header_image_mod || ( empty( $header_image_mod ) && '' !== get_random_header_image() ) ) { return true; } } else { if ( "random-$type-image" === $header_image_mod ) { return true; } elseif ( 'default' === $type && empty( $header_image_mod ) && '' !== get_random_header_image() ) { return true; } } return false; } function header_image() { $image = get_header_image(); if ( $image ) { echo esc_url( $image ); } } function get_uploaded_header_images() { $header_images = array(); $headers = get_posts( array( 'post_type' => 'attachment', 'meta_key' => '_wp_attachment_is_custom_header', 'meta_value' => get_option( 'stylesheet' ), 'orderby' => 'none', 'nopaging' => true, ) ); if ( empty( $headers ) ) { return array(); } foreach ( (array) $headers as $header ) { $url = sanitize_url( wp_get_attachment_url( $header->ID ) ); $header_data = wp_get_attachment_metadata( $header->ID ); $header_index = $header->ID; $header_images[ $header_index ] = array(); $header_images[ $header_index ]['attachment_id'] = $header->ID; $header_images[ $header_index ]['url'] = $url; $header_images[ $header_index ]['thumbnail_url'] = $url; $header_images[ $header_index ]['alt_text'] = get_post_meta( $header->ID, '_wp_attachment_image_alt', true ); if ( isset( $header_data['attachment_parent'] ) ) { $header_images[ $header_index ]['attachment_parent'] = $header_data['attachment_parent']; } else { $header_images[ $header_index ]['attachment_parent'] = ''; } if ( isset( $header_data['width'] ) ) { $header_images[ $header_index ]['width'] = $header_data['width']; } if ( isset( $header_data['height'] ) ) { $header_images[ $header_index ]['height'] = $header_data['height']; } } return $header_images; } function get_custom_header() { global $_wp_default_headers; if ( is_random_header_image() ) { $data = _get_random_header_data(); } else { $data = get_theme_mod( 'header_image_data' ); if ( ! $data && current_theme_supports( 'custom-header', 'default-image' ) ) { $directory_args = array( get_template_directory_uri(), get_stylesheet_directory_uri() ); $data = array(); $data['url'] = vsprintf( get_theme_support( 'custom-header', 'default-image' ), $directory_args ); $data['thumbnail_url'] = $data['url']; if ( ! empty( $_wp_default_headers ) ) { foreach ( (array) $_wp_default_headers as $default_header ) { $url = vsprintf( $default_header['url'], $directory_args ); if ( $data['url'] === $url ) { $data = $default_header; $data['url'] = $url; $data['thumbnail_url'] = vsprintf( $data['thumbnail_url'], $directory_args ); break; } } } } } $default = array( 'url' => '', 'thumbnail_url' => '', 'width' => get_theme_support( 'custom-header', 'width' ), 'height' => get_theme_support( 'custom-header', 'height' ), 'video' => get_theme_support( 'custom-header', 'video' ), ); return (object) wp_parse_args( $data, $default ); } function register_default_headers( $headers ) { global $_wp_default_headers; $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); } function unregister_default_headers( $header ) { global $_wp_default_headers; if ( is_array( $header ) ) { array_map( 'unregister_default_headers', $header ); } elseif ( isset( $_wp_default_headers[ $header ] ) ) { unset( $_wp_default_headers[ $header ] ); return true; } else { return false; } } function has_header_video() { return (bool) get_header_video_url(); } function get_header_video_url() { $id = absint( get_theme_mod( 'header_video' ) ); if ( $id ) { $url = wp_get_attachment_url( $id ); } else { $url = get_theme_mod( 'external_header_video' ); } $url = apply_filters( 'get_header_video_url', $url ); if ( ! $id && ! $url ) { return false; } return sanitize_url( set_url_scheme( $url ) ); } function the_header_video_url() { $video = get_header_video_url(); if ( $video ) { echo esc_url( $video ); } } function get_header_video_settings() { $header = get_custom_header(); $video_url = get_header_video_url(); $video_type = wp_check_filetype( $video_url, wp_get_mime_types() ); $settings = array( 'mimeType' => '', 'posterUrl' => get_header_image(), 'videoUrl' => $video_url, 'width' => absint( $header->width ), 'height' => absint( $header->height ), 'minWidth' => 900, 'minHeight' => 500, 'l10n' => array( 'pause' => __( 'Pause' ), 'play' => __( 'Play' ), 'pauseSpeak' => __( 'Video is paused.' ), 'playSpeak' => __( 'Video is playing.' ), ), ); if ( preg_match( '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#', $video_url ) ) { $settings['mimeType'] = 'video/x-youtube'; } elseif ( ! empty( $video_type['type'] ) ) { $settings['mimeType'] = $video_type['type']; } return apply_filters( 'header_video_settings', $settings ); } function has_custom_header() { if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) { return true; } return false; } function is_header_video_active() { if ( ! get_theme_support( 'custom-header', 'video' ) ) { return false; } $video_active_cb = get_theme_support( 'custom-header', 'video-active-callback' ); if ( empty( $video_active_cb ) || ! is_callable( $video_active_cb ) ) { $show_video = true; } else { $show_video = call_user_func( $video_active_cb ); } return apply_filters( 'is_header_video_active', $show_video ); } function get_custom_header_markup() { if ( ! has_custom_header() && ! is_customize_preview() ) { return ''; } return sprintf( '<div id="wp-custom-header" class="wp-custom-header">%s</div>', get_header_image_tag() ); } function the_custom_header_markup() { $custom_header = get_custom_header_markup(); if ( empty( $custom_header ) ) { return; } echo $custom_header; if ( is_header_video_active() && ( has_header_video() || is_customize_preview() ) ) { wp_enqueue_script( 'wp-custom-header' ); wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() ); } } function get_background_image() { return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); } function background_image() { echo get_background_image(); } function get_background_color() { return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); } function background_color() { echo get_background_color(); } function _custom_background_cb() { $background = set_url_scheme( get_background_image() ); $color = get_background_color(); if ( get_theme_support( 'custom-background', 'default-color' ) === $color ) { $color = false; } $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; if ( ! $background && ! $color ) { if ( is_customize_preview() ) { printf( '<style%s id="custom-background-css"></style>', $type_attr ); } return; } $style = $color ? 'background-color: ' . maybe_hash_hex_color( $color ) . ';' : ''; if ( $background ) { $image = ' background-image: url("' . sanitize_url( $background ) . '");'; $position_x = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ); $position_y = get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) ); if ( ! in_array( $position_x, array( 'left', 'center', 'right' ), true ) ) { $position_x = 'left'; } if ( ! in_array( $position_y, array( 'top', 'center', 'bottom' ), true ) ) { $position_y = 'top'; } $position = " background-position: $position_x $position_y;"; $size = get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ); if ( ! in_array( $size, array( 'auto', 'contain', 'cover' ), true ) ) { $size = 'auto'; } $size = " background-size: $size;"; $repeat = get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ); if ( ! in_array( $repeat, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ), true ) ) { $repeat = 'repeat'; } $repeat = " background-repeat: $repeat;"; $attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ); if ( 'fixed' !== $attachment ) { $attachment = 'scroll'; } $attachment = " background-attachment: $attachment;"; $style .= $image . $position . $size . $repeat . $attachment; } ?>
<style<?php echo $type_attr; ?> id="custom-background-css">
body.custom-background { <?php echo trim( $style ); ?> }
</style>
<?php
} function wp_custom_css_cb() { $styles = wp_get_custom_css(); if ( $styles || is_customize_preview() ) : $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?>
<style<?php echo $type_attr; ?> id="wp-custom-css">
<?php
echo strip_tags( $styles ); ?>
</style>
<?php
endif; } function wp_get_custom_css_post( $stylesheet = '' ) { if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } $custom_css_query_vars = array( 'post_type' => 'custom_css', 'post_status' => get_post_stati(), 'name' => sanitize_title( $stylesheet ), 'posts_per_page' => 1, 'no_found_rows' => true, 'cache_results' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'lazy_load_term_meta' => false, ); $post = null; if ( get_stylesheet() === $stylesheet ) { $post_id = get_theme_mod( 'custom_css_post_id' ); if ( $post_id > 0 && get_post( $post_id ) ) { $post = get_post( $post_id ); } if ( ! $post && -1 !== $post_id ) { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; set_theme_mod( 'custom_css_post_id', $post ? $post->ID : -1 ); } } else { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; } return $post; } function wp_get_custom_css( $stylesheet = '' ) { $css = ''; if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } $post = wp_get_custom_css_post( $stylesheet ); if ( $post ) { $css = $post->post_content; } $css = apply_filters( 'wp_get_custom_css', $css, $stylesheet ); return $css; } function wp_update_custom_css_post( $css, $args = array() ) { $args = wp_parse_args( $args, array( 'preprocessed' => '', 'stylesheet' => get_stylesheet(), ) ); $data = array( 'css' => $css, 'preprocessed' => $args['preprocessed'], ); $data = apply_filters( 'update_custom_css_data', $data, array_merge( $args, compact( 'css' ) ) ); $post_data = array( 'post_title' => $args['stylesheet'], 'post_name' => sanitize_title( $args['stylesheet'] ), 'post_type' => 'custom_css', 'post_status' => 'publish', 'post_content' => $data['css'], 'post_content_filtered' => $data['preprocessed'], ); $post = wp_get_custom_css_post( $args['stylesheet'] ); if ( $post ) { $post_data['ID'] = $post->ID; $r = wp_update_post( wp_slash( $post_data ), true ); } else { $r = wp_insert_post( wp_slash( $post_data ), true ); if ( ! is_wp_error( $r ) ) { if ( get_stylesheet() === $args['stylesheet'] ) { set_theme_mod( 'custom_css_post_id', $r ); } $revisions = wp_get_latest_revision_id_and_total_count( $r ); if ( ! is_wp_error( $revisions ) && 0 === $revisions['count'] ) { wp_save_post_revision( $r ); } } } if ( is_wp_error( $r ) ) { return $r; } return get_post( $r ); } function add_editor_style( $stylesheet = 'editor-style.css' ) { global $editor_styles; add_theme_support( 'editor-style' ); $editor_styles = (array) $editor_styles; $stylesheet = (array) $stylesheet; if ( is_rtl() ) { $rtl_stylesheet = str_replace( '.css', '-rtl.css', $stylesheet[0] ); $stylesheet[] = $rtl_stylesheet; } $editor_styles = array_merge( $editor_styles, $stylesheet ); } function remove_editor_styles() { if ( ! current_theme_supports( 'editor-style' ) ) { return false; } _remove_theme_support( 'editor-style' ); if ( is_admin() ) { $GLOBALS['editor_styles'] = array(); } return true; } function get_editor_stylesheets() { $stylesheets = array(); if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) { $editor_styles = $GLOBALS['editor_styles']; $editor_styles = array_unique( array_filter( $editor_styles ) ); $style_uri = get_stylesheet_directory_uri(); $style_dir = get_stylesheet_directory(); foreach ( $editor_styles as $key => $file ) { if ( preg_match( '~^(https?:)?//~', $file ) ) { $stylesheets[] = sanitize_url( $file ); unset( $editor_styles[ $key ] ); } } if ( is_child_theme() ) { $template_uri = get_template_directory_uri(); $template_dir = get_template_directory(); foreach ( $editor_styles as $key => $file ) { if ( $file && file_exists( "$template_dir/$file" ) ) { $stylesheets[] = "$template_uri/$file"; } } } foreach ( $editor_styles as $file ) { if ( $file && file_exists( "$style_dir/$file" ) ) { $stylesheets[] = "$style_uri/$file"; } } } return apply_filters( 'editor_stylesheets', $stylesheets ); } function get_theme_starter_content() { $theme_support = get_theme_support( 'starter-content' ); if ( is_array( $theme_support ) && ! empty( $theme_support[0] ) && is_array( $theme_support[0] ) ) { $config = $theme_support[0]; } else { $config = array(); } $core_content = array( 'widgets' => array( 'text_business_info' => array( 'text', array( 'title' => _x( 'Find Us', 'Theme starter content' ), 'text' => implode( '', array( '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", _x( '123 Main Street', 'Theme starter content' ) . "\n", _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", _x( 'Monday–Friday: 9:00AM–5:00PM', 'Theme starter content' ) . "\n", _x( 'Saturday & Sunday: 11:00AM–3:00PM', 'Theme starter content' ), ) ), 'filter' => true, 'visual' => true, ), ), 'text_about' => array( 'text', array( 'title' => _x( 'About This Site', 'Theme starter content' ), 'text' => _x( 'This may be a good place to introduce yourself and your site or include some credits.', 'Theme starter content' ), 'filter' => true, 'visual' => true, ), ), 'archives' => array( 'archives', array( 'title' => _x( 'Archives', 'Theme starter content' ), ), ), 'calendar' => array( 'calendar', array( 'title' => _x( 'Calendar', 'Theme starter content' ), ), ), 'categories' => array( 'categories', array( 'title' => _x( 'Categories', 'Theme starter content' ), ), ), 'meta' => array( 'meta', array( 'title' => _x( 'Meta', 'Theme starter content' ), ), ), 'recent-comments' => array( 'recent-comments', array( 'title' => _x( 'Recent Comments', 'Theme starter content' ), ), ), 'recent-posts' => array( 'recent-posts', array( 'title' => _x( 'Recent Posts', 'Theme starter content' ), ), ), 'search' => array( 'search', array( 'title' => _x( 'Search', 'Theme starter content' ), ), ), ), 'nav_menus' => array( 'link_home' => array( 'type' => 'custom', 'title' => _x( 'Home', 'Theme starter content' ), 'url' => home_url( '/' ), ), 'page_home' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{home}}', ), 'page_about' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{about}}', ), 'page_blog' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{blog}}', ), 'page_news' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{news}}', ), 'page_contact' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{contact}}', ), 'link_email' => array( 'title' => _x( 'Email', 'Theme starter content' ), 'url' => 'mailto:wordpress@example.com', ), 'link_facebook' => array( 'title' => _x( 'Facebook', 'Theme starter content' ), 'url' => 'https://www.facebook.com/wordpress', ), 'link_foursquare' => array( 'title' => _x( 'Foursquare', 'Theme starter content' ), 'url' => 'https://foursquare.com/', ), 'link_github' => array( 'title' => _x( 'GitHub', 'Theme starter content' ), 'url' => 'https://github.com/wordpress/', ), 'link_instagram' => array( 'title' => _x( 'Instagram', 'Theme starter content' ), 'url' => 'https://www.instagram.com/explore/tags/wordcamp/', ), 'link_linkedin' => array( 'title' => _x( 'LinkedIn', 'Theme starter content' ), 'url' => 'https://www.linkedin.com/company/1089783', ), 'link_pinterest' => array( 'title' => _x( 'Pinterest', 'Theme starter content' ), 'url' => 'https://www.pinterest.com/', ), 'link_twitter' => array( 'title' => _x( 'Twitter', 'Theme starter content' ), 'url' => 'https://twitter.com/wordpress', ), 'link_yelp' => array( 'title' => _x( 'Yelp', 'Theme starter content' ), 'url' => 'https://www.yelp.com', ), 'link_youtube' => array( 'title' => _x( 'YouTube', 'Theme starter content' ), 'url' => 'https://www.youtube.com/channel/UCdof4Ju7amm1chz1gi1T2ZA', ), ), 'posts' => array( 'home' => array( 'post_type' => 'page', 'post_title' => _x( 'Home', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'Welcome to your site! This is your homepage, which is what most visitors will see when they come to your site for the first time.', 'Theme starter content' ) ), ), 'about' => array( 'post_type' => 'page', 'post_title' => _x( 'About', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'You might be an artist who would like to introduce yourself and your work here or maybe you are a business with a mission to describe.', 'Theme starter content' ) ), ), 'contact' => array( 'post_type' => 'page', 'post_title' => _x( 'Contact', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'This is a page with some basic contact information, such as an address and phone number. You might also try a plugin to add a contact form.', 'Theme starter content' ) ), ), 'blog' => array( 'post_type' => 'page', 'post_title' => _x( 'Blog', 'Theme starter content' ), ), 'news' => array( 'post_type' => 'page', 'post_title' => _x( 'News', 'Theme starter content' ), ), 'homepage-section' => array( 'post_type' => 'page', 'post_title' => _x( 'A homepage section', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'This is an example of a homepage section. Homepage sections can be any page other than the homepage itself, including the page that shows your latest blog posts.', 'Theme starter content' ) ), ), ), ); $content = array(); foreach ( $config as $type => $args ) { switch ( $type ) { case 'options': case 'theme_mods': $content[ $type ] = $config[ $type ]; break; case 'widgets': foreach ( $config[ $type ] as $sidebar_id => $widgets ) { foreach ( $widgets as $id => $widget ) { if ( is_array( $widget ) ) { if ( ! empty( $core_content[ $type ][ $id ] ) ) { $widget = array( $core_content[ $type ][ $id ][0], array_merge( $core_content[ $type ][ $id ][1], $widget ), ); } $content[ $type ][ $sidebar_id ][] = $widget; } elseif ( is_string( $widget ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $widget ] ) ) { $content[ $type ][ $sidebar_id ][] = $core_content[ $type ][ $widget ]; } } } break; case 'nav_menus': foreach ( $config[ $type ] as $nav_menu_location => $nav_menu ) { if ( empty( $nav_menu['name'] ) ) { $nav_menu['name'] = $nav_menu_location; } $content[ $type ][ $nav_menu_location ]['name'] = $nav_menu['name']; foreach ( $nav_menu['items'] as $id => $nav_menu_item ) { if ( is_array( $nav_menu_item ) ) { if ( ! empty( $core_content[ $type ][ $id ] ) ) { $nav_menu_item = array_merge( $core_content[ $type ][ $id ], $nav_menu_item ); } $content[ $type ][ $nav_menu_location ]['items'][] = $nav_menu_item; } elseif ( is_string( $nav_menu_item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $nav_menu_item ] ) ) { $content[ $type ][ $nav_menu_location ]['items'][] = $core_content[ $type ][ $nav_menu_item ]; } } } break; case 'attachments': foreach ( $config[ $type ] as $id => $item ) { if ( ! empty( $item['file'] ) ) { $content[ $type ][ $id ] = $item; } } break; case 'posts': foreach ( $config[ $type ] as $id => $item ) { if ( is_array( $item ) ) { if ( ! empty( $core_content[ $type ][ $id ] ) ) { $item = array_merge( $core_content[ $type ][ $id ], $item ); } $content[ $type ][ $id ] = wp_array_slice_assoc( $item, array( 'post_type', 'post_title', 'post_excerpt', 'post_name', 'post_content', 'menu_order', 'comment_status', 'thumbnail', 'template', ) ); } elseif ( is_string( $item ) && ! empty( $core_content[ $type ][ $item ] ) ) { $content[ $type ][ $item ] = $core_content[ $type ][ $item ]; } } break; } } return apply_filters( 'get_theme_starter_content', $content, $config ); } function add_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! $args ) { $args = true; } switch ( $feature ) { case 'post-thumbnails': if ( true === get_theme_support( 'post-thumbnails' ) ) { return; } if ( isset( $args[0] ) && is_array( $args[0] ) && isset( $_wp_theme_features['post-thumbnails'] ) ) { $args[0] = array_unique( array_merge( $_wp_theme_features['post-thumbnails'][0], $args[0] ) ); } break; case 'post-formats': if ( isset( $args[0] ) && is_array( $args[0] ) ) { $post_formats = get_post_format_slugs(); unset( $post_formats['standard'] ); $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); } else { _doing_it_wrong( "add_theme_support( 'post-formats' )", __( 'You need to pass an array of post formats.' ), '5.6.0' ); return false; } break; case 'html5': if ( empty( $args[0] ) || ! is_array( $args[0] ) ) { _doing_it_wrong( "add_theme_support( 'html5' )", __( 'You need to pass an array of types.' ), '3.6.1' ); if ( ! empty( $args[0] ) && ! is_array( $args[0] ) ) { return false; } $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); } if ( isset( $_wp_theme_features['html5'] ) ) { $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] ); } break; case 'custom-logo': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'width' => null, 'height' => null, 'flex-width' => false, 'flex-height' => false, 'header-text' => '', 'unlink-homepage-logo' => false, ); $args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults ); if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) { $args[0]['flex-width'] = true; $args[0]['flex-height'] = true; } break; case 'custom-header-uploads': return add_theme_support( 'custom-header', array( 'uploads' => true ) ); case 'custom-header': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'default-image' => '', 'random-default' => false, 'width' => 0, 'height' => 0, 'flex-height' => false, 'flex-width' => false, 'default-text-color' => '', 'header-text' => true, 'uploads' => true, 'wp-head-callback' => '', 'admin-head-callback' => '', 'admin-preview-callback' => '', 'video' => false, 'video-active-callback' => 'is_front_page', ); $jit = isset( $args[0]['__jit'] ); unset( $args[0]['__jit'] ); if ( isset( $_wp_theme_features['custom-header'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] ); } if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } if ( defined( 'NO_HEADER_TEXT' ) ) { $args[0]['header-text'] = ! NO_HEADER_TEXT; } elseif ( isset( $args[0]['header-text'] ) ) { define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) ); } if ( defined( 'HEADER_IMAGE_WIDTH' ) ) { $args[0]['width'] = (int) HEADER_IMAGE_WIDTH; } elseif ( isset( $args[0]['width'] ) ) { define( 'HEADER_IMAGE_WIDTH', (int) $args[0]['width'] ); } if ( defined( 'HEADER_IMAGE_HEIGHT' ) ) { $args[0]['height'] = (int) HEADER_IMAGE_HEIGHT; } elseif ( isset( $args[0]['height'] ) ) { define( 'HEADER_IMAGE_HEIGHT', (int) $args[0]['height'] ); } if ( defined( 'HEADER_TEXTCOLOR' ) ) { $args[0]['default-text-color'] = HEADER_TEXTCOLOR; } elseif ( isset( $args[0]['default-text-color'] ) ) { define( 'HEADER_TEXTCOLOR', $args[0]['default-text-color'] ); } if ( defined( 'HEADER_IMAGE' ) ) { $args[0]['default-image'] = HEADER_IMAGE; } elseif ( isset( $args[0]['default-image'] ) ) { define( 'HEADER_IMAGE', $args[0]['default-image'] ); } if ( $jit && ! empty( $args[0]['default-image'] ) ) { $args[0]['random-default'] = false; } if ( $jit ) { if ( empty( $args[0]['width'] ) && empty( $args[0]['flex-width'] ) ) { $args[0]['flex-width'] = true; } if ( empty( $args[0]['height'] ) && empty( $args[0]['flex-height'] ) ) { $args[0]['flex-height'] = true; } } break; case 'custom-background': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'default-image' => '', 'default-preset' => 'default', 'default-position-x' => 'left', 'default-position-y' => 'top', 'default-size' => 'auto', 'default-repeat' => 'repeat', 'default-attachment' => 'scroll', 'default-color' => '', 'wp-head-callback' => '_custom_background_cb', 'admin-head-callback' => '', 'admin-preview-callback' => '', ); $jit = isset( $args[0]['__jit'] ); unset( $args[0]['__jit'] ); if ( isset( $_wp_theme_features['custom-background'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-background'][0], $args[0] ); } if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } if ( defined( 'BACKGROUND_COLOR' ) ) { $args[0]['default-color'] = BACKGROUND_COLOR; } elseif ( isset( $args[0]['default-color'] ) || $jit ) { define( 'BACKGROUND_COLOR', $args[0]['default-color'] ); } if ( defined( 'BACKGROUND_IMAGE' ) ) { $args[0]['default-image'] = BACKGROUND_IMAGE; } elseif ( isset( $args[0]['default-image'] ) || $jit ) { define( 'BACKGROUND_IMAGE', $args[0]['default-image'] ); } break; case 'title-tag': if ( did_action( 'wp_loaded' ) ) { _doing_it_wrong( "add_theme_support( 'title-tag' )", sprintf( __( 'Theme support for %1$s should be registered before the %2$s hook.' ), '<code>title-tag</code>', '<code>wp_loaded</code>' ), '4.1.0' ); return false; } } $_wp_theme_features[ $feature ] = $args; } function _custom_header_background_just_in_time() { global $custom_image_header, $custom_background; if ( current_theme_supports( 'custom-header' ) ) { add_theme_support( 'custom-header', array( '__jit' => true ) ); $args = get_theme_support( 'custom-header' ); if ( $args[0]['wp-head-callback'] ) { add_action( 'wp_head', $args[0]['wp-head-callback'] ); } if ( is_admin() ) { require_once ABSPATH . 'wp-admin/includes/class-custom-image-header.php'; $custom_image_header = new Custom_Image_Header( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); } } if ( current_theme_supports( 'custom-background' ) ) { add_theme_support( 'custom-background', array( '__jit' => true ) ); $args = get_theme_support( 'custom-background' ); add_action( 'wp_head', $args[0]['wp-head-callback'] ); if ( is_admin() ) { require_once ABSPATH . 'wp-admin/includes/class-custom-background.php'; $custom_background = new Custom_Background( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); } } } function _custom_logo_header_styles() { if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) { $classes = (array) get_theme_support( 'custom-logo', 'header-text' ); $classes = array_map( 'sanitize_html_class', $classes ); $classes = '.' . implode( ', .', $classes ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?>
<!-- Custom Logo: hide header text -->
<style id="custom-logo-css"<?php echo $type_attr; ?>>
<?php echo $classes; ?> {
position: absolute;
clip-path: inset(50%);
}
</style>
<?php
} } function get_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } if ( ! $args ) { return $_wp_theme_features[ $feature ]; } switch ( $feature ) { case 'custom-logo': case 'custom-header': case 'custom-background': if ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) ) { return $_wp_theme_features[ $feature ][0][ $args[0] ]; } return false; default: return $_wp_theme_features[ $feature ]; } } function remove_theme_support( $feature ) { if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ), true ) ) { return false; } return _remove_theme_support( $feature ); } function _remove_theme_support( $feature ) { global $_wp_theme_features; switch ( $feature ) { case 'custom-header-uploads': if ( ! isset( $_wp_theme_features['custom-header'] ) ) { return false; } add_theme_support( 'custom-header', array( 'uploads' => false ) ); return; } if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } switch ( $feature ) { case 'custom-header': if ( ! did_action( 'wp_loaded' ) ) { break; } $support = get_theme_support( 'custom-header' ); if ( isset( $support[0]['wp-head-callback'] ) ) { remove_action( 'wp_head', $support[0]['wp-head-callback'] ); } if ( isset( $GLOBALS['custom_image_header'] ) ) { remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) ); unset( $GLOBALS['custom_image_header'] ); } break; case 'custom-background': if ( ! did_action( 'wp_loaded' ) ) { break; } $support = get_theme_support( 'custom-background' ); if ( isset( $support[0]['wp-head-callback'] ) ) { remove_action( 'wp_head', $support[0]['wp-head-callback'] ); } remove_action( 'admin_menu', array( $GLOBALS['custom_background'], 'init' ) ); unset( $GLOBALS['custom_background'] ); break; } unset( $_wp_theme_features[ $feature ] ); return true; } function current_theme_supports( $feature, ...$args ) { global $_wp_theme_features; if ( 'custom-header-uploads' === $feature ) { return current_theme_supports( 'custom-header', 'uploads' ); } if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } if ( ! $args ) { return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); } switch ( $feature ) { case 'post-thumbnails': if ( true === $_wp_theme_features[ $feature ] ) { return true; } $content_type = $args[0]; return in_array( $content_type, $_wp_theme_features[ $feature ][0], true ); case 'html5': case 'post-formats': $type = $args[0]; return in_array( $type, $_wp_theme_features[ $feature ][0], true ); case 'custom-logo': case 'custom-header': case 'custom-background': return ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) && $_wp_theme_features[ $feature ][0][ $args[0] ] ); } return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); } function require_if_theme_supports( $feature, $file ) { if ( current_theme_supports( $feature ) ) { require $file; return true; } return false; } function register_theme_feature( $feature, $args = array() ) { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { $_wp_registered_theme_features = array(); } $defaults = array( 'type' => 'boolean', 'variadic' => false, 'description' => '', 'show_in_rest' => false, ); $args = wp_parse_args( $args, $defaults ); if ( true === $args['show_in_rest'] ) { $args['show_in_rest'] = array(); } if ( is_array( $args['show_in_rest'] ) ) { $args['show_in_rest'] = wp_parse_args( $args['show_in_rest'], array( 'schema' => array(), 'name' => $feature, 'prepare_callback' => null, ) ); } if ( ! in_array( $args['type'], array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { return new WP_Error( 'invalid_type', __( 'The feature "type" is not valid JSON Schema type.' ) ); } if ( true === $args['variadic'] && 'array' !== $args['type'] ) { return new WP_Error( 'variadic_must_be_array', __( 'When registering a "variadic" theme feature, the "type" must be an "array".' ) ); } if ( false !== $args['show_in_rest'] && in_array( $args['type'], array( 'array', 'object' ), true ) ) { if ( ! is_array( $args['show_in_rest'] ) || empty( $args['show_in_rest']['schema'] ) ) { return new WP_Error( 'missing_schema', __( 'When registering an "array" or "object" feature to show in the REST API, the feature\'s schema must also be defined.' ) ); } if ( 'array' === $args['type'] && ! isset( $args['show_in_rest']['schema']['items'] ) ) { return new WP_Error( 'missing_schema_items', __( 'When registering an "array" feature, the feature\'s schema must include the "items" keyword.' ) ); } if ( 'object' === $args['type'] && ! isset( $args['show_in_rest']['schema']['properties'] ) ) { return new WP_Error( 'missing_schema_properties', __( 'When registering an "object" feature, the feature\'s schema must include the "properties" keyword.' ) ); } } if ( is_array( $args['show_in_rest'] ) ) { if ( isset( $args['show_in_rest']['prepare_callback'] ) && ! is_callable( $args['show_in_rest']['prepare_callback'] ) ) { return new WP_Error( 'invalid_rest_prepare_callback', sprintf( __( 'The "%s" must be a callable function.' ), 'prepare_callback' ) ); } $args['show_in_rest']['schema'] = wp_parse_args( $args['show_in_rest']['schema'], array( 'description' => $args['description'], 'type' => $args['type'], 'default' => false, ) ); if ( is_bool( $args['show_in_rest']['schema']['default'] ) && ! in_array( 'boolean', (array) $args['show_in_rest']['schema']['type'], true ) ) { $args['show_in_rest']['schema']['type'] = (array) $args['show_in_rest']['schema']['type']; array_unshift( $args['show_in_rest']['schema']['type'], 'boolean' ); } $args['show_in_rest']['schema'] = rest_default_additional_properties_to_false( $args['show_in_rest']['schema'] ); } $_wp_registered_theme_features[ $feature ] = $args; return true; } function get_registered_theme_features() { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return array(); } return $_wp_registered_theme_features; } function get_registered_theme_feature( $feature ) { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return null; } return isset( $_wp_registered_theme_features[ $feature ] ) ? $_wp_registered_theme_features[ $feature ] : null; } function _delete_attachment_theme_mod( $id ) { $attachment_image = wp_get_attachment_url( $id ); $header_image = get_header_image(); $background_image = get_background_image(); $custom_logo_id = (int) get_theme_mod( 'custom_logo' ); $site_logo_id = (int) get_option( 'site_logo' ); if ( $custom_logo_id && $custom_logo_id === $id ) { remove_theme_mod( 'custom_logo' ); remove_theme_mod( 'header_text' ); } if ( $site_logo_id && $site_logo_id === $id ) { delete_option( 'site_logo' ); } if ( $header_image && $header_image === $attachment_image ) { remove_theme_mod( 'header_image' ); remove_theme_mod( 'header_image_data' ); } if ( $background_image && $background_image === $attachment_image ) { remove_theme_mod( 'background_image' ); } } function check_theme_switched() { $stylesheet = get_option( 'theme_switched' ); if ( $stylesheet ) { $old_theme = wp_get_theme( $stylesheet ); if ( get_option( 'theme_switched_via_customizer' ) ) { remove_action( 'after_switch_theme', '_wp_menus_changed' ); remove_action( 'after_switch_theme', '_wp_sidebars_changed' ); update_option( 'theme_switched_via_customizer', false ); } if ( $old_theme->exists() ) { do_action( 'after_switch_theme', $old_theme->get( 'Name' ), $old_theme ); } else { do_action( 'after_switch_theme', $stylesheet, $old_theme ); } flush_rewrite_rules(); update_option( 'theme_switched', false ); } } function _wp_customize_include() { $is_customize_admin_page = ( is_admin() && 'customize.php' === basename( $_SERVER['PHP_SELF'] ) ); $should_include = ( $is_customize_admin_page || ( isset( $_REQUEST['wp_customize'] ) && 'on' === $_REQUEST['wp_customize'] ) || ( ! empty( $_GET['customize_changeset_uuid'] ) || ! empty( $_POST['customize_changeset_uuid'] ) ) ); if ( ! $should_include ) { return; } $keys = array( 'changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel', 'customize_autosaved', ); $input_vars = array_merge( wp_array_slice_assoc( $_GET, $keys ), wp_array_slice_assoc( $_POST, $keys ) ); $theme = null; $autosaved = null; $messenger_channel = null; $changeset_uuid = false; $branching = false; if ( $is_customize_admin_page && isset( $input_vars['changeset_uuid'] ) ) { $changeset_uuid = sanitize_key( $input_vars['changeset_uuid'] ); } elseif ( ! empty( $input_vars['customize_changeset_uuid'] ) ) { $changeset_uuid = sanitize_key( $input_vars['customize_changeset_uuid'] ); } if ( $is_customize_admin_page && isset( $input_vars['theme'] ) ) { $theme = $input_vars['theme']; } elseif ( isset( $input_vars['customize_theme'] ) ) { $theme = $input_vars['customize_theme']; } if ( ! empty( $input_vars['customize_autosaved'] ) ) { $autosaved = true; } if ( isset( $input_vars['customize_messenger_channel'] ) ) { $messenger_channel = sanitize_key( $input_vars['customize_messenger_channel'] ); } $is_customize_save_action = ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && 'customize_save' === wp_unslash( $_REQUEST['action'] ) ); $settings_previewed = ! $is_customize_save_action; require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; $GLOBALS['wp_customize'] = new WP_Customize_Manager( compact( 'changeset_uuid', 'theme', 'messenger_channel', 'settings_previewed', 'autosaved', 'branching' ) ); } function _wp_customize_publish_changeset( $new_status, $old_status, $changeset_post ) { global $wp_customize; $is_publishing_changeset = ( 'customize_changeset' === $changeset_post->post_type && 'publish' === $new_status && 'publish' !== $old_status ); if ( ! $is_publishing_changeset ) { return; } if ( empty( $wp_customize ) ) { require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; $wp_customize = new WP_Customize_Manager( array( 'changeset_uuid' => $changeset_post->post_name, 'settings_previewed' => false, ) ); } if ( ! did_action( 'customize_register' ) ) { remove_action( 'customize_register', array( $wp_customize, 'register_controls' ) ); $wp_customize->register_controls(); do_action( 'customize_register', $wp_customize ); } $wp_customize->_publish_changeset_values( $changeset_post->ID ); if ( ! wp_revisions_enabled( $changeset_post ) ) { $wp_customize->trash_changeset_post( $changeset_post->ID ); } } function _wp_customize_changeset_filter_insert_post_data( $post_data, $supplied_post_data ) { if ( isset( $post_data['post_type'] ) && 'customize_changeset' === $post_data['post_type'] ) { if ( empty( $post_data['post_name'] ) && ! empty( $supplied_post_data['post_name'] ) ) { $post_data['post_name'] = $supplied_post_data['post_name']; } } return $post_data; } function _wp_customize_loader_settings() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $cross_domain = ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) ); $browser = array( 'mobile' => wp_is_mobile(), 'ios' => wp_is_mobile() && preg_match( '/iPad|iPod|iPhone/', $_SERVER['HTTP_USER_AGENT'] ), ); $settings = array( 'url' => esc_url( admin_url( 'customize.php' ) ), 'isCrossDomain' => $cross_domain, 'browser' => $browser, 'l10n' => array( 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ), 'mainIframeTitle' => __( 'Customizer' ), ), ); $script = 'var _wpCustomizeLoaderSettings = ' . wp_json_encode( $settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) . ';'; $wp_scripts = wp_scripts(); $data = $wp_scripts->get_data( 'customize-loader', 'data' ); if ( $data ) { $script = "$data\n$script"; } $wp_scripts->add_data( 'customize-loader', 'data', $script ); } function wp_customize_url( $stylesheet = '' ) { $url = admin_url( 'customize.php' ); if ( $stylesheet ) { $url = add_query_arg( 'theme', urlencode( $stylesheet ), $url ); } return esc_url( $url ); } function wp_customize_support_script() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $cross_domain = ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) ); ob_start(); ?>
<script>
(function() {
var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)');
<?php if ( $cross_domain ) : ?>
request = (function(){ var xhr = new XMLHttpRequest(); return ('withCredentials' in xhr); })();
<?php else : ?>
request = true;
<?php endif; ?>
b[c] = b[c].replace( rcs, ' ' );
// The customizer requires postMessage and CORS (if the site is cross domain).
b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs;
}());
</script>
<?php
wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) . "\n//# sourceURL=" . rawurlencode( __FUNCTION__ ) ); } function is_customize_preview() { global $wp_customize; return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); } function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { global $wpdb; unset( $old_status ); if ( 'customize_changeset' !== $post->post_type || 'publish' === $new_status ) { return; } $data = json_decode( $post->post_content, true ); if ( empty( $data['nav_menus_created_posts']['value'] ) ) { return; } if ( 'trash' === $new_status ) { foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { if ( ! empty( $post_id ) && 'draft' === get_post_status( $post_id ) ) { wp_trash_post( $post_id ); } } return; } $post_args = array(); if ( 'auto-draft' === $new_status ) { $post_args['post_date'] = $post->post_date; } else { $post_args['post_status'] = 'draft'; } foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) { continue; } $wpdb->update( $wpdb->posts, $post_args, array( 'ID' => $post_id ) ); clean_post_cache( $post_id ); } } function create_initial_theme_features() { register_theme_feature( 'align-wide', array( 'description' => __( 'Whether theme opts in to wide alignment CSS class.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'automatic-feed-links', array( 'description' => __( 'Whether posts and comments RSS feed links are added to head.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'block-templates', array( 'description' => __( 'Whether a theme uses block-based templates.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'block-template-parts', array( 'description' => __( 'Whether a theme uses block-based template parts.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'custom-background', array( 'description' => __( 'Custom background if defined by the theme.' ), 'type' => 'object', 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'default-image' => array( 'type' => 'string', 'format' => 'uri', ), 'default-preset' => array( 'type' => 'string', 'enum' => array( 'default', 'fill', 'fit', 'repeat', 'custom', ), ), 'default-position-x' => array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', ), ), 'default-position-y' => array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', ), ), 'default-size' => array( 'type' => 'string', 'enum' => array( 'auto', 'contain', 'cover', ), ), 'default-repeat' => array( 'type' => 'string', 'enum' => array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat', ), ), 'default-attachment' => array( 'type' => 'string', 'enum' => array( 'scroll', 'fixed', ), ), 'default-color' => array( 'type' => 'string', ), ), ), ), ) ); register_theme_feature( 'custom-header', array( 'description' => __( 'Custom header if defined by the theme.' ), 'type' => 'object', 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'default-image' => array( 'type' => 'string', 'format' => 'uri', ), 'random-default' => array( 'type' => 'boolean', ), 'width' => array( 'type' => 'integer', ), 'height' => array( 'type' => 'integer', ), 'flex-height' => array( 'type' => 'boolean', ), 'flex-width' => array( 'type' => 'boolean', ), 'default-text-color' => array( 'type' => 'string', ), 'header-text' => array( 'type' => 'boolean', ), 'uploads' => array( 'type' => 'boolean', ), 'video' => array( 'type' => 'boolean', ), ), ), ), ) ); register_theme_feature( 'custom-logo', array( 'type' => 'object', 'description' => __( 'Custom logo if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'width' => array( 'type' => 'integer', ), 'height' => array( 'type' => 'integer', ), 'flex-width' => array( 'type' => 'boolean', ), 'flex-height' => array( 'type' => 'boolean', ), 'header-text' => array( 'type' => 'array', 'items' => array( 'type' => 'string', ), ), 'unlink-homepage-logo' => array( 'type' => 'boolean', ), ), ), ), ) ); register_theme_feature( 'customize-selective-refresh-widgets', array( 'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'dark-editor-style', array( 'description' => __( 'Whether theme opts in to the dark editor style UI.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-colors', array( 'description' => __( 'Whether the theme disables custom colors.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-font-sizes', array( 'description' => __( 'Whether the theme disables custom font sizes.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-gradients', array( 'description' => __( 'Whether the theme disables custom gradients.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-layout-styles', array( 'description' => __( 'Whether the theme disables generated layout styles.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'editor-color-palette', array( 'type' => 'array', 'description' => __( 'Custom color palette if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), 'color' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-font-sizes', array( 'type' => 'array', 'description' => __( 'Custom font sizes if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'size' => array( 'type' => 'number', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-gradient-presets', array( 'type' => 'array', 'description' => __( 'Custom gradient presets if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'gradient' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-spacing-sizes', array( 'type' => 'array', 'description' => __( 'Custom spacing sizes if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'size' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-styles', array( 'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'html5', array( 'type' => 'array', 'description' => __( 'Allows use of HTML5 markup for search forms, comment forms, comment lists, gallery, and caption.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'string', 'enum' => array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'script', 'style', ), ), ), ), ) ); register_theme_feature( 'post-formats', array( 'type' => 'array', 'description' => __( 'Post formats supported.' ), 'show_in_rest' => array( 'name' => 'formats', 'schema' => array( 'items' => array( 'type' => 'string', 'enum' => get_post_format_slugs(), ), 'default' => array( 'standard' ), ), 'prepare_callback' => static function ( $formats ) { $formats = is_array( $formats ) ? array_values( $formats[0] ) : array(); $formats = array_merge( array( 'standard' ), $formats ); return $formats; }, ), ) ); register_theme_feature( 'post-thumbnails', array( 'type' => 'array', 'description' => __( 'The post types that support thumbnails or true if all post types are supported.' ), 'show_in_rest' => array( 'type' => array( 'boolean', 'array' ), 'schema' => array( 'items' => array( 'type' => 'string', ), ), ), ) ); register_theme_feature( 'responsive-embeds', array( 'description' => __( 'Whether the theme supports responsive embedded content.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'title-tag', array( 'description' => __( 'Whether the theme can manage the document title tag.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'wp-block-styles', array( 'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ), 'show_in_rest' => true, ) ); } function wp_is_block_theme() { if ( empty( $GLOBALS['wp_theme_directories'] ) ) { _doing_it_wrong( __FUNCTION__, __( 'This function should not be called before the theme directory is registered.' ), '6.8.0' ); return false; } return wp_get_theme()->is_block_theme(); } function wp_theme_get_element_class_name( $element ) { return WP_Theme_JSON::get_element_class_name( $element ); } function _add_default_theme_supports() { if ( ! wp_is_block_theme() ) { return; } add_theme_support( 'post-thumbnails' ); add_theme_support( 'responsive-embeds' ); add_theme_support( 'editor-styles' ); add_theme_support( 'html5', array( 'comment-form', 'comment-list', 'search-form', 'gallery', 'caption', 'style', 'script' ) ); add_theme_support( 'automatic-feed-links' ); add_filter( 'should_load_separate_core_block_assets', '__return_true' ); add_filter( 'should_load_block_assets_on_demand', '__return_true' ); add_filter( 'customize_panel_active', static function ( $active, WP_Customize_Panel $panel ) { if ( 'nav_menus' === $panel->id && ! current_theme_supports( 'menus' ) && ! current_theme_supports( 'widgets' ) ) { $active = false; } return $active; }, 10, 2 ); }
###require ABSPATH . WPINC . '/class-wp-theme.php';
final class WP_Theme implements ArrayAccess { public $update = false; private static $file_headers = array( 'Name' => 'Theme Name', 'ThemeURI' => 'Theme URI', 'Description' => 'Description', 'Author' => 'Author', 'AuthorURI' => 'Author URI', 'Version' => 'Version', 'Template' => 'Template', 'Status' => 'Status', 'Tags' => 'Tags', 'TextDomain' => 'Text Domain', 'DomainPath' => 'Domain Path', 'RequiresWP' => 'Requires at least', 'RequiresPHP' => 'Requires PHP', 'UpdateURI' => 'Update URI', ); private static $default_themes = array( 'classic' => 'WordPress Classic', 'default' => 'WordPress Default', 'twentyten' => 'Twenty Ten', 'twentyeleven' => 'Twenty Eleven', 'twentytwelve' => 'Twenty Twelve', 'twentythirteen' => 'Twenty Thirteen', 'twentyfourteen' => 'Twenty Fourteen', 'twentyfifteen' => 'Twenty Fifteen', 'twentysixteen' => 'Twenty Sixteen', 'twentyseventeen' => 'Twenty Seventeen', 'twentynineteen' => 'Twenty Nineteen', 'twentytwenty' => 'Twenty Twenty', 'twentytwentyone' => 'Twenty Twenty-One', 'twentytwentytwo' => 'Twenty Twenty-Two', 'twentytwentythree' => 'Twenty Twenty-Three', 'twentytwentyfour' => 'Twenty Twenty-Four', 'twentytwentyfive' => 'Twenty Twenty-Five', ); private static $tag_map = array( 'fixed-width' => 'fixed-layout', 'flexible-width' => 'fluid-layout', ); private $theme_root; private $headers = array(); private $headers_sanitized; private $block_theme; private $name_translated; private $errors; private $stylesheet; private $template; private $parent; private $theme_root_uri; private $textdomain_loaded; private $cache_hash; private $block_template_folders; private $default_template_folders = array( 'wp_template' => 'templates', 'wp_template_part' => 'parts', ); private static $persistently_cache; private static $cache_expiration = 1800; public function __construct( $theme_dir, $theme_root, $_child = null ) { global $wp_theme_directories; if ( ! isset( self::$persistently_cache ) ) { self::$persistently_cache = apply_filters( 'wp_cache_themes_persistently', false, 'WP_Theme' ); if ( self::$persistently_cache ) { wp_cache_add_global_groups( 'themes' ); if ( is_int( self::$persistently_cache ) ) { self::$cache_expiration = self::$persistently_cache; } } else { wp_cache_add_non_persistent_groups( 'themes' ); } } $theme_dir = (string) $theme_dir; $this->theme_root = $theme_root; $this->stylesheet = $theme_dir; if ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) && in_array( dirname( $theme_root ), (array) $wp_theme_directories, true ) ) { $this->stylesheet = basename( $this->theme_root ) . '/' . $this->stylesheet; $this->theme_root = dirname( $theme_root ); } $this->cache_hash = md5( $this->theme_root . '/' . $this->stylesheet ); $theme_file = $this->stylesheet . '/style.css'; $cache = $this->cache_get( 'theme' ); if ( is_array( $cache ) ) { foreach ( array( 'block_template_folders', 'block_theme', 'errors', 'headers', 'template' ) as $key ) { if ( isset( $cache[ $key ] ) ) { $this->$key = $cache[ $key ]; } } if ( $this->errors ) { return; } if ( isset( $cache['theme_root_template'] ) ) { $theme_root_template = $cache['theme_root_template']; } } elseif ( ! file_exists( $this->theme_root . '/' . $theme_file ) ) { $this->headers['Name'] = $this->stylesheet; if ( ! file_exists( $this->theme_root . '/' . $this->stylesheet ) ) { $this->errors = new WP_Error( 'theme_not_found', sprintf( __( 'The theme directory "%s" does not exist.' ), esc_html( $this->stylesheet ) ) ); } else { $this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) ); } $this->template = $this->stylesheet; $this->block_theme = false; $this->block_template_folders = $this->default_template_folders; $this->cache_add( 'theme', array( 'block_template_folders' => $this->block_template_folders, 'block_theme' => $this->block_theme, 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); if ( ! file_exists( $this->theme_root ) ) { $this->errors->add( 'theme_root_missing', __( '<strong>Error:</strong> The themes directory is either empty or does not exist. Please check your installation.' ) ); } return; } elseif ( ! is_readable( $this->theme_root . '/' . $theme_file ) ) { $this->headers['Name'] = $this->stylesheet; $this->errors = new WP_Error( 'theme_stylesheet_not_readable', __( 'Stylesheet is not readable.' ) ); $this->template = $this->stylesheet; $this->block_theme = false; $this->block_template_folders = $this->default_template_folders; $this->cache_add( 'theme', array( 'block_template_folders' => $this->block_template_folders, 'block_theme' => $this->block_theme, 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); return; } else { $this->headers = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' ); $default_theme_slug = array_search( $this->headers['Name'], self::$default_themes, true ); if ( $default_theme_slug ) { if ( basename( $this->stylesheet ) !== $default_theme_slug ) { $this->headers['Name'] .= '/' . $this->stylesheet; } } } if ( ! $this->template && $this->stylesheet === $this->headers['Template'] ) { $this->errors = new WP_Error( 'theme_child_invalid', sprintf( __( 'The theme defines itself as its parent theme. Please check the %s header.' ), '<code>Template</code>' ) ); $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, ) ); return; } if ( ! $this->template ) { $this->template = $this->headers['Template']; } if ( ! $this->template ) { $this->template = $this->stylesheet; $theme_path = $this->theme_root . '/' . $this->stylesheet; if ( ! $this->is_block_theme() && ! file_exists( $theme_path . '/index.php' ) ) { $error_message = sprintf( __( 'Template is missing. Standalone themes need to have a %1$s or %2$s template file. <a href="%3$s">Child themes</a> need to have a %4$s header in the %5$s stylesheet.' ), '<code>templates/index.html</code>', '<code>index.php</code>', __( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ), '<code>Template</code>', '<code>style.css</code>' ); $this->errors = new WP_Error( 'theme_no_index', $error_message ); $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->block_theme, 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); return; } } if ( ! is_array( $cache ) && $this->template !== $this->stylesheet && ! file_exists( $this->theme_root . '/' . $this->template . '/index.php' ) ) { $parent_dir = dirname( $this->stylesheet ); $directories = search_theme_directories(); if ( '.' !== $parent_dir && file_exists( $this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php' ) ) { $this->template = $parent_dir . '/' . $this->template; } elseif ( $directories && isset( $directories[ $this->template ] ) ) { $theme_root_template = $directories[ $this->template ]['theme_root']; } else { $this->errors = new WP_Error( 'theme_no_parent', sprintf( __( 'The parent theme is missing. Please install the "%s" parent theme.' ), esc_html( $this->template ) ) ); $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); $this->parent = new WP_Theme( $this->template, $this->theme_root, $this ); return; } } if ( $this->template !== $this->stylesheet ) { if ( $_child instanceof WP_Theme && $_child->template === $this->stylesheet ) { $_child->parent = null; $_child->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), esc_html( $_child->template ) ) ); $_child->cache_add( 'theme', array( 'block_template_folders' => $_child->get_block_template_folders(), 'block_theme' => $_child->is_block_theme(), 'headers' => $_child->headers, 'errors' => $_child->errors, 'stylesheet' => $_child->stylesheet, 'template' => $_child->template, ) ); if ( $_child->stylesheet === $this->template ) { $this->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), esc_html( $this->template ) ) ); $this->cache_add( 'theme', array( 'block_template_folders' => $this->get_block_template_folders(), 'block_theme' => $this->is_block_theme(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ) ); } return; } $this->parent = new WP_Theme( $this->template, isset( $theme_root_template ) ? $theme_root_template : $this->theme_root, $this ); } if ( wp_paused_themes()->get( $this->stylesheet ) && ( ! is_wp_error( $this->errors ) || ! isset( $this->errors->errors['theme_paused'] ) ) ) { $this->errors = new WP_Error( 'theme_paused', __( 'This theme failed to load properly and was paused within the admin backend.' ) ); } if ( ! is_array( $cache ) ) { $cache = array( 'block_theme' => $this->is_block_theme(), 'block_template_folders' => $this->get_block_template_folders(), 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template, ); if ( isset( $theme_root_template ) ) { $cache['theme_root_template'] = $theme_root_template; } $this->cache_add( 'theme', $cache ); } } public function __toString() { return (string) $this->display( 'Name' ); } public function __isset( $offset ) { static $properties = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', ); return in_array( $offset, $properties, true ); } public function __get( $offset ) { switch ( $offset ) { case 'name': case 'title': return $this->get( 'Name' ); case 'version': return $this->get( 'Version' ); case 'parent_theme': return $this->parent() ? $this->parent()->get( 'Name' ) : ''; case 'template_dir': return $this->get_template_directory(); case 'stylesheet_dir': return $this->get_stylesheet_directory(); case 'template': return $this->get_template(); case 'stylesheet': return $this->get_stylesheet(); case 'screenshot': return $this->get_screenshot( 'relative' ); case 'description': return $this->display( 'Description' ); case 'author': return $this->display( 'Author' ); case 'tags': return $this->get( 'Tags' ); case 'theme_root': return $this->get_theme_root(); case 'theme_root_uri': return $this->get_theme_root_uri(); default: return $this->offsetGet( $offset ); } } public function offsetSet( $offset, $value ) {} public function offsetUnset( $offset ) {} public function offsetExists( $offset ) { static $keys = array( 'Name', 'Version', 'Status', 'Title', 'Author', 'Author Name', 'Author URI', 'Description', 'Template', 'Stylesheet', 'Template Files', 'Stylesheet Files', 'Template Dir', 'Stylesheet Dir', 'Screenshot', 'Tags', 'Theme Root', 'Theme Root URI', 'Parent Theme', ); return in_array( $offset, $keys, true ); } public function offsetGet( $offset ) { switch ( $offset ) { case 'Name': case 'Title': return $this->get( 'Name' ); case 'Author': return $this->display( 'Author' ); case 'Author Name': return $this->display( 'Author', false ); case 'Author URI': return $this->display( 'AuthorURI' ); case 'Description': return $this->display( 'Description' ); case 'Version': case 'Status': return $this->get( $offset ); case 'Template': return $this->get_template(); case 'Stylesheet': return $this->get_stylesheet(); case 'Template Files': return $this->get_files( 'php', 1, true ); case 'Stylesheet Files': return $this->get_files( 'css', 0, false ); case 'Template Dir': return $this->get_template_directory(); case 'Stylesheet Dir': return $this->get_stylesheet_directory(); case 'Screenshot': return $this->get_screenshot( 'relative' ); case 'Tags': return $this->get( 'Tags' ); case 'Theme Root': return $this->get_theme_root(); case 'Theme Root URI': return $this->get_theme_root_uri(); case 'Parent Theme': return $this->parent() ? $this->parent()->get( 'Name' ) : ''; default: return null; } } public function errors() { return is_wp_error( $this->errors ) ? $this->errors : false; } public function exists() { return ! ( $this->errors() && in_array( 'theme_not_found', $this->errors()->get_error_codes(), true ) ); } public function parent() { return isset( $this->parent ) ? $this->parent : false; } public function __wakeup() { if ( $this->parent && ! $this->parent instanceof self ) { throw new UnexpectedValueException(); } if ( $this->headers && ! is_array( $this->headers ) ) { throw new UnexpectedValueException(); } foreach ( $this->headers as $value ) { if ( ! is_string( $value ) ) { throw new UnexpectedValueException(); } } $this->headers_sanitized = array(); } private function cache_add( $key, $data ) { return wp_cache_add( $key . '-' . $this->cache_hash, $data, 'themes', self::$cache_expiration ); } private function cache_get( $key ) { return wp_cache_get( $key . '-' . $this->cache_hash, 'themes' ); } public function cache_delete() { foreach ( array( 'theme', 'screenshot', 'headers', 'post_templates' ) as $key ) { wp_cache_delete( $key . '-' . $this->cache_hash, 'themes' ); } $this->template = null; $this->textdomain_loaded = null; $this->theme_root_uri = null; $this->parent = null; $this->errors = null; $this->headers_sanitized = null; $this->name_translated = null; $this->block_theme = null; $this->block_template_folders = null; $this->headers = array(); $this->__construct( $this->stylesheet, $this->theme_root ); $this->delete_pattern_cache(); } public function get( $header ) { if ( ! isset( $this->headers[ $header ] ) ) { return false; } if ( ! isset( $this->headers_sanitized ) ) { $this->headers_sanitized = $this->cache_get( 'headers' ); if ( ! is_array( $this->headers_sanitized ) ) { $this->headers_sanitized = array(); } } if ( isset( $this->headers_sanitized[ $header ] ) ) { return $this->headers_sanitized[ $header ]; } if ( self::$persistently_cache ) { foreach ( array_keys( $this->headers ) as $_header ) { $this->headers_sanitized[ $_header ] = $this->sanitize_header( $_header, $this->headers[ $_header ] ); } $this->cache_add( 'headers', $this->headers_sanitized ); } else { $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] ); } return $this->headers_sanitized[ $header ]; } public function display( $header, $markup = true, $translate = true ) { $value = $this->get( $header ); if ( false === $value ) { return false; } if ( $translate && ( empty( $value ) || ! $this->load_textdomain() ) ) { $translate = false; } if ( $translate ) { $value = $this->translate_header( $header, $value ); } if ( $markup ) { $value = $this->markup_header( $header, $value, $translate ); } return $value; } private function sanitize_header( $header, $value ) { switch ( $header ) { case 'Status': if ( ! $value ) { $value = 'publish'; break; } case 'Name': static $header_tags = array( 'abbr' => array( 'title' => true ), 'acronym' => array( 'title' => true ), 'code' => true, 'em' => true, 'strong' => true, ); $value = wp_kses( $value, $header_tags ); break; case 'Author': case 'Description': static $header_tags_with_a = array( 'a' => array( 'href' => true, 'title' => true, ), 'abbr' => array( 'title' => true ), 'acronym' => array( 'title' => true ), 'code' => true, 'em' => true, 'strong' => true, ); $value = wp_kses( $value, $header_tags_with_a ); break; case 'ThemeURI': case 'AuthorURI': $value = sanitize_url( $value ); break; case 'Tags': $value = array_filter( array_map( 'trim', explode( ',', strip_tags( $value ) ) ) ); break; case 'Version': case 'RequiresWP': case 'RequiresPHP': case 'UpdateURI': $value = strip_tags( $value ); break; } return $value; } private function markup_header( $header, $value, $translate ) { switch ( $header ) { case 'Name': if ( empty( $value ) ) { $value = esc_html( $this->get_stylesheet() ); } break; case 'Description': $value = wptexturize( $value ); break; case 'Author': if ( $this->get( 'AuthorURI' ) ) { $value = sprintf( '<a href="%1$s">%2$s</a>', $this->display( 'AuthorURI', true, $translate ), $value ); } elseif ( ! $value ) { $value = __( 'Anonymous' ); } break; case 'Tags': static $comma = null; if ( ! isset( $comma ) ) { $comma = wp_get_list_item_separator(); } $value = implode( $comma, $value ); break; case 'ThemeURI': case 'AuthorURI': $value = esc_url( $value ); break; } return $value; } private function translate_header( $header, $value ) { switch ( $header ) { case 'Name': if ( isset( $this->name_translated ) ) { return $this->name_translated; } $this->name_translated = translate( $value, $this->get( 'TextDomain' ) ); return $this->name_translated; case 'Tags': if ( empty( $value ) || ! function_exists( 'get_theme_feature_list' ) ) { return $value; } static $tags_list; if ( ! isset( $tags_list ) ) { $tags_list = array( 'black' => __( 'Black' ), 'blue' => __( 'Blue' ), 'brown' => __( 'Brown' ), 'gray' => __( 'Gray' ), 'green' => __( 'Green' ), 'orange' => __( 'Orange' ), 'pink' => __( 'Pink' ), 'purple' => __( 'Purple' ), 'red' => __( 'Red' ), 'silver' => __( 'Silver' ), 'tan' => __( 'Tan' ), 'white' => __( 'White' ), 'yellow' => __( 'Yellow' ), 'dark' => _x( 'Dark', 'color scheme' ), 'light' => _x( 'Light', 'color scheme' ), 'fixed-layout' => __( 'Fixed Layout' ), 'fluid-layout' => __( 'Fluid Layout' ), 'responsive-layout' => __( 'Responsive Layout' ), 'blavatar' => __( 'Blavatar' ), 'photoblogging' => __( 'Photoblogging' ), 'seasonal' => __( 'Seasonal' ), ); $feature_list = get_theme_feature_list( false ); foreach ( $feature_list as $tags ) { $tags_list += $tags; } } foreach ( $value as &$tag ) { if ( isset( $tags_list[ $tag ] ) ) { $tag = $tags_list[ $tag ]; } elseif ( isset( self::$tag_map[ $tag ] ) ) { $tag = $tags_list[ self::$tag_map[ $tag ] ]; } } return $value; default: $value = translate( $value, $this->get( 'TextDomain' ) ); } return $value; } public function get_stylesheet() { return $this->stylesheet; } public function get_template() { return $this->template; } public function get_stylesheet_directory() { if ( $this->errors() && in_array( 'theme_root_missing', $this->errors()->get_error_codes(), true ) ) { return ''; } return $this->theme_root . '/' . $this->stylesheet; } public function get_template_directory() { if ( $this->parent() ) { $theme_root = $this->parent()->theme_root; } else { $theme_root = $this->theme_root; } return $theme_root . '/' . $this->template; } public function get_stylesheet_directory_uri() { return $this->get_theme_root_uri() . '/' . str_replace( '%2F', '/', rawurlencode( $this->stylesheet ) ); } public function get_template_directory_uri() { if ( $this->parent() ) { $theme_root_uri = $this->parent()->get_theme_root_uri(); } else { $theme_root_uri = $this->get_theme_root_uri(); } return $theme_root_uri . '/' . str_replace( '%2F', '/', rawurlencode( $this->template ) ); } public function get_theme_root() { return $this->theme_root; } public function get_theme_root_uri() { if ( ! isset( $this->theme_root_uri ) ) { $this->theme_root_uri = get_theme_root_uri( $this->stylesheet, $this->theme_root ); } return $this->theme_root_uri; } public function get_screenshot( $uri = 'uri' ) { $screenshot = $this->cache_get( 'screenshot' ); if ( $screenshot ) { if ( 'relative' === $uri ) { return $screenshot; } return $this->get_stylesheet_directory_uri() . '/' . $screenshot; } elseif ( 0 === $screenshot ) { return false; } foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp', 'avif' ) as $ext ) { if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) { $this->cache_add( 'screenshot', 'screenshot.' . $ext ); if ( 'relative' === $uri ) { return 'screenshot.' . $ext; } return $this->get_stylesheet_directory_uri() . '/' . 'screenshot.' . $ext; } } $this->cache_add( 'screenshot', 0 ); return false; } public function get_files( $type = null, $depth = 0, $search_parent = false ) { $files = (array) self::scandir( $this->get_stylesheet_directory(), $type, $depth ); if ( $search_parent && $this->parent() ) { $files += (array) self::scandir( $this->get_template_directory(), $type, $depth ); } return array_filter( $files ); } public function get_post_templates() { if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) ) { return array(); } $post_templates = $this->cache_get( 'post_templates' ); if ( ! is_array( $post_templates ) ) { $post_templates = array(); $files = (array) $this->get_files( 'php', 1, true ); foreach ( $files as $file => $full_path ) { if ( ! preg_match( '|Template Name:(.*)$|mi', file_get_contents( $full_path ), $header ) ) { continue; } $types = array( 'page' ); if ( preg_match( '|Template Post Type:(.*)$|mi', file_get_contents( $full_path ), $type ) ) { $types = explode( ',', _cleanup_header_comment( $type[1] ) ); } foreach ( $types as $type ) { $type = sanitize_key( $type ); if ( ! isset( $post_templates[ $type ] ) ) { $post_templates[ $type ] = array(); } $post_templates[ $type ][ $file ] = _cleanup_header_comment( $header[1] ); } } $this->cache_add( 'post_templates', $post_templates ); } if ( current_theme_supports( 'block-templates' ) ) { $block_templates = get_block_templates( array(), 'wp_template' ); foreach ( get_post_types( array( 'public' => true ) ) as $type ) { foreach ( $block_templates as $block_template ) { if ( ! $block_template->is_custom ) { continue; } if ( isset( $block_template->post_types ) && ! in_array( $type, $block_template->post_types, true ) ) { continue; } $post_templates[ $type ][ $block_template->slug ] = $block_template->title; } } } if ( $this->load_textdomain() ) { foreach ( $post_templates as &$post_type ) { foreach ( $post_type as &$post_template ) { $post_template = $this->translate_header( 'Template Name', $post_template ); } } } return $post_templates; } public function get_page_templates( $post = null, $post_type = 'page' ) { if ( $post ) { $post_type = get_post_type( $post ); } $post_templates = $this->get_post_templates(); $post_templates = isset( $post_templates[ $post_type ] ) ? $post_templates[ $post_type ] : array(); $post_templates = (array) apply_filters( 'theme_templates', $post_templates, $this, $post, $post_type ); $post_templates = (array) apply_filters( "theme_{$post_type}_templates", $post_templates, $this, $post, $post_type ); return $post_templates; } private static function scandir( $path, $extensions = null, $depth = 0, $relative_path = '' ) { if ( ! is_dir( $path ) ) { return false; } if ( $extensions ) { $extensions = (array) $extensions; $_extensions = implode( '|', $extensions ); } $relative_path = trailingslashit( $relative_path ); if ( '/' === $relative_path ) { $relative_path = ''; } $results = scandir( $path ); $files = array(); $exclusions = (array) apply_filters( 'theme_scandir_exclusions', array( 'CVS', 'node_modules', 'vendor', 'bower_components' ) ); foreach ( $results as $result ) { if ( '.' === $result[0] || in_array( $result, $exclusions, true ) ) { continue; } if ( is_dir( $path . '/' . $result ) ) { if ( ! $depth ) { continue; } $found = self::scandir( $path . '/' . $result, $extensions, $depth - 1, $relative_path . $result ); $files = array_merge_recursive( $files, $found ); } elseif ( ! $extensions || preg_match( '~\.(' . $_extensions . ')$~', $result ) ) { $files[ $relative_path . $result ] = $path . '/' . $result; } } return $files; } public function load_textdomain() { if ( isset( $this->textdomain_loaded ) ) { return $this->textdomain_loaded; } $textdomain = $this->get( 'TextDomain' ); if ( ! $textdomain ) { $this->textdomain_loaded = false; return false; } if ( is_textdomain_loaded( $textdomain ) ) { $this->textdomain_loaded = true; return true; } $path = $this->get_stylesheet_directory(); $domainpath = $this->get( 'DomainPath' ); if ( $domainpath ) { $path .= $domainpath; } else { $path .= '/languages'; } $this->textdomain_loaded = load_theme_textdomain( $textdomain, $path ); return $this->textdomain_loaded; } public function is_allowed( $check = 'both', $blog_id = null ) { if ( ! is_multisite() ) { return true; } if ( 'both' === $check || 'network' === $check ) { $allowed = self::get_allowed_on_network(); if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) { return true; } } if ( 'both' === $check || 'site' === $check ) { $allowed = self::get_allowed_on_site( $blog_id ); if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) { return true; } } return false; } public function is_block_theme() { if ( isset( $this->block_theme ) ) { return $this->block_theme; } $paths_to_index_block_template = array( $this->get_file_path( '/templates/index.html' ), $this->get_file_path( '/block-templates/index.html' ), ); $this->block_theme = false; foreach ( $paths_to_index_block_template as $path_to_index_block_template ) { if ( is_file( $path_to_index_block_template ) && is_readable( $path_to_index_block_template ) ) { $this->block_theme = true; break; } } return $this->block_theme; } public function get_file_path( $file = '' ) { $file = ltrim( $file, '/' ); $stylesheet_directory = $this->get_stylesheet_directory(); $template_directory = $this->get_template_directory(); if ( empty( $file ) ) { $path = $stylesheet_directory; } elseif ( $stylesheet_directory !== $template_directory && file_exists( $stylesheet_directory . '/' . $file ) ) { $path = $stylesheet_directory . '/' . $file; } else { $path = $template_directory . '/' . $file; } return apply_filters( 'theme_file_path', $path, $file ); } public static function get_core_default_theme() { foreach ( array_reverse( self::$default_themes ) as $slug => $name ) { $theme = wp_get_theme( $slug ); if ( $theme->exists() ) { return $theme; } } return false; } public static function get_allowed( $blog_id = null ) { $network = (array) apply_filters( 'network_allowed_themes', self::get_allowed_on_network(), $blog_id ); return $network + self::get_allowed_on_site( $blog_id ); } public static function get_allowed_on_network() { static $allowed_themes; if ( ! isset( $allowed_themes ) ) { $allowed_themes = (array) get_site_option( 'allowedthemes' ); } $allowed_themes = apply_filters( 'allowed_themes', $allowed_themes ); return $allowed_themes; } public static function get_allowed_on_site( $blog_id = null ) { static $allowed_themes = array(); if ( ! $blog_id || ! is_multisite() ) { $blog_id = get_current_blog_id(); } if ( isset( $allowed_themes[ $blog_id ] ) ) { return (array) apply_filters( 'site_allowed_themes', $allowed_themes[ $blog_id ], $blog_id ); } $current = get_current_blog_id() === $blog_id; if ( $current ) { $allowed_themes[ $blog_id ] = get_option( 'allowedthemes' ); } else { switch_to_blog( $blog_id ); $allowed_themes[ $blog_id ] = get_option( 'allowedthemes' ); restore_current_blog(); } if ( false === $allowed_themes[ $blog_id ] ) { if ( $current ) { $allowed_themes[ $blog_id ] = get_option( 'allowed_themes' ); } else { switch_to_blog( $blog_id ); $allowed_themes[ $blog_id ] = get_option( 'allowed_themes' ); restore_current_blog(); } if ( ! is_array( $allowed_themes[ $blog_id ] ) || empty( $allowed_themes[ $blog_id ] ) ) { $allowed_themes[ $blog_id ] = array(); } else { $converted = array(); $themes = wp_get_themes(); foreach ( $themes as $stylesheet => $theme_data ) { if ( isset( $allowed_themes[ $blog_id ][ $theme_data->get( 'Name' ) ] ) ) { $converted[ $stylesheet ] = true; } } $allowed_themes[ $blog_id ] = $converted; } if ( is_admin() && $allowed_themes[ $blog_id ] ) { if ( $current ) { update_option( 'allowedthemes', $allowed_themes[ $blog_id ], false ); delete_option( 'allowed_themes' ); } else { switch_to_blog( $blog_id ); update_option( 'allowedthemes', $allowed_themes[ $blog_id ], false ); delete_option( 'allowed_themes' ); restore_current_blog(); } } } return (array) apply_filters( 'site_allowed_themes', $allowed_themes[ $blog_id ], $blog_id ); } public function get_block_template_folders() { if ( isset( $this->block_template_folders ) ) { return $this->block_template_folders; } $this->block_template_folders = $this->default_template_folders; $stylesheet_directory = $this->get_stylesheet_directory(); if ( file_exists( $stylesheet_directory . '/block-templates' ) || file_exists( $stylesheet_directory . '/block-template-parts' ) ) { $this->block_template_folders = array( 'wp_template' => 'block-templates', 'wp_template_part' => 'block-template-parts', ); } return $this->block_template_folders; } public function get_block_patterns() { $can_use_cached = ! wp_is_development_mode( 'theme' ); $pattern_data = $this->get_pattern_cache(); if ( is_array( $pattern_data ) ) { if ( $can_use_cached ) { return $pattern_data; } $this->delete_pattern_cache(); } $dirpath = $this->get_stylesheet_directory() . '/patterns'; $pattern_data = array(); if ( ! file_exists( $dirpath ) ) { if ( $can_use_cached ) { $this->set_pattern_cache( $pattern_data ); } return $pattern_data; } $files = (array) self::scandir( $dirpath, 'php', -1 ); $files = apply_filters( 'theme_block_pattern_files', $files, $dirpath ); $dirpath = trailingslashit( $dirpath ); if ( ! $files ) { if ( $can_use_cached ) { $this->set_pattern_cache( $pattern_data ); } return $pattern_data; } $default_headers = array( 'title' => 'Title', 'slug' => 'Slug', 'description' => 'Description', 'viewportWidth' => 'Viewport Width', 'inserter' => 'Inserter', 'categories' => 'Categories', 'keywords' => 'Keywords', 'blockTypes' => 'Block Types', 'postTypes' => 'Post Types', 'templateTypes' => 'Template Types', ); $properties_to_parse = array( 'categories', 'keywords', 'blockTypes', 'postTypes', 'templateTypes', ); foreach ( $files as $file ) { $pattern = get_file_data( $file, $default_headers ); if ( empty( $pattern['slug'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Could not register file "%s" as a block pattern ("Slug" field missing)' ), $file ), '6.0.0' ); continue; } if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern['slug'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")' ), $file, $pattern['slug'] ), '6.0.0' ); } if ( ! $pattern['title'] ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Could not register file "%s" as a block pattern ("Title" field missing)' ), $file ), '6.0.0' ); continue; } foreach ( $properties_to_parse as $property ) { if ( ! empty( $pattern[ $property ] ) ) { $pattern[ $property ] = array_filter( wp_parse_list( (string) $pattern[ $property ] ) ); } else { unset( $pattern[ $property ] ); } } $property = 'viewportWidth'; if ( ! empty( $pattern[ $property ] ) ) { $pattern[ $property ] = (int) $pattern[ $property ]; } else { unset( $pattern[ $property ] ); } $property = 'inserter'; if ( ! empty( $pattern[ $property ] ) ) { $pattern[ $property ] = in_array( strtolower( $pattern[ $property ] ), array( 'yes', 'true' ), true ); } else { unset( $pattern[ $property ] ); } $key = str_replace( $dirpath, '', $file ); $pattern_data[ $key ] = $pattern; } if ( $can_use_cached ) { $this->set_pattern_cache( $pattern_data ); } return $pattern_data; } private function get_pattern_cache() { if ( ! $this->exists() ) { return false; } $pattern_data = get_site_transient( 'wp_theme_files_patterns-' . $this->cache_hash ); if ( is_array( $pattern_data ) && $pattern_data['version'] === $this->get( 'Version' ) ) { return $pattern_data['patterns']; } return false; } private function set_pattern_cache( array $patterns ) { $pattern_data = array( 'version' => $this->get( 'Version' ), 'patterns' => $patterns, ); $cache_expiration = (int) apply_filters( 'wp_theme_files_cache_ttl', self::$cache_expiration, 'theme_block_patterns' ); if ( $cache_expiration <= 0 ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The %1$s filter must return an integer value greater than 0.' ), '<code>wp_theme_files_cache_ttl</code>' ), '6.6.0' ); $cache_expiration = self::$cache_expiration; } set_site_transient( 'wp_theme_files_patterns-' . $this->cache_hash, $pattern_data, $cache_expiration ); } public function delete_pattern_cache() { delete_site_transient( 'wp_theme_files_patterns-' . $this->cache_hash ); } public static function network_enable_theme( $stylesheets ) { if ( ! is_multisite() ) { return; } if ( ! is_array( $stylesheets ) ) { $stylesheets = array( $stylesheets ); } $allowed_themes = get_site_option( 'allowedthemes' ); foreach ( $stylesheets as $stylesheet ) { $allowed_themes[ $stylesheet ] = true; } update_site_option( 'allowedthemes', $allowed_themes ); } public static function network_disable_theme( $stylesheets ) { if ( ! is_multisite() ) { return; } if ( ! is_array( $stylesheets ) ) { $stylesheets = array( $stylesheets ); } $allowed_themes = get_site_option( 'allowedthemes' ); foreach ( $stylesheets as $stylesheet ) { if ( isset( $allowed_themes[ $stylesheet ] ) ) { unset( $allowed_themes[ $stylesheet ] ); } } update_site_option( 'allowedthemes', $allowed_themes ); } public static function sort_by_name( &$themes ) { if ( str_starts_with( get_user_locale(), 'en_' ) ) { uasort( $themes, array( 'WP_Theme', '_name_sort' ) ); } else { foreach ( $themes as $key => $theme ) { $theme->translate_header( 'Name', $theme->headers['Name'] ); } uasort( $themes, array( 'WP_Theme', '_name_sort_i18n' ) ); } } private static function _name_sort( $a, $b ) { return strnatcasecmp( $a->headers['Name'], $b->headers['Name'] ); } private static function _name_sort_i18n( $a, $b ) { return strnatcasecmp( $a->name_translated, $b->name_translated ); } private static function _check_headers_property_has_correct_type( $headers ) { if ( ! is_array( $headers ) ) { return false; } foreach ( $headers as $key => $value ) { if ( ! is_string( $key ) || ! is_string( $value ) ) { return false; } } return true; } }
###require ABSPATH . WPINC . '/class-wp-theme-json-schema.php';
class WP_Theme_JSON_Schema { const V1_TO_V2_RENAMED_PATHS = array( 'border.customRadius' => 'border.radius', 'spacing.customMargin' => 'spacing.margin', 'spacing.customPadding' => 'spacing.padding', 'typography.customLineHeight' => 'typography.lineHeight', ); public static function migrate( $theme_json, $origin = 'theme' ) { if ( ! isset( $theme_json['version'] ) ) { $theme_json = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, ); } switch ( $theme_json['version'] ) { case 1: $theme_json = self::migrate_v1_to_v2( $theme_json ); case 2: $theme_json = self::migrate_v2_to_v3( $theme_json, $origin ); } return $theme_json; } private static function migrate_v1_to_v2( $old ) { $new = $old; if ( isset( $old['settings'] ) ) { $new['settings'] = self::rename_paths( $old['settings'], self::V1_TO_V2_RENAMED_PATHS ); } $new['version'] = 2; return $new; } private static function migrate_v2_to_v3( $old, $origin ) { $new = $old; $new['version'] = 3; if ( 'custom' === $origin ) { return $new; } if ( isset( $old['settings']['typography']['fontSizes'] ) ) { $new['settings']['typography']['defaultFontSizes'] = false; } if ( isset( $old['settings']['spacing']['spacingSizes'] ) || isset( $old['settings']['spacing']['spacingScale'] ) ) { $new['settings']['spacing']['defaultSpacingSizes'] = false; } if ( isset( $old['settings']['spacing']['spacingSizes'] ) ) { unset( $new['settings']['spacing']['spacingScale'] ); } return $new; } private static function rename_paths( $settings, $paths_to_rename ) { $new_settings = $settings; self::rename_settings( $new_settings, $paths_to_rename ); if ( isset( $new_settings['blocks'] ) && is_array( $new_settings['blocks'] ) ) { foreach ( $new_settings['blocks'] as &$block_settings ) { self::rename_settings( $block_settings, $paths_to_rename ); } } return $new_settings; } private static function rename_settings( &$settings, $paths_to_rename ) { foreach ( $paths_to_rename as $original => $renamed ) { $original_path = explode( '.', $original ); $renamed_path = explode( '.', $renamed ); $current_value = _wp_array_get( $settings, $original_path, null ); if ( null !== $current_value ) { _wp_array_set( $settings, $renamed_path, $current_value ); self::unset_setting_by_path( $settings, $original_path ); } } } private static function unset_setting_by_path( &$settings, $path ) { $tmp_settings = &$settings; $last_key = array_pop( $path ); foreach ( $path as $key ) { $tmp_settings = &$tmp_settings[ $key ]; } unset( $tmp_settings[ $last_key ] ); } }
###require ABSPATH . WPINC . '/class-wp-theme-json-data.php';
class WP_Theme_JSON_Data { private $theme_json = null; private $origin = ''; public function __construct( $data = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA ), $origin = 'theme' ) { $this->origin = $origin; $this->theme_json = new WP_Theme_JSON( $data, $this->origin ); } public function update_with( $new_data ) { $this->theme_json->merge( new WP_Theme_JSON( $new_data, $this->origin ) ); return $this; } public function get_data() { return $this->theme_json->get_raw_data(); } public function get_theme_json() { return $this->theme_json; } }
###require ABSPATH . WPINC . '/class-wp-theme-json.php';
class WP_Theme_JSON { protected $theme_json = null; protected static $blocks_metadata = array(); const ROOT_CSS_PROPERTIES_SELECTOR = ':root'; const ROOT_BLOCK_SELECTOR = 'body'; const VALID_ORIGINS = array( 'default', 'blocks', 'theme', 'custom', ); const PRESETS_METADATA = array( array( 'path' => array( 'dimensions', 'aspectRatios' ), 'prevent_override' => array( 'dimensions', 'defaultAspectRatios' ), 'use_default_names' => false, 'value_key' => 'ratio', 'css_vars' => '--wp--preset--aspect-ratio--$slug', 'classes' => array(), 'properties' => array( 'aspect-ratio' ), ), array( 'path' => array( 'color', 'palette' ), 'prevent_override' => array( 'color', 'defaultPalette' ), 'use_default_names' => false, 'value_key' => 'color', 'css_vars' => '--wp--preset--color--$slug', 'classes' => array( '.has-$slug-color' => 'color', '.has-$slug-background-color' => 'background-color', '.has-$slug-border-color' => 'border-color', ), 'properties' => array( 'color', 'background-color', 'border-color' ), ), array( 'path' => array( 'color', 'gradients' ), 'prevent_override' => array( 'color', 'defaultGradients' ), 'use_default_names' => false, 'value_key' => 'gradient', 'css_vars' => '--wp--preset--gradient--$slug', 'classes' => array( '.has-$slug-gradient-background' => 'background' ), 'properties' => array( 'background' ), ), array( 'path' => array( 'color', 'duotone' ), 'prevent_override' => array( 'color', 'defaultDuotone' ), 'use_default_names' => false, 'value_func' => null, 'css_vars' => null, 'classes' => array(), 'properties' => array( 'filter' ), ), array( 'path' => array( 'typography', 'fontSizes' ), 'prevent_override' => array( 'typography', 'defaultFontSizes' ), 'use_default_names' => true, 'value_func' => 'wp_get_typography_font_size_value', 'css_vars' => '--wp--preset--font-size--$slug', 'classes' => array( '.has-$slug-font-size' => 'font-size' ), 'properties' => array( 'font-size' ), ), array( 'path' => array( 'typography', 'fontFamilies' ), 'prevent_override' => false, 'use_default_names' => false, 'value_key' => 'fontFamily', 'css_vars' => '--wp--preset--font-family--$slug', 'classes' => array( '.has-$slug-font-family' => 'font-family' ), 'properties' => array( 'font-family' ), ), array( 'path' => array( 'spacing', 'spacingSizes' ), 'prevent_override' => array( 'spacing', 'defaultSpacingSizes' ), 'use_default_names' => true, 'value_key' => 'size', 'css_vars' => '--wp--preset--spacing--$slug', 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), array( 'path' => array( 'shadow', 'presets' ), 'prevent_override' => array( 'shadow', 'defaultPresets' ), 'use_default_names' => false, 'value_key' => 'shadow', 'css_vars' => '--wp--preset--shadow--$slug', 'classes' => array(), 'properties' => array( 'box-shadow' ), ), array( 'path' => array( 'border', 'radiusSizes' ), 'prevent_override' => false, 'use_default_names' => false, 'value_key' => 'size', 'css_vars' => '--wp--preset--border-radius--$slug', 'classes' => array(), 'properties' => array( 'border-radius' ), ), ); const PROPERTIES_METADATA = array( 'aspect-ratio' => array( 'dimensions', 'aspectRatio' ), 'background' => array( 'color', 'gradient' ), 'background-color' => array( 'color', 'background' ), 'background-image' => array( 'background', 'backgroundImage' ), 'background-position' => array( 'background', 'backgroundPosition' ), 'background-repeat' => array( 'background', 'backgroundRepeat' ), 'background-size' => array( 'background', 'backgroundSize' ), 'background-attachment' => array( 'background', 'backgroundAttachment' ), 'border-radius' => array( 'border', 'radius' ), 'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ), 'border-top-right-radius' => array( 'border', 'radius', 'topRight' ), 'border-bottom-left-radius' => array( 'border', 'radius', 'bottomLeft' ), 'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ), 'border-color' => array( 'border', 'color' ), 'border-width' => array( 'border', 'width' ), 'border-style' => array( 'border', 'style' ), 'border-top-color' => array( 'border', 'top', 'color' ), 'border-top-width' => array( 'border', 'top', 'width' ), 'border-top-style' => array( 'border', 'top', 'style' ), 'border-right-color' => array( 'border', 'right', 'color' ), 'border-right-width' => array( 'border', 'right', 'width' ), 'border-right-style' => array( 'border', 'right', 'style' ), 'border-bottom-color' => array( 'border', 'bottom', 'color' ), 'border-bottom-width' => array( 'border', 'bottom', 'width' ), 'border-bottom-style' => array( 'border', 'bottom', 'style' ), 'border-left-color' => array( 'border', 'left', 'color' ), 'border-left-width' => array( 'border', 'left', 'width' ), 'border-left-style' => array( 'border', 'left', 'style' ), 'color' => array( 'color', 'text' ), 'text-align' => array( 'typography', 'textAlign' ), 'column-count' => array( 'typography', 'textColumns' ), 'font-family' => array( 'typography', 'fontFamily' ), 'font-size' => array( 'typography', 'fontSize' ), 'font-style' => array( 'typography', 'fontStyle' ), 'font-weight' => array( 'typography', 'fontWeight' ), 'letter-spacing' => array( 'typography', 'letterSpacing' ), 'line-height' => array( 'typography', 'lineHeight' ), 'margin' => array( 'spacing', 'margin' ), 'margin-top' => array( 'spacing', 'margin', 'top' ), 'margin-right' => array( 'spacing', 'margin', 'right' ), 'margin-bottom' => array( 'spacing', 'margin', 'bottom' ), 'margin-left' => array( 'spacing', 'margin', 'left' ), 'min-height' => array( 'dimensions', 'minHeight' ), 'outline-color' => array( 'outline', 'color' ), 'outline-offset' => array( 'outline', 'offset' ), 'outline-style' => array( 'outline', 'style' ), 'outline-width' => array( 'outline', 'width' ), 'padding' => array( 'spacing', 'padding' ), 'padding-top' => array( 'spacing', 'padding', 'top' ), 'padding-right' => array( 'spacing', 'padding', 'right' ), 'padding-bottom' => array( 'spacing', 'padding', 'bottom' ), 'padding-left' => array( 'spacing', 'padding', 'left' ), '--wp--style--root--padding' => array( 'spacing', 'padding' ), '--wp--style--root--padding-top' => array( 'spacing', 'padding', 'top' ), '--wp--style--root--padding-right' => array( 'spacing', 'padding', 'right' ), '--wp--style--root--padding-bottom' => array( 'spacing', 'padding', 'bottom' ), '--wp--style--root--padding-left' => array( 'spacing', 'padding', 'left' ), 'text-decoration' => array( 'typography', 'textDecoration' ), 'text-transform' => array( 'typography', 'textTransform' ), 'filter' => array( 'filter', 'duotone' ), 'box-shadow' => array( 'shadow' ), 'writing-mode' => array( 'typography', 'writingMode' ), ); const INDIRECT_PROPERTIES_METADATA = array( 'gap' => array( array( 'spacing', 'blockGap' ), ), 'column-gap' => array( array( 'spacing', 'blockGap', 'left' ), ), 'row-gap' => array( array( 'spacing', 'blockGap', 'top' ), ), 'max-width' => array( array( 'layout', 'contentSize' ), array( 'layout', 'wideSize' ), ), 'background-image' => array( array( 'background', 'backgroundImage', 'url' ), ), ); const PROTECTED_PROPERTIES = array( 'spacing.blockGap' => array( 'spacing', 'blockGap' ), ); const VALID_TOP_LEVEL_KEYS = array( 'blockTypes', 'customTemplates', 'description', 'patterns', 'settings', 'slug', 'styles', 'templateParts', 'title', 'version', ); const VALID_SETTINGS = array( 'appearanceTools' => null, 'useRootPaddingAwareAlignments' => null, 'background' => array( 'backgroundImage' => null, 'backgroundSize' => null, ), 'border' => array( 'color' => null, 'radius' => null, 'radiusSizes' => null, 'style' => null, 'width' => null, ), 'color' => array( 'background' => null, 'custom' => null, 'customDuotone' => null, 'customGradient' => null, 'defaultDuotone' => null, 'defaultGradients' => null, 'defaultPalette' => null, 'duotone' => null, 'gradients' => null, 'link' => null, 'heading' => null, 'button' => null, 'caption' => null, 'palette' => null, 'text' => null, ), 'custom' => null, 'dimensions' => array( 'aspectRatio' => null, 'aspectRatios' => null, 'defaultAspectRatios' => null, 'minHeight' => null, ), 'layout' => array( 'contentSize' => null, 'wideSize' => null, 'allowEditing' => null, 'allowCustomContentAndWideSize' => null, ), 'lightbox' => array( 'enabled' => null, 'allowEditing' => null, ), 'position' => array( 'fixed' => null, 'sticky' => null, ), 'spacing' => array( 'customSpacingSize' => null, 'defaultSpacingSizes' => null, 'spacingSizes' => null, 'spacingScale' => null, 'blockGap' => null, 'margin' => null, 'padding' => null, 'units' => null, ), 'shadow' => array( 'presets' => null, 'defaultPresets' => null, ), 'typography' => array( 'fluid' => null, 'customFontSize' => null, 'defaultFontSizes' => null, 'dropCap' => null, 'fontFamilies' => null, 'fontSizes' => null, 'fontStyle' => null, 'fontWeight' => null, 'letterSpacing' => null, 'lineHeight' => null, 'textAlign' => null, 'textColumns' => null, 'textDecoration' => null, 'textTransform' => null, 'writingMode' => null, ), ); const FONT_FAMILY_SCHEMA = array( array( 'fontFamily' => null, 'name' => null, 'slug' => null, 'fontFace' => array( array( 'ascentOverride' => null, 'descentOverride' => null, 'fontDisplay' => null, 'fontFamily' => null, 'fontFeatureSettings' => null, 'fontStyle' => null, 'fontStretch' => null, 'fontVariationSettings' => null, 'fontWeight' => null, 'lineGapOverride' => null, 'sizeAdjust' => null, 'src' => null, 'unicodeRange' => null, ), ), ), ); const VALID_STYLES = array( 'background' => array( 'backgroundImage' => null, 'backgroundPosition' => null, 'backgroundRepeat' => null, 'backgroundSize' => null, 'backgroundAttachment' => null, ), 'border' => array( 'color' => null, 'radius' => null, 'style' => null, 'width' => null, 'top' => null, 'right' => null, 'bottom' => null, 'left' => null, ), 'color' => array( 'background' => null, 'gradient' => null, 'text' => null, ), 'dimensions' => array( 'aspectRatio' => null, 'minHeight' => null, ), 'filter' => array( 'duotone' => null, ), 'outline' => array( 'color' => null, 'offset' => null, 'style' => null, 'width' => null, ), 'shadow' => null, 'spacing' => array( 'margin' => null, 'padding' => null, 'blockGap' => null, ), 'typography' => array( 'fontFamily' => null, 'fontSize' => null, 'fontStyle' => null, 'fontWeight' => null, 'letterSpacing' => null, 'lineHeight' => null, 'textAlign' => null, 'textColumns' => null, 'textDecoration' => null, 'textTransform' => null, 'writingMode' => null, ), 'css' => null, ); const VALID_ELEMENT_PSEUDO_SELECTORS = array( 'link' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), 'button' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), ); const ELEMENTS = array( 'link' => 'a:where(:not(.wp-element-button))', 'heading' => 'h1, h2, h3, h4, h5, h6', 'h1' => 'h1', 'h2' => 'h2', 'h3' => 'h3', 'h4' => 'h4', 'h5' => 'h5', 'h6' => 'h6', 'button' => '.wp-element-button, .wp-block-button__link', 'caption' => '.wp-element-caption, .wp-block-audio figcaption, .wp-block-embed figcaption, .wp-block-gallery figcaption, .wp-block-image figcaption, .wp-block-table figcaption, .wp-block-video figcaption', 'cite' => 'cite', 'textInput' => 'textarea, input:where([type=email],[type=number],[type=password],[type=search],[type=text],[type=tel],[type=url])', 'select' => 'select', ); const __EXPERIMENTAL_ELEMENT_CLASS_NAMES = array( 'button' => 'wp-element-button', 'caption' => 'wp-element-caption', ); const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = array( '__experimentalBorder' => 'border', 'color' => 'color', 'spacing' => 'spacing', 'typography' => 'typography', ); protected static function schema_in_root_and_per_origin( $schema ) { $schema_in_root_and_per_origin = $schema; foreach ( static::VALID_ORIGINS as $origin ) { $schema_in_root_and_per_origin[ $origin ] = $schema; } return $schema_in_root_and_per_origin; } public static function get_element_class_name( $element ) { $class_name = ''; if ( isset( static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $element ] ) ) { $class_name = static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $element ]; } return $class_name; } const APPEARANCE_TOOLS_OPT_INS = array( array( 'background', 'backgroundImage' ), array( 'background', 'backgroundSize' ), array( 'border', 'color' ), array( 'border', 'radius' ), array( 'border', 'style' ), array( 'border', 'width' ), array( 'color', 'link' ), array( 'color', 'heading' ), array( 'color', 'button' ), array( 'color', 'caption' ), array( 'dimensions', 'aspectRatio' ), array( 'dimensions', 'minHeight' ), array( 'position', 'sticky' ), array( 'spacing', 'blockGap' ), array( 'spacing', 'margin' ), array( 'spacing', 'padding' ), array( 'typography', 'lineHeight' ), ); const LATEST_SCHEMA = 3; public function __construct( $theme_json = array( 'version' => self::LATEST_SCHEMA ), $origin = 'theme' ) { if ( ! in_array( $origin, static::VALID_ORIGINS, true ) ) { $origin = 'theme'; } $this->theme_json = WP_Theme_JSON_Schema::migrate( $theme_json, $origin ); $blocks_metadata = static::get_blocks_metadata(); $valid_block_names = array_keys( $blocks_metadata ); $valid_element_names = array_keys( static::ELEMENTS ); $valid_variations = static::get_valid_block_style_variations( $blocks_metadata ); $this->theme_json = static::unwrap_shared_block_style_variations( $this->theme_json, $valid_variations ); $this->theme_json = static::sanitize( $this->theme_json, $valid_block_names, $valid_element_names, $valid_variations ); $this->theme_json = static::maybe_opt_in_into_settings( $this->theme_json ); $nodes = static::get_setting_nodes( $this->theme_json ); foreach ( $nodes as $node ) { foreach ( static::PRESETS_METADATA as $preset_metadata ) { $path = $node['path']; foreach ( $preset_metadata['path'] as $subpath ) { $path[] = $subpath; } $preset = _wp_array_get( $this->theme_json, $path, null ); if ( null !== $preset ) { if ( isset( $preset[0] ) || empty( $preset ) ) { _wp_array_set( $this->theme_json, $path, array( $origin => $preset ) ); } } } } $scale_path = array( 'settings', 'spacing', 'spacingScale' ); $spacing_scale = _wp_array_get( $this->theme_json, $scale_path, null ); if ( null !== $spacing_scale ) { if ( empty( array_intersect( array_keys( $spacing_scale ), static::VALID_ORIGINS ) ) ) { _wp_array_set( $this->theme_json, $scale_path, array( $origin => $spacing_scale ) ); } } $scale_path = array( 'settings', 'spacing', 'spacingScale', $origin ); $spacing_scale = _wp_array_get( $this->theme_json, $scale_path, null ); if ( isset( $spacing_scale ) ) { $sizes_path = array( 'settings', 'spacing', 'spacingSizes', $origin ); $spacing_sizes = _wp_array_get( $this->theme_json, $sizes_path, array() ); $spacing_scale_sizes = static::compute_spacing_sizes( $spacing_scale ); $merged_spacing_sizes = static::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); _wp_array_set( $this->theme_json, $sizes_path, $merged_spacing_sizes ); } } private static function unwrap_shared_block_style_variations( $theme_json, $valid_variations ) { if ( empty( $theme_json['styles']['variations'] ) || empty( $valid_variations ) ) { return $theme_json; } $new_theme_json = $theme_json; $variations = $new_theme_json['styles']['variations']; foreach ( $valid_variations as $block_type => $registered_variations ) { foreach ( $registered_variations as $variation_name ) { $block_level_data = $new_theme_json['styles']['blocks'][ $block_type ]['variations'][ $variation_name ] ?? array(); $top_level_data = $variations[ $variation_name ] ?? array(); $merged_data = array_replace_recursive( $top_level_data, $block_level_data ); if ( ! empty( $merged_data ) ) { _wp_array_set( $new_theme_json, array( 'styles', 'blocks', $block_type, 'variations', $variation_name ), $merged_data ); } } } unset( $new_theme_json['styles']['variations'] ); return $new_theme_json; } protected static function maybe_opt_in_into_settings( $theme_json ) { $new_theme_json = $theme_json; if ( isset( $new_theme_json['settings']['appearanceTools'] ) && true === $new_theme_json['settings']['appearanceTools'] ) { static::do_opt_in_into_settings( $new_theme_json['settings'] ); } if ( isset( $new_theme_json['settings']['blocks'] ) && is_array( $new_theme_json['settings']['blocks'] ) ) { foreach ( $new_theme_json['settings']['blocks'] as &$block ) { if ( isset( $block['appearanceTools'] ) && ( true === $block['appearanceTools'] ) ) { static::do_opt_in_into_settings( $block ); } } } return $new_theme_json; } protected static function do_opt_in_into_settings( &$context ) { foreach ( static::APPEARANCE_TOOLS_OPT_INS as $path ) { if ( 'unset prop' === _wp_array_get( $context, $path, 'unset prop' ) ) { _wp_array_set( $context, $path, true ); } } unset( $context['appearanceTools'] ); } protected static function sanitize( $input, $valid_block_names, $valid_element_names, $valid_variations ) { $output = array(); if ( ! is_array( $input ) ) { return $output; } $output = array_intersect_key( $input, array_flip( static::VALID_TOP_LEVEL_KEYS ) ); $styles_non_top_level = static::VALID_STYLES; foreach ( array_keys( $styles_non_top_level ) as $section ) { if ( array_key_exists( $section, $styles_non_top_level ) && is_array( $styles_non_top_level[ $section ] ) ) { foreach ( array_keys( $styles_non_top_level[ $section ] ) as $prop ) { if ( 'top' === $styles_non_top_level[ $section ][ $prop ] ) { unset( $styles_non_top_level[ $section ][ $prop ] ); } } } } $schema = array(); $schema_styles_elements = array(); foreach ( $valid_element_names as $element ) { $schema_styles_elements[ $element ] = $styles_non_top_level; if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { $schema_styles_elements[ $element ][ $pseudo_selector ] = $styles_non_top_level; } } } $schema_styles_blocks = array(); $schema_settings_blocks = array(); foreach ( $valid_block_names as $block ) { $schema_settings_blocks[ $block ] = static::VALID_SETTINGS; $schema_styles_blocks[ $block ] = $styles_non_top_level; $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements; } $block_style_variation_styles = static::VALID_STYLES; $block_style_variation_styles['blocks'] = $schema_styles_blocks; $block_style_variation_styles['elements'] = $schema_styles_elements; foreach ( $valid_block_names as $block ) { $style_variation_names = array(); if ( ! empty( $input['styles']['blocks'][ $block ]['variations'] ) && is_array( $input['styles']['blocks'][ $block ]['variations'] ) && isset( $valid_variations[ $block ] ) ) { $style_variation_names = array_intersect( array_keys( $input['styles']['blocks'][ $block ]['variations'] ), $valid_variations[ $block ] ); } $schema_styles_variations = array(); if ( ! empty( $style_variation_names ) ) { $schema_styles_variations = array_fill_keys( $style_variation_names, $block_style_variation_styles ); } $schema_styles_blocks[ $block ]['variations'] = $schema_styles_variations; } $schema['styles'] = static::VALID_STYLES; $schema['styles']['blocks'] = $schema_styles_blocks; $schema['styles']['elements'] = $schema_styles_elements; $schema['settings'] = static::VALID_SETTINGS; $schema['settings']['blocks'] = $schema_settings_blocks; $schema['settings']['typography']['fontFamilies'] = static::schema_in_root_and_per_origin( static::FONT_FAMILY_SCHEMA ); foreach ( array( 'styles', 'settings' ) as $subtree ) { if ( ! isset( $input[ $subtree ] ) ) { continue; } if ( ! is_array( $input[ $subtree ] ) ) { unset( $output[ $subtree ] ); continue; } $result = static::remove_keys_not_in_schema( $input[ $subtree ], $schema[ $subtree ] ); if ( empty( $result ) ) { unset( $output[ $subtree ] ); } else { $output[ $subtree ] = static::resolve_custom_css_format( $result ); } } return $output; } protected static function append_to_selector( $selector, $to_append ) { if ( ! str_contains( $selector, ',' ) ) { return $selector . $to_append; } $new_selectors = array(); $selectors = explode( ',', $selector ); foreach ( $selectors as $sel ) { $new_selectors[] = $sel . $to_append; } return implode( ',', $new_selectors ); } protected static function prepend_to_selector( $selector, $to_prepend ) { if ( ! str_contains( $selector, ',' ) ) { return $to_prepend . $selector; } $new_selectors = array(); $selectors = explode( ',', $selector ); foreach ( $selectors as $sel ) { $new_selectors[] = $to_prepend . $sel; } return implode( ',', $new_selectors ); } protected static function get_blocks_metadata() { $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); $style_registry = WP_Block_Styles_Registry::get_instance(); $blocks = array_diff_key( $blocks, static::$blocks_metadata ); if ( empty( $blocks ) ) { $registered_styles = $style_registry->get_all_registered(); foreach ( static::$blocks_metadata as $block_name => $block_metadata ) { if ( ! empty( $registered_styles[ $block_name ] ) ) { $style_selectors = $block_metadata['styleVariations'] ?? array(); foreach ( $registered_styles[ $block_name ] as $block_style ) { if ( ! isset( $style_selectors[ $block_style['name'] ] ) ) { $style_selectors[ $block_style['name'] ] = static::get_block_style_variation_selector( $block_style['name'], $block_metadata['selector'] ); } } static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors; } } return static::$blocks_metadata; } foreach ( $blocks as $block_name => $block_type ) { $root_selector = wp_get_block_css_selector( $block_type ); static::$blocks_metadata[ $block_name ]['selector'] = $root_selector; static::$blocks_metadata[ $block_name ]['selectors'] = static::get_block_selectors( $block_type, $root_selector ); $elements = static::get_block_element_selectors( $root_selector ); if ( ! empty( $elements ) ) { static::$blocks_metadata[ $block_name ]['elements'] = $elements; } $duotone_selector = wp_get_block_css_selector( $block_type, 'filter.duotone' ); if ( null === $duotone_selector ) { $duotone_support = isset( $block_type->supports['color']['__experimentalDuotone'] ) ? $block_type->supports['color']['__experimentalDuotone'] : null; if ( $duotone_support ) { $root_selector = wp_get_block_css_selector( $block_type ); $duotone_selector = static::scope_selector( $root_selector, $duotone_support ); } } if ( null !== $duotone_selector ) { static::$blocks_metadata[ $block_name ]['duotone'] = $duotone_selector; } $style_selectors = array(); if ( ! empty( $block_type->styles ) ) { foreach ( $block_type->styles as $style ) { $style_selectors[ $style['name'] ] = static::get_block_style_variation_selector( $style['name'], static::$blocks_metadata[ $block_name ]['selector'] ); } } $registered_styles = $style_registry->get_registered_styles_for_block( $block_name ); foreach ( $registered_styles as $style ) { $style_selectors[ $style['name'] ] = static::get_block_style_variation_selector( $style['name'], static::$blocks_metadata[ $block_name ]['selector'] ); } if ( ! empty( $style_selectors ) ) { static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors; } } return static::$blocks_metadata; } protected static function remove_keys_not_in_schema( $tree, $schema ) { if ( ! is_array( $tree ) ) { return $tree; } foreach ( $tree as $key => $value ) { if ( ! array_key_exists( $key, $schema ) ) { unset( $tree[ $key ] ); continue; } if ( is_array( $schema[ $key ] ) ) { if ( ! is_array( $value ) ) { unset( $tree[ $key ] ); } elseif ( wp_is_numeric_array( $value ) ) { foreach ( $value as $item_key => $item_value ) { if ( isset( $schema[ $key ][0] ) && is_array( $schema[ $key ][0] ) ) { $tree[ $key ][ $item_key ] = self::remove_keys_not_in_schema( $item_value, $schema[ $key ][0] ); } else { $tree[ $key ][ $item_key ] = $item_value; } } } else { $tree[ $key ] = self::remove_keys_not_in_schema( $value, $schema[ $key ] ); if ( empty( $tree[ $key ] ) ) { unset( $tree[ $key ] ); } } } } return $tree; } public function get_settings() { if ( ! isset( $this->theme_json['settings'] ) ) { return array(); } else { return $this->theme_json['settings']; } } public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = null, $options = array() ) { if ( null === $origins ) { $origins = static::VALID_ORIGINS; } if ( is_string( $types ) ) { _deprecated_argument( __FUNCTION__, '5.9.0' ); if ( 'block_styles' === $types ) { $types = array( 'styles', 'presets' ); } elseif ( 'css_variables' === $types ) { $types = array( 'variables' ); } else { $types = array( 'variables', 'styles', 'presets' ); } } $blocks_metadata = static::get_blocks_metadata(); $style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata, $options ); $setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata ); $root_style_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $style_nodes, 'selector' ), true ); $root_settings_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $setting_nodes, 'selector' ), true ); if ( ! empty( $options['scope'] ) ) { foreach ( $setting_nodes as &$node ) { $node['selector'] = static::scope_selector( $options['scope'], $node['selector'] ); } foreach ( $style_nodes as &$node ) { $node = static::scope_style_node_selectors( $options['scope'], $node ); } unset( $node ); } if ( ! empty( $options['root_selector'] ) ) { if ( false !== $root_settings_key ) { $setting_nodes[ $root_settings_key ]['selector'] = $options['root_selector']; } if ( false !== $root_style_key ) { $style_nodes[ $root_style_key ]['selector'] = $options['root_selector']; } } $stylesheet = ''; if ( in_array( 'variables', $types, true ) ) { $stylesheet .= $this->get_css_variables( $setting_nodes, $origins ); } if ( in_array( 'styles', $types, true ) ) { if ( false !== $root_style_key && empty( $options['skip_root_layout_styles'] ) ) { $stylesheet .= $this->get_root_layout_rules( $style_nodes[ $root_style_key ]['selector'], $style_nodes[ $root_style_key ] ); } $stylesheet .= $this->get_block_classes( $style_nodes ); } elseif ( in_array( 'base-layout-styles', $types, true ) ) { $root_selector = static::ROOT_BLOCK_SELECTOR; $columns_selector = '.wp-block-columns'; $post_template_selector = '.wp-block-post-template'; if ( ! empty( $options['scope'] ) ) { $root_selector = static::scope_selector( $options['scope'], $root_selector ); $columns_selector = static::scope_selector( $options['scope'], $columns_selector ); $post_template_selector = static::scope_selector( $options['scope'], $post_template_selector ); } if ( ! empty( $options['root_selector'] ) ) { $root_selector = $options['root_selector']; } $base_styles_nodes = array( array( 'path' => array( 'styles' ), 'selector' => $root_selector, ), array( 'path' => array( 'styles', 'blocks', 'core/columns' ), 'selector' => $columns_selector, 'name' => 'core/columns', ), array( 'path' => array( 'styles', 'blocks', 'core/post-template' ), 'selector' => $post_template_selector, 'name' => 'core/post-template', ), ); foreach ( $base_styles_nodes as $base_style_node ) { $stylesheet .= $this->get_layout_styles( $base_style_node, $types ); } } if ( in_array( 'presets', $types, true ) ) { $stylesheet .= $this->get_preset_classes( $setting_nodes, $origins ); } if ( in_array( 'custom-css', $types, true ) ) { $stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) ); } return $stylesheet; } protected function process_blocks_custom_css( $css, $selector ) { $processed_css = ''; if ( empty( $css ) ) { return $processed_css; } $parts = explode( '&', $css ); foreach ( $parts as $part ) { if ( empty( $part ) ) { continue; } $is_root_css = ( ! str_contains( $part, '{' ) ); if ( $is_root_css ) { $processed_css .= ':root :where(' . trim( $selector ) . '){' . trim( $part ) . '}'; } else { $part = explode( '{', str_replace( '}', '', $part ) ); if ( count( $part ) !== 2 ) { continue; } $nested_selector = $part[0]; $css_value = $part[1]; $matches = array(); $has_pseudo_element = preg_match( '/([>+~\s]*::[a-zA-Z-]+)/', $nested_selector, $matches ); $pseudo_part = $has_pseudo_element ? $matches[1] : ''; $nested_selector = $has_pseudo_element ? str_replace( $pseudo_part, '', $nested_selector ) : $nested_selector; $part_selector = str_starts_with( $nested_selector, ' ' ) ? static::scope_selector( $selector, $nested_selector ) : static::append_to_selector( $selector, $nested_selector ); $final_selector = ":root :where($part_selector)$pseudo_part"; $processed_css .= $final_selector . '{' . trim( $css_value ) . '}'; } } return $processed_css; } public function get_custom_css() { _deprecated_function( __METHOD__, '6.7.0', 'get_stylesheet' ); $stylesheet = isset( $this->theme_json['styles']['css'] ) ? $this->theme_json['styles']['css'] : ''; if ( isset( $this->theme_json['styles']['blocks'] ) ) { foreach ( $this->theme_json['styles']['blocks'] as $name => $node ) { $custom_block_css = isset( $this->theme_json['styles']['blocks'][ $name ]['css'] ) ? $this->theme_json['styles']['blocks'][ $name ]['css'] : null; if ( $custom_block_css ) { $selector = static::$blocks_metadata[ $name ]['selector']; $stylesheet .= $this->process_blocks_custom_css( $custom_block_css, $selector ); } } } return $stylesheet; } public function get_custom_templates() { $custom_templates = array(); if ( ! isset( $this->theme_json['customTemplates'] ) || ! is_array( $this->theme_json['customTemplates'] ) ) { return $custom_templates; } foreach ( $this->theme_json['customTemplates'] as $item ) { if ( isset( $item['name'] ) ) { $custom_templates[ $item['name'] ] = array( 'title' => isset( $item['title'] ) ? $item['title'] : '', 'postTypes' => isset( $item['postTypes'] ) ? $item['postTypes'] : array( 'page' ), ); } } return $custom_templates; } public function get_template_parts() { $template_parts = array(); if ( ! isset( $this->theme_json['templateParts'] ) || ! is_array( $this->theme_json['templateParts'] ) ) { return $template_parts; } foreach ( $this->theme_json['templateParts'] as $item ) { if ( isset( $item['name'] ) ) { $template_parts[ $item['name'] ] = array( 'title' => isset( $item['title'] ) ? $item['title'] : '', 'area' => isset( $item['area'] ) ? $item['area'] : '', ); } } return $template_parts; } protected function get_block_classes( $style_nodes ) { $block_rules = ''; foreach ( $style_nodes as $metadata ) { if ( null === $metadata['selector'] ) { continue; } $block_rules .= static::get_styles_for_block( $metadata ); } return $block_rules; } protected function get_layout_styles( $block_metadata, $types = array() ) { $block_rules = ''; $block_type = null; if ( current_theme_supports( 'disable-layout-styles' ) ) { return $block_rules; } if ( isset( $block_metadata['name'] ) ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_metadata['name'] ); if ( ! block_has_support( $block_type, 'layout', false ) && ! block_has_support( $block_type, '__experimentalLayout', false ) ) { return $block_rules; } } $selector = isset( $block_metadata['selector'] ) ? $block_metadata['selector'] : ''; $has_block_gap_support = isset( $this->theme_json['settings']['spacing']['blockGap'] ); $has_fallback_gap_support = ! $has_block_gap_support; $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); $layout_definitions = wp_get_layout_definitions(); $layout_selector_pattern = '/^[a-zA-Z0-9\-\.\,\ *+>:\(\)]*$/'; if ( $has_block_gap_support || $has_fallback_gap_support ) { $block_gap_value = null; if ( ! $has_block_gap_support ) { $block_gap_value = static::ROOT_BLOCK_SELECTOR === $selector ? '0.5em' : null; if ( ! empty( $block_type ) ) { $block_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) ? $block_type->supports['spacing']['blockGap']['__experimentalDefault'] : null; } } else { $block_gap_value = static::get_property_value( $node, array( 'spacing', 'blockGap' ) ); } if ( is_array( $block_gap_value ) ) { if ( isset( $block_gap_value['top'] ) && isset( $block_gap_value['left'] ) ) { $gap_row = static::get_property_value( $node, array( 'spacing', 'blockGap', 'top' ) ); $gap_column = static::get_property_value( $node, array( 'spacing', 'blockGap', 'left' ) ); $block_gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column; } else { $block_gap_value = null; } } if ( null !== $block_gap_value && false !== $block_gap_value && '' !== $block_gap_value ) { foreach ( $layout_definitions as $layout_definition_key => $layout_definition ) { if ( ! $has_block_gap_support && 'flex' !== $layout_definition_key && 'grid' !== $layout_definition_key ) { continue; } $class_name = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false; $spacing_rules = isset( $layout_definition['spacingStyles'] ) ? $layout_definition['spacingStyles'] : array(); if ( ! empty( $class_name ) && ! empty( $spacing_rules ) ) { foreach ( $spacing_rules as $spacing_rule ) { $declarations = array(); if ( isset( $spacing_rule['selector'] ) && preg_match( $layout_selector_pattern, $spacing_rule['selector'] ) && ! empty( $spacing_rule['rules'] ) ) { foreach ( $spacing_rule['rules'] as $css_property => $css_value ) { $current_css_value = is_string( $css_value ) ? $css_value : $block_gap_value; if ( static::is_safe_css_declaration( $css_property, $current_css_value ) ) { $declarations[] = array( 'name' => $css_property, 'value' => $current_css_value, ); } } if ( ! $has_block_gap_support ) { $format = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(.%2$s%3$s)' : ':where(%1$s.%2$s%3$s)'; $layout_selector = sprintf( $format, $selector, $class_name, $spacing_rule['selector'] ); } else { $format = static::ROOT_BLOCK_SELECTOR === $selector ? ':root :where(.%2$s)%3$s' : ':root :where(%1$s-%2$s)%3$s'; $layout_selector = sprintf( $format, $selector, $class_name, $spacing_rule['selector'] ); } $block_rules .= static::to_ruleset( $layout_selector, $declarations ); } } } } } } if ( static::ROOT_BLOCK_SELECTOR === $selector ) { $valid_display_modes = array( 'block', 'flex', 'grid' ); foreach ( $layout_definitions as $layout_definition ) { $class_name = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false; $base_style_rules = isset( $layout_definition['baseStyles'] ) ? $layout_definition['baseStyles'] : array(); if ( ! empty( $class_name ) && is_array( $base_style_rules ) ) { if ( ! empty( $layout_definition['displayMode'] ) && is_string( $layout_definition['displayMode'] ) && in_array( $layout_definition['displayMode'], $valid_display_modes, true ) ) { $layout_selector = sprintf( '%s .%s', $selector, $class_name ); $block_rules .= static::to_ruleset( $layout_selector, array( array( 'name' => 'display', 'value' => $layout_definition['displayMode'], ), ) ); } foreach ( $base_style_rules as $base_style_rule ) { $declarations = array(); if ( in_array( 'base-layout-styles', $types, true ) && ( 'default' === $layout_definition['name'] || 'constrained' === $layout_definition['name'] ) ) { continue; } if ( isset( $base_style_rule['selector'] ) && preg_match( $layout_selector_pattern, $base_style_rule['selector'] ) && ! empty( $base_style_rule['rules'] ) ) { foreach ( $base_style_rule['rules'] as $css_property => $css_value ) { if ( is_string( $css_value ) && ( str_contains( $css_value, '--global--content-size' ) || str_contains( $css_value, '--global--wide-size' ) ) && ! isset( $this->theme_json['settings']['layout']['contentSize'] ) && ! isset( $this->theme_json['settings']['layout']['wideSize'] ) ) { continue; } if ( static::is_safe_css_declaration( $css_property, $css_value ) ) { $declarations[] = array( 'name' => $css_property, 'value' => $css_value, ); } } $layout_selector = sprintf( '.%s%s', $class_name, $base_style_rule['selector'] ); $block_rules .= static::to_ruleset( $layout_selector, $declarations ); } } } } } return $block_rules; } protected function get_preset_classes( $setting_nodes, $origins ) { $preset_rules = ''; foreach ( $setting_nodes as $metadata ) { if ( null === $metadata['selector'] ) { continue; } $selector = $metadata['selector']; $node = _wp_array_get( $this->theme_json, $metadata['path'], array() ); $preset_rules .= static::compute_preset_classes( $node, $selector, $origins ); } return $preset_rules; } protected function get_css_variables( $nodes, $origins ) { $stylesheet = ''; foreach ( $nodes as $metadata ) { if ( null === $metadata['selector'] ) { continue; } $selector = $metadata['selector']; $node = _wp_array_get( $this->theme_json, $metadata['path'], array() ); $declarations = static::compute_preset_vars( $node, $origins ); $theme_vars_declarations = static::compute_theme_vars( $node ); foreach ( $theme_vars_declarations as $theme_vars_declaration ) { $declarations[] = $theme_vars_declaration; } $stylesheet .= static::to_ruleset( $selector, $declarations ); } return $stylesheet; } protected static function to_ruleset( $selector, $declarations ) { if ( empty( $declarations ) ) { return ''; } $declaration_block = array_reduce( $declarations, static function ( $carry, $element ) { return $carry .= $element['name'] . ': ' . $element['value'] . ';'; }, '' ); return $selector . '{' . $declaration_block . '}'; } protected static function compute_preset_classes( $settings, $selector, $origins ) { if ( static::ROOT_BLOCK_SELECTOR === $selector || static::ROOT_CSS_PROPERTIES_SELECTOR === $selector ) { $selector = ''; } $stylesheet = ''; foreach ( static::PRESETS_METADATA as $preset_metadata ) { if ( empty( $preset_metadata['classes'] ) ) { continue; } $slugs = static::get_settings_slugs( $settings, $preset_metadata, $origins ); foreach ( $preset_metadata['classes'] as $class => $property ) { foreach ( $slugs as $slug ) { $css_var = static::replace_slug_in_string( $preset_metadata['css_vars'], $slug ); $class_name = static::replace_slug_in_string( $class, $slug ); $new_selector = '' === $selector ? $class_name : static::append_to_selector( $selector, $class_name ); $stylesheet .= static::to_ruleset( $new_selector, array( array( 'name' => $property, 'value' => 'var(' . $css_var . ') !important', ), ) ); } } } return $stylesheet; } public static function scope_selector( $scope, $selector ) { if ( ! $scope || ! $selector ) { return $selector; } $scopes = explode( ',', $scope ); $selectors = explode( ',', $selector ); $selectors_scoped = array(); foreach ( $scopes as $outer ) { foreach ( $selectors as $inner ) { $outer = trim( $outer ); $inner = trim( $inner ); if ( ! empty( $outer ) && ! empty( $inner ) ) { $selectors_scoped[] = $outer . ' ' . $inner; } elseif ( empty( $outer ) ) { $selectors_scoped[] = $inner; } elseif ( empty( $inner ) ) { $selectors_scoped[] = $outer; } } } $result = implode( ', ', $selectors_scoped ); return $result; } protected static function scope_style_node_selectors( $scope, $node ) { $node['selector'] = static::scope_selector( $scope, $node['selector'] ); if ( empty( $node['selectors'] ) ) { return $node; } foreach ( $node['selectors'] as $feature => $selector ) { if ( is_string( $selector ) ) { $node['selectors'][ $feature ] = static::scope_selector( $scope, $selector ); } if ( is_array( $selector ) ) { foreach ( $selector as $subfeature => $subfeature_selector ) { $node['selectors'][ $feature ][ $subfeature ] = static::scope_selector( $scope, $subfeature_selector ); } } } return $node; } protected static function get_settings_values_by_slug( $settings, $preset_metadata, $origins ) { $preset_per_origin = _wp_array_get( $settings, $preset_metadata['path'], array() ); $result = array(); foreach ( $origins as $origin ) { if ( ! isset( $preset_per_origin[ $origin ] ) ) { continue; } foreach ( $preset_per_origin[ $origin ] as $preset ) { $slug = _wp_to_kebab_case( $preset['slug'] ); $value = ''; if ( isset( $preset_metadata['value_key'], $preset[ $preset_metadata['value_key'] ] ) ) { $value_key = $preset_metadata['value_key']; $value = $preset[ $value_key ]; } elseif ( isset( $preset_metadata['value_func'] ) && is_callable( $preset_metadata['value_func'] ) ) { $value_func = $preset_metadata['value_func']; $value = call_user_func( $value_func, $preset, $settings ); } else { continue; } $result[ $slug ] = $value; } } return $result; } protected static function get_settings_slugs( $settings, $preset_metadata, $origins = null ) { if ( null === $origins ) { $origins = static::VALID_ORIGINS; } $preset_per_origin = _wp_array_get( $settings, $preset_metadata['path'], array() ); $result = array(); foreach ( $origins as $origin ) { if ( ! isset( $preset_per_origin[ $origin ] ) ) { continue; } foreach ( $preset_per_origin[ $origin ] as $preset ) { $slug = _wp_to_kebab_case( $preset['slug'] ); $result[ $slug ] = $slug; } } return $result; } protected static function replace_slug_in_string( $input, $slug ) { return strtr( $input, array( '$slug' => $slug ) ); } protected static function compute_preset_vars( $settings, $origins ) { $declarations = array(); foreach ( static::PRESETS_METADATA as $preset_metadata ) { if ( empty( $preset_metadata['css_vars'] ) ) { continue; } $values_by_slug = static::get_settings_values_by_slug( $settings, $preset_metadata, $origins ); foreach ( $values_by_slug as $slug => $value ) { $declarations[] = array( 'name' => static::replace_slug_in_string( $preset_metadata['css_vars'], $slug ), 'value' => $value, ); } } return $declarations; } protected static function compute_theme_vars( $settings ) { $declarations = array(); $custom_values = isset( $settings['custom'] ) ? $settings['custom'] : array(); $css_vars = static::flatten_tree( $custom_values ); foreach ( $css_vars as $key => $value ) { $declarations[] = array( 'name' => '--wp--custom--' . $key, 'value' => $value, ); } return $declarations; } protected static function flatten_tree( $tree, $prefix = '', $token = '--' ) { $result = array(); foreach ( $tree as $property => $value ) { $new_key = $prefix . str_replace( '/', '-', strtolower( _wp_to_kebab_case( $property ) ) ); if ( is_array( $value ) ) { $new_prefix = $new_key . $token; $flattened_subtree = static::flatten_tree( $value, $new_prefix, $token ); foreach ( $flattened_subtree as $subtree_key => $subtree_value ) { $result[ $subtree_key ] = $subtree_value; } } else { $result[ $new_key ] = $value; } } return $result; } protected static function compute_style_properties( $styles, $settings = array(), $properties = null, $theme_json = null, $selector = null, $use_root_padding = null ) { if ( empty( $styles ) ) { return array(); } if ( null === $properties ) { $properties = static::PROPERTIES_METADATA; } $declarations = array(); $root_variable_duplicates = array(); $root_style_length = strlen( '--wp--style--root--' ); foreach ( $properties as $css_property => $value_path ) { if ( ! is_array( $value_path ) ) { continue; } $is_root_style = str_starts_with( $css_property, '--wp--style--root--' ); if ( $is_root_style && ( static::ROOT_BLOCK_SELECTOR !== $selector || ! $use_root_padding ) ) { continue; } $value = static::get_property_value( $styles, $value_path, $theme_json ); if ( '--wp--style--root--padding' === $css_property && is_string( $value ) ) { continue; } if ( $is_root_style && $use_root_padding ) { $root_variable_duplicates[] = substr( $css_property, $root_style_length ); } if ( 'background-image' === $css_property && ! empty( $value ) ) { $background_styles = wp_style_engine_get_styles( array( 'background' => array( 'backgroundImage' => $value ) ) ); $value = $background_styles['declarations'][ $css_property ]; } if ( empty( $value ) && static::ROOT_BLOCK_SELECTOR !== $selector && ! empty( $styles['background']['backgroundImage']['id'] ) ) { if ( 'background-size' === $css_property ) { $value = 'cover'; } if ( 'background-position' === $css_property ) { $background_size = $styles['background']['backgroundSize'] ?? null; $value = 'contain' === $background_size ? '50% 50%' : null; } } $has_missing_value = empty( $value ) && ! is_numeric( $value ); if ( $has_missing_value || is_array( $value ) ) { continue; } $path_string = implode( '.', $value_path ); if ( isset( static::PROTECTED_PROPERTIES[ $path_string ] ) && _wp_array_get( $settings, static::PROTECTED_PROPERTIES[ $path_string ], null ) === null ) { continue; } if ( 'font-size' === $css_property ) { $value = wp_get_typography_font_size_value( array( 'size' => $value ), $settings ); } if ( 'aspect-ratio' === $css_property ) { $declarations[] = array( 'name' => 'min-height', 'value' => 'unset', ); } $declarations[] = array( 'name' => $css_property, 'value' => $value, ); } foreach ( $root_variable_duplicates as $duplicate ) { $discard = array_search( $duplicate, array_column( $declarations, 'name' ), true ); if ( is_numeric( $discard ) ) { array_splice( $declarations, $discard, 1 ); } } return $declarations; } protected static function get_property_value( $styles, $path, $theme_json = null ) { $value = _wp_array_get( $styles, $path, '' ); if ( '' === $value || null === $value ) { return ''; } if ( is_array( $value ) && isset( $value['ref'] ) ) { $value_path = explode( '.', $value['ref'] ); $ref_value = _wp_array_get( $theme_json, $value_path ); $ref_value_url = $ref_value['url'] ?? null; if ( ! empty( $ref_value ) && ( is_string( $ref_value ) || is_string( $ref_value_url ) ) ) { $value = $ref_value; } if ( is_array( $ref_value ) && isset( $ref_value['ref'] ) ) { $path_string = json_encode( $path ); $ref_value_string = json_encode( $ref_value ); _doing_it_wrong( 'get_property_value', sprintf( __( 'Your %1$s file uses a dynamic value (%2$s) for the path at %3$s. However, the value at %3$s is also a dynamic value (pointing to %4$s) and pointing to another dynamic value is not supported. Please update %3$s to point directly to %4$s.' ), 'theme.json', $ref_value_string, $path_string, $ref_value['ref'] ), '6.1.0' ); } } if ( is_array( $value ) ) { return $value; } return $value; } protected static function get_setting_nodes( $theme_json, $selectors = array() ) { $nodes = array(); if ( ! isset( $theme_json['settings'] ) ) { return $nodes; } $nodes[] = array( 'path' => array( 'settings' ), 'selector' => static::ROOT_CSS_PROPERTIES_SELECTOR, ); if ( ! isset( $theme_json['settings']['blocks'] ) ) { return $nodes; } foreach ( $theme_json['settings']['blocks'] as $name => $node ) { $selector = null; if ( isset( $selectors[ $name ]['selector'] ) ) { $selector = $selectors[ $name ]['selector']; } $nodes[] = array( 'path' => array( 'settings', 'blocks', $name ), 'selector' => $selector, ); } return $nodes; } protected static function get_style_nodes( $theme_json, $selectors = array(), $options = array() ) { $nodes = array(); if ( ! isset( $theme_json['styles'] ) ) { return $nodes; } $nodes[] = array( 'path' => array( 'styles' ), 'selector' => static::ROOT_BLOCK_SELECTOR, ); if ( isset( $theme_json['styles']['elements'] ) ) { foreach ( self::ELEMENTS as $element => $selector ) { if ( ! isset( $theme_json['styles']['elements'][ $element ] ) ) { continue; } $nodes[] = array( 'path' => array( 'styles', 'elements', $element ), 'selector' => static::ELEMENTS[ $element ], ); if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { if ( isset( $theme_json['styles']['elements'][ $element ][ $pseudo_selector ] ) ) { $nodes[] = array( 'path' => array( 'styles', 'elements', $element ), 'selector' => static::append_to_selector( static::ELEMENTS[ $element ], $pseudo_selector ), ); } } } } } if ( ! isset( $theme_json['styles']['blocks'] ) ) { return $nodes; } $block_nodes = static::get_block_nodes( $theme_json, $selectors, $options ); foreach ( $block_nodes as $block_node ) { $nodes[] = $block_node; } return apply_filters( 'wp_theme_json_get_style_nodes', $nodes ); } public function get_styles_block_nodes() { return static::get_block_nodes( $this->theme_json ); } private static function update_separator_declarations( $declarations ) { $background_color = ''; $border_color_matches = false; $text_color_matches = false; foreach ( $declarations as $declaration ) { if ( 'background-color' === $declaration['name'] && ! $background_color && isset( $declaration['value'] ) ) { $background_color = $declaration['value']; } elseif ( 'border-color' === $declaration['name'] ) { $border_color_matches = true; } elseif ( 'color' === $declaration['name'] ) { $text_color_matches = true; } if ( $background_color && $border_color_matches && $text_color_matches ) { break; } } if ( $background_color && ! $border_color_matches && ! $text_color_matches ) { $declarations[] = array( 'name' => 'color', 'value' => $background_color, ); } return $declarations; } private static function get_block_nodes( $theme_json, $selectors = array(), $options = array() ) { $nodes = array(); if ( ! isset( $theme_json['styles']['blocks'] ) ) { return $nodes; } $include_variations = $options['include_block_style_variations'] ?? false; $include_node_paths_only = $options['include_node_paths_only'] ?? false; if ( ! $include_node_paths_only ) { $selectors = empty( $selectors ) ? static::get_blocks_metadata() : $selectors; } foreach ( $theme_json['styles']['blocks'] as $name => $node ) { $node_path = array( 'styles', 'blocks', $name ); if ( $include_node_paths_only ) { $variation_paths = array(); if ( $include_variations && isset( $node['variations'] ) ) { foreach ( $node['variations'] as $variation => $variation_node ) { $variation_paths[] = array( 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), ); } } $node = array( 'path' => $node_path, ); if ( ! empty( $variation_paths ) ) { $node['variations'] = $variation_paths; } $nodes[] = $node; } else { $selector = null; if ( isset( $selectors[ $name ]['selector'] ) ) { $selector = $selectors[ $name ]['selector']; } $duotone_selector = null; if ( isset( $selectors[ $name ]['duotone'] ) ) { $duotone_selector = $selectors[ $name ]['duotone']; } $feature_selectors = null; if ( isset( $selectors[ $name ]['selectors'] ) ) { $feature_selectors = $selectors[ $name ]['selectors']; } $variation_selectors = array(); if ( $include_variations && isset( $node['variations'] ) ) { foreach ( $node['variations'] as $variation => $node ) { $variation_selectors[] = array( 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), 'selector' => $selectors[ $name ]['styleVariations'][ $variation ], ); } } $nodes[] = array( 'name' => $name, 'path' => $node_path, 'selector' => $selector, 'selectors' => $feature_selectors, 'duotone' => $duotone_selector, 'features' => $feature_selectors, 'variations' => $variation_selectors, 'css' => $selector, ); } if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) { $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); if ( $include_node_paths_only ) { $nodes[] = array( 'path' => $node_path, ); continue; } $nodes[] = array( 'path' => $node_path, 'selector' => $selectors[ $name ]['elements'][ $element ], ); if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) { $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); $nodes[] = array( 'path' => $node_path, 'selector' => static::append_to_selector( $selectors[ $name ]['elements'][ $element ], $pseudo_selector ), ); } } } } } } return $nodes; } public function get_styles_for_block( $block_metadata ) { $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments']; $selector = $block_metadata['selector']; $settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array(); $feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node ); $is_root_selector = static::ROOT_BLOCK_SELECTOR === $selector; $style_variation_declarations = array(); $style_variation_custom_css = array(); if ( ! empty( $block_metadata['variations'] ) ) { foreach ( $block_metadata['variations'] as $style_variation ) { $style_variation_node = _wp_array_get( $this->theme_json, $style_variation['path'], array() ); $clean_style_variation_selector = trim( $style_variation['selector'] ); $variation_declarations = static::get_feature_declarations_for_node( $block_metadata, $style_variation_node ); foreach ( $variation_declarations as $current_selector => $new_declarations ) { $clean_current_selector = preg_replace( '/,\s+/', ',', $current_selector ); $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_current_selector ); $split_selectors = explode( ',', $shortened_selector ); $updated_selectors = array_map( static function ( $split_selector ) use ( $clean_style_variation_selector ) { return $clean_style_variation_selector . $split_selector; }, $split_selectors ); $combined_selectors = implode( ',', $updated_selectors ); $style_variation_declarations[ $combined_selectors ] = $new_declarations; } $style_variation_declarations[ $style_variation['selector'] ] = static::compute_style_properties( $style_variation_node, $settings, null, $this->theme_json ); if ( isset( $style_variation_node['css'] ) ) { $style_variation_custom_css[ $style_variation['selector'] ] = $this->process_blocks_custom_css( $style_variation_node['css'], $style_variation['selector'] ); } } } $is_processing_element = in_array( 'elements', $block_metadata['path'], true ); $current_element = $is_processing_element ? $block_metadata['path'][ count( $block_metadata['path'] ) - 1 ] : null; $element_pseudo_allowed = array(); if ( isset( $current_element, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] ) ) { $element_pseudo_allowed = static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ]; } $pseudo_matches = array_values( array_filter( $element_pseudo_allowed, static function ( $pseudo_selector ) use ( $selector ) { return preg_match( '/' . preg_quote( $pseudo_selector, '/' ) . '(?!-)/', $selector ) === 1; } ) ); $pseudo_selector = isset( $pseudo_matches[0] ) ? $pseudo_matches[0] : null; if ( $pseudo_selector && isset( $node[ $pseudo_selector ] ) && isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] ) && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true ) ) { $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json, $selector, $use_root_padding ); } else { $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json, $selector, $use_root_padding ); } $block_rules = ''; $declarations_duotone = array(); $should_set_root_min_height = false; foreach ( $declarations as $index => $declaration ) { if ( 'filter' === $declaration['name'] ) { if ( 'unset' !== $declaration['value'] ) { $declarations_duotone[] = $declaration; } unset( $declarations[ $index ] ); } if ( $is_root_selector && ( 'background-image' === $declaration['name'] || 'background' === $declaration['name'] ) ) { $should_set_root_min_height = true; } } if ( $should_set_root_min_height ) { $block_rules .= static::to_ruleset( 'html', array( array( 'name' => 'min-height', 'value' => 'calc(100% - var(--wp-admin--admin-bar--height, 0px))', ), ) ); } if ( '.wp-block-separator' === $selector ) { $declarations = static::update_separator_declarations( $declarations ); } $element_only_selector = $is_root_selector || ( $current_element && isset( static::ELEMENTS[ $current_element ] ) && ! isset( static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $current_element ] ) && static::ELEMENTS[ $current_element ] === $selector ); $general_selector = $element_only_selector ? $selector : ":root :where($selector)"; $block_rules .= static::to_ruleset( $general_selector, $declarations ); if ( isset( $block_metadata['duotone'] ) && ! empty( $declarations_duotone ) ) { $block_rules .= static::to_ruleset( $block_metadata['duotone'], $declarations_duotone ); } if ( ! $is_root_selector && ! empty( $block_metadata['name'] ) ) { $block_rules .= $this->get_layout_styles( $block_metadata ); } foreach ( $feature_declarations as $feature_selector => $individual_feature_declarations ) { $block_rules .= static::to_ruleset( ":root :where($feature_selector)", $individual_feature_declarations ); } foreach ( $style_variation_declarations as $style_variation_selector => $individual_style_variation_declarations ) { $block_rules .= static::to_ruleset( ":root :where($style_variation_selector)", $individual_style_variation_declarations ); if ( isset( $style_variation_custom_css[ $style_variation_selector ] ) ) { $block_rules .= $style_variation_custom_css[ $style_variation_selector ]; } } if ( isset( $node['css'] ) && ! $is_root_selector ) { $block_rules .= $this->process_blocks_custom_css( $node['css'], $selector ); } return $block_rules; } public function get_root_layout_rules( $selector, $block_metadata ) { $css = ''; $settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array(); $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments']; if ( isset( $settings['layout']['contentSize'] ) || isset( $settings['layout']['wideSize'] ) ) { $content_size = isset( $settings['layout']['contentSize'] ) ? $settings['layout']['contentSize'] : $settings['layout']['wideSize']; $content_size = static::is_safe_css_declaration( 'max-width', $content_size ) ? $content_size : 'initial'; $wide_size = isset( $settings['layout']['wideSize'] ) ? $settings['layout']['wideSize'] : $settings['layout']['contentSize']; $wide_size = static::is_safe_css_declaration( 'max-width', $wide_size ) ? $wide_size : 'initial'; $css .= static::ROOT_CSS_PROPERTIES_SELECTOR . ' { --wp--style--global--content-size: ' . $content_size . ';'; $css .= '--wp--style--global--wide-size: ' . $wide_size . '; }'; } $css .= ':where(body) { margin: 0; }'; if ( $use_root_padding ) { $css .= '.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }'; $css .= '.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }'; $css .= '.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }'; $css .= '.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) { padding-right: 0; padding-left: 0; }'; $css .= '.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) > .alignfull { margin-left: 0; margin-right: 0; }'; } $css .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; $css .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; $css .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; if ( isset( $this->theme_json['settings']['spacing']['blockGap'] ) ) { $block_gap_value = static::get_property_value( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ) ); $css .= ":where(.wp-site-blocks) > * { margin-block-start: $block_gap_value; margin-block-end: 0; }"; $css .= ':where(.wp-site-blocks) > :first-child { margin-block-start: 0; }'; $css .= ':where(.wp-site-blocks) > :last-child { margin-block-end: 0; }'; $css .= static::ROOT_CSS_PROPERTIES_SELECTOR . " { --wp--style--block-gap: $block_gap_value; }"; } $css .= $this->get_layout_styles( $block_metadata ); return $css; } protected static function get_metadata_boolean( $data, $path, $default_value = false ) { if ( is_bool( $path ) ) { return $path; } if ( is_array( $path ) ) { $value = _wp_array_get( $data, $path ); if ( null !== $value ) { return $value; } } return $default_value; } public function merge( $incoming ) { $incoming_data = $incoming->get_raw_data(); $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); $flattened_spacing_scale = array(); foreach ( static::VALID_ORIGINS as $origin ) { $scale_path = array( 'settings', 'spacing', 'spacingScale', $origin ); $base_spacing_scale = _wp_array_get( $this->theme_json, $scale_path, array() ); $flattened_spacing_scale = array_replace( $flattened_spacing_scale, $base_spacing_scale ); $spacing_scale = _wp_array_get( $incoming_data, $scale_path, null ); if ( ! isset( $spacing_scale ) ) { continue; } $flattened_spacing_scale = array_replace( $flattened_spacing_scale, $spacing_scale ); $sizes_path = array( 'settings', 'spacing', 'spacingSizes', $origin ); $spacing_sizes = _wp_array_get( $incoming_data, $sizes_path, array() ); $spacing_scale_sizes = static::compute_spacing_sizes( $flattened_spacing_scale ); $merged_spacing_sizes = static::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); _wp_array_set( $incoming_data, $sizes_path, $merged_spacing_sizes ); } $nodes = static::get_setting_nodes( $incoming_data ); $slugs_global = static::get_default_slugs( $this->theme_json, array( 'settings' ) ); foreach ( $nodes as $node ) { $path = $node['path']; $path[] = 'spacing'; $path[] = 'units'; $content = _wp_array_get( $incoming_data, $path, null ); if ( isset( $content ) ) { _wp_array_set( $this->theme_json, $path, $content ); } foreach ( static::PRESETS_METADATA as $preset_metadata ) { $prevent_override = $preset_metadata['prevent_override']; if ( is_array( $prevent_override ) ) { $global_path = array_merge( array( 'settings' ), $prevent_override ); $global_value = _wp_array_get( $this->theme_json, $global_path, null ); $node_level_path = array_merge( $node['path'], $prevent_override ); $prevent_override = _wp_array_get( $this->theme_json, $node_level_path, $global_value ); } foreach ( static::VALID_ORIGINS as $origin ) { $base_path = $node['path']; foreach ( $preset_metadata['path'] as $leaf ) { $base_path[] = $leaf; } $path = $base_path; $path[] = $origin; $content = _wp_array_get( $incoming_data, $path, null ); if ( ! isset( $content ) ) { continue; } if ( 'theme' === $origin && $preset_metadata['use_default_names'] ) { foreach ( $content as $key => $item ) { if ( ! isset( $item['name'] ) ) { $name = static::get_name_from_defaults( $item['slug'], $base_path ); if ( null !== $name ) { $content[ $key ]['name'] = $name; } } } } if ( 'theme' === $origin && $prevent_override ) { $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] ); $preset_global = _wp_array_get( $slugs_global, $preset_metadata['path'], array() ); $preset_node = _wp_array_get( $slugs_node, $preset_metadata['path'], array() ); $preset_slugs = array_merge_recursive( $preset_global, $preset_node ); $content = static::filter_slugs( $content, $preset_slugs ); } _wp_array_set( $this->theme_json, $path, $content ); } } } $style_nodes = static::get_block_nodes( $this->theme_json, array(), array( 'include_node_paths_only' => true ) ); $style_nodes[] = array( 'path' => array( 'styles' ) ); foreach ( $style_nodes as $style_node ) { $path = $style_node['path']; $background_image_path = array_merge( $path, static::PROPERTIES_METADATA['background-image'] ); $content = _wp_array_get( $incoming_data, $background_image_path, null ); if ( isset( $content ) ) { _wp_array_set( $this->theme_json, $background_image_path, $content ); } } } public function get_svg_filters( $origins ) { $blocks_metadata = static::get_blocks_metadata(); $setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata ); $filters = ''; foreach ( $setting_nodes as $metadata ) { $node = _wp_array_get( $this->theme_json, $metadata['path'], array() ); if ( empty( $node['color']['duotone'] ) ) { continue; } $duotone_presets = $node['color']['duotone']; foreach ( $origins as $origin ) { if ( ! isset( $duotone_presets[ $origin ] ) ) { continue; } foreach ( $duotone_presets[ $origin ] as $duotone_preset ) { $filters .= WP_Duotone::get_filter_svg_from_preset( $duotone_preset ); } } } return $filters; } protected static function should_override_preset( $theme_json, $path, $override ) { _deprecated_function( __METHOD__, '6.0.0', 'get_metadata_boolean' ); if ( is_bool( $override ) ) { return $override; } if ( is_array( $override ) ) { $value = _wp_array_get( $theme_json, array_merge( $path, $override ) ); if ( isset( $value ) ) { return ! $value; } $value = _wp_array_get( $theme_json, array_merge( array( 'settings' ), $override ) ); if ( isset( $value ) ) { return ! $value; } return true; } } protected static function get_default_slugs( $data, $node_path ) { $slugs = array(); foreach ( static::PRESETS_METADATA as $metadata ) { $path = $node_path; foreach ( $metadata['path'] as $leaf ) { $path[] = $leaf; } $path[] = 'default'; $preset = _wp_array_get( $data, $path, null ); if ( ! isset( $preset ) ) { continue; } $slugs_for_preset = array(); foreach ( $preset as $item ) { if ( isset( $item['slug'] ) ) { $slugs_for_preset[] = $item['slug']; } } _wp_array_set( $slugs, $metadata['path'], $slugs_for_preset ); } return $slugs; } protected function get_name_from_defaults( $slug, $base_path ) { $path = $base_path; $path[] = 'default'; $default_content = _wp_array_get( $this->theme_json, $path, null ); if ( ! $default_content ) { return null; } foreach ( $default_content as $item ) { if ( $slug === $item['slug'] ) { return $item['name']; } } return null; } protected static function filter_slugs( $node, $slugs ) { if ( empty( $slugs ) ) { return $node; } $new_node = array(); foreach ( $node as $value ) { if ( isset( $value['slug'] ) && ! in_array( $value['slug'], $slugs, true ) ) { $new_node[] = $value; } } return $new_node; } public static function remove_insecure_properties( $theme_json, $origin = 'theme' ) { if ( ! in_array( $origin, static::VALID_ORIGINS, true ) ) { $origin = 'theme'; } $sanitized = array(); $theme_json = WP_Theme_JSON_Schema::migrate( $theme_json, $origin ); $blocks_metadata = static::get_blocks_metadata(); $valid_block_names = array_keys( $blocks_metadata ); $valid_element_names = array_keys( static::ELEMENTS ); $valid_variations = static::get_valid_block_style_variations( $blocks_metadata ); $theme_json = static::sanitize( $theme_json, $valid_block_names, $valid_element_names, $valid_variations ); $blocks_metadata = static::get_blocks_metadata(); $style_options = array( 'include_block_style_variations' => true ); $style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata, $style_options ); foreach ( $style_nodes as $metadata ) { $input = _wp_array_get( $theme_json, $metadata['path'], array() ); if ( empty( $input ) ) { continue; } if ( isset( $input['css'] ) && current_user_can( 'edit_css' ) ) { $output = $input; } else { $output = static::remove_insecure_styles( $input ); } $current_element = $metadata['path'][ count( $metadata['path'] ) - 1 ]; if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] as $pseudo_selector ) { if ( isset( $input[ $pseudo_selector ] ) ) { $output[ $pseudo_selector ] = static::remove_insecure_styles( $input[ $pseudo_selector ] ); } } } if ( ! empty( $output ) ) { _wp_array_set( $sanitized, $metadata['path'], $output ); } if ( isset( $metadata['variations'] ) ) { foreach ( $metadata['variations'] as $variation ) { $variation_input = _wp_array_get( $theme_json, $variation['path'], array() ); if ( empty( $variation_input ) ) { continue; } $variation_output = static::remove_insecure_styles( $variation_input ); if ( isset( $variation_input['blocks'] ) ) { $variation_output['blocks'] = static::remove_insecure_inner_block_styles( $variation_input['blocks'] ); } if ( isset( $variation_input['elements'] ) ) { $variation_output['elements'] = static::remove_insecure_element_styles( $variation_input['elements'] ); } if ( ! empty( $variation_output ) ) { _wp_array_set( $sanitized, $variation['path'], $variation_output ); } } } } $setting_nodes = static::get_setting_nodes( $theme_json ); foreach ( $setting_nodes as $metadata ) { $input = _wp_array_get( $theme_json, $metadata['path'], array() ); if ( empty( $input ) ) { continue; } $output = static::remove_insecure_settings( $input ); if ( ! empty( $output ) ) { _wp_array_set( $sanitized, $metadata['path'], $output ); } } if ( empty( $sanitized['styles'] ) ) { unset( $theme_json['styles'] ); } else { $theme_json['styles'] = $sanitized['styles']; } if ( empty( $sanitized['settings'] ) ) { unset( $theme_json['settings'] ); } else { $theme_json['settings'] = $sanitized['settings']; } return $theme_json; } protected static function remove_insecure_element_styles( $elements ) { $sanitized = array(); $valid_element_names = array_keys( static::ELEMENTS ); foreach ( $valid_element_names as $element_name ) { $element_input = $elements[ $element_name ] ?? null; if ( $element_input ) { $element_output = static::remove_insecure_styles( $element_input ); if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) { if ( isset( $element_input[ $pseudo_selector ] ) ) { $element_output[ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $pseudo_selector ] ); } } } $sanitized[ $element_name ] = $element_output; } } return $sanitized; } protected static function remove_insecure_inner_block_styles( $blocks ) { $sanitized = array(); foreach ( $blocks as $block_type => $block_input ) { $block_output = static::remove_insecure_styles( $block_input ); if ( isset( $block_input['elements'] ) ) { $block_output['elements'] = static::remove_insecure_element_styles( $block_input['elements'] ); } $sanitized[ $block_type ] = $block_output; } return $sanitized; } protected static function remove_insecure_settings( $input ) { $output = array(); foreach ( static::PRESETS_METADATA as $preset_metadata ) { foreach ( static::VALID_ORIGINS as $origin ) { $path_with_origin = $preset_metadata['path']; $path_with_origin[] = $origin; $presets = _wp_array_get( $input, $path_with_origin, null ); if ( null === $presets ) { continue; } $escaped_preset = array(); foreach ( $presets as $preset ) { if ( esc_attr( esc_html( $preset['name'] ) ) === $preset['name'] && sanitize_html_class( $preset['slug'] ) === $preset['slug'] ) { $value = null; if ( isset( $preset_metadata['value_key'], $preset[ $preset_metadata['value_key'] ] ) ) { $value = $preset[ $preset_metadata['value_key'] ]; } elseif ( isset( $preset_metadata['value_func'] ) && is_callable( $preset_metadata['value_func'] ) ) { $value = call_user_func( $preset_metadata['value_func'], $preset ); } $preset_is_valid = true; foreach ( $preset_metadata['properties'] as $property ) { if ( ! static::is_safe_css_declaration( $property, $value ) ) { $preset_is_valid = false; break; } } if ( $preset_is_valid ) { $escaped_preset[] = $preset; } } } if ( ! empty( $escaped_preset ) ) { _wp_array_set( $output, $path_with_origin, $escaped_preset ); } } } static::remove_indirect_properties( $input, $output ); return $output; } protected static function remove_insecure_styles( $input ) { $output = array(); $declarations = static::compute_style_properties( $input ); foreach ( $declarations as $declaration ) { if ( static::is_safe_css_declaration( $declaration['name'], $declaration['value'] ) ) { $path = static::PROPERTIES_METADATA[ $declaration['name'] ]; $value = _wp_array_get( $input, $path, array() ); if ( ! is_array( $value ) ) { _wp_array_set( $output, $path, $value ); } } } static::remove_indirect_properties( $input, $output ); return $output; } protected static function is_safe_css_declaration( $property_name, $property_value ) { $style_to_validate = $property_name . ': ' . $property_value; $filtered = esc_html( safecss_filter_attr( $style_to_validate ) ); return ! empty( trim( $filtered ) ); } private static function remove_indirect_properties( $input, &$output ) { foreach ( static::INDIRECT_PROPERTIES_METADATA as $property => $paths ) { foreach ( $paths as $path ) { $value = _wp_array_get( $input, $path ); if ( is_string( $value ) && static::is_safe_css_declaration( $property, $value ) ) { _wp_array_set( $output, $path, $value ); } } } } public function get_raw_data() { return $this->theme_json; } public static function get_from_editor_settings( $settings ) { $theme_settings = array( 'version' => static::LATEST_SCHEMA, 'settings' => array(), ); if ( isset( $settings['disableCustomColors'] ) ) { $theme_settings['settings']['color']['custom'] = ! $settings['disableCustomColors']; } if ( isset( $settings['disableCustomGradients'] ) ) { $theme_settings['settings']['color']['customGradient'] = ! $settings['disableCustomGradients']; } if ( isset( $settings['disableCustomFontSizes'] ) ) { $theme_settings['settings']['typography']['customFontSize'] = ! $settings['disableCustomFontSizes']; } if ( isset( $settings['enableCustomLineHeight'] ) ) { $theme_settings['settings']['typography']['lineHeight'] = $settings['enableCustomLineHeight']; } if ( isset( $settings['enableCustomUnits'] ) ) { $theme_settings['settings']['spacing']['units'] = ( true === $settings['enableCustomUnits'] ) ? array( 'px', 'em', 'rem', 'vh', 'vw', '%' ) : $settings['enableCustomUnits']; } if ( isset( $settings['colors'] ) ) { $theme_settings['settings']['color']['palette'] = $settings['colors']; } if ( isset( $settings['gradients'] ) ) { $theme_settings['settings']['color']['gradients'] = $settings['gradients']; } if ( isset( $settings['fontSizes'] ) ) { $font_sizes = $settings['fontSizes']; foreach ( $font_sizes as $key => $font_size ) { if ( is_numeric( $font_size['size'] ) ) { $font_sizes[ $key ]['size'] = $font_size['size'] . 'px'; } } $theme_settings['settings']['typography']['fontSizes'] = $font_sizes; } if ( isset( $settings['enableCustomSpacing'] ) ) { $theme_settings['settings']['spacing']['padding'] = $settings['enableCustomSpacing']; } if ( isset( $settings['spacingSizes'] ) ) { $theme_settings['settings']['spacing']['spacingSizes'] = $settings['spacingSizes']; } return $theme_settings; } public function get_patterns() { if ( isset( $this->theme_json['patterns'] ) && is_array( $this->theme_json['patterns'] ) ) { return $this->theme_json['patterns']; } return array(); } public function get_data() { $output = $this->theme_json; $nodes = static::get_setting_nodes( $output ); foreach ( $nodes as $node ) { foreach ( static::PRESETS_METADATA as $preset_metadata ) { $path = $node['path']; foreach ( $preset_metadata['path'] as $preset_metadata_path ) { $path[] = $preset_metadata_path; } $preset = _wp_array_get( $output, $path, null ); if ( null === $preset ) { continue; } $items = array(); if ( isset( $preset['theme'] ) ) { foreach ( $preset['theme'] as $item ) { $slug = $item['slug']; unset( $item['slug'] ); $items[ $slug ] = $item; } } if ( isset( $preset['custom'] ) ) { foreach ( $preset['custom'] as $item ) { $slug = $item['slug']; unset( $item['slug'] ); $items[ $slug ] = $item; } } $flattened_preset = array(); foreach ( $items as $slug => $value ) { $flattened_preset[] = array_merge( array( 'slug' => (string) $slug ), $value ); } _wp_array_set( $output, $path, $flattened_preset ); } } foreach ( $nodes as $node ) { $all_opt_ins_are_set = true; foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) { $full_path = $node['path']; foreach ( $opt_in_path as $opt_in_path_item ) { $full_path[] = $opt_in_path_item; } $opt_in_value = _wp_array_get( $output, $full_path, 'unset prop' ); if ( 'unset prop' === $opt_in_value ) { $all_opt_ins_are_set = false; break; } } if ( $all_opt_ins_are_set ) { $node_path_with_appearance_tools = $node['path']; $node_path_with_appearance_tools[] = 'appearanceTools'; _wp_array_set( $output, $node_path_with_appearance_tools, true ); foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) { $full_path = $node['path']; foreach ( $opt_in_path as $opt_in_path_item ) { $full_path[] = $opt_in_path_item; } $opt_in_value = _wp_array_get( $output, $full_path, 'unset prop' ); if ( true !== $opt_in_value ) { continue; } if ( ( 1 === count( $node['path'] ) ) && ( 'settings' === $node['path'][0] ) ) { unset( $output['settings'][ $opt_in_path[0] ][ $opt_in_path[1] ] ); if ( empty( $output['settings'][ $opt_in_path[0] ] ) ) { unset( $output['settings'][ $opt_in_path[0] ] ); } } elseif ( ( 3 === count( $node['path'] ) ) && ( 'settings' === $node['path'][0] ) && ( 'blocks' === $node['path'][1] ) ) { $block_name = $node['path'][2]; unset( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ][ $opt_in_path[1] ] ); if ( empty( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ] ) ) { unset( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ] ); } } } } } wp_recursive_ksort( $output ); return $output; } public function set_spacing_sizes() { _deprecated_function( __METHOD__, '6.6.0' ); $spacing_scale = isset( $this->theme_json['settings']['spacing']['spacingScale'] ) ? $this->theme_json['settings']['spacing']['spacingScale'] : array(); if ( ! isset( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['steps'] ) || ! isset( $spacing_scale['mediumStep'] ) || ! isset( $spacing_scale['unit'] ) || ! isset( $spacing_scale['operator'] ) || ! isset( $spacing_scale['increment'] ) || ! isset( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['increment'] ) || ! is_numeric( $spacing_scale['mediumStep'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) { if ( ! empty( $spacing_scale ) ) { wp_trigger_error( __METHOD__, sprintf( __( 'Some of the %1$s %2$s values are invalid' ), 'theme.json', 'settings.spacing.spacingScale' ), E_USER_NOTICE ); } return null; } if ( 0 === $spacing_scale['steps'] ) { return null; } $spacing_sizes = static::compute_spacing_sizes( $spacing_scale ); if ( $spacing_scale['steps'] <= 7 ) { for ( $spacing_sizes_count = 0; $spacing_sizes_count < count( $spacing_sizes ); $spacing_sizes_count++ ) { $spacing_sizes[ $spacing_sizes_count ]['name'] = (string) ( $spacing_sizes_count + 1 ); } } _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_sizes ); } private static function merge_spacing_sizes( $base, $incoming ) { if ( empty( $base ) ) { return $incoming; } $merged = array(); foreach ( $base as $item ) { $merged[ $item['slug'] ] = $item; } foreach ( $incoming as $item ) { $merged[ $item['slug'] ] = $item; } ksort( $merged, SORT_NUMERIC ); return array_values( $merged ); } private static function compute_spacing_sizes( $spacing_scale ) { if ( ! isset( $spacing_scale['steps'] ) || ! is_numeric( $spacing_scale['steps'] ) || 0 === $spacing_scale['steps'] || ! isset( $spacing_scale['mediumStep'] ) || ! is_numeric( $spacing_scale['mediumStep'] ) || ! isset( $spacing_scale['unit'] ) || ! isset( $spacing_scale['operator'] ) || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) || ! isset( $spacing_scale['increment'] ) || ! is_numeric( $spacing_scale['increment'] ) ) { return array(); } $unit = '%' === $spacing_scale['unit'] ? '%' : sanitize_title( $spacing_scale['unit'] ); $current_step = $spacing_scale['mediumStep']; $steps_mid_point = round( $spacing_scale['steps'] / 2, 0 ); $x_small_count = null; $below_sizes = array(); $slug = 40; $remainder = 0; for ( $below_midpoint_count = $steps_mid_point - 1; $spacing_scale['steps'] > 1 && $slug > 0 && $below_midpoint_count > 0; $below_midpoint_count-- ) { if ( '+' === $spacing_scale['operator'] ) { $current_step -= $spacing_scale['increment']; } elseif ( $spacing_scale['increment'] > 1 ) { $current_step /= $spacing_scale['increment']; } else { $current_step *= $spacing_scale['increment']; } if ( $current_step <= 0 ) { $remainder = $below_midpoint_count; break; } $below_sizes[] = array( 'name' => $below_midpoint_count === $steps_mid_point - 1 ? __( 'Small' ) : sprintf( __( '%sX-Small' ), (string) $x_small_count ), 'slug' => (string) $slug, 'size' => round( $current_step, 2 ) . $unit, ); if ( $below_midpoint_count === $steps_mid_point - 2 ) { $x_small_count = 2; } if ( $below_midpoint_count < $steps_mid_point - 2 ) { ++$x_small_count; } $slug -= 10; } $below_sizes = array_reverse( $below_sizes ); $below_sizes[] = array( 'name' => __( 'Medium' ), 'slug' => '50', 'size' => $spacing_scale['mediumStep'] . $unit, ); $current_step = $spacing_scale['mediumStep']; $x_large_count = null; $above_sizes = array(); $slug = 60; $steps_above = ( $spacing_scale['steps'] - $steps_mid_point ) + $remainder; for ( $above_midpoint_count = 0; $above_midpoint_count < $steps_above; $above_midpoint_count++ ) { $current_step = '+' === $spacing_scale['operator'] ? $current_step + $spacing_scale['increment'] : ( $spacing_scale['increment'] >= 1 ? $current_step * $spacing_scale['increment'] : $current_step / $spacing_scale['increment'] ); $above_sizes[] = array( 'name' => 0 === $above_midpoint_count ? __( 'Large' ) : sprintf( __( '%sX-Large' ), (string) $x_large_count ), 'slug' => (string) $slug, 'size' => round( $current_step, 2 ) . $unit, ); if ( 1 === $above_midpoint_count ) { $x_large_count = 2; } if ( $above_midpoint_count > 1 ) { ++$x_large_count; } $slug += 10; } $spacing_sizes = $below_sizes; foreach ( $above_sizes as $above_sizes_item ) { $spacing_sizes[] = $above_sizes_item; } return $spacing_sizes; } private static function convert_custom_properties( $value ) { $prefix = 'var:'; $prefix_len = strlen( $prefix ); $token_in = '|'; $token_out = '--'; if ( str_starts_with( $value, $prefix ) ) { $unwrapped_name = str_replace( $token_in, $token_out, substr( $value, $prefix_len ) ); $value = "var(--wp--$unwrapped_name)"; } return $value; } private static function resolve_custom_css_format( $tree ) { $prefix = 'var:'; foreach ( $tree as $key => $data ) { if ( is_string( $data ) && str_starts_with( $data, $prefix ) ) { $tree[ $key ] = self::convert_custom_properties( $data ); } elseif ( is_array( $data ) ) { $tree[ $key ] = self::resolve_custom_css_format( $data ); } } return $tree; } protected static function get_block_selectors( $block_type, $root_selector ) { if ( ! empty( $block_type->selectors ) ) { return $block_type->selectors; } $selectors = array( 'root' => $root_selector ); foreach ( static::BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS as $key => $feature ) { $feature_selector = wp_get_block_css_selector( $block_type, $key ); if ( null !== $feature_selector ) { $selectors[ $feature ] = array( 'root' => $feature_selector ); } } return $selectors; } protected static function get_block_element_selectors( $root_selector ) { $block_selectors = explode( ',', $root_selector ); $element_selectors = array(); foreach ( static::ELEMENTS as $el_name => $el_selector ) { $element_selector = array(); foreach ( $block_selectors as $selector ) { if ( $selector === $el_selector ) { $element_selector = array( $el_selector ); break; } $element_selector[] = static::prepend_to_selector( $el_selector, $selector . ' ' ); } $element_selectors[ $el_name ] = implode( ',', $element_selector ); } return $element_selectors; } protected function get_feature_declarations_for_node( $metadata, &$node ) { $declarations = array(); if ( ! isset( $metadata['selectors'] ) ) { return $declarations; } $settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array(); foreach ( $metadata['selectors'] as $feature => $feature_selectors ) { if ( 'root' === $feature || empty( $node[ $feature ] ) ) { continue; } if ( is_array( $feature_selectors ) ) { foreach ( $feature_selectors as $subfeature => $subfeature_selector ) { if ( 'root' === $subfeature || empty( $node[ $feature ][ $subfeature ] ) ) { continue; } $subfeature_node = array( $feature => array( $subfeature => $node[ $feature ][ $subfeature ], ), ); $new_declarations = static::compute_style_properties( $subfeature_node, $settings, null, $this->theme_json ); if ( isset( $declarations[ $subfeature_selector ] ) ) { foreach ( $new_declarations as $new_declaration ) { $declarations[ $subfeature_selector ][] = $new_declaration; } } else { $declarations[ $subfeature_selector ] = $new_declarations; } unset( $node[ $feature ][ $subfeature ] ); } } if ( is_string( $feature_selectors ) || ( isset( $feature_selectors['root'] ) && $feature_selectors['root'] ) ) { $feature_selector = is_string( $feature_selectors ) ? $feature_selectors : $feature_selectors['root']; $feature_node = array( $feature => $node[ $feature ] ); $new_declarations = static::compute_style_properties( $feature_node, $settings, null, $this->theme_json ); if ( isset( $declarations[ $feature_selector ] ) ) { foreach ( $new_declarations as $new_declaration ) { $declarations[ $feature_selector ][] = $new_declaration; } } else { $declarations[ $feature_selector ] = $new_declarations; } unset( $node[ $feature ] ); } } return $declarations; } private static function convert_variables_to_value( $styles, $values ) { foreach ( $styles as $key => $style ) { if ( empty( $style ) ) { continue; } if ( is_array( $style ) ) { $styles[ $key ] = self::convert_variables_to_value( $style, $values ); continue; } if ( 0 <= strpos( $style, 'var(' ) ) { $has_matches = preg_match_all( '/var\(([^),]+)?,?\s?(\S+)?\)/', $style, $var_parts ); if ( $has_matches ) { $resolved_style = $styles[ $key ]; foreach ( $var_parts[1] as $index => $var_part ) { $key_in_values = 'var(' . $var_part . ')'; $rule_to_replace = $var_parts[0][ $index ]; $fallback = $var_parts[2][ $index ]; $resolved_style = str_replace( array( $rule_to_replace, $fallback, ), array( isset( $values[ $key_in_values ] ) ? $values[ $key_in_values ] : $rule_to_replace, isset( $values[ $fallback ] ) ? $values[ $fallback ] : $fallback, ), $resolved_style ); } $styles[ $key ] = $resolved_style; } } } return $styles; } public static function resolve_variables( $theme_json ) { $settings = $theme_json->get_settings(); $styles = $theme_json->get_raw_data()['styles']; $preset_vars = static::compute_preset_vars( $settings, static::VALID_ORIGINS ); $theme_vars = static::compute_theme_vars( $settings ); $vars = array_reduce( array_merge( $preset_vars, $theme_vars ), function ( $carry, $item ) { $name = $item['name']; $carry[ "var({$name})" ] = $item['value']; return $carry; }, array() ); $theme_json->theme_json['styles'] = self::convert_variables_to_value( $styles, $vars ); return $theme_json; } protected static function get_block_style_variation_selector( $variation_name, $block_selector ) { $variation_class = ".is-style-$variation_name"; if ( ! $block_selector ) { return $variation_class; } $limit = 1; $selector_parts = explode( ',', $block_selector ); $result = array(); foreach ( $selector_parts as $part ) { $result[] = preg_replace_callback( '/((?::\([^)]+\))?\s*)([^\s:]+)/', function ( $matches ) use ( $variation_class ) { return $matches[1] . $matches[2] . $variation_class; }, $part, $limit ); } return implode( ',', $result ); } protected static function get_valid_block_style_variations( $blocks_metadata = array() ) { $valid_variations = array(); $blocks_metadata = empty( $blocks_metadata ) ? static::get_blocks_metadata() : $blocks_metadata; foreach ( $blocks_metadata as $block_name => $block_meta ) { if ( ! isset( $block_meta['styleVariations'] ) ) { continue; } $valid_variations[ $block_name ] = array_keys( $block_meta['styleVariations'] ); } return $valid_variations; } }
require ABSPATH . WPINC . '/class-wp-theme-json-resolver.php';
###require ABSPATH . WPINC . '/class-wp-duotone.php';
class WP_Duotone { private static $global_styles_block_names; private static $global_styles_presets; private static $used_global_styles_presets = array(); private static $used_svg_filter_data = array(); private static $block_css_declarations = array(); private static function colord_clamp( $number, $min = 0, $max = 1 ) { return $number > $max ? $max : ( $number > $min ? $number : $min ); } private static function colord_clamp_hue( $degrees ) { $degrees = is_finite( $degrees ) ? $degrees % 360 : 0; return $degrees > 0 ? $degrees : $degrees + 360; } private static function colord_parse_hue( $value, $unit = 'deg' ) { $angle_units = array( 'grad' => 360 / 400, 'turn' => 360, 'rad' => 360 / ( M_PI * 2 ), ); $factor = isset( $angle_units[ $unit ] ) ? $angle_units[ $unit ] : 1; return (float) $value * $factor; } private static function colord_parse_hex( $hex ) { $is_match = preg_match( '/^#([0-9a-f]{3,8})$/i', $hex, $hex_match ); if ( ! $is_match ) { return null; } $hex = $hex_match[1]; if ( 4 >= strlen( $hex ) ) { return array( 'r' => (int) base_convert( $hex[0] . $hex[0], 16, 10 ), 'g' => (int) base_convert( $hex[1] . $hex[1], 16, 10 ), 'b' => (int) base_convert( $hex[2] . $hex[2], 16, 10 ), 'a' => 4 === strlen( $hex ) ? round( base_convert( $hex[3] . $hex[3], 16, 10 ) / 255, 2 ) : 1, ); } if ( 6 === strlen( $hex ) || 8 === strlen( $hex ) ) { return array( 'r' => (int) base_convert( substr( $hex, 0, 2 ), 16, 10 ), 'g' => (int) base_convert( substr( $hex, 2, 2 ), 16, 10 ), 'b' => (int) base_convert( substr( $hex, 4, 2 ), 16, 10 ), 'a' => 8 === strlen( $hex ) ? round( (int) base_convert( substr( $hex, 6, 2 ), 16, 10 ) / 255, 2 ) : 1, ); } return null; } private static function colord_clamp_rgba( $rgba ) { $rgba['r'] = self::colord_clamp( $rgba['r'], 0, 255 ); $rgba['g'] = self::colord_clamp( $rgba['g'], 0, 255 ); $rgba['b'] = self::colord_clamp( $rgba['b'], 0, 255 ); $rgba['a'] = self::colord_clamp( $rgba['a'] ); return $rgba; } private static function colord_parse_rgba_string( $input ) { $is_match = preg_match( '/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i', $input, $match ); if ( ! $is_match ) { $is_match = preg_match( '/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i', $input, $match ); } if ( ! $is_match ) { return null; } for ( $i = 1; $i <= 8; $i++ ) { if ( ! isset( $match[ $i ] ) ) { $match[ $i ] = ''; } } if ( $match[2] !== $match[4] || $match[4] !== $match[6] ) { return null; } return self::colord_clamp_rgba( array( 'r' => (float) $match[1] / ( $match[2] ? 100 / 255 : 1 ), 'g' => (float) $match[3] / ( $match[4] ? 100 / 255 : 1 ), 'b' => (float) $match[5] / ( $match[6] ? 100 / 255 : 1 ), 'a' => '' === $match[7] ? 1 : (float) $match[7] / ( $match[8] ? 100 : 1 ), ) ); } private static function colord_clamp_hsla( $hsla ) { $hsla['h'] = self::colord_clamp_hue( $hsla['h'] ); $hsla['s'] = self::colord_clamp( $hsla['s'], 0, 100 ); $hsla['l'] = self::colord_clamp( $hsla['l'], 0, 100 ); $hsla['a'] = self::colord_clamp( $hsla['a'] ); return $hsla; } private static function colord_hsva_to_rgba( $hsva ) { $h = ( $hsva['h'] / 360 ) * 6; $s = $hsva['s'] / 100; $v = $hsva['v'] / 100; $a = $hsva['a']; $hh = floor( $h ); $b = $v * ( 1 - $s ); $c = $v * ( 1 - ( $h - $hh ) * $s ); $d = $v * ( 1 - ( 1 - $h + $hh ) * $s ); $module = $hh % 6; return array( 'r' => array( $v, $c, $b, $b, $d, $v )[ $module ] * 255, 'g' => array( $d, $v, $v, $c, $b, $b )[ $module ] * 255, 'b' => array( $b, $b, $d, $v, $v, $c )[ $module ] * 255, 'a' => $a, ); } private static function colord_hsla_to_hsva( $hsla ) { $h = $hsla['h']; $s = $hsla['s']; $l = $hsla['l']; $a = $hsla['a']; $s *= ( $l < 50 ? $l : 100 - $l ) / 100; return array( 'h' => $h, 's' => $s > 0 ? ( ( 2 * $s ) / ( $l + $s ) ) * 100 : 0, 'v' => $l + $s, 'a' => $a, ); } private static function colord_hsla_to_rgba( $hsla ) { return self::colord_hsva_to_rgba( self::colord_hsla_to_hsva( $hsla ) ); } private static function colord_parse_hsla_string( $input ) { $is_match = preg_match( '/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i', $input, $match ); if ( ! $is_match ) { $is_match = preg_match( '/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i', $input, $match ); } if ( ! $is_match ) { return null; } for ( $i = 1; $i <= 6; $i++ ) { if ( ! isset( $match[ $i ] ) ) { $match[ $i ] = ''; } } $hsla = self::colord_clamp_hsla( array( 'h' => self::colord_parse_hue( $match[1], $match[2] ), 's' => (float) $match[3], 'l' => (float) $match[4], 'a' => '' === $match[5] ? 1 : (float) $match[5] / ( $match[6] ? 100 : 1 ), ) ); return self::colord_hsla_to_rgba( $hsla ); } private static function colord_parse( $input ) { $result = self::colord_parse_hex( $input ); if ( ! $result ) { $result = self::colord_parse_rgba_string( $input ); } if ( ! $result ) { $result = self::colord_parse_hsla_string( $input ); } return $result; } private static function get_slug_from_attribute( $duotone_attr ) { preg_match( '/(?|var:preset\|duotone\|(\S+)|var\(--wp--preset--duotone--(\S+)\))/', $duotone_attr, $matches ); return ! empty( $matches[1] ) ? $matches[1] : ''; } private static function is_preset( $duotone_attr ) { $slug = self::get_slug_from_attribute( $duotone_attr ); $filter_id = self::get_filter_id( $slug ); return array_key_exists( $filter_id, self::get_all_global_styles_presets() ); } private static function get_css_custom_property_name( $slug ) { return "--wp--preset--duotone--$slug"; } private static function get_filter_id( $slug ) { return "wp-duotone-$slug"; } private static function get_css_var( $slug ) { $name = self::get_css_custom_property_name( $slug ); return "var($name)"; } private static function get_filter_url( $filter_id ) { return "url(#$filter_id)"; } private static function get_filter_svg( $filter_id, $colors ) { $duotone_values = array( 'r' => array(), 'g' => array(), 'b' => array(), 'a' => array(), ); foreach ( $colors as $color_str ) { $color = self::colord_parse( $color_str ); if ( null === $color ) { $error_message = sprintf( __( '"%1$s" in %2$s %3$s is not a hex or rgb string.' ), $color_str, 'theme.json', 'settings.color.duotone' ); _doing_it_wrong( __METHOD__, $error_message, '6.3.0' ); } else { $duotone_values['r'][] = $color['r'] / 255; $duotone_values['g'][] = $color['g'] / 255; $duotone_values['b'][] = $color['b'] / 255; $duotone_values['a'][] = $color['a']; } } ob_start(); ?>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 0 0"
width="0"
height="0"
focusable="false"
role="none"
style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
>
<defs>
<filter id="<?php echo esc_attr( $filter_id ); ?>">
<feColorMatrix
color-interpolation-filters="sRGB"
type="matrix"
values="
.299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
"
/>
<feComponentTransfer color-interpolation-filters="sRGB" >
<feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?>" />
<feFuncG type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['g'] ) ); ?>" />
<feFuncB type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['b'] ) ); ?>" />
<feFuncA type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['a'] ) ); ?>" />
</feComponentTransfer>
<feComposite in2="SourceGraphic" operator="in" />
</filter>
</defs>
</svg>
<?php
$svg = ob_get_clean(); if ( ! SCRIPT_DEBUG ) { $svg = preg_replace( "/[\r\n\t ]+/", ' ', $svg ); $svg = str_replace( '> <', '><', $svg ); $svg = trim( $svg ); } return $svg; } public static function get_filter_id_from_preset( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0' ); $filter_id = ''; if ( isset( $preset['slug'] ) ) { $filter_id = self::get_filter_id( $preset['slug'] ); } return $filter_id; } public static function get_filter_svg_from_preset( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0' ); $filter_id = self::get_filter_id_from_preset( $preset ); return self::get_filter_svg( $filter_id, $preset['colors'] ); } private static function get_svg_definitions( $sources ) { $svgs = ''; foreach ( $sources as $filter_id => $filter_data ) { $colors = $filter_data['colors']; $svgs .= self::get_filter_svg( $filter_id, $colors ); } return $svgs; } private static function get_global_styles_presets( $sources ) { $css = WP_Theme_JSON::ROOT_CSS_PROPERTIES_SELECTOR . '{'; foreach ( $sources as $filter_id => $filter_data ) { $slug = $filter_data['slug']; $colors = $filter_data['colors']; $css_property_name = self::get_css_custom_property_name( $slug ); $declaration_value = is_string( $colors ) ? $colors : self::get_filter_url( $filter_id ); $css .= "$css_property_name:$declaration_value;"; } $css .= '}'; return $css; } private static function enqueue_block_css( $filter_id, $duotone_selector, $filter_value ) { $selectors = explode( ',', $duotone_selector ); $selectors_scoped = array(); foreach ( $selectors as $selector_part ) { $selectors_scoped[] = '.' . $filter_id . trim( $selector_part ); } $selector = implode( ', ', $selectors_scoped ); self::$block_css_declarations[] = array( 'selector' => $selector, 'declarations' => array( 'filter' => $filter_value, ), ); } private static function enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $filter_data ) { self::$used_svg_filter_data[ $filter_id ] = $filter_data; self::enqueue_block_css( $filter_id, $duotone_selector, $filter_value ); } private static function enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ) { $global_styles_presets = self::get_all_global_styles_presets(); if ( ! array_key_exists( $filter_id, $global_styles_presets ) ) { $error_message = sprintf( __( 'The duotone id "%1$s" is not registered in %2$s settings' ), $filter_id, 'theme.json' ); _doing_it_wrong( __METHOD__, $error_message, '6.3.0' ); return; } self::$used_global_styles_presets[ $filter_id ] = $global_styles_presets[ $filter_id ]; self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $global_styles_presets[ $filter_id ] ); } public static function register_duotone_support( $block_type ) { if ( block_has_support( $block_type, array( 'filter', 'duotone' ), null ) ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } } private static function get_selector( $block_type ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return null; } $duotone_support = block_has_support( $block_type, array( 'filter', 'duotone' ) ); if ( ! $duotone_support ) { return null; } $experimental_duotone = isset( $block_type->supports['color']['__experimentalDuotone'] ) ? $block_type->supports['color']['__experimentalDuotone'] : false; if ( $experimental_duotone ) { $root_selector = wp_get_block_css_selector( $block_type ); return is_string( $experimental_duotone ) ? WP_Theme_JSON::scope_selector( $root_selector, $experimental_duotone ) : $root_selector; } return wp_get_block_css_selector( $block_type, array( 'filter', 'duotone' ), true ); } private static function get_all_global_styles_presets() { if ( isset( self::$global_styles_presets ) ) { return self::$global_styles_presets; } $tree = wp_get_global_settings(); $presets_by_origin = isset( $tree['color']['duotone'] ) ? $tree['color']['duotone'] : array(); self::$global_styles_presets = array(); foreach ( $presets_by_origin as $presets ) { foreach ( $presets as $preset ) { $filter_id = self::get_filter_id( _wp_to_kebab_case( $preset['slug'] ) ); self::$global_styles_presets[ $filter_id ] = $preset; } } return self::$global_styles_presets; } private static function get_all_global_style_block_names() { if ( isset( self::$global_styles_block_names ) ) { return self::$global_styles_block_names; } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $block_nodes = $tree->get_styles_block_nodes(); $theme_json = $tree->get_raw_data(); self::$global_styles_block_names = array(); foreach ( $block_nodes as $block_node ) { if ( empty( $block_node['duotone'] ) ) { continue; } $duotone_attr_path = array_merge( $block_node['path'], array( 'filter', 'duotone' ) ); $duotone_attr = _wp_array_get( $theme_json, $duotone_attr_path, array() ); if ( empty( $duotone_attr ) ) { continue; } $slug = self::get_slug_from_attribute( $duotone_attr ); if ( $slug && $slug !== $duotone_attr ) { self::$global_styles_block_names[ $block_node['name'] ] = $slug; } } return self::$global_styles_block_names; } public static function render_duotone_support( $block_content, $block, $wp_block ) { if ( ! $block['blockName'] ) { return $block_content; } $duotone_selector = self::get_selector( $wp_block->block_type ); if ( ! $duotone_selector ) { return $block_content; } $global_styles_block_names = self::get_all_global_style_block_names(); $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] ); $has_global_styles_duotone = array_key_exists( $block['blockName'], $global_styles_block_names ); if ( ! $has_duotone_attribute && ! $has_global_styles_duotone ) { return $block_content; } if ( $has_duotone_attribute ) { $duotone_attr = $block['attrs']['style']['color']['duotone']; $is_preset = is_string( $duotone_attr ) && self::is_preset( $duotone_attr ); $is_css = is_string( $duotone_attr ) && ! $is_preset; $is_custom = is_array( $duotone_attr ); if ( $is_preset ) { $slug = self::get_slug_from_attribute( $duotone_attr ); $filter_id = self::get_filter_id( $slug ); $filter_value = self::get_css_var( $slug ); self::enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ); } elseif ( $is_css ) { $slug = wp_unique_id( sanitize_key( $duotone_attr . '-' ) ); $filter_id = self::get_filter_id( $slug ); $filter_value = $duotone_attr; self::enqueue_block_css( $filter_id, $duotone_selector, $filter_value ); } elseif ( $is_custom ) { $slug = wp_unique_id( sanitize_key( implode( '-', $duotone_attr ) . '-' ) ); $filter_id = self::get_filter_id( $slug ); $filter_value = self::get_filter_url( $filter_id ); $filter_data = array( 'slug' => $slug, 'colors' => $duotone_attr, ); self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $filter_data ); } } elseif ( $has_global_styles_duotone ) { $slug = $global_styles_block_names[ $block['blockName'] ]; $filter_id = self::get_filter_id( $slug ); $filter_value = self::get_css_var( $slug ); self::enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ); } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( $filter_id ); } return $tags->get_updated_html(); } public static function restore_image_outer_container( $block_content ) { if ( wp_theme_has_theme_json() ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); $wrapper_query = array( 'tag_name' => 'div', 'class_name' => 'wp-block-image', ); if ( ! $tags->next_tag( $wrapper_query ) ) { return $block_content; } $tags->set_bookmark( 'wrapper-div' ); $tags->next_tag(); $inner_classnames = explode( ' ', $tags->get_attribute( 'class' ) ); foreach ( $inner_classnames as $classname ) { if ( 0 === strpos( $classname, 'wp-duotone' ) ) { $tags->remove_class( $classname ); $tags->seek( 'wrapper-div' ); $tags->add_class( $classname ); break; } } return $tags->get_updated_html(); } public static function output_block_styles() { if ( ! empty( self::$block_css_declarations ) ) { wp_style_engine_get_stylesheet_from_css_rules( self::$block_css_declarations, array( 'context' => 'block-supports', ) ); } } public static function output_global_styles() { if ( ! empty( self::$used_global_styles_presets ) ) { wp_add_inline_style( 'global-styles', self::get_global_styles_presets( self::$used_global_styles_presets ) ); } } public static function output_footer_assets() { if ( ! empty( self::$used_svg_filter_data ) ) { echo self::get_svg_definitions( self::$used_svg_filter_data ); } if ( ! wp_is_block_theme() ) { $style_tag_id = 'core-block-supports-duotone'; wp_register_style( $style_tag_id, false ); if ( ! empty( self::$used_global_styles_presets ) ) { wp_add_inline_style( $style_tag_id, self::get_global_styles_presets( self::$used_global_styles_presets ) ); } if ( ! empty( self::$block_css_declarations ) ) { wp_add_inline_style( $style_tag_id, wp_style_engine_get_stylesheet_from_css_rules( self::$block_css_declarations ) ); } wp_enqueue_style( $style_tag_id ); } } public static function add_editor_settings( $settings ) { $global_styles_presets = self::get_all_global_styles_presets(); if ( ! empty( $global_styles_presets ) ) { if ( ! isset( $settings['styles'] ) ) { $settings['styles'] = array(); } $settings['styles'][] = array( 'assets' => self::get_svg_definitions( $global_styles_presets ), '__unstableType' => 'svgs', 'isGlobalStyles' => false, ); $settings['styles'][] = array( 'css' => self::get_global_styles_presets( $global_styles_presets ), '__unstableType' => 'presets', 'isGlobalStyles' => false, ); } return $settings; } public static function migrate_experimental_duotone_support_flag( $settings, $metadata ) { $duotone_support = isset( $metadata['supports']['color']['__experimentalDuotone'] ) ? $metadata['supports']['color']['__experimentalDuotone'] : null; if ( ! isset( $settings['supports']['filter']['duotone'] ) && null !== $duotone_support ) { _wp_array_set( $settings, array( 'supports', 'filter', 'duotone' ), (bool) $duotone_support ); } return $settings; } public static function get_filter_css_property_value_from_preset( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0' ); if ( isset( $preset['colors'] ) && is_string( $preset['colors'] ) ) { return $preset['colors']; } $filter_id = self::get_filter_id_from_preset( $preset ); return 'url(#' . $filter_id . ')'; } }
###require ABSPATH . WPINC . '/global-styles-and-settings.php';
function wp_get_global_settings( $path = array(), $context = array() ) { if ( ! empty( $context['block_name'] ) ) { $new_path = array( 'blocks', $context['block_name'] ); foreach ( $path as $subpath ) { $new_path[] = $subpath; } $path = $new_path; } $origin = 'custom'; if ( ! wp_theme_has_theme_json() || ( isset( $context['origin'] ) && 'base' === $context['origin'] ) ) { $origin = 'theme'; } $cache_group = 'theme_json'; $cache_key = 'wp_get_global_settings_' . $origin; $can_use_cached = ! wp_is_development_mode( 'theme' ); $settings = false; if ( $can_use_cached ) { $settings = wp_cache_get( $cache_key, $cache_group ); } if ( false === $settings ) { $settings = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_settings(); if ( $can_use_cached ) { wp_cache_set( $cache_key, $settings, $cache_group ); } } return _wp_array_get( $settings, $path, $settings ); } function wp_get_global_styles( $path = array(), $context = array() ) { if ( ! empty( $context['block_name'] ) ) { $path = array_merge( array( 'blocks', $context['block_name'] ), $path ); } $origin = 'custom'; if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) { $origin = 'theme'; } $resolve_variables = isset( $context['transforms'] ) && is_array( $context['transforms'] ) && in_array( 'resolve-variables', $context['transforms'], true ); $merged_data = WP_Theme_JSON_Resolver::get_merged_data( $origin ); if ( $resolve_variables ) { $merged_data = WP_Theme_JSON::resolve_variables( $merged_data ); } $styles = $merged_data->get_raw_data()['styles']; return _wp_array_get( $styles, $path, $styles ); } function wp_get_global_stylesheet( $types = array() ) { $can_use_cached = empty( $types ) && ! wp_is_development_mode( 'theme' ); $cache_group = 'theme_json'; $cache_key = 'wp_get_global_stylesheet'; if ( $can_use_cached ) { $cached = wp_cache_get( $cache_key, $cache_group ); if ( $cached ) { return $cached; } } $tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( WP_Theme_JSON_Resolver::get_merged_data() ); $supports_theme_json = wp_theme_has_theme_json(); if ( empty( $types ) && ! $supports_theme_json ) { $types = array( 'variables', 'presets', 'base-layout-styles' ); } elseif ( empty( $types ) ) { $types = array( 'variables', 'styles', 'presets' ); } $styles_variables = ''; if ( in_array( 'variables', $types, true ) ) { $origins = array( 'default', 'theme', 'custom' ); $styles_variables = $tree->get_stylesheet( array( 'variables' ), $origins ); $types = array_diff( $types, array( 'variables' ) ); } $styles_rest = ''; if ( ! empty( $types ) ) { $origins = array( 'default', 'theme', 'custom' ); if ( ! $supports_theme_json && ( current_theme_supports( 'appearance-tools' ) || current_theme_supports( 'border' ) ) && current_theme_supports( 'editor-color-palette' ) ) { $origins = array( 'default', 'theme' ); } elseif ( ! $supports_theme_json ) { $origins = array( 'default' ); } $styles_rest = $tree->get_stylesheet( $types, $origins ); } $stylesheet = $styles_variables . $styles_rest; if ( $can_use_cached ) { wp_cache_set( $cache_key, $stylesheet, $cache_group ); } return $stylesheet; } function wp_add_global_styles_for_blocks() { global $wp_styles; $tree = WP_Theme_JSON_Resolver::get_merged_data(); $tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( $tree ); $block_nodes = $tree->get_styles_block_nodes(); $can_use_cached = ! wp_is_development_mode( 'theme' ); $update_cache = false; if ( $can_use_cached ) { $cache_hash = md5( wp_json_encode( $tree->get_raw_data() ) ); $cache_key = 'wp_styles_for_blocks'; $cached = get_transient( $cache_key ); if ( ! is_array( $cached ) || $cached['hash'] !== $cache_hash ) { $cached = array( 'hash' => $cache_hash, 'blocks' => array(), ); $update_cache = true; } } foreach ( $block_nodes as $metadata ) { if ( $can_use_cached ) { $cache_node_key = isset( $metadata['name'] ) ? $metadata['name'] : md5( wp_json_encode( $metadata ) ); if ( isset( $cached['blocks'][ $cache_node_key ] ) ) { $block_css = $cached['blocks'][ $cache_node_key ]; } else { $block_css = $tree->get_styles_for_block( $metadata ); $cached['blocks'][ $cache_node_key ] = $block_css; $update_cache = true; } } else { $block_css = $tree->get_styles_for_block( $metadata ); } if ( ! wp_should_load_block_assets_on_demand() ) { wp_add_inline_style( 'global-styles', $block_css ); continue; } $stylesheet_handle = 'global-styles'; if ( isset( $metadata['name'] ) ) { if ( str_starts_with( $metadata['name'], 'core/' ) ) { $block_name = str_replace( 'core/', '', $metadata['name'] ); $block_handle = 'wp-block-' . $block_name; if ( in_array( $block_handle, $wp_styles->queue, true ) ) { wp_add_inline_style( $stylesheet_handle, $block_css ); } } else { wp_add_inline_style( $stylesheet_handle, $block_css ); } } if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) { $block_name = wp_get_block_name_from_theme_json_path( $metadata['path'] ); if ( $block_name ) { if ( str_starts_with( $block_name, 'core/' ) ) { $block_name = str_replace( 'core/', '', $block_name ); $block_handle = 'wp-block-' . $block_name; if ( in_array( $block_handle, $wp_styles->queue, true ) ) { wp_add_inline_style( $stylesheet_handle, $block_css ); } } else { wp_add_inline_style( $stylesheet_handle, $block_css ); } } } } if ( $update_cache ) { set_transient( $cache_key, $cached ); } } function wp_get_block_name_from_theme_json_path( $path ) { if ( count( $path ) >= 3 && 'styles' === $path[0] && 'blocks' === $path[1] && str_contains( $path[2], '/' ) ) { return $path[2]; } $result = array_values( array_filter( $path, static function ( $item ) { if ( str_contains( $item, 'core/' ) ) { return true; } return false; } ) ); if ( isset( $result[0] ) ) { return $result[0]; } return ''; } function wp_theme_has_theme_json() { static $theme_has_support = array(); $stylesheet = get_stylesheet(); if ( isset( $theme_has_support[ $stylesheet ] ) && ! wp_is_development_mode( 'theme' ) ) { return $theme_has_support[ $stylesheet ]; } $stylesheet_directory = get_stylesheet_directory(); $template_directory = get_template_directory(); if ( $stylesheet_directory !== $template_directory && file_exists( $stylesheet_directory . '/theme.json' ) ) { $path = $stylesheet_directory . '/theme.json'; } else { $path = $template_directory . '/theme.json'; } $path = apply_filters( 'theme_file_path', $path, 'theme.json' ); $theme_has_support[ $stylesheet ] = file_exists( $path ); return $theme_has_support[ $stylesheet ]; } function wp_clean_theme_json_cache() { wp_cache_delete( 'wp_get_global_stylesheet', 'theme_json' ); wp_cache_delete( 'wp_get_global_styles_svg_filters', 'theme_json' ); wp_cache_delete( 'wp_get_global_settings_custom', 'theme_json' ); wp_cache_delete( 'wp_get_global_settings_theme', 'theme_json' ); wp_cache_delete( 'wp_get_global_styles_custom_css', 'theme_json' ); wp_cache_delete( 'wp_get_theme_data_template_parts', 'theme_json' ); WP_Theme_JSON_Resolver::clean_cached_data(); } function wp_get_theme_directory_pattern_slugs() { return WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) )->get_patterns(); } function wp_get_theme_data_custom_templates() { return WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) )->get_custom_templates(); } function wp_get_theme_data_template_parts() { $cache_group = 'theme_json'; $cache_key = 'wp_get_theme_data_template_parts'; $can_use_cached = ! wp_is_development_mode( 'theme' ); if ( $can_use_cached ) { $metadata = wp_cache_get( $cache_key, $cache_group ); if ( false !== $metadata ) { return $metadata; } } $metadata = WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) )->get_template_parts(); if ( $can_use_cached ) { wp_cache_set( $cache_key, $metadata, $cache_group ); } return $metadata; } function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = false ) { if ( empty( $target ) ) { return null; } $has_selectors = ! empty( $block_type->selectors ); $root_selector = null; if ( $has_selectors && isset( $block_type->selectors['root'] ) ) { $root_selector = $block_type->selectors['root']; } elseif ( isset( $block_type->supports['__experimentalSelector'] ) && is_string( $block_type->supports['__experimentalSelector'] ) ) { $root_selector = $block_type->supports['__experimentalSelector']; } else { $block_name = str_replace( '/', '-', str_replace( 'core/', '', $block_type->name ) ); $root_selector = ".wp-block-{$block_name}"; } if ( 'root' === $target ) { return $root_selector; } if ( is_string( $target ) ) { $target = explode( '.', $target ); } if ( 1 === count( $target ) ) { $fallback_selector = $fallback ? $root_selector : null; if ( $has_selectors ) { $path = array( current( $target ), 'root' ); $feature_selector = _wp_array_get( $block_type->selectors, $path, null ); if ( $feature_selector ) { return $feature_selector; } $feature_selector = _wp_array_get( $block_type->selectors, $target, null ); return is_string( $feature_selector ) ? $feature_selector : $fallback_selector; } $path = array( current( $target ), '__experimentalSelector' ); $feature_selector = _wp_array_get( $block_type->supports, $path, null ); if ( null === $feature_selector ) { return $fallback_selector; } return WP_Theme_JSON::scope_selector( $root_selector, $feature_selector ); } $subfeature_selector = null; if ( $has_selectors ) { $subfeature_selector = _wp_array_get( $block_type->selectors, $target, null ); } if ( $subfeature_selector ) { return $subfeature_selector; } if ( $fallback ) { return wp_get_block_css_selector( $block_type, $target[0], $fallback ); } return null; }
###require ABSPATH . WPINC . '/class-wp-block-template.php';
class WP_Block_Template { public $type; public $theme; public $slug; public $id; public $title = ''; public $content = ''; public $description = ''; public $source = 'theme'; public $origin; public $wp_id; public $status; public $has_theme_file; public $is_custom = true; public $author; public $plugin; public $post_types; public $area; public $modified; }
###require ABSPATH . WPINC . '/class-wp-block-templates-registry.php';
final class WP_Block_Templates_Registry { private $registered_templates = array(); private static $instance = null; public function register( $template_name, $args = array() ) { $template = null; $error_message = ''; $error_code = ''; if ( ! is_string( $template_name ) ) { $error_message = __( 'Template names must be strings.' ); $error_code = 'template_name_no_string'; } elseif ( preg_match( '/[A-Z]+/', $template_name ) ) { $error_message = __( 'Template names must not contain uppercase characters.' ); $error_code = 'template_name_no_uppercase'; } elseif ( ! preg_match( '/^[a-z0-9_\-]+\/\/[a-z0-9_\-]+$/', $template_name ) ) { $error_message = __( 'Template names must contain a namespace prefix. Example: my-plugin//my-custom-template' ); $error_code = 'template_no_prefix'; } elseif ( $this->is_registered( $template_name ) ) { $error_message = sprintf( __( 'Template "%s" is already registered.' ), $template_name ); $error_code = 'template_already_registered'; } if ( $error_message ) { _doing_it_wrong( __METHOD__, $error_message, '6.7.0' ); return new WP_Error( $error_code, $error_message ); } if ( ! $template ) { $theme_name = get_stylesheet(); list( $plugin, $slug ) = explode( '//', $template_name ); $default_template_types = get_default_block_template_types(); $template = new WP_Block_Template(); $template->id = $theme_name . '//' . $slug; $template->theme = $theme_name; $template->plugin = $plugin; $template->author = null; $template->content = isset( $args['content'] ) ? $args['content'] : ''; $template->source = 'plugin'; $template->slug = $slug; $template->type = 'wp_template'; $template->title = isset( $args['title'] ) ? $args['title'] : $template_name; $template->description = isset( $args['description'] ) ? $args['description'] : ''; $template->status = 'publish'; $template->origin = 'plugin'; $template->is_custom = ! isset( $default_template_types[ $template_name ] ); $template->post_types = isset( $args['post_types'] ) ? $args['post_types'] : array(); } $this->registered_templates[ $template_name ] = $template; return $template; } public function get_all_registered() { return $this->registered_templates; } public function get_registered( $template_name ) { if ( ! $this->is_registered( $template_name ) ) { return null; } return $this->registered_templates[ $template_name ]; } public function get_by_slug( $template_slug ) { $all_templates = $this->get_all_registered(); if ( ! $all_templates ) { return null; } foreach ( $all_templates as $template ) { if ( $template->slug === $template_slug ) { return $template; } } return null; } public function get_by_query( $query = array() ) { $all_templates = $this->get_all_registered(); if ( ! $all_templates ) { return array(); } $query = wp_parse_args( $query, array( 'slug__in' => array(), 'slug__not_in' => array(), 'post_type' => '', ) ); $slugs_to_include = $query['slug__in']; $slugs_to_skip = $query['slug__not_in']; $post_type = $query['post_type']; $matching_templates = array(); foreach ( $all_templates as $template_name => $template ) { if ( $slugs_to_include && ! in_array( $template->slug, $slugs_to_include, true ) ) { continue; } if ( $slugs_to_skip && in_array( $template->slug, $slugs_to_skip, true ) ) { continue; } if ( $post_type && ! in_array( $post_type, $template->post_types, true ) ) { continue; } $matching_templates[ $template_name ] = $template; } return $matching_templates; } public function is_registered( $template_name ) { return isset( $template_name, $this->registered_templates[ $template_name ] ); } public function unregister( $template_name ) { if ( ! $this->is_registered( $template_name ) ) { $error_message = sprintf( __( 'Template "%s" is not registered.' ), $template_name ); _doing_it_wrong( __METHOD__, $error_message, '6.7.0' ); return new WP_Error( 'template_not_registered', $error_message ); } $unregistered_template = $this->registered_templates[ $template_name ]; unset( $this->registered_templates[ $template_name ] ); return $unregistered_template; } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } }
###require ABSPATH . WPINC . '/block-template-utils.php';
if ( ! defined( 'WP_TEMPLATE_PART_AREA_HEADER' ) ) { define( 'WP_TEMPLATE_PART_AREA_HEADER', 'header' ); } if ( ! defined( 'WP_TEMPLATE_PART_AREA_FOOTER' ) ) { define( 'WP_TEMPLATE_PART_AREA_FOOTER', 'footer' ); } if ( ! defined( 'WP_TEMPLATE_PART_AREA_SIDEBAR' ) ) { define( 'WP_TEMPLATE_PART_AREA_SIDEBAR', 'sidebar' ); } if ( ! defined( 'WP_TEMPLATE_PART_AREA_UNCATEGORIZED' ) ) { define( 'WP_TEMPLATE_PART_AREA_UNCATEGORIZED', 'uncategorized' ); } function get_block_theme_folders( $theme_stylesheet = null ) { $theme = wp_get_theme( (string) $theme_stylesheet ); if ( ! $theme->exists() ) { return array( 'wp_template' => 'templates', 'wp_template_part' => 'parts', ); } return $theme->get_block_template_folders(); } function get_allowed_block_template_part_areas() { $default_area_definitions = array( array( 'area' => WP_TEMPLATE_PART_AREA_UNCATEGORIZED, 'label' => _x( 'General', 'template part area' ), 'description' => __( 'General templates often perform a specific role like displaying post content, and are not tied to any particular area.' ), 'icon' => 'layout', 'area_tag' => 'div', ), array( 'area' => WP_TEMPLATE_PART_AREA_HEADER, 'label' => _x( 'Header', 'template part area' ), 'description' => __( 'The Header template defines a page area that typically contains a title, logo, and main navigation.' ), 'icon' => 'header', 'area_tag' => 'header', ), array( 'area' => WP_TEMPLATE_PART_AREA_FOOTER, 'label' => _x( 'Footer', 'template part area' ), 'description' => __( 'The Footer template defines a page area that typically contains site credits, social links, or any other combination of blocks.' ), 'icon' => 'footer', 'area_tag' => 'footer', ), ); return apply_filters( 'default_wp_template_part_areas', $default_area_definitions ); } function get_default_block_template_types() { $default_template_types = array( 'index' => array( 'title' => _x( 'Index', 'Template name' ), 'description' => __( 'Used as a fallback template for all pages when a more specific template is not defined.' ), ), 'home' => array( 'title' => _x( 'Blog Home', 'Template name' ), 'description' => __( 'Displays the latest posts as either the site homepage or as the "Posts page" as defined under reading settings. If it exists, the Front Page template overrides this template when posts are shown on the homepage.' ), ), 'front-page' => array( 'title' => _x( 'Front Page', 'Template name' ), 'description' => __( 'Displays your site\'s homepage, whether it is set to display latest posts or a static page. The Front Page template takes precedence over all templates.' ), ), 'singular' => array( 'title' => _x( 'Single Entries', 'Template name' ), 'description' => __( 'Displays any single entry, such as a post or a page. This template will serve as a fallback when a more specific template (e.g. Single Post, Page, or Attachment) cannot be found.' ), ), 'single' => array( 'title' => _x( 'Single Posts', 'Template name' ), 'description' => __( 'Displays a single post on your website unless a custom template has been applied to that post or a dedicated template exists.' ), ), 'page' => array( 'title' => _x( 'Pages', 'Template name' ), 'description' => __( 'Displays a static page unless a custom template has been applied to that page or a dedicated template exists.' ), ), 'archive' => array( 'title' => _x( 'All Archives', 'Template name' ), 'description' => __( 'Displays any archive, including posts by a single author, category, tag, taxonomy, custom post type, and date. This template will serve as a fallback when more specific templates (e.g. Category or Tag) cannot be found.' ), ), 'author' => array( 'title' => _x( 'Author Archives', 'Template name' ), 'description' => __( 'Displays a single author\'s post archive. This template will serve as a fallback when a more specific template (e.g. Author: Admin) cannot be found.' ), ), 'category' => array( 'title' => _x( 'Category Archives', 'Template name' ), 'description' => __( 'Displays a post category archive. This template will serve as a fallback when a more specific template (e.g. Category: Recipes) cannot be found.' ), ), 'taxonomy' => array( 'title' => _x( 'Taxonomy', 'Template name' ), 'description' => __( 'Displays a custom taxonomy archive. Like categories and tags, taxonomies have terms which you use to classify things. For example: a taxonomy named "Art" can have multiple terms, such as "Modern" and "18th Century." This template will serve as a fallback when a more specific template (e.g. Taxonomy: Art) cannot be found.' ), ), 'date' => array( 'title' => _x( 'Date Archives', 'Template name' ), 'description' => __( 'Displays a post archive when a specific date is visited (e.g., example.com/2023/).' ), ), 'tag' => array( 'title' => _x( 'Tag Archives', 'Template name' ), 'description' => __( 'Displays a post tag archive. This template will serve as a fallback when a more specific template (e.g. Tag: Pizza) cannot be found.' ), ), 'attachment' => array( 'title' => __( 'Attachment Pages' ), 'description' => __( 'Displays when a visitor views the dedicated page that exists for any media attachment.' ), ), 'search' => array( 'title' => _x( 'Search Results', 'Template name' ), 'description' => __( 'Displays when a visitor performs a search on your website.' ), ), 'privacy-policy' => array( 'title' => __( 'Privacy Policy' ), 'description' => __( 'Displays your site\'s Privacy Policy page.' ), ), '404' => array( 'title' => _x( 'Page: 404', 'Template name' ), 'description' => __( 'Displays when a visitor views a non-existent page, such as a dead link or a mistyped URL.' ), ), ); $post_formats = get_post_format_strings(); foreach ( $post_formats as $post_format_slug => $post_format_name ) { $default_template_types[ 'taxonomy-post_format-post-format-' . $post_format_slug ] = array( 'title' => sprintf( _x( 'Post Format: %s', 'Template name' ), $post_format_name ), 'description' => sprintf( __( 'Displays the %s post format archive.' ), $post_format_name ), ); } return apply_filters( 'default_template_types', $default_template_types ); } function _filter_block_template_part_area( $type ) { $allowed_areas = array_map( static function ( $item ) { return $item['area']; }, get_allowed_block_template_part_areas() ); if ( in_array( $type, $allowed_areas, true ) ) { return $type; } $warning_message = sprintf( __( '"%1$s" is not a supported wp_template_part area value and has been added as "%2$s".' ), $type, WP_TEMPLATE_PART_AREA_UNCATEGORIZED ); wp_trigger_error( __FUNCTION__, $warning_message ); return WP_TEMPLATE_PART_AREA_UNCATEGORIZED; } function _get_block_templates_paths( $base_directory ) { static $template_path_list = array(); if ( isset( $template_path_list[ $base_directory ] ) ) { return $template_path_list[ $base_directory ]; } $path_list = array(); if ( is_dir( $base_directory ) ) { $nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) ); $nested_html_files = new RegexIterator( $nested_files, '/^.+\.html$/i', RecursiveRegexIterator::GET_MATCH ); foreach ( $nested_html_files as $path => $file ) { $path_list[] = $path; } } $template_path_list[ $base_directory ] = $path_list; return $path_list; } function _get_block_template_file( $template_type, $slug ) { if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) { return null; } $themes = array( get_stylesheet() => get_stylesheet_directory(), get_template() => get_template_directory(), ); foreach ( $themes as $theme_slug => $theme_dir ) { $template_base_paths = get_block_theme_folders( $theme_slug ); $file_path = $theme_dir . '/' . $template_base_paths[ $template_type ] . '/' . $slug . '.html'; if ( file_exists( $file_path ) ) { $new_template_item = array( 'slug' => $slug, 'path' => $file_path, 'theme' => $theme_slug, 'type' => $template_type, ); if ( 'wp_template_part' === $template_type ) { return _add_block_template_part_area_info( $new_template_item ); } return _add_block_template_info( $new_template_item ); } } return null; } function _get_block_templates_files( $template_type, $query = array() ) { if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) { return null; } $default_template_types = array(); if ( 'wp_template' === $template_type ) { $default_template_types = get_default_block_template_types(); } $slugs_to_include = isset( $query['slug__in'] ) ? $query['slug__in'] : array(); $slugs_to_skip = isset( $query['slug__not_in'] ) ? $query['slug__not_in'] : array(); $area = isset( $query['area'] ) ? $query['area'] : null; $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; $stylesheet = get_stylesheet(); $template = get_template(); $themes = array( $stylesheet => get_stylesheet_directory(), ); if ( $stylesheet !== $template ) { $themes[ $template ] = get_template_directory(); } $template_files = array(); foreach ( $themes as $theme_slug => $theme_dir ) { $template_base_paths = get_block_theme_folders( $theme_slug ); $theme_template_files = _get_block_templates_paths( $theme_dir . '/' . $template_base_paths[ $template_type ] ); foreach ( $theme_template_files as $template_file ) { $template_base_path = $template_base_paths[ $template_type ]; $template_slug = substr( $template_file, strpos( $template_file, $template_base_path . DIRECTORY_SEPARATOR ) + 1 + strlen( $template_base_path ), -5 ); if ( ! empty( $slugs_to_include ) && ! in_array( $template_slug, $slugs_to_include, true ) ) { continue; } if ( ! empty( $slugs_to_skip ) && in_array( $template_slug, $slugs_to_skip, true ) ) { continue; } if ( isset( $template_files[ $template_slug ] ) ) { continue; } $new_template_item = array( 'slug' => $template_slug, 'path' => $template_file, 'theme' => $theme_slug, 'type' => $template_type, ); if ( 'wp_template_part' === $template_type ) { $candidate = _add_block_template_part_area_info( $new_template_item ); if ( ! isset( $area ) || $area === $candidate['area'] ) { $template_files[ $template_slug ] = $candidate; } } if ( 'wp_template' === $template_type ) { $candidate = _add_block_template_info( $new_template_item ); $is_custom = ! isset( $default_template_types[ $candidate['slug'] ] ); if ( ! $post_type || ( $post_type && isset( $candidate['postTypes'] ) && in_array( $post_type, $candidate['postTypes'], true ) ) ) { $template_files[ $template_slug ] = $candidate; } if ( $post_type && ! isset( $candidate['postTypes'] ) && $is_custom ) { $template_files[ $template_slug ] = $candidate; } } } } return array_values( $template_files ); } function _add_block_template_info( $template_item ) { if ( ! wp_theme_has_theme_json() ) { return $template_item; } $theme_data = wp_get_theme_data_custom_templates(); if ( isset( $theme_data[ $template_item['slug'] ] ) ) { $template_item['title'] = $theme_data[ $template_item['slug'] ]['title']; $template_item['postTypes'] = $theme_data[ $template_item['slug'] ]['postTypes']; } return $template_item; } function _add_block_template_part_area_info( $template_info ) { if ( wp_theme_has_theme_json() ) { $theme_data = wp_get_theme_data_template_parts(); } if ( isset( $theme_data[ $template_info['slug'] ]['area'] ) ) { $template_info['title'] = $theme_data[ $template_info['slug'] ]['title']; $template_info['area'] = _filter_block_template_part_area( $theme_data[ $template_info['slug'] ]['area'] ); } else { $template_info['area'] = WP_TEMPLATE_PART_AREA_UNCATEGORIZED; } return $template_info; } function _flatten_blocks( &$blocks ) { $all_blocks = array(); $queue = array(); foreach ( $blocks as &$block ) { $queue[] = &$block; } while ( count( $queue ) > 0 ) { $block = &$queue[0]; array_shift( $queue ); $all_blocks[] = &$block; if ( ! empty( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as &$inner_block ) { $queue[] = &$inner_block; } } } return $all_blocks; } function _inject_theme_attribute_in_template_part_block( &$block ) { if ( 'core/template-part' === $block['blockName'] && ! isset( $block['attrs']['theme'] ) ) { $block['attrs']['theme'] = get_stylesheet(); } } function _remove_theme_attribute_from_template_part_block( &$block ) { if ( 'core/template-part' === $block['blockName'] && isset( $block['attrs']['theme'] ) ) { unset( $block['attrs']['theme'] ); } } function _build_block_template_result_from_file( $template_file, $template_type ) { $default_template_types = get_default_block_template_types(); $theme = get_stylesheet(); $template = new WP_Block_Template(); $template->id = $theme . '//' . $template_file['slug']; $template->theme = $theme; $template->content = file_get_contents( $template_file['path'] ); $template->slug = $template_file['slug']; $template->source = 'theme'; $template->type = $template_type; $template->title = ! empty( $template_file['title'] ) ? $template_file['title'] : $template_file['slug']; $template->status = 'publish'; $template->has_theme_file = true; $template->is_custom = true; $template->modified = null; if ( 'wp_template' === $template_type ) { $registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template_file['slug'] ); if ( $registered_template ) { $template->plugin = $registered_template->plugin; $template->title = empty( $template->title ) || $template->title === $template->slug ? $registered_template->title : $template->title; $template->description = empty( $template->description ) ? $registered_template->description : $template->description; } } if ( 'wp_template' === $template_type && isset( $default_template_types[ $template_file['slug'] ] ) ) { $template->description = $default_template_types[ $template_file['slug'] ]['description']; $template->title = $default_template_types[ $template_file['slug'] ]['title']; $template->is_custom = false; } if ( 'wp_template' === $template_type && isset( $template_file['postTypes'] ) ) { $template->post_types = $template_file['postTypes']; } if ( 'wp_template_part' === $template_type && isset( $template_file['area'] ) ) { $template->area = $template_file['area']; } if ( 'wp_template_part' === $template->type ) { $content = get_comment_delimited_block_content( 'core/template-part', array(), $template->content ); $content = apply_block_hooks_to_content( $content, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); $template->content = remove_serialized_parent_block( $content ); } else { $template->content = apply_block_hooks_to_content( $template->content, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); } return $template; } function _wp_build_title_and_description_for_single_post_type_block_template( $post_type, $slug, WP_Block_Template $template ) { $post_type_object = get_post_type_object( $post_type ); $default_args = array( 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => 1, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'ignore_sticky_posts' => true, 'no_found_rows' => true, ); $args = array( 'name' => $slug, ); $args = wp_parse_args( $args, $default_args ); $posts_query = new WP_Query( $args ); if ( empty( $posts_query->posts ) ) { $template->title = sprintf( __( 'Not found: %1$s (%2$s)' ), $post_type_object->labels->singular_name, $slug ); return false; } $post_title = $posts_query->posts[0]->post_title; $template->title = sprintf( __( '%1$s: %2$s' ), $post_type_object->labels->singular_name, $post_title ); $template->description = sprintf( __( 'Template for %s' ), $post_title ); $args = array( 'title' => $post_title, ); $args = wp_parse_args( $args, $default_args ); $posts_with_same_title_query = new WP_Query( $args ); if ( count( $posts_with_same_title_query->posts ) > 1 ) { $template->title = sprintf( __( '%1$s (%2$s)' ), $template->title, $slug ); } return true; } function _wp_build_title_and_description_for_taxonomy_block_template( $taxonomy, $slug, WP_Block_Template $template ) { $taxonomy_object = get_taxonomy( $taxonomy ); $default_args = array( 'taxonomy' => $taxonomy, 'hide_empty' => false, 'update_term_meta_cache' => false, ); $term_query = new WP_Term_Query(); $args = array( 'number' => 1, 'slug' => $slug, ); $args = wp_parse_args( $args, $default_args ); $terms_query = $term_query->query( $args ); if ( empty( $terms_query ) ) { $template->title = sprintf( __( 'Not found: %1$s (%2$s)' ), $taxonomy_object->labels->singular_name, $slug ); return false; } $term_title = $terms_query[0]->name; $template->title = sprintf( __( '%1$s: %2$s' ), $taxonomy_object->labels->singular_name, $term_title ); $template->description = sprintf( __( 'Template for %s' ), $term_title ); $term_query = new WP_Term_Query(); $args = array( 'number' => 2, 'name' => $term_title, ); $args = wp_parse_args( $args, $default_args ); $terms_with_same_title_query = $term_query->query( $args ); if ( count( $terms_with_same_title_query ) > 1 ) { $template->title = sprintf( __( '%1$s (%2$s)' ), $template->title, $slug ); } return true; } function _build_block_template_object_from_post_object( $post, $terms = array(), $meta = array() ) { if ( empty( $terms['wp_theme'] ) ) { return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) ); } $theme = $terms['wp_theme']; $default_template_types = get_default_block_template_types(); $template_file = _get_block_template_file( $post->post_type, $post->post_name ); $has_theme_file = get_stylesheet() === $theme && null !== $template_file; $template = new WP_Block_Template(); $template->wp_id = $post->ID; $template->id = $theme . '//' . $post->post_name; $template->theme = $theme; $template->content = $post->post_content; $template->slug = $post->post_name; $template->source = 'custom'; $template->origin = ! empty( $meta['origin'] ) ? $meta['origin'] : null; $template->type = $post->post_type; $template->description = $post->post_excerpt; $template->title = $post->post_title; $template->status = $post->post_status; $template->has_theme_file = $has_theme_file; $template->is_custom = empty( $meta['is_wp_suggestion'] ); $template->author = $post->post_author; $template->modified = $post->post_modified; if ( 'wp_template' === $post->post_type && $has_theme_file && isset( $template_file['postTypes'] ) ) { $template->post_types = $template_file['postTypes']; } if ( 'wp_template' === $post->post_type && isset( $default_template_types[ $template->slug ] ) ) { $template->is_custom = false; } if ( 'wp_template_part' === $post->post_type && isset( $terms['wp_template_part_area'] ) ) { $template->area = $terms['wp_template_part_area']; } return $template; } function _build_block_template_result_from_post( $post ) { $post_id = wp_is_post_revision( $post ); if ( ! $post_id ) { $post_id = $post; } $parent_post = get_post( $post_id ); $post->post_name = $parent_post->post_name; $post->post_type = $parent_post->post_type; $terms = get_the_terms( $parent_post, 'wp_theme' ); if ( is_wp_error( $terms ) ) { return $terms; } if ( ! $terms ) { return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) ); } $terms = array( 'wp_theme' => $terms[0]->name, ); if ( 'wp_template_part' === $parent_post->post_type ) { $type_terms = get_the_terms( $parent_post, 'wp_template_part_area' ); if ( ! is_wp_error( $type_terms ) && false !== $type_terms ) { $terms['wp_template_part_area'] = $type_terms[0]->name; } } $meta = array( 'origin' => get_post_meta( $parent_post->ID, 'origin', true ), 'is_wp_suggestion' => get_post_meta( $parent_post->ID, 'is_wp_suggestion', true ), ); $template = _build_block_template_object_from_post_object( $post, $terms, $meta ); if ( is_wp_error( $template ) ) { return $template; } if ( 'wp_template' === $parent_post->post_type && empty( $template->description ) && ( empty( $template->title ) || $template->title === $template->slug ) ) { $matches = array(); if ( preg_match( '/(author|page|single|tag|category|taxonomy)-(.+)/', $template->slug, $matches ) ) { $type = $matches[1]; $slug_remaining = $matches[2]; switch ( $type ) { case 'author': $nice_name = $slug_remaining; $users = get_users( array( 'capability' => 'edit_posts', 'search' => $nice_name, 'search_columns' => array( 'user_nicename' ), 'fields' => 'display_name', ) ); if ( empty( $users ) ) { $template->title = sprintf( __( 'Deleted author: %s' ), $nice_name ); } else { $author_name = $users[0]; $template->title = sprintf( __( 'Author: %s' ), $author_name ); $template->description = sprintf( __( 'Template for %s' ), $author_name ); $users_with_same_name = get_users( array( 'capability' => 'edit_posts', 'search' => $author_name, 'search_columns' => array( 'display_name' ), 'fields' => 'display_name', ) ); if ( count( $users_with_same_name ) > 1 ) { $template->title = sprintf( __( '%1$s (%2$s)' ), $template->title, $nice_name ); } } break; case 'page': _wp_build_title_and_description_for_single_post_type_block_template( 'page', $slug_remaining, $template ); break; case 'single': $post_types = get_post_types(); foreach ( $post_types as $post_type ) { $post_type_length = strlen( $post_type ) + 1; if ( 0 === strncmp( $slug_remaining, $post_type . '-', $post_type_length ) ) { $slug = substr( $slug_remaining, $post_type_length, strlen( $slug_remaining ) ); $found = _wp_build_title_and_description_for_single_post_type_block_template( $post_type, $slug, $template ); if ( $found ) { break; } } } break; case 'tag': _wp_build_title_and_description_for_taxonomy_block_template( 'post_tag', $slug_remaining, $template ); break; case 'category': _wp_build_title_and_description_for_taxonomy_block_template( 'category', $slug_remaining, $template ); break; case 'taxonomy': $taxonomies = get_taxonomies(); foreach ( $taxonomies as $taxonomy ) { $taxonomy_length = strlen( $taxonomy ) + 1; if ( 0 === strncmp( $slug_remaining, $taxonomy . '-', $taxonomy_length ) ) { $slug = substr( $slug_remaining, $taxonomy_length, strlen( $slug_remaining ) ); $found = _wp_build_title_and_description_for_taxonomy_block_template( $taxonomy, $slug, $template ); if ( $found ) { break; } } } break; } } } if ( 'wp_template' === $post->post_type ) { $registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug ); if ( $registered_template ) { $template->plugin = $registered_template->plugin; $template->origin = 'theme' !== $template->origin && 'theme' !== $template->source ? 'plugin' : $template->origin; $template->title = empty( $template->title ) || $template->title === $template->slug ? $registered_template->title : $template->title; $template->description = empty( $template->description ) ? $registered_template->description : $template->description; } } if ( 'wp_template_part' === $template->type ) { $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); $attributes = ! empty( $existing_ignored_hooked_blocks ) ? array( 'metadata' => array( 'ignoredHookedBlocks' => json_decode( $existing_ignored_hooked_blocks, true ) ) ) : array(); $content = get_comment_delimited_block_content( 'core/template-part', $attributes, $template->content ); $content = apply_block_hooks_to_content( $content, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); $template->content = remove_serialized_parent_block( $content ); } else { $template->content = apply_block_hooks_to_content( $template->content, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); } return $template; } function get_block_templates( $query = array(), $template_type = 'wp_template' ) { $templates = apply_filters( 'pre_get_block_templates', null, $query, $template_type ); if ( ! is_null( $templates ) ) { return $templates; } $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; $wp_query_args = array( 'post_status' => array( 'auto-draft', 'draft', 'publish' ), 'post_type' => $template_type, 'posts_per_page' => -1, 'no_found_rows' => true, 'lazy_load_term_meta' => false, 'tax_query' => array( array( 'taxonomy' => 'wp_theme', 'field' => 'name', 'terms' => get_stylesheet(), ), ), ); if ( 'wp_template_part' === $template_type && isset( $query['area'] ) ) { $wp_query_args['tax_query'][] = array( 'taxonomy' => 'wp_template_part_area', 'field' => 'name', 'terms' => $query['area'], ); $wp_query_args['tax_query']['relation'] = 'AND'; } if ( ! empty( $query['slug__in'] ) ) { $wp_query_args['post_name__in'] = $query['slug__in']; $wp_query_args['posts_per_page'] = count( array_unique( $query['slug__in'] ) ); } if ( isset( $query['wp_id'] ) ) { $wp_query_args['p'] = $query['wp_id']; } else { $wp_query_args['post_status'] = 'publish'; } $template_query = new WP_Query( $wp_query_args ); $query_result = array(); foreach ( $template_query->posts as $post ) { $template = _build_block_template_result_from_post( $post ); if ( is_wp_error( $template ) ) { continue; } if ( $post_type && ! $template->is_custom ) { continue; } if ( $post_type && isset( $template->post_types ) && ! in_array( $post_type, $template->post_types, true ) ) { continue; } $query_result[] = $template; } if ( ! isset( $query['wp_id'] ) ) { $query['slug__not_in'] = wp_list_pluck( $query_result, 'slug' ); $template_files_query = $query; unset( $template_files_query['post_type'] ); $template_files = _get_block_templates_files( $template_type, $template_files_query ); foreach ( $template_files as $template_file ) { if ( ! isset( $query['post_type'] ) || ( isset( $template_file['postTypes'] ) && in_array( $query['post_type'], $template_file['postTypes'], true ) ) ) { $query_result[] = _build_block_template_result_from_file( $template_file, $template_type ); } elseif ( ! isset( $template_file['postTypes'] ) ) { $candidate = _build_block_template_result_from_file( $template_file, $template_type ); $default_template_types = get_default_block_template_types(); if ( ! isset( $default_template_types[ $candidate->slug ] ) ) { $query_result[] = $candidate; } } } if ( 'wp_template' === $template_type ) { $registered_templates = WP_Block_Templates_Registry::get_instance()->get_by_query( $query ); $matching_registered_templates = array_filter( $registered_templates, function ( $registered_template ) use ( $template_files ) { foreach ( $template_files as $template_file ) { if ( $template_file['slug'] === $registered_template->slug ) { return false; } } return true; } ); $matching_registered_templates = array_map( function ( $template ) { $template->content = apply_block_hooks_to_content( $template->content, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); return $template; }, $matching_registered_templates ); $query_result = array_merge( $query_result, $matching_registered_templates ); } } return apply_filters( 'get_block_templates', $query_result, $query, $template_type ); } function get_block_template( $id, $template_type = 'wp_template' ) { $block_template = apply_filters( 'pre_get_block_template', null, $id, $template_type ); if ( ! is_null( $block_template ) ) { return $block_template; } $parts = explode( '//', $id, 2 ); if ( count( $parts ) < 2 ) { return null; } list( $theme, $slug ) = $parts; $wp_query_args = array( 'post_name__in' => array( $slug ), 'post_type' => $template_type, 'post_status' => array( 'auto-draft', 'draft', 'publish', 'trash' ), 'posts_per_page' => 1, 'no_found_rows' => true, 'tax_query' => array( array( 'taxonomy' => 'wp_theme', 'field' => 'name', 'terms' => $theme, ), ), ); $template_query = new WP_Query( $wp_query_args ); $posts = $template_query->posts; if ( count( $posts ) > 0 ) { $template = _build_block_template_result_from_post( $posts[0] ); if ( ! is_wp_error( $template ) ) { return $template; } } $block_template = get_block_file_template( $id, $template_type ); return apply_filters( 'get_block_template', $block_template, $id, $template_type ); } function get_block_file_template( $id, $template_type = 'wp_template' ) { $block_template = apply_filters( 'pre_get_block_file_template', null, $id, $template_type ); if ( ! is_null( $block_template ) ) { return $block_template; } $parts = explode( '//', $id, 2 ); if ( count( $parts ) < 2 ) { return apply_filters( 'get_block_file_template', null, $id, $template_type ); } list( $theme, $slug ) = $parts; if ( get_stylesheet() === $theme ) { $template_file = _get_block_template_file( $template_type, $slug ); if ( null !== $template_file ) { $block_template = _build_block_template_result_from_file( $template_file, $template_type ); return apply_filters( 'get_block_file_template', $block_template, $id, $template_type ); } } $block_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $slug ); if ( $block_template ) { $block_template->content = apply_block_hooks_to_content( $block_template->content, $block_template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); } return apply_filters( 'get_block_file_template', $block_template, $id, $template_type ); } function block_template_part( $part ) { $template_part = get_block_template( get_stylesheet() . '//' . $part, 'wp_template_part' ); if ( ! $template_part || empty( $template_part->content ) ) { return; } echo do_blocks( $template_part->content ); } function block_header_area() { block_template_part( 'header' ); } function block_footer_area() { block_template_part( 'footer' ); } function wp_is_theme_directory_ignored( $path ) { $directories_to_ignore = array( '.DS_Store', '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' ); foreach ( $directories_to_ignore as $directory ) { if ( str_starts_with( $path, $directory ) ) { return true; } } return false; } function wp_generate_block_templates_export_file() { $wp_version = wp_get_wp_version(); if ( ! class_exists( 'ZipArchive' ) ) { return new WP_Error( 'missing_zip_package', __( 'Zip Export not supported.' ) ); } $obscura = wp_generate_password( 12, false, false ); $theme_name = basename( get_stylesheet() ); $filename = get_temp_dir() . $theme_name . $obscura . '.zip'; $zip = new ZipArchive(); if ( true !== $zip->open( $filename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) { return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.' ) ); } $zip->addEmptyDir( 'templates' ); $zip->addEmptyDir( 'parts' ); $theme_path = wp_normalize_path( get_stylesheet_directory() ); $theme_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_path ), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ( $theme_files as $file ) { if ( ! $file->isDir() ) { $file_path = wp_normalize_path( $file ); $relative_path = substr( $file_path, strlen( $theme_path ) + 1 ); if ( ! wp_is_theme_directory_ignored( $relative_path ) ) { $zip->addFile( $file_path, $relative_path ); } } } $templates = get_block_templates(); foreach ( $templates as $template ) { $template->content = traverse_and_serialize_blocks( parse_blocks( $template->content ), '_remove_theme_attribute_from_template_part_block' ); $zip->addFromString( 'templates/' . $template->slug . '.html', $template->content ); } $template_parts = get_block_templates( array(), 'wp_template_part' ); foreach ( $template_parts as $template_part ) { $zip->addFromString( 'parts/' . $template_part->slug . '.html', $template_part->content ); } $tree = WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) ); $tree->merge( WP_Theme_JSON_Resolver::get_user_data() ); $theme_json_raw = $tree->get_data(); if ( $theme_json_raw['version'] ) { $theme_json_version = 'wp/' . substr( $wp_version, 0, 3 ); $schema = array( '$schema' => 'https://schemas.wp.org/' . $theme_json_version . '/theme.json' ); $theme_json_raw = array_merge( $schema, $theme_json_raw ); } $theme_json_encoded = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); $theme_json_tabbed = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json_encoded ); $zip->addFromString( 'theme.json', $theme_json_tabbed ); $zip->close(); return $filename; } function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) { if ( 'index' === $slug ) { return apply_filters( 'index_template_hierarchy', array( 'index' ) ); } if ( $is_custom ) { return apply_filters( 'page_template_hierarchy', array( 'page', 'singular', 'index' ) ); } if ( 'front-page' === $slug ) { return apply_filters( 'frontpage_template_hierarchy', array( 'front-page', 'home', 'index' ) ); } $matches = array(); $template_hierarchy = array( $slug ); if ( ! empty( $template_prefix ) ) { list( $type ) = explode( '-', $template_prefix ); if ( ! in_array( $template_prefix, array( $slug, $type ), true ) ) { $template_hierarchy[] = $template_prefix; } if ( $slug !== $type ) { $template_hierarchy[] = $type; } } elseif ( preg_match( '/^(author|category|archive|tag|page)-.+$/', $slug, $matches ) ) { $template_hierarchy[] = $matches[1]; } elseif ( preg_match( '/^(taxonomy|single)-(.+)$/', $slug, $matches ) ) { $type = $matches[1]; $slug_remaining = $matches[2]; $items = 'single' === $type ? get_post_types() : get_taxonomies(); foreach ( $items as $item ) { if ( ! str_starts_with( $slug_remaining, $item ) ) { continue; } if ( $slug_remaining === $item ) { $template_hierarchy[] = $type; break; } if ( strlen( $slug_remaining ) > strlen( $item ) + 1 ) { $template_hierarchy[] = "$type-$item"; $template_hierarchy[] = $type; break; } } } if ( str_starts_with( $slug, 'author' ) || str_starts_with( $slug, 'taxonomy' ) || str_starts_with( $slug, 'category' ) || str_starts_with( $slug, 'tag' ) || 'date' === $slug ) { $template_hierarchy[] = 'archive'; } if ( 'attachment' === $slug ) { $template_hierarchy[] = 'single'; } if ( str_starts_with( $slug, 'single' ) || str_starts_with( $slug, 'page' ) || 'attachment' === $slug ) { $template_hierarchy[] = 'singular'; } $template_hierarchy[] = 'index'; $template_type = ''; if ( ! empty( $template_prefix ) ) { list( $template_type ) = explode( '-', $template_prefix ); } else { list( $template_type ) = explode( '-', $slug ); } $valid_template_types = array( '404', 'archive', 'attachment', 'author', 'category', 'date', 'embed', 'frontpage', 'home', 'index', 'page', 'paged', 'privacypolicy', 'search', 'single', 'singular', 'tag', 'taxonomy' ); if ( in_array( $template_type, $valid_template_types, true ) ) { return apply_filters( "{$template_type}_template_hierarchy", $template_hierarchy ); } return $template_hierarchy; } function inject_ignored_hooked_blocks_metadata_attributes( $changes, $deprecated = null ) { if ( null !== $deprecated ) { _deprecated_argument( __FUNCTION__, '6.5.3' ); } if ( ! isset( $changes->post_content ) ) { return $changes; } $hooked_blocks = get_hooked_blocks(); if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) { return $changes; } $meta = isset( $changes->meta_input ) ? $changes->meta_input : array(); $terms = isset( $changes->tax_input ) ? $changes->tax_input : array(); if ( empty( $changes->ID ) ) { $post = $changes; } else { $post = get_post( $changes->ID ); $post_id = wp_is_post_revision( $post ); if ( $post_id ) { $parent_post = get_post( $post_id ); $post->post_name = $parent_post->post_name; $post->post_type = $parent_post->post_type; } $post = (object) array_merge( (array) $post, (array) $changes ); $type_terms = get_the_terms( $changes->ID, 'wp_theme' ); $terms['wp_theme'] = ! is_wp_error( $type_terms ) && ! empty( $type_terms ) ? $type_terms[0]->name : null; } $post->post_modified = current_time( 'mysql' ); if ( empty( $post->post_author ) ) { $post->post_author = get_current_user_id(); } if ( 'wp_template_part' === $post->post_type && ! isset( $terms['wp_template_part_area'] ) ) { $area_terms = get_the_terms( $changes->ID, 'wp_template_part_area' ); $terms['wp_template_part_area'] = ! is_wp_error( $area_terms ) && ! empty( $area_terms ) ? $area_terms[0]->name : null; } $template = _build_block_template_object_from_post_object( new WP_Post( $post ), $terms, $meta ); if ( is_wp_error( $template ) ) { return $template; } if ( 'wp_template_part' === $post->post_type ) { $attributes = array(); $existing_ignored_hooked_blocks = isset( $post->ID ) ? get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ) : ''; if ( ! empty( $existing_ignored_hooked_blocks ) ) { $attributes['metadata'] = array( 'ignoredHookedBlocks' => json_decode( $existing_ignored_hooked_blocks, true ), ); } $content = get_comment_delimited_block_content( 'core/template-part', $attributes, $changes->post_content ); $content = apply_block_hooks_to_content( $content, $template, 'set_ignored_hooked_blocks_metadata' ); $changes->post_content = remove_serialized_parent_block( $content ); $wrapper_block_markup = extract_serialized_parent_block( $content ); $wrapper_block = parse_blocks( $wrapper_block_markup )[0]; $ignored_hooked_blocks = $wrapper_block['attrs']['metadata']['ignoredHookedBlocks'] ?? array(); if ( ! empty( $ignored_hooked_blocks ) ) { if ( ! isset( $changes->meta_input ) ) { $changes->meta_input = array(); } $changes->meta_input['_wp_ignored_hooked_blocks'] = wp_json_encode( $ignored_hooked_blocks ); } } else { $changes->post_content = apply_block_hooks_to_content( $changes->post_content, $template, 'set_ignored_hooked_blocks_metadata' ); } return $changes; }
###require ABSPATH . WPINC . '/block-template.php';
function _add_template_loader_filters() { if ( isset( $_GET['_wp-find-template'] ) && current_theme_supports( 'block-templates' ) ) { add_action( 'pre_get_posts', '_resolve_template_for_new_post' ); } } function wp_render_empty_block_template_warning( $block_template ) { wp_enqueue_style( 'wp-empty-template-alert' ); return sprintf( '<div id="wp-empty-template-alert">
<h2>%1$s</h2>
<p>%2$s</p>
<a href="%3$s" class="wp-element-button">
%4$s
</a>
</div>', esc_html( $block_template->title ), __( 'This page is blank because the template is empty. You can reset or customize it in the Site Editor.' ), get_edit_post_link( $block_template->wp_id, 'site-editor' ), __( 'Edit template' ) ); } function locate_block_template( $template, $type, array $templates ) { global $_wp_current_template_content, $_wp_current_template_id; if ( ! current_theme_supports( 'block-templates' ) ) { return $template; } if ( $template ) { $relative_template_path = str_replace( array( get_stylesheet_directory() . '/', get_template_directory() . '/' ), '', $template ); $index = array_search( $relative_template_path, $templates, true ); $templates = array_slice( $templates, 0, $index + 1 ); } $block_template = resolve_block_template( $type, $templates, $template ); if ( $block_template ) { $_wp_current_template_id = $block_template->id; if ( empty( $block_template->content ) ) { if ( is_user_logged_in() ) { $_wp_current_template_content = wp_render_empty_block_template_warning( $block_template ); } else { if ( $block_template->has_theme_file ) { $theme_template = _get_block_template_file( 'wp_template', $block_template->slug ); $_wp_current_template_content = file_get_contents( $theme_template['path'] ); } else { $_wp_current_template_content = $block_template->content; } } } elseif ( ! empty( $block_template->content ) ) { $_wp_current_template_content = $block_template->content; } if ( isset( $_GET['_wp-find-template'] ) ) { wp_send_json_success( $block_template ); } } else { if ( $template ) { return $template; } if ( 'index' === $type ) { if ( isset( $_GET['_wp-find-template'] ) ) { wp_send_json_error( array( 'message' => __( 'No matching template found.' ) ) ); } } else { return ''; } } add_action( 'wp_head', '_block_template_viewport_meta_tag', 0 ); remove_action( 'wp_head', '_wp_render_title_tag', 1 ); add_action( 'wp_head', '_block_template_render_title_tag', 1 ); return ABSPATH . WPINC . '/template-canvas.php'; } function resolve_block_template( $template_type, $template_hierarchy, $fallback_template ) { if ( ! $template_type ) { return null; } if ( empty( $template_hierarchy ) ) { $template_hierarchy = array( $template_type ); } $slugs = array_map( '_strip_template_file_suffix', $template_hierarchy ); $query = array( 'slug__in' => $slugs, ); $templates = get_block_templates( $query ); $slug_priorities = array_flip( $slugs ); usort( $templates, static function ( $template_a, $template_b ) use ( $slug_priorities ) { return $slug_priorities[ $template_a->slug ] - $slug_priorities[ $template_b->slug ]; } ); $theme_base_path = get_stylesheet_directory() . DIRECTORY_SEPARATOR; $parent_theme_base_path = get_template_directory() . DIRECTORY_SEPARATOR; if ( str_starts_with( $fallback_template, $theme_base_path ) && ! str_contains( $fallback_template, $parent_theme_base_path ) ) { $fallback_template_slug = substr( $fallback_template, strpos( $fallback_template, $theme_base_path ) + strlen( $theme_base_path ), -4 ); if ( count( $templates ) && $fallback_template_slug === $templates[0]->slug && 'theme' === $templates[0]->source ) { $template_file = _get_block_template_file( 'wp_template', $fallback_template_slug ); if ( $template_file && get_template() === $template_file['theme'] ) { array_shift( $templates ); } } } return count( $templates ) ? $templates[0] : null; } function _block_template_render_title_tag() { echo '<title>' . wp_get_document_title() . '</title>' . "\n"; } function get_the_block_template_html() { global $_wp_current_template_id, $_wp_current_template_content, $wp_embed, $wp_query; if ( ! $_wp_current_template_content ) { if ( is_user_logged_in() ) { return '<h1>' . esc_html__( 'No matching template found' ) . '</h1>'; } return ''; } $content = $wp_embed->run_shortcode( $_wp_current_template_content ); $content = $wp_embed->autoembed( $content ); $content = shortcode_unautop( $content ); $content = do_shortcode( $content ); if ( $_wp_current_template_id && str_starts_with( $_wp_current_template_id, get_stylesheet() . '//' ) && is_singular() && 1 === $wp_query->post_count && have_posts() ) { while ( have_posts() ) { the_post(); $content = do_blocks( $content ); } } else { $content = do_blocks( $content ); } $content = wptexturize( $content ); $content = convert_smilies( $content ); $content = wp_filter_content_tags( $content, 'template' ); $content = str_replace( ']]>', ']]>', $content ); return '<div class="wp-site-blocks">' . $content . '</div>'; } function _block_template_viewport_meta_tag() { echo '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n"; } function _strip_template_file_suffix( $template_file ) { return preg_replace( '/\.(php|html)$/', '', $template_file ); } function _block_template_render_without_post_block_context( $context ) { if ( isset( $context['postType'] ) && 'wp_template' === $context['postType'] ) { unset( $context['postId'] ); unset( $context['postType'] ); } return $context; } function _resolve_template_for_new_post( $wp_query ) { if ( ! $wp_query->is_main_query() ) { return; } remove_filter( 'pre_get_posts', '_resolve_template_for_new_post' ); $page_id = isset( $wp_query->query['page_id'] ) ? $wp_query->query['page_id'] : null; $p = isset( $wp_query->query['p'] ) ? $wp_query->query['p'] : null; $post_id = $page_id ? $page_id : $p; $post = get_post( $post_id ); if ( $post && 'auto-draft' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) { $wp_query->set( 'post_status', 'auto-draft' ); } } function register_block_template( $template_name, $args = array() ) { return WP_Block_Templates_Registry::get_instance()->register( $template_name, $args ); } function unregister_block_template( $template_name ) { return WP_Block_Templates_Registry::get_instance()->unregister( $template_name ); }
###require ABSPATH . WPINC . '/theme-templates.php';
function wp_set_unique_slug_on_create_template_part( $post_id ) { $post = get_post( $post_id ); if ( 'auto-draft' !== $post->post_status ) { return; } if ( ! $post->post_name ) { wp_update_post( array( 'ID' => $post_id, 'post_name' => 'custom_slug_' . uniqid(), ) ); } $terms = get_the_terms( $post_id, 'wp_theme' ); if ( ! is_array( $terms ) || ! count( $terms ) ) { wp_set_post_terms( $post_id, get_stylesheet(), 'wp_theme' ); } } function wp_filter_wp_template_unique_post_slug( $override_slug, $slug, $post_id, $post_status, $post_type ) { if ( 'wp_template' !== $post_type && 'wp_template_part' !== $post_type ) { return $override_slug; } if ( ! $override_slug ) { $override_slug = $slug; } $theme = get_stylesheet(); $terms = get_the_terms( $post_id, 'wp_theme' ); if ( $terms && ! is_wp_error( $terms ) ) { $theme = $terms[0]->name; } $check_query_args = array( 'post_name__in' => array( $override_slug ), 'post_type' => $post_type, 'posts_per_page' => 1, 'no_found_rows' => true, 'post__not_in' => array( $post_id ), 'tax_query' => array( array( 'taxonomy' => 'wp_theme', 'field' => 'name', 'terms' => $theme, ), ), ); $check_query = new WP_Query( $check_query_args ); $posts = $check_query->posts; if ( count( $posts ) > 0 ) { $suffix = 2; do { $query_args = $check_query_args; $alt_post_name = _truncate_post_slug( $override_slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; $query_args['post_name__in'] = array( $alt_post_name ); $query = new WP_Query( $query_args ); ++$suffix; } while ( count( $query->posts ) > 0 ); $override_slug = $alt_post_name; } return $override_slug; } function wp_enqueue_block_template_skip_link() { global $_wp_current_template_content; if ( ! has_action( 'wp_footer', 'the_block_template_skip_link' ) ) { return; } remove_action( 'wp_footer', 'the_block_template_skip_link' ); if ( ! current_theme_supports( 'block-templates' ) ) { return; } if ( ! $_wp_current_template_content ) { return; } $skip_link_styles = '
.skip-link.screen-reader-text {
border: 0;
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute !important;
width: 1px;
word-wrap: normal !important;
}
.skip-link.screen-reader-text:focus {
background-color: #eee;
clip-path: none;
color: #444;
display: block;
font-size: 1em;
height: auto;
left: 5px;
line-height: normal;
padding: 15px 23px 14px;
text-decoration: none;
top: 5px;
width: auto;
z-index: 100000;
}'; $handle = 'wp-block-template-skip-link'; wp_register_style( $handle, false ); wp_add_inline_style( $handle, $skip_link_styles ); wp_enqueue_style( $handle ); ob_start(); ?>
<script>
( function() {
var skipLinkTarget = document.querySelector( 'main' ),
sibling,
skipLinkTargetID,
skipLink;
// Early exit if a skip-link target can't be located.
if ( ! skipLinkTarget ) {
return;
}
/*
* Get the site wrapper.
* The skip-link will be injected in the beginning of it.
*/
sibling = document.querySelector( '.wp-site-blocks' );
// Early exit if the root element was not found.
if ( ! sibling ) {
return;
}
// Get the skip-link target's ID, and generate one if it doesn't exist.
skipLinkTargetID = skipLinkTarget.id;
if ( ! skipLinkTargetID ) {
skipLinkTargetID = 'wp--skip-link--target';
skipLinkTarget.id = skipLinkTargetID;
}
// Create the skip link.
skipLink = document.createElement( 'a' );
skipLink.classList.add( 'skip-link', 'screen-reader-text' );
skipLink.id = 'wp-skip-link';
skipLink.href = '#' + skipLinkTargetID;
skipLink.innerText = '<?php esc_html_e( 'Skip to content' ); ?>';
// Inject the skip link.
sibling.parentElement.insertBefore( skipLink, sibling );
}() );
</script>
<?php
$skip_link_script = wp_remove_surrounding_empty_script_tags( ob_get_clean() ); $script_handle = 'wp-block-template-skip-link'; wp_register_script( $script_handle, false, array(), false, array( 'in_footer' => true ) ); wp_add_inline_script( $script_handle, $skip_link_script ); wp_enqueue_script( $script_handle ); } function wp_enable_block_templates() { if ( wp_is_block_theme() || wp_theme_has_theme_json() ) { add_theme_support( 'block-templates' ); } }
###require ABSPATH . WPINC . '/theme-previews.php';
function wp_get_theme_preview_path( $current_stylesheet = null ) { if ( ! current_user_can( 'switch_themes' ) ) { return $current_stylesheet; } $preview_stylesheet = ! empty( $_GET['wp_theme_preview'] ) ? sanitize_text_field( wp_unslash( $_GET['wp_theme_preview'] ) ) : null; $wp_theme = wp_get_theme( $preview_stylesheet ); if ( ! is_wp_error( $wp_theme->errors() ) ) { if ( current_filter() === 'template' ) { $theme_path = $wp_theme->get_template(); } else { $theme_path = $wp_theme->get_stylesheet(); } return sanitize_text_field( $theme_path ); } return $current_stylesheet; } function wp_attach_theme_preview_middleware() { if ( ! current_user_can( 'switch_themes' ) ) { return; } wp_add_inline_script( 'wp-api-fetch', sprintf( 'wp.apiFetch.use( wp.apiFetch.createThemePreviewMiddleware( %s ) );', wp_json_encode( sanitize_text_field( wp_unslash( $_GET['wp_theme_preview'] ) ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); } function wp_block_theme_activate_nonce() { $nonce_handle = 'switch-theme_' . wp_get_theme_preview_path(); ?>
<script type="text/javascript">
window.WP_BLOCK_THEME_ACTIVATE_NONCE = <?php echo wp_json_encode( wp_create_nonce( $nonce_handle ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ); ?>;
</script>
<?php
} function wp_initialize_theme_preview_hooks() { if ( ! empty( $_GET['wp_theme_preview'] ) ) { add_filter( 'stylesheet', 'wp_get_theme_preview_path' ); add_filter( 'template', 'wp_get_theme_preview_path' ); add_action( 'init', 'wp_attach_theme_preview_middleware' ); add_action( 'admin_head', 'wp_block_theme_activate_nonce' ); } }
###require ABSPATH . WPINC . '/template.php';
function get_query_template( $type, $templates = array() ) { $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); if ( empty( $templates ) ) { $templates = array( "{$type}.php" ); } $templates = apply_filters( "{$type}_template_hierarchy", $templates ); $template = locate_template( $templates ); $template = locate_block_template( $template, $type, $templates ); return apply_filters( "{$type}_template", $template, $type, $templates ); } function get_index_template() { return get_query_template( 'index' ); } function get_404_template() { return get_query_template( '404' ); } function get_archive_template() { $post_types = array_filter( (array) get_query_var( 'post_type' ) ); $templates = array(); if ( count( $post_types ) === 1 ) { $post_type = reset( $post_types ); $templates[] = "archive-{$post_type}.php"; } $templates[] = 'archive.php'; return get_query_template( 'archive', $templates ); } function get_post_type_archive_template() { $post_type = get_query_var( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $obj = get_post_type_object( $post_type ); if ( ! ( $obj instanceof WP_Post_Type ) || ! $obj->has_archive ) { return ''; } return get_archive_template(); } function get_author_template() { $author = get_queried_object(); $templates = array(); if ( $author instanceof WP_User ) { $templates[] = "author-{$author->user_nicename}.php"; $templates[] = "author-{$author->ID}.php"; } $templates[] = 'author.php'; return get_query_template( 'author', $templates ); } function get_category_template() { $category = get_queried_object(); $templates = array(); if ( ! empty( $category->slug ) ) { $slug_decoded = urldecode( $category->slug ); if ( $slug_decoded !== $category->slug ) { $templates[] = "category-{$slug_decoded}.php"; } $templates[] = "category-{$category->slug}.php"; $templates[] = "category-{$category->term_id}.php"; } $templates[] = 'category.php'; return get_query_template( 'category', $templates ); } function get_tag_template() { $tag = get_queried_object(); $templates = array(); if ( ! empty( $tag->slug ) ) { $slug_decoded = urldecode( $tag->slug ); if ( $slug_decoded !== $tag->slug ) { $templates[] = "tag-{$slug_decoded}.php"; } $templates[] = "tag-{$tag->slug}.php"; $templates[] = "tag-{$tag->term_id}.php"; } $templates[] = 'tag.php'; return get_query_template( 'tag', $templates ); } function get_taxonomy_template() { $term = get_queried_object(); $templates = array(); if ( ! empty( $term->slug ) ) { $taxonomy = $term->taxonomy; $slug_decoded = urldecode( $term->slug ); if ( $slug_decoded !== $term->slug ) { $templates[] = "taxonomy-$taxonomy-{$slug_decoded}.php"; } $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; $templates[] = "taxonomy-$taxonomy-{$term->term_id}.php"; $templates[] = "taxonomy-$taxonomy.php"; } $templates[] = 'taxonomy.php'; return get_query_template( 'taxonomy', $templates ); } function get_date_template() { return get_query_template( 'date' ); } function get_home_template() { $templates = array( 'home.php', 'index.php' ); return get_query_template( 'home', $templates ); } function get_front_page_template() { $templates = array( 'front-page.php' ); return get_query_template( 'frontpage', $templates ); } function get_privacy_policy_template() { $templates = array( 'privacy-policy.php' ); return get_query_template( 'privacypolicy', $templates ); } function get_page_template() { $id = get_queried_object_id(); $template = get_page_template_slug(); $pagename = get_query_var( 'pagename' ); if ( ! $pagename && $id ) { $post = get_queried_object(); if ( $post ) { $pagename = $post->post_name; } } $templates = array(); if ( $template && 0 === validate_file( $template ) ) { $templates[] = $template; } if ( $pagename ) { $pagename_decoded = urldecode( $pagename ); if ( $pagename_decoded !== $pagename ) { $templates[] = "page-{$pagename_decoded}.php"; } $templates[] = "page-{$pagename}.php"; } if ( $id ) { $templates[] = "page-{$id}.php"; } $templates[] = 'page.php'; return get_query_template( 'page', $templates ); } function get_search_template() { return get_query_template( 'search' ); } function get_single_template() { $object = get_queried_object(); $templates = array(); if ( ! empty( $object->post_type ) ) { $template = get_page_template_slug( $object ); if ( $template && 0 === validate_file( $template ) ) { $templates[] = $template; } $name_decoded = urldecode( $object->post_name ); if ( $name_decoded !== $object->post_name ) { $templates[] = "single-{$object->post_type}-{$name_decoded}.php"; } $templates[] = "single-{$object->post_type}-{$object->post_name}.php"; $templates[] = "single-{$object->post_type}.php"; } $templates[] = 'single.php'; return get_query_template( 'single', $templates ); } function get_embed_template() { $object = get_queried_object(); $templates = array(); if ( ! empty( $object->post_type ) ) { $post_format = get_post_format( $object ); if ( $post_format ) { $templates[] = "embed-{$object->post_type}-{$post_format}.php"; } $templates[] = "embed-{$object->post_type}.php"; } $templates[] = 'embed.php'; return get_query_template( 'embed', $templates ); } function get_singular_template() { return get_query_template( 'singular' ); } function get_attachment_template() { $attachment = get_queried_object(); $templates = array(); if ( $attachment ) { if ( str_contains( $attachment->post_mime_type, '/' ) ) { list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); } else { list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); } if ( ! empty( $subtype ) ) { $templates[] = "{$type}-{$subtype}.php"; $templates[] = "{$subtype}.php"; } $templates[] = "{$type}.php"; } $templates[] = 'attachment.php'; return get_query_template( 'attachment', $templates ); } function wp_set_template_globals() { global $wp_stylesheet_path, $wp_template_path; $wp_stylesheet_path = get_stylesheet_directory(); $wp_template_path = get_template_directory(); } function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) { global $wp_stylesheet_path, $wp_template_path; if ( ! isset( $wp_stylesheet_path ) || ! isset( $wp_template_path ) ) { wp_set_template_globals(); } $is_child_theme = is_child_theme(); $located = ''; foreach ( (array) $template_names as $template_name ) { if ( ! $template_name ) { continue; } if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) { $located = $wp_stylesheet_path . '/' . $template_name; break; } elseif ( $is_child_theme && file_exists( $wp_template_path . '/' . $template_name ) ) { $located = $wp_template_path . '/' . $template_name; break; } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) { $located = ABSPATH . WPINC . '/theme-compat/' . $template_name; break; } } if ( $load && '' !== $located ) { load_template( $located, $load_once, $args ); } return $located; } function load_template( $_template_file, $load_once = true, $args = array() ) { global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; if ( is_array( $wp_query->query_vars ) ) { extract( $wp_query->query_vars, EXTR_SKIP ); } if ( isset( $s ) ) { $s = esc_attr( $s ); } do_action( 'wp_before_load_template', $_template_file, $load_once, $args ); if ( $load_once ) { require_once $_template_file; } else { require $_template_file; } do_action( 'wp_after_load_template', $_template_file, $load_once, $args ); } function wp_should_output_buffer_template_for_enhancement(): bool { return (bool) apply_filters( 'wp_should_output_buffer_template_for_enhancement', has_filter( 'wp_template_enhancement_output_buffer' ) || has_action( 'wp_finalized_template_enhancement_output_buffer' ) ); } function wp_start_template_enhancement_output_buffer(): bool { if ( ! wp_should_output_buffer_template_for_enhancement() ) { return false; } $started = ob_start( 'wp_finalize_template_enhancement_output_buffer', 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE ); if ( $started ) { do_action( 'wp_template_enhancement_output_buffer_started' ); } return $started; } function wp_finalize_template_enhancement_output_buffer( string $output, int $phase ): string { if ( ( $phase & PHP_OUTPUT_HANDLER_CLEAN ) !== 0 ) { return $output; } $is_html_content_type = null; $html_content_types = array( 'text/html', 'application/xhtml+xml' ); foreach ( headers_list() as $header ) { $header_parts = explode( ':', strtolower( $header ), 2 ); if ( count( $header_parts ) === 2 && 'content-type' === $header_parts[0] ) { $media_type = trim( strtok( $header_parts[1], ';' ), " \t" ); $is_html_content_type = in_array( $media_type, $html_content_types, true ); break; } } if ( null === $is_html_content_type ) { $is_html_content_type = in_array( ini_get( 'default_mimetype' ), $html_content_types, true ); } if ( ! $is_html_content_type ) { do_action( 'wp_finalized_template_enhancement_output_buffer', $output ); return $output; } $filtered_output = $output; $did_just_catch = false; $error_log = array(); set_error_handler( static function ( int $level, string $message, ?string $file = null, ?int $line = null ) use ( &$error_log, &$did_just_catch ) { if ( E_USER_ERROR === $level ) { throw new Exception( __( 'User error triggered:' ) . ' ' . $message ); } if ( $did_just_catch ) { $level = E_USER_ERROR; } if ( error_reporting() & $level ) { $error_log[] = compact( 'level', 'message', 'file', 'line' ); } return false; } ); $original_display_errors = ini_get( 'display_errors' ); if ( $original_display_errors ) { ini_set( 'display_errors', 0 ); } try { $filtered_output = (string) apply_filters( 'wp_template_enhancement_output_buffer', $filtered_output, $output ); } catch ( Throwable $throwable ) { $did_just_catch = true; trigger_error( sprintf( __( 'Uncaught "%s" thrown:' ), get_class( $throwable ) ) . ' ' . $throwable->getMessage(), E_USER_WARNING ); $did_just_catch = false; } try { do_action( 'wp_finalized_template_enhancement_output_buffer', $filtered_output ); } catch ( Throwable $throwable ) { $did_just_catch = true; trigger_error( sprintf( __( 'Uncaught "%s" thrown:' ), get_class( $throwable ) ) . ' ' . $throwable->getMessage(), E_USER_WARNING ); $did_just_catch = false; } if ( $original_display_errors && 'stderr' !== $original_display_errors ) { foreach ( $error_log as $error ) { switch ( $error['level'] ) { case E_USER_NOTICE: $type = 'Notice'; break; case E_USER_DEPRECATED: $type = 'Deprecated'; break; case E_USER_WARNING: $type = 'Warning'; break; default: $type = 'Error'; } if ( ini_get( 'html_errors' ) ) { $format = "%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%s</b><br />\n%s"; } else { $format = "%s\n%s: %s in %s on line %s\n%s"; } $filtered_output .= sprintf( $format, ini_get( 'error_prepend_string' ), $type, $error['message'], $error['file'], $error['line'], ini_get( 'error_append_string' ) ); } ini_set( 'display_errors', $original_display_errors ); } restore_error_handler(); return $filtered_output; }
###require ABSPATH . WPINC . '/https-detection.php';
function wp_is_using_https() { if ( ! wp_is_home_url_using_https() ) { return false; } return wp_is_site_url_using_https(); } function wp_is_home_url_using_https() { return 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME ); } function wp_is_site_url_using_https() { $site_url = apply_filters( 'site_url', get_option( 'siteurl' ), '', null, null ); return 'https' === wp_parse_url( $site_url, PHP_URL_SCHEME ); } function wp_is_https_supported() { $https_detection_errors = wp_get_https_detection_errors(); return empty( $https_detection_errors ); } function wp_get_https_detection_errors() { $support_errors = apply_filters( 'pre_wp_get_https_detection_errors', null ); if ( is_wp_error( $support_errors ) ) { return $support_errors->errors; } $support_errors = new WP_Error(); $response = wp_remote_request( home_url( '/', 'https' ), array( 'headers' => array( 'Cache-Control' => 'no-cache', ), 'sslverify' => true, ) ); if ( is_wp_error( $response ) ) { $unverified_response = wp_remote_request( home_url( '/', 'https' ), array( 'headers' => array( 'Cache-Control' => 'no-cache', ), 'sslverify' => false, ) ); if ( is_wp_error( $unverified_response ) ) { $support_errors->add( 'https_request_failed', __( 'HTTPS request failed.' ) ); } else { $support_errors->add( 'ssl_verification_failed', __( 'SSL verification failed.' ) ); } $response = $unverified_response; } if ( ! is_wp_error( $response ) ) { if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { $support_errors->add( 'bad_response_code', wp_remote_retrieve_response_message( $response ) ); } elseif ( false === wp_is_local_html_output( wp_remote_retrieve_body( $response ) ) ) { $support_errors->add( 'bad_response_source', __( 'It looks like the response did not come from this site.' ) ); } } return $support_errors->errors; } function wp_is_local_html_output( $html ) { if ( has_action( 'wp_head', 'rsd_link' ) ) { $pattern = preg_replace( '#^https?:(?=//)#', '', esc_url( site_url( 'xmlrpc.php?rsd', 'rpc' ) ) ); return str_contains( $html, $pattern ); } if ( has_action( 'wp_head', 'rest_output_link_wp_head' ) ) { $pattern = preg_replace( '#^https?:(?=//)#', '', esc_url( get_rest_url() ) ); return str_contains( $html, $pattern ); } return null; }
###require ABSPATH . WPINC . '/https-migration.php';
function wp_should_replace_insecure_home_url() { $should_replace_insecure_home_url = wp_is_using_https() && get_option( 'https_migration_required' ) && wp_parse_url( home_url(), PHP_URL_HOST ) === wp_parse_url( site_url(), PHP_URL_HOST ); return apply_filters( 'wp_should_replace_insecure_home_url', $should_replace_insecure_home_url ); } function wp_replace_insecure_home_url( $content ) { if ( ! wp_should_replace_insecure_home_url() ) { return $content; } $https_url = home_url( '', 'https' ); $http_url = str_replace( 'https://', 'http://', $https_url ); $escaped_https_url = str_replace( '/', '\/', $https_url ); $escaped_http_url = str_replace( '/', '\/', $http_url ); return str_replace( array( $http_url, $escaped_http_url, ), array( $https_url, $escaped_https_url, ), $content ); } function wp_update_urls_to_https() { $orig_home = get_option( 'home' ); $orig_siteurl = get_option( 'siteurl' ); $home = str_replace( 'http://', 'https://', $orig_home ); $siteurl = str_replace( 'http://', 'https://', $orig_siteurl ); update_option( 'home', $home ); update_option( 'siteurl', $siteurl ); if ( ! wp_is_using_https() ) { update_option( 'home', $orig_home ); update_option( 'siteurl', $orig_siteurl ); return false; } return true; } function wp_update_https_migration_required( $old_url, $new_url ) { if ( wp_installing() ) { return; } if ( untrailingslashit( (string) $old_url ) !== str_replace( 'https://', 'http://', untrailingslashit( (string) $new_url ) ) ) { delete_option( 'https_migration_required' ); return; } $https_migration_required = get_option( 'fresh_site' ) ? false : true; update_option( 'https_migration_required', $https_migration_required ); }
###require ABSPATH . WPINC . '/class-wp-user-request.php';
final class WP_User_Request { public $ID = 0; public $user_id = 0; public $email = ''; public $action_name = ''; public $status = ''; public $created_timestamp = null; public $modified_timestamp = null; public $confirmed_timestamp = null; public $completed_timestamp = null; public $request_data = array(); public $confirm_key = ''; public function __construct( $post ) { $this->ID = $post->ID; $this->user_id = $post->post_author; $this->email = $post->post_title; $this->action_name = $post->post_name; $this->status = $post->post_status; $this->created_timestamp = strtotime( $post->post_date_gmt ); $this->modified_timestamp = strtotime( $post->post_modified_gmt ); $this->confirmed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_confirmed_timestamp', true ); $this->completed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_completed_timestamp', true ); $this->request_data = json_decode( $post->post_content, true ); $this->confirm_key = $post->post_password; } }
###require ABSPATH . WPINC . '/user.php';
function wp_signon( $credentials = array(), $secure_cookie = '' ) { global $auth_secure_cookie, $wpdb; if ( empty( $credentials ) ) { $credentials = array( 'user_login' => '', 'user_password' => '', 'remember' => false, ); if ( ! empty( $_POST['log'] ) && is_string( $_POST['log'] ) ) { $credentials['user_login'] = wp_unslash( $_POST['log'] ); } if ( ! empty( $_POST['pwd'] ) && is_string( $_POST['pwd'] ) ) { $credentials['user_password'] = $_POST['pwd']; } if ( ! empty( $_POST['rememberme'] ) ) { $credentials['remember'] = $_POST['rememberme']; } } if ( ! empty( $credentials['remember'] ) ) { $credentials['remember'] = true; } else { $credentials['remember'] = false; } do_action_ref_array( 'wp_authenticate', array( &$credentials['user_login'], &$credentials['user_password'] ) ); if ( '' === $secure_cookie ) { $secure_cookie = is_ssl(); } $secure_cookie = apply_filters( 'secure_signon_cookie', $secure_cookie, $credentials ); $auth_secure_cookie = $secure_cookie; add_filter( 'authenticate', 'wp_authenticate_cookie', 30, 3 ); $user = wp_authenticate( $credentials['user_login'], $credentials['user_password'] ); if ( is_wp_error( $user ) ) { return $user; } wp_set_auth_cookie( $user->ID, $credentials['remember'], $secure_cookie ); if ( ! empty( $user->user_activation_key ) ) { $wpdb->update( $wpdb->users, array( 'user_activation_key' => '', ), array( 'ID' => $user->ID ) ); $user->user_activation_key = ''; } do_action( 'wp_login', $user->user_login, $user ); return $user; } function wp_authenticate_username_password( $user, $username, $password ) { if ( $user instanceof WP_User ) { return $user; } if ( empty( $username ) || empty( $password ) ) { if ( is_wp_error( $user ) ) { return $user; } $error = new WP_Error(); if ( empty( $username ) ) { $error->add( 'empty_username', __( '<strong>Error:</strong> The username field is empty.' ) ); } if ( empty( $password ) ) { $error->add( 'empty_password', __( '<strong>Error:</strong> The password field is empty.' ) ); } return $error; } $user = get_user_by( 'login', $username ); if ( ! $user ) { return new WP_Error( 'invalid_username', sprintf( __( '<strong>Error:</strong> The username <strong>%s</strong> is not registered on this site. If you are unsure of your username, try your email address instead.' ), $username ) ); } $user = apply_filters( 'wp_authenticate_user', $user, $password ); if ( is_wp_error( $user ) ) { return $user; } $valid = wp_check_password( $password, $user->user_pass, $user->ID ); if ( ! $valid ) { return new WP_Error( 'incorrect_password', sprintf( __( '<strong>Error:</strong> The password you entered for the username %s is incorrect.' ), '<strong>' . $username . '</strong>' ) . ' <a href="' . wp_lostpassword_url() . '">' . __( 'Lost your password?' ) . '</a>' ); } if ( wp_password_needs_rehash( $user->user_pass, $user->ID ) ) { wp_set_password( $password, $user->ID ); } return $user; } function wp_authenticate_email_password( $user, $email, $password ) { if ( $user instanceof WP_User ) { return $user; } if ( empty( $email ) || empty( $password ) ) { if ( is_wp_error( $user ) ) { return $user; } $error = new WP_Error(); if ( empty( $email ) ) { $error->add( 'empty_username', __( '<strong>Error:</strong> The email field is empty.' ) ); } if ( empty( $password ) ) { $error->add( 'empty_password', __( '<strong>Error:</strong> The password field is empty.' ) ); } return $error; } if ( ! is_email( $email ) ) { return $user; } $user = get_user_by( 'email', $email ); if ( ! $user ) { return new WP_Error( 'invalid_email', __( 'Unknown email address. Check again or try your username.' ) ); } $user = apply_filters( 'wp_authenticate_user', $user, $password ); if ( is_wp_error( $user ) ) { return $user; } $valid = wp_check_password( $password, $user->user_pass, $user->ID ); if ( ! $valid ) { return new WP_Error( 'incorrect_password', sprintf( __( '<strong>Error:</strong> The password you entered for the email address %s is incorrect.' ), '<strong>' . $email . '</strong>' ) . ' <a href="' . wp_lostpassword_url() . '">' . __( 'Lost your password?' ) . '</a>' ); } if ( wp_password_needs_rehash( $user->user_pass, $user->ID ) ) { wp_set_password( $password, $user->ID ); } return $user; } function wp_authenticate_cookie( $user, $username, $password ) { global $auth_secure_cookie; if ( $user instanceof WP_User ) { return $user; } if ( empty( $username ) && empty( $password ) ) { $user_id = wp_validate_auth_cookie(); if ( $user_id ) { return new WP_User( $user_id ); } if ( $auth_secure_cookie ) { $auth_cookie = SECURE_AUTH_COOKIE; } else { $auth_cookie = AUTH_COOKIE; } if ( ! empty( $_COOKIE[ $auth_cookie ] ) ) { return new WP_Error( 'expired_session', __( 'Please log in again.' ) ); } } return $user; } function wp_authenticate_application_password( $input_user, $username, $password ) { if ( $input_user instanceof WP_User ) { return $input_user; } if ( ! WP_Application_Passwords::is_in_use() ) { return $input_user; } $is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ); $is_api_request = apply_filters( 'application_password_is_api_request', $is_api_request ); if ( ! $is_api_request ) { return $input_user; } $error = null; $user = get_user_by( 'login', $username ); if ( ! $user && is_email( $username ) ) { $user = get_user_by( 'email', $username ); } if ( ! $user ) { if ( is_email( $username ) ) { $error = new WP_Error( 'invalid_email', __( '<strong>Error:</strong> Unknown email address. Check again or try your username.' ) ); } else { $error = new WP_Error( 'invalid_username', __( '<strong>Error:</strong> Unknown username. Check again or try your email address.' ) ); } } elseif ( ! wp_is_application_passwords_available() ) { $error = new WP_Error( 'application_passwords_disabled', __( 'Application passwords are not available.' ) ); } elseif ( ! wp_is_application_passwords_available_for_user( $user ) ) { $error = new WP_Error( 'application_passwords_disabled_for_user', __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' ) ); } if ( $error ) { do_action( 'application_password_failed_authentication', $error ); return $error; } $password = preg_replace( '/[^a-z\d]/i', '', $password ); $hashed_passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID ); foreach ( $hashed_passwords as $key => $item ) { if ( ! WP_Application_Passwords::check_password( $password, $item['password'] ) ) { continue; } $error = new WP_Error(); do_action( 'wp_authenticate_application_password_errors', $error, $user, $item, $password ); if ( $error->has_errors() ) { do_action( 'application_password_failed_authentication', $error ); return $error; } WP_Application_Passwords::record_application_password_usage( $user->ID, $item['uuid'] ); do_action( 'application_password_did_authenticate', $user, $item ); return $user; } $error = new WP_Error( 'incorrect_password', __( 'The provided password is an invalid application password.' ) ); do_action( 'application_password_failed_authentication', $error ); return $error; } function wp_validate_application_password( $input_user ) { if ( ! empty( $input_user ) ) { return $input_user; } if ( ! wp_is_application_passwords_available() ) { return $input_user; } if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) { return $input_user; } $authenticated = wp_authenticate_application_password( null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ); if ( $authenticated instanceof WP_User ) { return $authenticated->ID; } return $input_user; } function wp_authenticate_spam_check( $user ) { if ( $user instanceof WP_User && is_multisite() ) { $spammed = apply_filters( 'check_is_user_spammed', is_user_spammy( $user ), $user ); if ( $spammed ) { return new WP_Error( 'spammer_account', __( '<strong>Error:</strong> Your account has been marked as a spammer.' ) ); } } return $user; } function wp_validate_logged_in_cookie( $user_id ) { if ( $user_id ) { return $user_id; } if ( is_blog_admin() || is_network_admin() || empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) { return false; } return wp_validate_auth_cookie( $_COOKIE[ LOGGED_IN_COOKIE ], 'logged_in' ); } function count_user_posts( $userid, $post_type = 'post', $public_only = false ) { global $wpdb; $post_type = array_unique( (array) $post_type ); sort( $post_type ); $where = get_posts_by_author_sql( $post_type, true, $userid, $public_only ); $query = "SELECT COUNT(*) FROM $wpdb->posts $where"; $last_changed = wp_cache_get_last_changed( 'posts' ); $cache_key = 'count_user_posts:' . md5( $query ); $count = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( false === $count ) { $count = $wpdb->get_var( $query ); wp_cache_set_salted( $cache_key, $count, 'post-queries', $last_changed ); } return apply_filters( 'get_usernumposts', $count, $userid, $post_type, $public_only ); } function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) { global $wpdb; if ( empty( $users ) || ! is_array( $users ) ) { return array(); } $pre = apply_filters( 'pre_count_many_users_posts', null, $users, $post_type, $public_only ); if ( null !== $pre ) { return $pre; } $users = array_unique( array_filter( array_map( 'intval', $users ) ) ); sort( $users ); $post_type = array_unique( (array) $post_type ); sort( $post_type ); $userlist = implode( ',', $users ); $where = get_posts_by_author_sql( $post_type, true, null, $public_only ); $query = "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author"; $cache_key = 'count_many_users_posts:' . md5( $query ); $cache_salts = array( wp_cache_get_last_changed( 'posts' ), wp_cache_get_last_changed( 'users' ) ); $count = wp_cache_get_salted( $cache_key, 'post-queries', $cache_salts ); if ( false === $count ) { $result = $wpdb->get_results( $query, ARRAY_N ); $count = array_fill_keys( $users, 0 ); foreach ( $result as $row ) { $count[ $row[0] ] = $row[1]; } wp_cache_set_salted( $cache_key, $count, 'post-queries', $cache_salts, HOUR_IN_SECONDS ); } return $count; } function get_current_user_id() { if ( ! function_exists( 'wp_get_current_user' ) ) { return 0; } $user = wp_get_current_user(); return ( isset( $user->ID ) ? (int) $user->ID : 0 ); } function get_user_option( $option, $user = 0, $deprecated = '' ) { global $wpdb; if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '3.0.0' ); } if ( empty( $user ) ) { $user = get_current_user_id(); } $user = get_userdata( $user ); if ( ! $user ) { return false; } $prefix = $wpdb->get_blog_prefix(); if ( $user->has_prop( $prefix . $option ) ) { $result = $user->get( $prefix . $option ); } elseif ( $user->has_prop( $option ) ) { $result = $user->get( $option ); } else { $result = false; } return apply_filters( "get_user_option_{$option}", $result, $option, $user ); } function update_user_option( $user_id, $option_name, $newvalue, $is_global = false ) { global $wpdb; if ( ! $is_global ) { $option_name = $wpdb->get_blog_prefix() . $option_name; } return update_user_meta( $user_id, $option_name, $newvalue ); } function delete_user_option( $user_id, $option_name, $is_global = false ) { global $wpdb; if ( ! $is_global ) { $option_name = $wpdb->get_blog_prefix() . $option_name; } return delete_user_meta( $user_id, $option_name ); } function get_user( $user_id ) { return get_user_by( 'id', $user_id ); } function get_users( $args = array() ) { $args = wp_parse_args( $args ); $args['count_total'] = false; $user_search = new WP_User_Query( $args ); return (array) $user_search->get_results(); } function wp_list_users( $args = array() ) { $defaults = array( 'orderby' => 'name', 'order' => 'ASC', 'number' => '', 'exclude_admin' => true, 'show_fullname' => false, 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true, 'style' => 'list', 'html' => true, 'exclude' => '', 'include' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); $return = ''; $query_args = wp_array_slice_assoc( $parsed_args, array( 'orderby', 'order', 'number', 'exclude', 'include' ) ); $query_args['fields'] = 'ids'; $query_args = apply_filters( 'wp_list_users_args', $query_args, $parsed_args ); $users = get_users( $query_args ); foreach ( $users as $user_id ) { $user = get_userdata( $user_id ); if ( $parsed_args['exclude_admin'] && 'admin' === $user->display_name ) { continue; } if ( $parsed_args['show_fullname'] && '' !== $user->first_name && '' !== $user->last_name ) { $name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $user->first_name, $user->last_name ); } else { $name = $user->display_name; } if ( ! $parsed_args['html'] ) { $return .= $name . ', '; continue; } if ( 'list' === $parsed_args['style'] ) { $return .= '<li>'; } $row = $name; if ( ! empty( $parsed_args['feed_image'] ) || ! empty( $parsed_args['feed'] ) ) { $row .= ' '; if ( empty( $parsed_args['feed_image'] ) ) { $row .= '('; } $row .= '<a href="' . get_author_feed_link( $user->ID, $parsed_args['feed_type'] ) . '"'; $alt = ''; if ( ! empty( $parsed_args['feed'] ) ) { $alt = ' alt="' . esc_attr( $parsed_args['feed'] ) . '"'; $name = $parsed_args['feed']; } $row .= '>'; if ( ! empty( $parsed_args['feed_image'] ) ) { $row .= '<img src="' . esc_url( $parsed_args['feed_image'] ) . '" style="border: none;"' . $alt . ' />'; } else { $row .= $name; } $row .= '</a>'; if ( empty( $parsed_args['feed_image'] ) ) { $row .= ')'; } } $return .= $row; $return .= ( 'list' === $parsed_args['style'] ) ? '</li>' : ', '; } $return = rtrim( $return, ', ' ); if ( ! $parsed_args['echo'] ) { return $return; } echo $return; } function get_blogs_of_user( $user_id, $all = false ) { global $wpdb; $user_id = (int) $user_id; if ( empty( $user_id ) ) { return array(); } $sites = apply_filters( 'pre_get_blogs_of_user', null, $user_id, $all ); if ( null !== $sites ) { return $sites; } $keys = get_user_meta( $user_id ); if ( empty( $keys ) ) { return array(); } if ( ! is_multisite() ) { $site_id = get_current_blog_id(); $sites = array( $site_id => new stdClass() ); $sites[ $site_id ]->userblog_id = $site_id; $sites[ $site_id ]->blogname = get_option( 'blogname' ); $sites[ $site_id ]->domain = ''; $sites[ $site_id ]->path = ''; $sites[ $site_id ]->site_id = 1; $sites[ $site_id ]->siteurl = get_option( 'siteurl' ); $sites[ $site_id ]->archived = 0; $sites[ $site_id ]->spam = 0; $sites[ $site_id ]->deleted = 0; return $sites; } $site_ids = array(); if ( isset( $keys[ $wpdb->base_prefix . 'capabilities' ] ) && defined( 'MULTISITE' ) ) { $site_ids[] = 1; unset( $keys[ $wpdb->base_prefix . 'capabilities' ] ); } $keys = array_keys( $keys ); foreach ( $keys as $key ) { if ( ! str_ends_with( $key, 'capabilities' ) ) { continue; } if ( $wpdb->base_prefix && ! str_starts_with( $key, $wpdb->base_prefix ) ) { continue; } $site_id = str_replace( array( $wpdb->base_prefix, '_capabilities' ), '', $key ); if ( ! is_numeric( $site_id ) ) { continue; } $site_ids[] = (int) $site_id; } $sites = array(); if ( ! empty( $site_ids ) ) { $args = array( 'number' => '', 'site__in' => $site_ids, ); if ( ! $all ) { $args['archived'] = 0; $args['spam'] = 0; $args['deleted'] = 0; } $_sites = get_sites( $args ); foreach ( $_sites as $site ) { $sites[ $site->id ] = (object) array( 'userblog_id' => $site->id, 'blogname' => $site->blogname, 'domain' => $site->domain, 'path' => $site->path, 'site_id' => $site->network_id, 'siteurl' => $site->siteurl, 'archived' => $site->archived, 'mature' => $site->mature, 'spam' => $site->spam, 'deleted' => $site->deleted, ); } } return apply_filters( 'get_blogs_of_user', $sites, $user_id, $all ); } function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) { global $wpdb; $user_id = (int) $user_id; $blog_id = (int) $blog_id; if ( empty( $user_id ) ) { $user_id = get_current_user_id(); } if ( empty( $user_id ) ) { return false; } else { $user = get_userdata( $user_id ); if ( ! $user instanceof WP_User ) { return false; } } if ( ! is_multisite() ) { return true; } if ( empty( $blog_id ) ) { $blog_id = get_current_blog_id(); } $blog = get_site( $blog_id ); if ( ! $blog || ! isset( $blog->domain ) || $blog->archived || $blog->spam || $blog->deleted ) { return false; } if ( 1 === $blog_id ) { $capabilities_key = $wpdb->base_prefix . 'capabilities'; } else { $capabilities_key = $wpdb->base_prefix . $blog_id . '_capabilities'; } $has_cap = get_user_meta( $user_id, $capabilities_key, true ); return is_array( $has_cap ); } function add_user_meta( $user_id, $meta_key, $meta_value, $unique = false ) { return add_metadata( 'user', $user_id, $meta_key, $meta_value, $unique ); } function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) { return delete_metadata( 'user', $user_id, $meta_key, $meta_value ); } function get_user_meta( $user_id, $key = '', $single = false ) { return get_metadata( 'user', $user_id, $key, $single ); } function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) { return update_metadata( 'user', $user_id, $meta_key, $meta_value, $prev_value ); } function count_users( $strategy = 'time', $site_id = null ) { global $wpdb; if ( ! $site_id ) { $site_id = get_current_blog_id(); } $pre = apply_filters( 'pre_count_users', null, $strategy, $site_id ); if ( null !== $pre ) { return $pre; } $blog_prefix = $wpdb->get_blog_prefix( $site_id ); $result = array(); if ( 'time' === $strategy ) { if ( is_multisite() && get_current_blog_id() !== $site_id ) { switch_to_blog( $site_id ); $avail_roles = wp_roles()->get_names(); restore_current_blog(); } else { $avail_roles = wp_roles()->get_names(); } $select_count = array(); foreach ( $avail_roles as $this_role => $name ) { $select_count[] = $wpdb->prepare( 'COUNT(NULLIF(`meta_value` LIKE %s, false))', '%' . $wpdb->esc_like( '"' . $this_role . '"' ) . '%' ); } $select_count[] = "COUNT(NULLIF(`meta_value` = 'a:0:{}', false))"; $select_count = implode( ', ', $select_count ); $row = $wpdb->get_row( "
SELECT {$select_count}, COUNT(*)
FROM {$wpdb->usermeta}
INNER JOIN {$wpdb->users} ON user_id = ID
WHERE meta_key = '{$blog_prefix}capabilities'
", ARRAY_N ); $col = 0; $role_counts = array(); foreach ( $avail_roles as $this_role => $name ) { $count = (int) $row[ $col++ ]; if ( $count > 0 ) { $role_counts[ $this_role ] = $count; } } $role_counts['none'] = (int) $row[ $col++ ]; $total_users = (int) $row[ $col ]; $result['total_users'] = $total_users; $result['avail_roles'] =& $role_counts; } else { $avail_roles = array( 'none' => 0, ); $users_of_blog = $wpdb->get_col( "
SELECT meta_value
FROM {$wpdb->usermeta}
INNER JOIN {$wpdb->users} ON user_id = ID
WHERE meta_key = '{$blog_prefix}capabilities'
" ); foreach ( $users_of_blog as $caps_meta ) { $b_roles = maybe_unserialize( $caps_meta ); if ( ! is_array( $b_roles ) ) { continue; } if ( empty( $b_roles ) ) { ++$avail_roles['none']; } foreach ( $b_roles as $b_role => $val ) { if ( isset( $avail_roles[ $b_role ] ) ) { ++$avail_roles[ $b_role ]; } else { $avail_roles[ $b_role ] = 1; } } } $result['total_users'] = count( $users_of_blog ); $result['avail_roles'] =& $avail_roles; } return $result; } function get_user_count( $network_id = null ) { if ( ! is_multisite() && null !== $network_id ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Unable to pass %s if not using multisite.' ), '<code>$network_id</code>' ), '6.0.0' ); } return (int) get_network_option( $network_id, 'user_count', -1 ); } function wp_maybe_update_user_counts( $network_id = null ) { if ( ! is_multisite() && null !== $network_id ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Unable to pass %s if not using multisite.' ), '<code>$network_id</code>' ), '6.0.0' ); } $is_small_network = ! wp_is_large_user_count( $network_id ); if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) ) { return false; } return wp_update_user_counts( $network_id ); } function wp_update_user_counts( $network_id = null ) { global $wpdb; if ( ! is_multisite() && null !== $network_id ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Unable to pass %s if not using multisite.' ), '<code>$network_id</code>' ), '6.0.0' ); } $query = "SELECT COUNT(ID) as c FROM $wpdb->users"; if ( is_multisite() ) { $query .= " WHERE spam = '0' AND deleted = '0'"; } $count = $wpdb->get_var( $query ); return update_network_option( $network_id, 'user_count', $count ); } function wp_schedule_update_user_counts() { if ( ! is_main_site() ) { return; } if ( ! wp_next_scheduled( 'wp_update_user_counts' ) && ! wp_installing() ) { wp_schedule_event( time(), 'twicedaily', 'wp_update_user_counts' ); } } function wp_is_large_user_count( $network_id = null ) { if ( ! is_multisite() && null !== $network_id ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Unable to pass %s if not using multisite.' ), '<code>$network_id</code>' ), '6.0.0' ); } $count = get_user_count( $network_id ); return apply_filters( 'wp_is_large_user_count', $count > 10000, $count, $network_id ); } function setup_userdata( $for_user_id = 0 ) { global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_identity; if ( ! $for_user_id ) { $for_user_id = get_current_user_id(); } $user = get_userdata( $for_user_id ); if ( ! $user ) { $user_ID = 0; $user_level = 0; $userdata = null; $user_login = ''; $user_email = ''; $user_url = ''; $user_identity = ''; return; } $user_ID = (int) $user->ID; $user_level = (int) $user->user_level; $userdata = $user; $user_login = $user->user_login; $user_email = $user->user_email; $user_url = $user->user_url; $user_identity = $user->display_name; } function wp_dropdown_users( $args = '' ) { $defaults = array( 'show_option_all' => '', 'show_option_none' => '', 'hide_if_only_one_author' => '', 'orderby' => 'display_name', 'order' => 'ASC', 'include' => '', 'exclude' => '', 'multi' => 0, 'show' => 'display_name', 'echo' => 1, 'selected' => 0, 'name' => 'user', 'class' => '', 'id' => '', 'blog_id' => get_current_blog_id(), 'who' => '', 'include_selected' => false, 'option_none_value' => -1, 'role' => '', 'role__in' => array(), 'role__not_in' => array(), 'capability' => '', 'capability__in' => array(), 'capability__not_in' => array(), ); $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0; $parsed_args = wp_parse_args( $args, $defaults ); $query_args = wp_array_slice_assoc( $parsed_args, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who', 'role', 'role__in', 'role__not_in', 'capability', 'capability__in', 'capability__not_in', ) ); $fields = array( 'ID', 'user_login' ); $show = ! empty( $parsed_args['show'] ) ? $parsed_args['show'] : 'display_name'; if ( 'display_name_with_login' === $show ) { $fields[] = 'display_name'; } else { $fields[] = $show; } $query_args['fields'] = $fields; $show_option_all = $parsed_args['show_option_all']; $show_option_none = $parsed_args['show_option_none']; $option_none_value = $parsed_args['option_none_value']; $query_args = apply_filters( 'wp_dropdown_users_args', $query_args, $parsed_args ); $users = get_users( $query_args ); $output = ''; if ( ! empty( $users ) && ( empty( $parsed_args['hide_if_only_one_author'] ) || count( $users ) > 1 ) ) { $name = esc_attr( $parsed_args['name'] ); if ( $parsed_args['multi'] && ! $parsed_args['id'] ) { $id = ''; } else { $id = $parsed_args['id'] ? " id='" . esc_attr( $parsed_args['id'] ) . "'" : " id='$name'"; } $output = "<select name='{$name}'{$id} class='" . $parsed_args['class'] . "'>\n"; if ( $show_option_all ) { $output .= "\t<option value='0'>$show_option_all</option>\n"; } if ( $show_option_none ) { $_selected = selected( $option_none_value, $parsed_args['selected'], false ); $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$_selected>$show_option_none</option>\n"; } if ( $parsed_args['include_selected'] && ( $parsed_args['selected'] > 0 ) ) { $found_selected = false; $parsed_args['selected'] = (int) $parsed_args['selected']; foreach ( (array) $users as $user ) { $user->ID = (int) $user->ID; if ( $user->ID === $parsed_args['selected'] ) { $found_selected = true; } } if ( ! $found_selected ) { $selected_user = get_userdata( $parsed_args['selected'] ); if ( $selected_user ) { $users[] = $selected_user; } } } foreach ( (array) $users as $user ) { if ( 'display_name_with_login' === $show ) { $display = sprintf( _x( '%1$s (%2$s)', 'user dropdown' ), $user->display_name, $user->user_login ); } elseif ( ! empty( $user->$show ) ) { $display = $user->$show; } else { $display = '(' . $user->user_login . ')'; } $_selected = selected( $user->ID, $parsed_args['selected'], false ); $output .= "\t<option value='$user->ID'$_selected>" . esc_html( $display ) . "</option>\n"; } $output .= '</select>'; } $html = apply_filters( 'wp_dropdown_users', $output ); if ( $parsed_args['echo'] ) { echo $html; } return $html; } function sanitize_user_field( $field, $value, $user_id, $context ) { $int_fields = array( 'ID' ); if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } if ( 'raw' === $context ) { return $value; } if ( ! is_string( $value ) && ! is_numeric( $value ) ) { return $value; } $prefixed = str_contains( $field, 'user_' ); if ( 'edit' === $context ) { if ( $prefixed ) { $value = apply_filters( "edit_{$field}", $value, $user_id ); } else { $value = apply_filters( "edit_user_{$field}", $value, $user_id ); } if ( 'description' === $field ) { $value = esc_html( $value ); } else { $value = esc_attr( $value ); } } elseif ( 'db' === $context ) { if ( $prefixed ) { $value = apply_filters( "pre_{$field}", $value ); } else { $value = apply_filters( "pre_user_{$field}", $value ); } } else { if ( $prefixed ) { $value = apply_filters( "{$field}", $value, $user_id, $context ); } else { $value = apply_filters( "user_{$field}", $value, $user_id, $context ); } } if ( 'user_url' === $field ) { $value = esc_url( $value ); } if ( 'attribute' === $context ) { $value = esc_attr( $value ); } elseif ( 'js' === $context ) { $value = esc_js( $value ); } if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } return $value; } function update_user_caches( $user ) { if ( $user instanceof WP_User ) { if ( ! $user->exists() ) { return false; } $user = $user->data; } wp_cache_add( $user->ID, $user, 'users' ); wp_cache_add( $user->user_login, $user->ID, 'userlogins' ); wp_cache_add( $user->user_nicename, $user->ID, 'userslugs' ); if ( ! empty( $user->user_email ) ) { wp_cache_add( $user->user_email, $user->ID, 'useremail' ); } } function clean_user_cache( $user ) { if ( is_numeric( $user ) ) { $user = new WP_User( $user ); } if ( ! $user->exists() ) { return; } wp_cache_delete( $user->ID, 'users' ); wp_cache_delete( $user->user_login, 'userlogins' ); wp_cache_delete( $user->user_nicename, 'userslugs' ); if ( ! empty( $user->user_email ) ) { wp_cache_delete( $user->user_email, 'useremail' ); } wp_cache_delete( $user->ID, 'user_meta' ); wp_cache_set_users_last_changed(); do_action( 'clean_user_cache', $user->ID, $user ); } function username_exists( $username ) { $user = get_user_by( 'login', $username ); if ( $user ) { $user_id = $user->ID; } else { $user_id = false; } return apply_filters( 'username_exists', $user_id, $username ); } function email_exists( $email ) { $user = get_user_by( 'email', $email ); if ( $user ) { $user_id = $user->ID; } else { $user_id = false; } return apply_filters( 'email_exists', $user_id, $email ); } function validate_username( $username ) { $sanitized = sanitize_user( $username, true ); $valid = ( $sanitized === $username && ! empty( $sanitized ) ); return apply_filters( 'validate_username', $valid, $username ); } function wp_insert_user( $userdata ) { global $wpdb; if ( $userdata instanceof stdClass ) { $userdata = get_object_vars( $userdata ); } elseif ( $userdata instanceof WP_User ) { $userdata = $userdata->to_array(); } if ( ! empty( $userdata['ID'] ) ) { $user_id = (int) $userdata['ID']; $update = true; $old_user_data = get_userdata( $user_id ); if ( ! $old_user_data ) { return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) ); } $old_user_data->user_email = wp_slash( $old_user_data->user_email ); $user_pass = ! empty( $userdata['user_pass'] ) ? $userdata['user_pass'] : $old_user_data->user_pass; } else { $update = false; if ( empty( $userdata['user_pass'] ) ) { wp_trigger_error( __FUNCTION__, __( 'The user_pass field is required when creating a new user. The user will need to reset their password before logging in.' ), E_USER_WARNING ); $userdata['user_pass'] = ''; } $user_pass = wp_hash_password( $userdata['user_pass'] ); } $sanitized_user_login = sanitize_user( $userdata['user_login'], true ); $pre_user_login = apply_filters( 'pre_user_login', $sanitized_user_login ); $user_login = trim( $pre_user_login ); if ( empty( $user_login ) ) { return new WP_Error( 'empty_user_login', __( 'Cannot create a user with an empty login name.' ) ); } elseif ( mb_strlen( $user_login ) > 60 ) { return new WP_Error( 'user_login_too_long', __( 'Username may not be longer than 60 characters.' ) ); } if ( ! $update && username_exists( $user_login ) ) { return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) ); } $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ), true ) ) { return new WP_Error( 'invalid_username', __( 'Sorry, that username is not allowed.' ) ); } if ( ! empty( $userdata['user_nicename'] ) ) { $user_nicename = sanitize_user( $userdata['user_nicename'], true ); } else { $user_nicename = mb_substr( $user_login, 0, 50 ); } $user_nicename = sanitize_title( $user_nicename ); $user_nicename = apply_filters( 'pre_user_nicename', $user_nicename ); if ( empty( $user_nicename ) ) { return new WP_Error( 'empty_user_nicename', __( 'Cannot create a user with an empty nicename.' ) ); } elseif ( mb_strlen( $user_nicename ) > 50 ) { return new WP_Error( 'user_nicename_too_long', __( 'Nicename may not be longer than 50 characters.' ) ); } $user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $user_nicename, $user_login ) ); if ( $user_nicename_check ) { $suffix = 2; while ( $user_nicename_check ) { $base_length = 49 - mb_strlen( $suffix ); $alt_user_nicename = mb_substr( $user_nicename, 0, $base_length ) . "-$suffix"; $user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $alt_user_nicename, $user_login ) ); ++$suffix; } $user_nicename = $alt_user_nicename; } $raw_user_email = empty( $userdata['user_email'] ) ? '' : $userdata['user_email']; $user_email = apply_filters( 'pre_user_email', $raw_user_email ); if ( ( ! $update || ( ! empty( $old_user_data ) && 0 !== strcasecmp( $user_email, $old_user_data->user_email ) ) ) && ! defined( 'WP_IMPORTING' ) && email_exists( $user_email ) ) { return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) ); } $raw_user_url = empty( $userdata['user_url'] ) ? '' : $userdata['user_url']; $user_url = apply_filters( 'pre_user_url', $raw_user_url ); if ( mb_strlen( $user_url ) > 100 ) { return new WP_Error( 'user_url_too_long', __( 'User URL may not be longer than 100 characters.' ) ); } $user_registered = empty( $userdata['user_registered'] ) ? gmdate( 'Y-m-d H:i:s' ) : $userdata['user_registered']; $user_activation_key = empty( $userdata['user_activation_key'] ) ? '' : $userdata['user_activation_key']; if ( ! empty( $userdata['spam'] ) && ! is_multisite() ) { return new WP_Error( 'no_spam', __( 'Sorry, marking a user as spam is only supported on Multisite.' ) ); } $spam = empty( $userdata['spam'] ) ? 0 : (bool) $userdata['spam']; $meta = array(); $nickname = empty( $userdata['nickname'] ) ? $user_login : $userdata['nickname']; $meta['nickname'] = apply_filters( 'pre_user_nickname', $nickname ); $first_name = empty( $userdata['first_name'] ) ? '' : $userdata['first_name']; $meta['first_name'] = apply_filters( 'pre_user_first_name', $first_name ); $last_name = empty( $userdata['last_name'] ) ? '' : $userdata['last_name']; $meta['last_name'] = apply_filters( 'pre_user_last_name', $last_name ); if ( empty( $userdata['display_name'] ) ) { if ( $update ) { $display_name = $user_login; } elseif ( $meta['first_name'] && $meta['last_name'] ) { $display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $meta['first_name'], $meta['last_name'] ); } elseif ( $meta['first_name'] ) { $display_name = $meta['first_name']; } elseif ( $meta['last_name'] ) { $display_name = $meta['last_name']; } else { $display_name = $user_login; } } else { $display_name = $userdata['display_name']; } $display_name = apply_filters( 'pre_user_display_name', $display_name ); $description = empty( $userdata['description'] ) ? '' : $userdata['description']; $meta['description'] = apply_filters( 'pre_user_description', $description ); $meta['rich_editing'] = empty( $userdata['rich_editing'] ) ? 'true' : $userdata['rich_editing']; $meta['syntax_highlighting'] = empty( $userdata['syntax_highlighting'] ) ? 'true' : $userdata['syntax_highlighting']; $meta['comment_shortcuts'] = empty( $userdata['comment_shortcuts'] ) || 'false' === $userdata['comment_shortcuts'] ? 'false' : 'true'; $admin_color = empty( $userdata['admin_color'] ) ? 'fresh' : $userdata['admin_color']; $meta['admin_color'] = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $admin_color ); $meta['use_ssl'] = empty( $userdata['use_ssl'] ) ? '0' : '1'; $meta['show_admin_bar_front'] = empty( $userdata['show_admin_bar_front'] ) ? 'true' : $userdata['show_admin_bar_front']; $meta['locale'] = isset( $userdata['locale'] ) ? $userdata['locale'] : ''; $compacted = compact( 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'display_name' ); $data = wp_unslash( $compacted ); if ( ! $update ) { $data = $data + compact( 'user_login' ); } if ( is_multisite() ) { $data = $data + compact( 'spam' ); } $data = apply_filters( 'wp_pre_insert_user_data', $data, $update, ( $update ? $user_id : null ), $userdata ); if ( empty( $data ) || ! is_array( $data ) ) { return new WP_Error( 'empty_data', __( 'Not enough data to create this user.' ) ); } if ( $update ) { if ( $user_email !== $old_user_data->user_email || $user_pass !== $old_user_data->user_pass ) { $data['user_activation_key'] = ''; } $wpdb->update( $wpdb->users, $data, array( 'ID' => $user_id ) ); } else { $wpdb->insert( $wpdb->users, $data ); $user_id = (int) $wpdb->insert_id; } $user = new WP_User( $user_id ); if ( ! $update ) { do_action( 'wp_set_password', $userdata['user_pass'], $user_id, $user ); } $meta = apply_filters( 'insert_user_meta', $meta, $user, $update, $userdata ); $custom_meta = array(); if ( array_key_exists( 'meta_input', $userdata ) && is_array( $userdata['meta_input'] ) && ! empty( $userdata['meta_input'] ) ) { $custom_meta = $userdata['meta_input']; } $custom_meta = apply_filters( 'insert_custom_user_meta', $custom_meta, $user, $update, $userdata ); $meta = array_merge( $meta, $custom_meta ); if ( $update ) { foreach ( $meta as $key => $value ) { update_user_meta( $user_id, $key, $value ); } } else { foreach ( $meta as $key => $value ) { add_user_meta( $user_id, $key, $value ); } } foreach ( wp_get_user_contact_methods( $user ) as $key => $value ) { if ( isset( $userdata[ $key ] ) ) { update_user_meta( $user_id, $key, $userdata[ $key ] ); } } if ( isset( $userdata['role'] ) ) { $user->set_role( $userdata['role'] ); } elseif ( ! $update ) { $user->set_role( get_option( 'default_role' ) ); } clean_user_cache( $user_id ); if ( $update ) { do_action( 'profile_update', $user_id, $old_user_data, $userdata ); if ( isset( $userdata['spam'] ) && $userdata['spam'] !== $old_user_data->spam ) { if ( '1' === $userdata['spam'] ) { do_action( 'make_spam_user', $user_id ); } else { do_action( 'make_ham_user', $user_id ); } } } else { do_action( 'user_register', $user_id, $userdata ); } return $user_id; } function wp_update_user( $userdata ) { if ( $userdata instanceof stdClass ) { $userdata = get_object_vars( $userdata ); } elseif ( $userdata instanceof WP_User ) { $userdata = $userdata->to_array(); } $userdata_raw = $userdata; $user_id = isset( $userdata['ID'] ) ? (int) $userdata['ID'] : 0; if ( ! $user_id ) { return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) ); } $user_obj = get_userdata( $user_id ); if ( ! $user_obj ) { return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) ); } $user = $user_obj->to_array(); foreach ( _get_additional_user_keys( $user_obj ) as $key ) { $user[ $key ] = get_user_meta( $user_id, $key, true ); } $user = add_magic_quotes( $user ); if ( ! empty( $userdata['user_pass'] ) && $userdata['user_pass'] !== $user_obj->user_pass ) { $plaintext_pass = $userdata['user_pass']; $userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] ); do_action( 'wp_set_password', $plaintext_pass, $user_id, $user_obj ); $send_password_change_email = apply_filters( 'send_password_change_email', true, $user, $userdata ); } if ( isset( $userdata['user_email'] ) && $user['user_email'] !== $userdata['user_email'] ) { $send_email_change_email = apply_filters( 'send_email_change_email', true, $user, $userdata ); } clean_user_cache( $user_obj ); $userdata = array_merge( $user, $userdata ); $user_id = wp_insert_user( $userdata ); if ( is_wp_error( $user_id ) ) { return $user_id; } $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $switched_locale = false; if ( ! empty( $send_password_change_email ) || ! empty( $send_email_change_email ) ) { $switched_locale = switch_to_user_locale( $user_id ); } if ( ! empty( $send_password_change_email ) ) { $pass_change_text = __( 'Hi ###USERNAME###,
This notice confirms that your password was changed on ###SITENAME###.
If you did not change your password, please contact the Site Administrator at
###ADMIN_EMAIL###
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $pass_change_email = array( 'to' => $user['user_email'], 'subject' => __( '[%s] Password Changed' ), 'message' => $pass_change_text, 'headers' => '', ); $pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata ); $pass_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $pass_change_email['message'] ); $pass_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $pass_change_email['message'] ); $pass_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $pass_change_email['message'] ); $pass_change_email['message'] = str_replace( '###SITENAME###', $blog_name, $pass_change_email['message'] ); $pass_change_email['message'] = str_replace( '###SITEURL###', home_url(), $pass_change_email['message'] ); wp_mail( $pass_change_email['to'], sprintf( $pass_change_email['subject'], $blog_name ), $pass_change_email['message'], $pass_change_email['headers'] ); } if ( ! empty( $send_email_change_email ) ) { $email_change_text = __( 'Hi ###USERNAME###,
This notice confirms that your email address on ###SITENAME### was changed to ###NEW_EMAIL###.
If you did not change your email, please contact the Site Administrator at
###ADMIN_EMAIL###
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $email_change_email = array( 'to' => $user['user_email'], 'subject' => __( '[%s] Email Changed' ), 'message' => $email_change_text, 'headers' => '', ); $email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata ); $email_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###NEW_EMAIL###', $userdata['user_email'], $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITENAME###', $blog_name, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] ); wp_mail( $email_change_email['to'], sprintf( $email_change_email['subject'], $blog_name ), $email_change_email['message'], $email_change_email['headers'] ); } if ( $switched_locale ) { restore_previous_locale(); } $current_user = wp_get_current_user(); if ( $current_user->ID === $user_id ) { if ( isset( $plaintext_pass ) ) { $logged_in_cookie = wp_parse_auth_cookie( '', 'logged_in' ); $default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $user_id, false ); wp_clear_auth_cookie(); $remember = false; $token = ''; if ( false !== $logged_in_cookie ) { $token = $logged_in_cookie['token']; } if ( false !== $logged_in_cookie && ( (int) $logged_in_cookie['expiration'] - time() ) > $default_cookie_life ) { $remember = true; } wp_set_auth_cookie( $user_id, $remember, '', $token ); } } do_action( 'wp_update_user', $user_id, $userdata, $userdata_raw ); return $user_id; } function wp_create_user( $username, $password, $email = '' ) { $user_login = wp_slash( $username ); $user_email = wp_slash( $email ); $user_pass = $password; $userdata = compact( 'user_login', 'user_email', 'user_pass' ); return wp_insert_user( $userdata ); } function _get_additional_user_keys( $user ) { $keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front', 'locale' ); return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) ); } function wp_get_user_contact_methods( $user = null ) { $methods = array(); return apply_filters( 'user_contactmethods', $methods, $user ); } function _wp_get_user_contactmethods( $user = null ) { return wp_get_user_contact_methods( $user ); } function wp_get_password_hint() { $hint = __( 'Hint: The password should be at least twelve characters long. To make it stronger, use upper and lower case letters, numbers, and symbols like ! " ? $ % ^ & ).' ); return apply_filters( 'password_hint', $hint ); } function get_password_reset_key( $user ) { if ( ! ( $user instanceof WP_User ) ) { return new WP_Error( 'invalidcombo', __( '<strong>Error:</strong> There is no account with that username or email address.' ) ); } do_action_deprecated( 'retreive_password', array( $user->user_login ), '1.5.1', 'retrieve_password' ); do_action( 'retrieve_password', $user->user_login ); $password_reset_allowed = wp_is_password_reset_allowed_for_user( $user ); if ( ! $password_reset_allowed ) { return new WP_Error( 'no_password_reset', __( 'Password reset is not allowed for this user' ) ); } elseif ( is_wp_error( $password_reset_allowed ) ) { return $password_reset_allowed; } $key = wp_generate_password( 20, false ); do_action( 'retrieve_password_key', $user->user_login, $key ); $hashed = time() . ':' . wp_fast_hash( $key ); $key_saved = wp_update_user( array( 'ID' => $user->ID, 'user_activation_key' => $hashed, ) ); if ( is_wp_error( $key_saved ) ) { return $key_saved; } return $key; } function check_password_reset_key( $key, $login ) { $key = preg_replace( '/[^a-z0-9]/i', '', $key ); if ( empty( $key ) || ! is_string( $key ) ) { return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); } if ( empty( $login ) || ! is_string( $login ) ) { return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); } $user = get_user_by( 'login', $login ); if ( ! $user ) { return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); } $expiration_duration = apply_filters( 'password_reset_expiration', DAY_IN_SECONDS ); if ( str_contains( $user->user_activation_key, ':' ) ) { list( $pass_request_time, $pass_key ) = explode( ':', $user->user_activation_key, 2 ); $expiration_time = $pass_request_time + $expiration_duration; } else { $pass_key = $user->user_activation_key; $expiration_time = false; } if ( ! $pass_key ) { return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); } $hash_is_correct = wp_verify_fast_hash( $key, $pass_key ); if ( $hash_is_correct && $expiration_time && time() < $expiration_time ) { return $user; } elseif ( $hash_is_correct && $expiration_time ) { return new WP_Error( 'expired_key', __( 'Invalid key.' ) ); } if ( hash_equals( $user->user_activation_key, $key ) || ( $hash_is_correct && ! $expiration_time ) ) { $return = new WP_Error( 'expired_key', __( 'Invalid key.' ) ); $user_id = $user->ID; return apply_filters( 'password_reset_key_expired', $return, $user_id ); } return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); } function retrieve_password( $user_login = '' ) { $errors = new WP_Error(); $user_data = false; if ( ! $user_login && ! empty( $_POST['user_login'] ) && is_string( $_POST['user_login'] ) ) { $user_login = $_POST['user_login']; } $user_login = trim( wp_unslash( $user_login ) ); if ( empty( $user_login ) ) { $errors->add( 'empty_username', __( '<strong>Error:</strong> Please enter a username or email address.' ) ); } elseif ( strpos( $user_login, '@' ) ) { $user_data = get_user_by( 'email', $user_login ); if ( empty( $user_data ) ) { $user_data = get_user_by( 'login', $user_login ); } if ( empty( $user_data ) ) { $errors->add( 'invalid_email', __( '<strong>Error:</strong> There is no account with that username or email address.' ) ); } } else { $user_data = get_user_by( 'login', $user_login ); } $user_data = apply_filters( 'lostpassword_user_data', $user_data, $errors ); do_action( 'lostpassword_post', $errors, $user_data ); $errors = apply_filters( 'lostpassword_errors', $errors, $user_data ); if ( $errors->has_errors() ) { return $errors; } if ( ! $user_data ) { $errors->add( 'invalidcombo', __( '<strong>Error:</strong> There is no account with that username or email address.' ) ); return $errors; } if ( ! apply_filters( 'send_retrieve_password_email', true, $user_login, $user_data ) ) { return true; } $user_login = $user_data->user_login; $user_email = $user_data->user_email; $key = get_password_reset_key( $user_data ); if ( is_wp_error( $key ) ) { return $key; } $locale = get_user_locale( $user_data ); $switched_locale = switch_to_user_locale( $user_data->ID ); if ( is_multisite() ) { $site_name = get_network()->site_name; } else { $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); } $message = __( 'Someone has requested a password reset for the following account:' ) . "\r\n\r\n"; $message .= sprintf( __( 'Site Name: %s' ), $site_name ) . "\r\n\r\n"; $message .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n\r\n"; $message .= __( 'If this was a mistake, ignore this email and nothing will happen.' ) . "\r\n\r\n"; $message .= __( 'To reset your password, visit the following address:' ) . "\r\n\r\n"; $message .= network_site_url( 'wp-login.php?login=' . rawurlencode( $user_login ) . "&key=$key&action=rp", 'login' ) . '&wp_lang=' . $locale . "\r\n\r\n"; if ( ! is_user_logged_in() ) { $requester_ip = $_SERVER['REMOTE_ADDR']; if ( $requester_ip ) { $message .= sprintf( __( 'This password reset request originated from the IP address %s.' ), $requester_ip ) . "\r\n"; } } $title = sprintf( __( '[%s] Password Reset' ), $site_name ); $title = apply_filters( 'retrieve_password_title', $title, $user_login, $user_data ); $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data ); if ( ! $message ) { return true; } $defaults = array( 'to' => $user_email, 'subject' => $title, 'message' => $message, 'headers' => '', ); $notification_email = apply_filters( 'retrieve_password_notification_email', $defaults, $key, $user_login, $user_data ); if ( $switched_locale ) { restore_previous_locale(); } if ( is_array( $notification_email ) ) { $notification_email = array_merge( $defaults, $notification_email ); } else { $notification_email = $defaults; } list( $to, $subject, $message, $headers ) = array_values( $notification_email ); $subject = wp_specialchars_decode( $subject ); if ( ! wp_mail( $to, $subject, $message, $headers ) ) { $errors->add( 'retrieve_password_email_failure', sprintf( __( '<strong>Error:</strong> The email could not be sent. Your site may not be correctly configured to send emails. <a href="%s">Get support for resetting your password</a>.' ), esc_url( __( 'https://wordpress.org/documentation/article/reset-your-password/' ) ) ) ); return $errors; } return true; } function reset_password( $user, $new_pass ) { do_action( 'password_reset', $user, $new_pass ); wp_set_password( $new_pass, $user->ID ); update_user_meta( $user->ID, 'default_password_nag', false ); do_action( 'after_password_reset', $user, $new_pass ); } function register_new_user( $user_login, $user_email ) { $errors = new WP_Error(); $sanitized_user_login = sanitize_user( $user_login ); $user_email = apply_filters( 'user_registration_email', $user_email ); if ( '' === $sanitized_user_login ) { $errors->add( 'empty_username', __( '<strong>Error:</strong> Please enter a username.' ) ); } elseif ( ! validate_username( $user_login ) ) { $errors->add( 'invalid_username', __( '<strong>Error:</strong> This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); $sanitized_user_login = ''; } elseif ( username_exists( $sanitized_user_login ) ) { $errors->add( 'username_exists', __( '<strong>Error:</strong> This username is already registered. Please choose another one.' ) ); } else { $illegal_user_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $sanitized_user_login ), array_map( 'strtolower', $illegal_user_logins ), true ) ) { $errors->add( 'invalid_username', __( '<strong>Error:</strong> Sorry, that username is not allowed.' ) ); } } if ( '' === $user_email ) { $errors->add( 'empty_email', __( '<strong>Error:</strong> Please type your email address.' ) ); } elseif ( ! is_email( $user_email ) ) { $errors->add( 'invalid_email', __( '<strong>Error:</strong> The email address is not correct.' ) ); $user_email = ''; } elseif ( email_exists( $user_email ) ) { $errors->add( 'email_exists', sprintf( __( '<strong>Error:</strong> This email address is already registered. <a href="%s">Log in</a> with this address or choose another one.' ), wp_login_url() ) ); } do_action( 'register_post', $sanitized_user_login, $user_email, $errors ); $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email ); if ( $errors->has_errors() ) { return $errors; } $user_pass = wp_generate_password( 12, false ); $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email ); if ( ! $user_id || is_wp_error( $user_id ) ) { $errors->add( 'registerfail', sprintf( __( '<strong>Error:</strong> Could not register you… please contact the <a href="mailto:%s">site admin</a>!' ), get_option( 'admin_email' ) ) ); return $errors; } update_user_meta( $user_id, 'default_password_nag', true ); if ( ! empty( $_COOKIE['wp_lang'] ) ) { $wp_lang = sanitize_text_field( $_COOKIE['wp_lang'] ); if ( in_array( $wp_lang, get_available_languages(), true ) ) { update_user_meta( $user_id, 'locale', $wp_lang ); } } do_action( 'register_new_user', $user_id ); return $user_id; } function wp_send_new_user_notifications( $user_id, $notify = 'both' ) { wp_new_user_notification( $user_id, null, $notify ); } function wp_get_session_token() { $cookie = wp_parse_auth_cookie( '', 'logged_in' ); return ! empty( $cookie['token'] ) ? $cookie['token'] : ''; } function wp_get_all_sessions() { $manager = WP_Session_Tokens::get_instance( get_current_user_id() ); return $manager->get_all(); } function wp_destroy_current_session() { $token = wp_get_session_token(); if ( $token ) { $manager = WP_Session_Tokens::get_instance( get_current_user_id() ); $manager->destroy( $token ); } } function wp_destroy_other_sessions() { $token = wp_get_session_token(); if ( $token ) { $manager = WP_Session_Tokens::get_instance( get_current_user_id() ); $manager->destroy_others( $token ); } } function wp_destroy_all_sessions() { $manager = WP_Session_Tokens::get_instance( get_current_user_id() ); $manager->destroy_all(); } function wp_get_users_with_no_role( $site_id = null ) { global $wpdb; if ( ! $site_id ) { $site_id = get_current_blog_id(); } $prefix = $wpdb->get_blog_prefix( $site_id ); if ( is_multisite() && get_current_blog_id() !== $site_id ) { switch_to_blog( $site_id ); $role_names = wp_roles()->get_names(); restore_current_blog(); } else { $role_names = wp_roles()->get_names(); } $regex = implode( '|', array_keys( $role_names ) ); $regex = preg_replace( '/[^a-zA-Z_\|-]/', '', $regex ); $users = $wpdb->get_col( $wpdb->prepare( "SELECT user_id
FROM $wpdb->usermeta
WHERE meta_key = '{$prefix}capabilities'
AND meta_value NOT REGEXP %s", $regex ) ); return $users; } function _wp_get_current_user() { global $current_user; if ( ! empty( $current_user ) ) { if ( $current_user instanceof WP_User ) { return $current_user; } if ( is_object( $current_user ) && isset( $current_user->ID ) ) { $cur_id = $current_user->ID; $current_user = null; wp_set_current_user( $cur_id ); return $current_user; } $current_user = null; wp_set_current_user( 0 ); return $current_user; } if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { wp_set_current_user( 0 ); return $current_user; } $user_id = apply_filters( 'determine_current_user', false ); if ( ! $user_id ) { wp_set_current_user( 0 ); return $current_user; } wp_set_current_user( $user_id ); return $current_user; } function send_confirmation_on_profile_email() { global $errors; $current_user = wp_get_current_user(); if ( ! is_object( $errors ) ) { $errors = new WP_Error(); } if ( $current_user->ID !== (int) $_POST['user_id'] ) { return false; } if ( $current_user->user_email !== $_POST['email'] ) { if ( ! is_email( $_POST['email'] ) ) { $errors->add( 'user_email', __( '<strong>Error:</strong> The email address is not correct.' ), array( 'form-field' => 'email', ) ); return; } if ( email_exists( $_POST['email'] ) ) { $errors->add( 'user_email', __( '<strong>Error:</strong> The email address is already used.' ), array( 'form-field' => 'email', ) ); delete_user_meta( $current_user->ID, '_new_email' ); return; } $hash = md5( $_POST['email'] . time() . wp_rand() ); $new_user_email = array( 'hash' => $hash, 'newemail' => $_POST['email'], ); update_user_meta( $current_user->ID, '_new_email', $new_user_email ); $sitename = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $email_text = __( 'Howdy ###USERNAME###,
You recently requested to have the email address on your account changed.
If this is correct, please click on the following link to change it:
###ADMIN_URL###
You can safely ignore and delete this email if you do not want to
take this action.
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $content = apply_filters( 'new_user_email_content', $email_text, $new_user_email ); $content = str_replace( '###USERNAME###', $current_user->user_login, $content ); $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'profile.php?newuseremail=' . $hash ) ), $content ); $content = str_replace( '###EMAIL###', $_POST['email'], $content ); $content = str_replace( '###SITENAME###', $sitename, $content ); $content = str_replace( '###SITEURL###', home_url(), $content ); wp_mail( $_POST['email'], sprintf( __( '[%s] Email Change Request' ), $sitename ), $content ); $_POST['email'] = $current_user->user_email; } } function new_user_email_admin_notice() { global $pagenow; if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) ) { $email = get_user_meta( get_current_user_id(), '_new_email', true ); if ( $email ) { $message = sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ); wp_admin_notice( $message, array( 'type' => 'info' ) ); } } } function _wp_privacy_action_request_types() { return array( 'export_personal_data', 'remove_personal_data', ); } function wp_register_user_personal_data_exporter( $exporters ) { $exporters['wordpress-user'] = array( 'exporter_friendly_name' => __( 'WordPress User' ), 'callback' => 'wp_user_personal_data_exporter', ); return $exporters; } function wp_user_personal_data_exporter( $email_address ) { $email_address = trim( $email_address ); $data_to_export = array(); $user = get_user_by( 'email', $email_address ); if ( ! $user ) { return array( 'data' => array(), 'done' => true, ); } $user_meta = get_user_meta( $user->ID ); $user_props_to_export = array( 'ID' => __( 'User ID' ), 'user_login' => __( 'User Login Name' ), 'user_nicename' => __( 'User Nice Name' ), 'user_email' => __( 'User Email' ), 'user_url' => __( 'User URL' ), 'user_registered' => __( 'User Registration Date' ), 'display_name' => __( 'User Display Name' ), 'nickname' => __( 'User Nickname' ), 'first_name' => __( 'User First Name' ), 'last_name' => __( 'User Last Name' ), 'description' => __( 'User Description' ), ); $user_data_to_export = array(); foreach ( $user_props_to_export as $key => $name ) { $value = ''; switch ( $key ) { case 'ID': case 'user_login': case 'user_nicename': case 'user_email': case 'user_url': case 'user_registered': case 'display_name': $value = $user->data->$key; break; case 'nickname': case 'first_name': case 'last_name': case 'description': $value = $user_meta[ $key ][0]; break; } if ( ! empty( $value ) ) { $user_data_to_export[] = array( 'name' => $name, 'value' => $value, ); } } $reserved_names = array_values( $user_props_to_export ); $_extra_data = apply_filters( 'wp_privacy_additional_user_profile_data', array(), $user, $reserved_names ); if ( is_array( $_extra_data ) && ! empty( $_extra_data ) ) { $extra_data = array_filter( $_extra_data, static function ( $item ) use ( $reserved_names ) { return ! in_array( $item['name'], $reserved_names, true ); } ); if ( count( $extra_data ) !== count( $_extra_data ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Filter %s returned items with reserved names.' ), '<code>wp_privacy_additional_user_profile_data</code>' ), '5.4.0' ); } if ( ! empty( $extra_data ) ) { $user_data_to_export = array_merge( $user_data_to_export, $extra_data ); } } $data_to_export[] = array( 'group_id' => 'user', 'group_label' => __( 'User' ), 'group_description' => __( 'User’s profile data.' ), 'item_id' => "user-{$user->ID}", 'data' => $user_data_to_export, ); if ( isset( $user_meta['community-events-location'] ) ) { $location = maybe_unserialize( $user_meta['community-events-location'][0] ); $location_props_to_export = array( 'description' => __( 'City' ), 'country' => __( 'Country' ), 'latitude' => __( 'Latitude' ), 'longitude' => __( 'Longitude' ), 'ip' => __( 'IP' ), ); $location_data_to_export = array(); foreach ( $location_props_to_export as $key => $name ) { if ( ! empty( $location[ $key ] ) ) { $location_data_to_export[] = array( 'name' => $name, 'value' => $location[ $key ], ); } } $data_to_export[] = array( 'group_id' => 'community-events-location', 'group_label' => __( 'Community Events Location' ), 'group_description' => __( 'User’s location data used for the Community Events in the WordPress Events and News dashboard widget.' ), 'item_id' => "community-events-location-{$user->ID}", 'data' => $location_data_to_export, ); } if ( isset( $user_meta['session_tokens'] ) ) { $session_tokens = maybe_unserialize( $user_meta['session_tokens'][0] ); $session_tokens_props_to_export = array( 'expiration' => __( 'Expiration' ), 'ip' => __( 'IP' ), 'ua' => __( 'User Agent' ), 'login' => __( 'Last Login' ), ); foreach ( $session_tokens as $token_key => $session_token ) { $session_tokens_data_to_export = array(); foreach ( $session_tokens_props_to_export as $key => $name ) { if ( ! empty( $session_token[ $key ] ) ) { $value = $session_token[ $key ]; if ( in_array( $key, array( 'expiration', 'login' ), true ) ) { $value = date_i18n( 'F d, Y H:i A', $value ); } $session_tokens_data_to_export[] = array( 'name' => $name, 'value' => $value, ); } } $data_to_export[] = array( 'group_id' => 'session-tokens', 'group_label' => __( 'Session Tokens' ), 'group_description' => __( 'User’s Session Tokens data.' ), 'item_id' => "session-tokens-{$user->ID}-{$token_key}", 'data' => $session_tokens_data_to_export, ); } } return array( 'data' => $data_to_export, 'done' => true, ); } function _wp_privacy_account_request_confirmed( $request_id ) { $request = wp_get_user_request( $request_id ); if ( ! $request ) { return; } if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) { return; } update_post_meta( $request_id, '_wp_user_request_confirmed_timestamp', time() ); wp_update_post( array( 'ID' => $request_id, 'post_status' => 'request-confirmed', ) ); } function _wp_privacy_send_request_confirmation_notification( $request_id ) { $request = wp_get_user_request( $request_id ); if ( ! ( $request instanceof WP_User_Request ) || 'request-confirmed' !== $request->status ) { return; } $already_notified = (bool) get_post_meta( $request_id, '_wp_admin_notified', true ); if ( $already_notified ) { return; } if ( 'export_personal_data' === $request->action_name ) { $manage_url = admin_url( 'export-personal-data.php' ); } elseif ( 'remove_personal_data' === $request->action_name ) { $manage_url = admin_url( 'erase-personal-data.php' ); } $action_description = wp_user_request_action_description( $request->action_name ); $admin_email = apply_filters( 'user_request_confirmed_email_to', get_site_option( 'admin_email' ), $request ); $email_data = array( 'request' => $request, 'user_email' => $request->email, 'description' => $action_description, 'manage_url' => $manage_url, 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), 'siteurl' => home_url(), 'admin_email' => $admin_email, ); $subject = sprintf( __( '[%1$s] Action Confirmed: %2$s' ), $email_data['sitename'], $action_description ); $subject = apply_filters( 'user_request_confirmed_email_subject', $subject, $email_data['sitename'], $email_data ); $content = __( 'Howdy,
A user data privacy request has been confirmed on ###SITENAME###:
User: ###USER_EMAIL###
Request: ###DESCRIPTION###
You can view and manage these data privacy requests here:
###MANAGE_URL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $content = apply_filters_deprecated( 'user_confirmed_action_email_content', array( $content, $email_data ), '5.8.0', sprintf( __( '%1$s or %2$s' ), 'user_request_confirmed_email_content', 'user_erasure_fulfillment_email_content' ) ); $content = apply_filters( 'user_request_confirmed_email_content', $content, $email_data ); $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); $content = str_replace( '###USER_EMAIL###', $email_data['user_email'], $content ); $content = str_replace( '###DESCRIPTION###', $email_data['description'], $content ); $content = str_replace( '###MANAGE_URL###', sanitize_url( $email_data['manage_url'] ), $content ); $content = str_replace( '###SITEURL###', sanitize_url( $email_data['siteurl'] ), $content ); $headers = ''; $headers = apply_filters( 'user_request_confirmed_email_headers', $headers, $subject, $content, $request_id, $email_data ); $email_sent = wp_mail( $email_data['admin_email'], $subject, $content, $headers ); if ( $email_sent ) { update_post_meta( $request_id, '_wp_admin_notified', true ); } } function _wp_privacy_send_erasure_fulfillment_notification( $request_id ) { $request = wp_get_user_request( $request_id ); if ( ! ( $request instanceof WP_User_Request ) || 'request-completed' !== $request->status ) { return; } $already_notified = (bool) get_post_meta( $request_id, '_wp_user_notified', true ); if ( $already_notified ) { return; } if ( ! empty( $request->user_id ) ) { $switched_locale = switch_to_user_locale( $request->user_id ); } else { $switched_locale = switch_to_locale( get_locale() ); } $user_email = apply_filters( 'user_erasure_fulfillment_email_to', $request->email, $request ); $email_data = array( 'request' => $request, 'message_recipient' => $user_email, 'privacy_policy_url' => get_privacy_policy_url(), 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), 'siteurl' => home_url(), ); $subject = sprintf( __( '[%s] Erasure Request Fulfilled' ), $email_data['sitename'] ); $subject = apply_filters_deprecated( 'user_erasure_complete_email_subject', array( $subject, $email_data['sitename'], $email_data ), '5.8.0', 'user_erasure_fulfillment_email_subject' ); $subject = apply_filters( 'user_erasure_fulfillment_email_subject', $subject, $email_data['sitename'], $email_data ); $content = __( 'Howdy,
Your request to erase your personal data on ###SITENAME### has been completed.
If you have any follow-up questions or concerns, please contact the site administrator.
Regards,
All at ###SITENAME###
###SITEURL###' ); if ( ! empty( $email_data['privacy_policy_url'] ) ) { $content = __( 'Howdy,
Your request to erase your personal data on ###SITENAME### has been completed.
If you have any follow-up questions or concerns, please contact the site administrator.
For more information, you can also read our privacy policy: ###PRIVACY_POLICY_URL###
Regards,
All at ###SITENAME###
###SITEURL###' ); } $content = apply_filters_deprecated( 'user_confirmed_action_email_content', array( $content, $email_data ), '5.8.0', sprintf( __( '%1$s or %2$s' ), 'user_erasure_fulfillment_email_content', 'user_request_confirmed_email_content' ) ); $content = apply_filters( 'user_erasure_fulfillment_email_content', $content, $email_data ); $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); $content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content ); $content = str_replace( '###SITEURL###', sanitize_url( $email_data['siteurl'] ), $content ); $headers = ''; $headers = apply_filters_deprecated( 'user_erasure_complete_email_headers', array( $headers, $subject, $content, $request_id, $email_data ), '5.8.0', 'user_erasure_fulfillment_email_headers' ); $headers = apply_filters( 'user_erasure_fulfillment_email_headers', $headers, $subject, $content, $request_id, $email_data ); $email_sent = wp_mail( $user_email, $subject, $content, $headers ); if ( $switched_locale ) { restore_previous_locale(); } if ( $email_sent ) { update_post_meta( $request_id, '_wp_user_notified', true ); } } function _wp_privacy_account_request_confirmed_message( $request_id ) { $request = wp_get_user_request( $request_id ); $message = '<p class="success">' . __( 'Action has been confirmed.' ) . '</p>'; $message .= '<p>' . __( 'The site administrator has been notified and will fulfill your request as soon as possible.' ) . '</p>'; if ( $request && in_array( $request->action_name, _wp_privacy_action_request_types(), true ) ) { if ( 'export_personal_data' === $request->action_name ) { $message = '<p class="success">' . __( 'Thanks for confirming your export request.' ) . '</p>'; $message .= '<p>' . __( 'The site administrator has been notified. You will receive a link to download your export via email when they fulfill your request.' ) . '</p>'; } elseif ( 'remove_personal_data' === $request->action_name ) { $message = '<p class="success">' . __( 'Thanks for confirming your erasure request.' ) . '</p>'; $message .= '<p>' . __( 'The site administrator has been notified. You will receive an email confirmation when they erase your data.' ) . '</p>'; } } $message = apply_filters( 'user_request_action_confirmed_message', $message, $request_id ); return $message; } function wp_create_user_request( $email_address = '', $action_name = '', $request_data = array(), $status = 'pending' ) { $email_address = sanitize_email( $email_address ); $action_name = sanitize_key( $action_name ); if ( ! is_email( $email_address ) ) { return new WP_Error( 'invalid_email', __( 'Invalid email address.' ) ); } if ( ! in_array( $action_name, _wp_privacy_action_request_types(), true ) ) { return new WP_Error( 'invalid_action', __( 'Invalid action name.' ) ); } if ( ! in_array( $status, array( 'pending', 'confirmed' ), true ) ) { return new WP_Error( 'invalid_status', __( 'Invalid request status.' ) ); } $user = get_user_by( 'email', $email_address ); $user_id = $user && ! is_wp_error( $user ) ? $user->ID : 0; $requests_query = new WP_Query( array( 'post_type' => 'user_request', 'post_name__in' => array( $action_name ), 'title' => $email_address, 'post_status' => array( 'request-pending', 'request-confirmed', ), 'fields' => 'ids', ) ); if ( $requests_query->found_posts ) { return new WP_Error( 'duplicate_request', __( 'An incomplete personal data request for this email address already exists.' ) ); } $request_id = wp_insert_post( array( 'post_author' => $user_id, 'post_name' => $action_name, 'post_title' => $email_address, 'post_content' => wp_json_encode( $request_data ), 'post_status' => 'request-' . $status, 'post_type' => 'user_request', 'post_date' => current_time( 'mysql', false ), 'post_date_gmt' => current_time( 'mysql', true ), ), true ); return $request_id; } function wp_user_request_action_description( $action_name ) { switch ( $action_name ) { case 'export_personal_data': $description = __( 'Export Personal Data' ); break; case 'remove_personal_data': $description = __( 'Erase Personal Data' ); break; default: $description = sprintf( __( 'Confirm the "%s" action' ), $action_name ); break; } return apply_filters( 'user_request_action_description', $description, $action_name ); } function wp_send_user_request( $request_id ) { $request_id = absint( $request_id ); $request = wp_get_user_request( $request_id ); if ( ! $request ) { return new WP_Error( 'invalid_request', __( 'Invalid personal data request.' ) ); } if ( ! empty( $request->user_id ) ) { $switched_locale = switch_to_user_locale( $request->user_id ); } else { $switched_locale = switch_to_locale( get_locale() ); } $request->confirm_key = wp_generate_user_request_key( $request_id ); $email_data = array( 'request' => $request, 'email' => $request->email, 'description' => wp_user_request_action_description( $request->action_name ), 'confirm_url' => add_query_arg( array( 'action' => 'confirmaction', 'request_id' => $request_id, 'confirm_key' => $request->confirm_key, ), wp_login_url() ), 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), 'siteurl' => home_url(), ); $subject = sprintf( __( '[%1$s] Confirm Action: %2$s' ), $email_data['sitename'], $email_data['description'] ); $subject = apply_filters( 'user_request_action_email_subject', $subject, $email_data['sitename'], $email_data ); $content = __( 'Howdy,
A request has been made to perform the following action on your account:
###DESCRIPTION###
To confirm this, please click on the following link:
###CONFIRM_URL###
You can safely ignore and delete this email if you do not want to
take this action.
Regards,
All at ###SITENAME###
###SITEURL###' ); $content = apply_filters( 'user_request_action_email_content', $content, $email_data ); $content = str_replace( '###DESCRIPTION###', $email_data['description'], $content ); $content = str_replace( '###CONFIRM_URL###', sanitize_url( $email_data['confirm_url'] ), $content ); $content = str_replace( '###EMAIL###', $email_data['email'], $content ); $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); $content = str_replace( '###SITEURL###', sanitize_url( $email_data['siteurl'] ), $content ); $headers = ''; $headers = apply_filters( 'user_request_action_email_headers', $headers, $subject, $content, $request_id, $email_data ); $email_sent = wp_mail( $email_data['email'], $subject, $content, $headers ); if ( $switched_locale ) { restore_previous_locale(); } if ( ! $email_sent ) { return new WP_Error( 'privacy_email_error', __( 'Unable to send personal data export confirmation email.' ) ); } return true; } function wp_generate_user_request_key( $request_id ) { $key = wp_generate_password( 20, false ); wp_update_post( array( 'ID' => $request_id, 'post_status' => 'request-pending', 'post_password' => wp_fast_hash( $key ), ) ); return $key; } function wp_validate_user_request_key( $request_id, $key ) { $request_id = absint( $request_id ); $request = wp_get_user_request( $request_id ); $saved_key = $request->confirm_key; $key_request_time = $request->modified_timestamp; if ( ! $request || ! $saved_key || ! $key_request_time ) { return new WP_Error( 'invalid_request', __( 'Invalid personal data request.' ) ); } if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) { return new WP_Error( 'expired_request', __( 'This personal data request has expired.' ) ); } if ( empty( $key ) ) { return new WP_Error( 'missing_key', __( 'The confirmation key is missing from this personal data request.' ) ); } $expiration_duration = (int) apply_filters( 'user_request_key_expiration', DAY_IN_SECONDS ); $expiration_time = $key_request_time + $expiration_duration; if ( ! wp_verify_fast_hash( $key, $saved_key ) ) { return new WP_Error( 'invalid_key', __( 'The confirmation key is invalid for this personal data request.' ) ); } if ( ! $expiration_time || time() > $expiration_time ) { return new WP_Error( 'expired_key', __( 'The confirmation key has expired for this personal data request.' ) ); } return true; } function wp_get_user_request( $request_id ) { $request_id = absint( $request_id ); $post = get_post( $request_id ); if ( ! $post || 'user_request' !== $post->post_type ) { return false; } return new WP_User_Request( $post ); } function wp_is_application_passwords_supported() { return is_ssl() || 'local' === wp_get_environment_type(); } function wp_is_application_passwords_available() { return apply_filters( 'wp_is_application_passwords_available', wp_is_application_passwords_supported() ); } function wp_is_application_passwords_available_for_user( $user ) { if ( ! wp_is_application_passwords_available() ) { return false; } if ( ! is_object( $user ) ) { $user = get_userdata( $user ); } if ( ! $user || ! $user->exists() ) { return false; } return apply_filters( 'wp_is_application_passwords_available_for_user', true, $user ); } function wp_register_persisted_preferences_meta() { global $wpdb; $meta_key = $wpdb->get_blog_prefix() . 'persisted_preferences'; register_meta( 'user', $meta_key, array( 'type' => 'object', 'single' => true, 'show_in_rest' => array( 'name' => 'persisted_preferences', 'type' => 'object', 'schema' => array( 'type' => 'object', 'context' => array( 'edit' ), 'properties' => array( '_modified' => array( 'description' => __( 'The date and time the preferences were updated.' ), 'type' => 'string', 'format' => 'date-time', 'readonly' => false, ), ), 'additionalProperties' => true, ), ), ) ); } function wp_cache_set_users_last_changed() { wp_cache_set_last_changed( 'users' ); } function wp_is_password_reset_allowed_for_user( $user ) { if ( ! is_object( $user ) ) { $user = get_userdata( $user ); } if ( ! $user || ! $user->exists() ) { return false; } $allow = true; if ( is_multisite() && is_user_spammy( $user ) ) { $allow = false; } return apply_filters( 'allow_password_reset', $allow, $user->ID ); }
###require ABSPATH . WPINC . '/class-wp-user-query.php';
class WP_User_Query { public $query_vars = array(); private $results; private $total_users = 0; public $meta_query = false; public $request; private $compat_fields = array( 'results', 'total_users' ); public $query_fields; public $query_from; public $query_where; public $query_orderby; public $query_limit; public function __construct( $query = null ) { if ( ! empty( $query ) ) { $this->prepare_query( $query ); $this->query(); } } public static function fill_query_vars( $args ) { $defaults = array( 'blog_id' => get_current_blog_id(), 'role' => '', 'role__in' => array(), 'role__not_in' => array(), 'capability' => '', 'capability__in' => array(), 'capability__not_in' => array(), 'meta_key' => '', 'meta_value' => '', 'meta_compare' => '', 'include' => array(), 'exclude' => array(), 'search' => '', 'search_columns' => array(), 'orderby' => 'login', 'order' => 'ASC', 'offset' => '', 'number' => '', 'paged' => 1, 'count_total' => true, 'fields' => 'all', 'who' => '', 'has_published_posts' => null, 'nicename' => '', 'nicename__in' => array(), 'nicename__not_in' => array(), 'login' => '', 'login__in' => array(), 'login__not_in' => array(), 'cache_results' => true, ); return wp_parse_args( $args, $defaults ); } public function prepare_query( $query = array() ) { global $wpdb, $wp_roles; if ( empty( $this->query_vars ) || ! empty( $query ) ) { $this->query_limit = null; $this->query_vars = $this->fill_query_vars( $query ); } do_action_ref_array( 'pre_get_users', array( &$this ) ); $qv =& $this->query_vars; $qv = $this->fill_query_vars( $qv ); $allowed_fields = array( 'id', 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'user_status', 'display_name', ); if ( is_multisite() ) { $allowed_fields[] = 'spam'; $allowed_fields[] = 'deleted'; } if ( is_array( $qv['fields'] ) ) { $qv['fields'] = array_map( 'strtolower', $qv['fields'] ); $qv['fields'] = array_intersect( array_unique( $qv['fields'] ), $allowed_fields ); if ( empty( $qv['fields'] ) ) { $qv['fields'] = array( 'id' ); } $this->query_fields = array(); foreach ( $qv['fields'] as $field ) { $field = 'id' === $field ? 'ID' : sanitize_key( $field ); $this->query_fields[] = "$wpdb->users.$field"; } $this->query_fields = implode( ',', $this->query_fields ); } elseif ( 'all_with_meta' === $qv['fields'] || 'all' === $qv['fields'] || ! in_array( $qv['fields'], $allowed_fields, true ) ) { $this->query_fields = "$wpdb->users.ID"; } else { $field = 'id' === strtolower( $qv['fields'] ) ? 'ID' : sanitize_key( $qv['fields'] ); $this->query_fields = "$wpdb->users.$field"; } if ( isset( $qv['count_total'] ) && $qv['count_total'] ) { $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; } $this->query_from = "FROM $wpdb->users"; $this->query_where = 'WHERE 1=1'; if ( ! empty( $qv['include'] ) ) { $include = wp_parse_id_list( $qv['include'] ); } else { $include = false; } $blog_id = 0; if ( isset( $qv['blog_id'] ) ) { $blog_id = absint( $qv['blog_id'] ); } if ( $qv['has_published_posts'] && $blog_id ) { if ( true === $qv['has_published_posts'] ) { $post_types = get_post_types( array( 'public' => true ) ); } else { $post_types = (array) $qv['has_published_posts']; } foreach ( $post_types as &$post_type ) { $post_type = $wpdb->prepare( '%s', $post_type ); } $posts_table = $wpdb->get_blog_prefix( $blog_id ) . 'posts'; $this->query_where .= " AND $wpdb->users.ID IN ( SELECT DISTINCT $posts_table.post_author FROM $posts_table WHERE $posts_table.post_status = 'publish' AND $posts_table.post_type IN ( " . implode( ', ', $post_types ) . ' ) )'; } if ( '' !== $qv['nicename'] ) { $this->query_where .= $wpdb->prepare( ' AND user_nicename = %s', $qv['nicename'] ); } if ( ! empty( $qv['nicename__in'] ) ) { $sanitized_nicename__in = array_map( 'esc_sql', $qv['nicename__in'] ); $nicename__in = implode( "','", $sanitized_nicename__in ); $this->query_where .= " AND user_nicename IN ( '$nicename__in' )"; } if ( ! empty( $qv['nicename__not_in'] ) ) { $sanitized_nicename__not_in = array_map( 'esc_sql', $qv['nicename__not_in'] ); $nicename__not_in = implode( "','", $sanitized_nicename__not_in ); $this->query_where .= " AND user_nicename NOT IN ( '$nicename__not_in' )"; } if ( '' !== $qv['login'] ) { $this->query_where .= $wpdb->prepare( ' AND user_login = %s', $qv['login'] ); } if ( ! empty( $qv['login__in'] ) ) { $sanitized_login__in = array_map( 'esc_sql', $qv['login__in'] ); $login__in = implode( "','", $sanitized_login__in ); $this->query_where .= " AND user_login IN ( '$login__in' )"; } if ( ! empty( $qv['login__not_in'] ) ) { $sanitized_login__not_in = array_map( 'esc_sql', $qv['login__not_in'] ); $login__not_in = implode( "','", $sanitized_login__not_in ); $this->query_where .= " AND user_login NOT IN ( '$login__not_in' )"; } $this->meta_query = new WP_Meta_Query(); $this->meta_query->parse_query_vars( $qv ); if ( isset( $qv['who'] ) && 'authors' === $qv['who'] && $blog_id ) { _deprecated_argument( 'WP_User_Query', '5.9.0', sprintf( __( '%1$s is deprecated. Use %2$s instead.' ), '<code>who</code>', '<code>capability</code>' ) ); $who_query = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'user_level', 'value' => 0, 'compare' => '!=', ); $qv['blog_id'] = 0; $blog_id = 0; if ( empty( $this->meta_query->queries ) ) { $this->meta_query->queries = array( $who_query ); } else { $this->meta_query->queries = array( 'relation' => 'AND', array( $this->meta_query->queries, $who_query ), ); } $this->meta_query->parse_query_vars( $this->meta_query->queries ); } $roles = array(); if ( isset( $qv['role'] ) ) { if ( is_array( $qv['role'] ) ) { $roles = $qv['role']; } elseif ( is_string( $qv['role'] ) && ! empty( $qv['role'] ) ) { $roles = array_map( 'trim', explode( ',', $qv['role'] ) ); } } $role__in = array(); if ( isset( $qv['role__in'] ) ) { $role__in = (array) $qv['role__in']; } $role__not_in = array(); if ( isset( $qv['role__not_in'] ) ) { $role__not_in = (array) $qv['role__not_in']; } $available_roles = array(); if ( ! empty( $qv['capability'] ) || ! empty( $qv['capability__in'] ) || ! empty( $qv['capability__not_in'] ) ) { $wp_roles->for_site( $blog_id ); $available_roles = $wp_roles->roles; } $capabilities = array(); if ( ! empty( $qv['capability'] ) ) { if ( is_array( $qv['capability'] ) ) { $capabilities = $qv['capability']; } elseif ( is_string( $qv['capability'] ) ) { $capabilities = array_map( 'trim', explode( ',', $qv['capability'] ) ); } } $capability__in = array(); if ( ! empty( $qv['capability__in'] ) ) { $capability__in = (array) $qv['capability__in']; } $capability__not_in = array(); if ( ! empty( $qv['capability__not_in'] ) ) { $capability__not_in = (array) $qv['capability__not_in']; } $caps_with_roles = array(); foreach ( $available_roles as $role => $role_data ) { $role_caps = array_keys( array_filter( $role_data['capabilities'] ) ); foreach ( $capabilities as $cap ) { if ( in_array( $cap, $role_caps, true ) ) { $caps_with_roles[ $cap ][] = $role; break; } } foreach ( $capability__in as $cap ) { if ( in_array( $cap, $role_caps, true ) ) { $role__in[] = $role; break; } } foreach ( $capability__not_in as $cap ) { if ( in_array( $cap, $role_caps, true ) ) { $role__not_in[] = $role; break; } } } $role__in = array_merge( $role__in, $capability__in ); $role__not_in = array_merge( $role__not_in, $capability__not_in ); $roles = array_unique( $roles ); $role__in = array_unique( $role__in ); $role__not_in = array_unique( $role__not_in ); if ( $blog_id && ! empty( $capabilities ) ) { $capabilities_clauses = array( 'relation' => 'AND' ); foreach ( $capabilities as $cap ) { $clause = array( 'relation' => 'OR' ); $clause[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $cap . '"', 'compare' => 'LIKE', ); if ( ! empty( $caps_with_roles[ $cap ] ) ) { foreach ( $caps_with_roles[ $cap ] as $role ) { $clause[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'LIKE', ); } } $capabilities_clauses[] = $clause; } $role_queries[] = $capabilities_clauses; if ( empty( $this->meta_query->queries ) ) { $this->meta_query->queries[] = $capabilities_clauses; } else { $this->meta_query->queries = array( 'relation' => 'AND', array( $this->meta_query->queries, array( $capabilities_clauses ) ), ); } $this->meta_query->parse_query_vars( $this->meta_query->queries ); } if ( $blog_id && ( ! empty( $roles ) || ! empty( $role__in ) || ! empty( $role__not_in ) || is_multisite() ) ) { $role_queries = array(); $roles_clauses = array( 'relation' => 'AND' ); if ( ! empty( $roles ) ) { foreach ( $roles as $role ) { $roles_clauses[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'LIKE', ); } $role_queries[] = $roles_clauses; } $role__in_clauses = array( 'relation' => 'OR' ); if ( ! empty( $role__in ) ) { foreach ( $role__in as $role ) { $role__in_clauses[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'LIKE', ); } $role_queries[] = $role__in_clauses; } $role__not_in_clauses = array( 'relation' => 'AND' ); if ( ! empty( $role__not_in ) ) { foreach ( $role__not_in as $role ) { $role__not_in_clauses[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'NOT LIKE', ); } $role_queries[] = $role__not_in_clauses; } if ( empty( $role_queries ) ) { $role_queries[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'compare' => 'EXISTS', ); } $role_queries['relation'] = 'AND'; if ( empty( $this->meta_query->queries ) ) { $this->meta_query->queries = $role_queries; } else { $this->meta_query->queries = array( 'relation' => 'AND', array( $this->meta_query->queries, $role_queries ), ); } $this->meta_query->parse_query_vars( $this->meta_query->queries ); } if ( ! empty( $this->meta_query->queries ) ) { $clauses = $this->meta_query->get_sql( 'user', $wpdb->users, 'ID', $this ); $this->query_from .= $clauses['join']; $this->query_where .= $clauses['where']; if ( $this->meta_query->has_or_relation() ) { $this->query_fields = 'DISTINCT ' . $this->query_fields; } } $qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : ''; $order = $this->parse_order( $qv['order'] ); if ( empty( $qv['orderby'] ) ) { $ordersby = array( 'user_login' => $order ); } elseif ( is_array( $qv['orderby'] ) ) { $ordersby = $qv['orderby']; } else { $ordersby = preg_split( '/[,\s]+/', $qv['orderby'] ); } $orderby_array = array(); foreach ( $ordersby as $_key => $_value ) { if ( ! $_value ) { continue; } if ( is_int( $_key ) ) { $_orderby = $_value; $_order = $order; } else { $_orderby = $_key; $_order = $_value; } $parsed = $this->parse_orderby( $_orderby ); if ( ! $parsed ) { continue; } if ( 'nicename__in' === $_orderby || 'login__in' === $_orderby ) { $orderby_array[] = $parsed; } else { $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); } } if ( empty( $orderby_array ) ) { $orderby_array[] = "user_login $order"; } $this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array ); if ( isset( $qv['number'] ) && $qv['number'] > 0 ) { if ( $qv['offset'] ) { $this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] ); } else { $this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] ); } } $search = ''; if ( isset( $qv['search'] ) ) { $search = trim( $qv['search'] ); } if ( $search ) { $leading_wild = ( ltrim( $search, '*' ) !== $search ); $trailing_wild = ( rtrim( $search, '*' ) !== $search ); if ( $leading_wild && $trailing_wild ) { $wild = 'both'; } elseif ( $leading_wild ) { $wild = 'leading'; } elseif ( $trailing_wild ) { $wild = 'trailing'; } else { $wild = false; } if ( $wild ) { $search = trim( $search, '*' ); } $search_columns = array(); if ( $qv['search_columns'] ) { $search_columns = array_intersect( $qv['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name' ) ); } if ( ! $search_columns ) { if ( str_contains( $search, '@' ) ) { $search_columns = array( 'user_email' ); } elseif ( is_numeric( $search ) ) { $search_columns = array( 'user_login', 'ID' ); } elseif ( preg_match( '|^https?://|', $search ) && ! ( is_multisite() && wp_is_large_network( 'users' ) ) ) { $search_columns = array( 'user_url' ); } else { $search_columns = array( 'user_login', 'user_url', 'user_email', 'user_nicename', 'display_name' ); } } $search_columns = apply_filters( 'user_search_columns', $search_columns, $search, $this ); $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild ); } if ( ! empty( $include ) ) { $ids = implode( ',', $include ); $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; } elseif ( ! empty( $qv['exclude'] ) ) { $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)"; } if ( ! empty( $qv['date_query'] ) && is_array( $qv['date_query'] ) ) { $date_query = new WP_Date_Query( $qv['date_query'], 'user_registered' ); $this->query_where .= $date_query->get_sql(); } do_action_ref_array( 'pre_user_query', array( &$this ) ); } public function query() { global $wpdb; if ( ! did_action( 'plugins_loaded' ) ) { _doing_it_wrong( 'WP_User_Query::query', sprintf( __( 'User queries should not be run before the %s hook.' ), '<code>plugins_loaded</code>' ), '6.1.1' ); } $qv =& $this->query_vars; if ( is_array( $qv['fields'] ) && count( $qv['fields'] ) > 3 ) { $qv['cache_results'] = false; } $this->results = apply_filters_ref_array( 'users_pre_query', array( null, &$this ) ); if ( null === $this->results ) { $this->request = "SELECT {$this->query_fields}
{$this->query_from}
{$this->query_where}
{$this->query_orderby}
{$this->query_limit}"; $cache_value = false; $cache_key = $this->generate_cache_key( $qv, $this->request ); $cache_group = 'user-queries'; $last_changed = $this->get_cache_last_changed( $qv ); if ( $qv['cache_results'] ) { $cache_value = wp_cache_get_salted( $cache_key, $cache_group, $last_changed ); } if ( false !== $cache_value ) { $this->results = $cache_value['user_data']; $this->total_users = $cache_value['total_users']; } else { if ( is_array( $qv['fields'] ) ) { $this->results = $wpdb->get_results( $this->request ); } else { $this->results = $wpdb->get_col( $this->request ); } if ( isset( $qv['count_total'] ) && $qv['count_total'] ) { $found_users_query = apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()', $this ); $this->total_users = (int) $wpdb->get_var( $found_users_query ); } if ( $qv['cache_results'] ) { $cache_value = array( 'user_data' => $this->results, 'total_users' => $this->total_users, ); wp_cache_set_salted( $cache_key, $cache_value, $cache_group, $last_changed ); } } } if ( ! $this->results ) { return; } if ( is_array( $qv['fields'] ) && isset( $this->results[0]->ID ) ) { foreach ( $this->results as $result ) { $result->id = $result->ID; } } elseif ( 'all_with_meta' === $qv['fields'] || 'all' === $qv['fields'] ) { if ( function_exists( 'cache_users' ) ) { cache_users( $this->results ); } $r = array(); foreach ( $this->results as $userid ) { if ( 'all_with_meta' === $qv['fields'] ) { $r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] ); } else { $r[] = new WP_User( $userid, '', $qv['blog_id'] ); } } $this->results = $r; } } public function get( $query_var ) { if ( isset( $this->query_vars[ $query_var ] ) ) { return $this->query_vars[ $query_var ]; } return null; } public function set( $query_var, $value ) { $this->query_vars[ $query_var ] = $value; } protected function get_search_sql( $search, $columns, $wild = false ) { global $wpdb; $searches = array(); $leading_wild = ( 'leading' === $wild || 'both' === $wild ) ? '%' : ''; $trailing_wild = ( 'trailing' === $wild || 'both' === $wild ) ? '%' : ''; $like = $leading_wild . $wpdb->esc_like( $search ) . $trailing_wild; foreach ( $columns as $column ) { if ( 'ID' === $column ) { $searches[] = $wpdb->prepare( "$column = %s", $search ); } else { $searches[] = $wpdb->prepare( "$column LIKE %s", $like ); } } return ' AND (' . implode( ' OR ', $searches ) . ')'; } public function get_results() { return $this->results; } public function get_total() { return $this->total_users; } protected function parse_orderby( $orderby ) { global $wpdb; $meta_query_clauses = $this->meta_query->get_clauses(); $_orderby = ''; if ( in_array( $orderby, array( 'login', 'nicename', 'email', 'url', 'registered' ), true ) ) { $_orderby = 'user_' . $orderby; } elseif ( in_array( $orderby, array( 'user_login', 'user_nicename', 'user_email', 'user_url', 'user_registered' ), true ) ) { $_orderby = $orderby; } elseif ( 'name' === $orderby || 'display_name' === $orderby ) { $_orderby = 'display_name'; } elseif ( 'post_count' === $orderby ) { $where = get_posts_by_author_sql( 'post' ); $this->query_from .= " LEFT OUTER JOIN (
SELECT post_author, COUNT(*) as post_count
FROM $wpdb->posts
$where
GROUP BY post_author
) p ON ({$wpdb->users}.ID = p.post_author)"; $_orderby = 'post_count'; } elseif ( 'ID' === $orderby || 'id' === $orderby ) { $_orderby = 'ID'; } elseif ( 'meta_value' === $orderby || $this->get( 'meta_key' ) === $orderby ) { $_orderby = "$wpdb->usermeta.meta_value"; } elseif ( 'meta_value_num' === $orderby ) { $_orderby = "$wpdb->usermeta.meta_value+0"; } elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) { $include = wp_parse_id_list( $this->query_vars['include'] ); $include_sql = implode( ',', $include ); $_orderby = "FIELD( $wpdb->users.ID, $include_sql )"; } elseif ( 'nicename__in' === $orderby ) { $sanitized_nicename__in = array_map( 'esc_sql', $this->query_vars['nicename__in'] ); $nicename__in = implode( "','", $sanitized_nicename__in ); $_orderby = "FIELD( user_nicename, '$nicename__in' )"; } elseif ( 'login__in' === $orderby ) { $sanitized_login__in = array_map( 'esc_sql', $this->query_vars['login__in'] ); $login__in = implode( "','", $sanitized_login__in ); $_orderby = "FIELD( user_login, '$login__in' )"; } elseif ( isset( $meta_query_clauses[ $orderby ] ) ) { $meta_clause = $meta_query_clauses[ $orderby ]; $_orderby = sprintf( 'CAST(%s.meta_value AS %s)', esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) ); } return $_orderby; } protected function generate_cache_key( array $deprecated, $sql ) { global $wpdb; $sql = $wpdb->remove_placeholder_escape( $sql ); $key = md5( $sql ); return "get_users:$key"; } protected function get_cache_last_changed( array $args ) { $last_changed = (array) wp_cache_get_last_changed( 'users' ); if ( empty( $args['orderby'] ) ) { $ordersby = array( 'user_login' => '' ); } elseif ( is_array( $args['orderby'] ) ) { $ordersby = $args['orderby']; } else { $ordersby = preg_split( '/[,\s]+/', $args['orderby'] ); } $blog_id = 0; if ( isset( $args['blog_id'] ) ) { $blog_id = absint( $args['blog_id'] ); } if ( $args['has_published_posts'] || in_array( 'post_count', $ordersby, true ) ) { $switch = $blog_id && get_current_blog_id() !== $blog_id; if ( $switch ) { switch_to_blog( $blog_id ); } $last_changed[] = wp_cache_get_last_changed( 'posts' ); if ( $switch ) { restore_current_blog(); } } return $last_changed; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'DESC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } public function __get( $name ) { if ( in_array( $name, $this->compat_fields, true ) ) { return $this->$name; } wp_trigger_error( __METHOD__, "The property `{$name}` is not declared. Getting a dynamic property is " . 'deprecated since version 6.4.0! Instead, declare the property on the class.', E_USER_DEPRECATED ); return null; } public function __set( $name, $value ) { if ( in_array( $name, $this->compat_fields, true ) ) { $this->$name = $value; return; } wp_trigger_error( __METHOD__, "The property `{$name}` is not declared. Setting a dynamic property is " . 'deprecated since version 6.4.0! Instead, declare the property on the class.', E_USER_DEPRECATED ); } public function __isset( $name ) { if ( in_array( $name, $this->compat_fields, true ) ) { return isset( $this->$name ); } wp_trigger_error( __METHOD__, "The property `{$name}` is not declared. Checking `isset()` on a dynamic property " . 'is deprecated since version 6.4.0! Instead, declare the property on the class.', E_USER_DEPRECATED ); return false; } public function __unset( $name ) { if ( in_array( $name, $this->compat_fields, true ) ) { unset( $this->$name ); return; } wp_trigger_error( __METHOD__, "A property `{$name}` is not declared. Unsetting a dynamic property is " . 'deprecated since version 6.4.0! Instead, declare the property on the class.', E_USER_DEPRECATED ); } public function __call( $name, $arguments ) { if ( 'get_search_sql' === $name ) { return $this->get_search_sql( ...$arguments ); } return false; } }
###require ABSPATH . WPINC . '/class-wp-session-tokens.php';
abstract class WP_Session_Tokens { protected $user_id; protected function __construct( $user_id ) { $this->user_id = $user_id; } final public static function get_instance( $user_id ) { $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' ); return new $manager( $user_id ); } private function hash_token( $token ) { return hash( 'sha256', $token ); } final public function get( $token ) { $verifier = $this->hash_token( $token ); return $this->get_session( $verifier ); } final public function verify( $token ) { $verifier = $this->hash_token( $token ); return (bool) $this->get_session( $verifier ); } final public function create( $expiration ) { $session = apply_filters( 'attach_session_information', array(), $this->user_id ); $session['expiration'] = $expiration; if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { $session['ip'] = $_SERVER['REMOTE_ADDR']; } if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) { $session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); } $session['login'] = time(); $token = wp_generate_password( 43, false, false ); $this->update( $token, $session ); return $token; } final public function update( $token, $session ) { $verifier = $this->hash_token( $token ); $this->update_session( $verifier, $session ); } final public function destroy( $token ) { $verifier = $this->hash_token( $token ); $this->update_session( $verifier, null ); } final public function destroy_others( $token_to_keep ) { $verifier = $this->hash_token( $token_to_keep ); $session = $this->get_session( $verifier ); if ( $session ) { $this->destroy_other_sessions( $verifier ); } else { $this->destroy_all_sessions(); } } final protected function is_still_valid( $session ) { return $session['expiration'] >= time(); } final public function destroy_all() { $this->destroy_all_sessions(); } final public static function destroy_all_for_all_users() { $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' ); call_user_func( array( $manager, 'drop_sessions' ) ); } final public function get_all() { return array_values( $this->get_sessions() ); } abstract protected function get_sessions(); abstract protected function get_session( $verifier ); abstract protected function update_session( $verifier, $session = null ); abstract protected function destroy_other_sessions( $verifier ); abstract protected function destroy_all_sessions(); public static function drop_sessions() {} }
###require ABSPATH . WPINC . '/class-wp-user-meta-session-tokens.php';
class WP_User_Meta_Session_Tokens extends WP_Session_Tokens { protected function get_sessions() { $sessions = get_user_meta( $this->user_id, 'session_tokens', true ); if ( ! is_array( $sessions ) ) { return array(); } $sessions = array_map( array( $this, 'prepare_session' ), $sessions ); return array_filter( $sessions, array( $this, 'is_still_valid' ) ); } protected function prepare_session( $session ) { if ( is_int( $session ) ) { return array( 'expiration' => $session ); } return $session; } protected function get_session( $verifier ) { $sessions = $this->get_sessions(); if ( isset( $sessions[ $verifier ] ) ) { return $sessions[ $verifier ]; } return null; } protected function update_session( $verifier, $session = null ) { $sessions = $this->get_sessions(); if ( $session ) { $sessions[ $verifier ] = $session; } else { unset( $sessions[ $verifier ] ); } $this->update_sessions( $sessions ); } protected function update_sessions( $sessions ) { if ( $sessions ) { update_user_meta( $this->user_id, 'session_tokens', $sessions ); } else { delete_user_meta( $this->user_id, 'session_tokens' ); } } protected function destroy_other_sessions( $verifier ) { $session = $this->get_session( $verifier ); $this->update_sessions( array( $verifier => $session ) ); } protected function destroy_all_sessions() { $this->update_sessions( array() ); } public static function drop_sessions() { delete_metadata( 'user', 0, 'session_tokens', false, true ); } }
require ABSPATH . WPINC . '/general-template.php';
###require ABSPATH . WPINC . '/link-template.php';
function the_permalink( $post = 0 ) { echo esc_url( apply_filters( 'the_permalink', get_permalink( $post ), $post ) ); } function user_trailingslashit( $url, $type_of_url = '' ) { global $wp_rewrite; if ( $wp_rewrite->use_trailing_slashes ) { $url = trailingslashit( $url ); } else { $url = untrailingslashit( $url ); } return apply_filters( 'user_trailingslashit', $url, $type_of_url ); } function permalink_anchor( $mode = 'id' ) { $post = get_post(); switch ( strtolower( $mode ) ) { case 'title': $title = sanitize_title( $post->post_title ) . '-' . $post->ID; echo '<a id="' . $title . '"></a>'; break; case 'id': default: echo '<a id="post-' . $post->ID . '"></a>'; break; } } function wp_force_plain_post_permalink( $post = null, $sample = null ) { if ( null === $sample && is_object( $post ) && isset( $post->filter ) && 'sample' === $post->filter ) { $sample = true; } else { $post = get_post( $post ); $sample = null !== $sample ? $sample : false; } if ( ! $post ) { return true; } $post_status_obj = get_post_status_object( get_post_status( $post ) ); $post_type_obj = get_post_type_object( get_post_type( $post ) ); if ( ! $post_status_obj || ! $post_type_obj ) { return true; } if ( is_post_status_viewable( $post_status_obj ) || ( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) || ( $post_status_obj->protected && $sample ) ) { return false; } return true; } function get_the_permalink( $post = 0, $leavename = false ) { return get_permalink( $post, $leavename ); } function get_permalink( $post = 0, $leavename = false ) { $rewritecode = array( '%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%', ); if ( is_object( $post ) && isset( $post->filter ) && 'sample' === $post->filter ) { $sample = true; } else { $post = get_post( $post ); $sample = false; } if ( empty( $post->ID ) ) { return false; } if ( 'page' === $post->post_type ) { return get_page_link( $post, $leavename, $sample ); } elseif ( 'attachment' === $post->post_type ) { return get_attachment_link( $post, $leavename ); } elseif ( in_array( $post->post_type, get_post_types( array( '_builtin' => false ) ), true ) ) { return get_post_permalink( $post, $leavename, $sample ); } $permalink = get_option( 'permalink_structure' ); $permalink = apply_filters( 'pre_post_link', $permalink, $post, $leavename ); if ( $permalink && ! wp_force_plain_post_permalink( $post ) ) { $category = ''; if ( str_contains( $permalink, '%category%' ) ) { $cats = get_the_category( $post->ID ); if ( $cats ) { $cats = wp_list_sort( $cats, array( 'term_id' => 'ASC', ) ); $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post ); $category_object = get_term( $category_object, 'category' ); $category = $category_object->slug; if ( $category_object->parent ) { $category = get_category_parents( $category_object->parent, false, '/', true ) . $category; } } if ( empty( $category ) ) { $default_category = get_term( get_option( 'default_category' ), 'category' ); if ( $default_category && ! is_wp_error( $default_category ) ) { $category = $default_category->slug; } } } $author = ''; if ( str_contains( $permalink, '%author%' ) ) { $authordata = get_userdata( $post->post_author ); $author = $authordata->user_nicename; } $date = explode( ' ', str_replace( array( '-', ':' ), ' ', $post->post_date ) ); $rewritereplace = array( $date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name, ); $permalink = home_url( str_replace( $rewritecode, $rewritereplace, $permalink ) ); $permalink = user_trailingslashit( $permalink, 'single' ); } else { $permalink = home_url( '?p=' . $post->ID ); } return apply_filters( 'post_link', $permalink, $post, $leavename ); } function get_post_permalink( $post = 0, $leavename = false, $sample = false ) { global $wp_rewrite; $post = get_post( $post ); if ( ! $post ) { return false; } $post_link = $wp_rewrite->get_extra_permastruct( $post->post_type ); $slug = $post->post_name; $force_plain_link = wp_force_plain_post_permalink( $post ); $post_type = get_post_type_object( $post->post_type ); if ( $post_type->hierarchical ) { $slug = get_page_uri( $post ); } if ( ! empty( $post_link ) && ( ! $force_plain_link || $sample ) ) { if ( ! $leavename ) { $post_link = str_replace( "%$post->post_type%", $slug, $post_link ); } $post_link = home_url( user_trailingslashit( $post_link ) ); } else { if ( $post_type->query_var && ( isset( $post->post_status ) && ! $force_plain_link ) ) { $post_link = add_query_arg( $post_type->query_var, $slug, '' ); } else { $post_link = add_query_arg( array( 'post_type' => $post->post_type, 'p' => $post->ID, ), '' ); } $post_link = home_url( $post_link ); } return apply_filters( 'post_type_link', $post_link, $post, $leavename, $sample ); } function get_page_link( $post = 0, $leavename = false, $sample = false ) { $post = get_post( $post ); if ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID ) { $link = home_url( '/' ); } else { $link = _get_page_link( $post, $leavename, $sample ); } return apply_filters( 'page_link', $link, $post->ID, $sample ); } function _get_page_link( $post = 0, $leavename = false, $sample = false ) { global $wp_rewrite; $post = get_post( $post ); $force_plain_link = wp_force_plain_post_permalink( $post ); $link = $wp_rewrite->get_page_permastruct(); if ( ! empty( $link ) && ( ( isset( $post->post_status ) && ! $force_plain_link ) || $sample ) ) { if ( ! $leavename ) { $link = str_replace( '%pagename%', get_page_uri( $post ), $link ); } $link = home_url( $link ); $link = user_trailingslashit( $link, 'page' ); } else { $link = home_url( '?page_id=' . $post->ID ); } return apply_filters( '_get_page_link', $link, $post->ID ); } function get_attachment_link( $post = null, $leavename = false ) { global $wp_rewrite; $link = false; $post = get_post( $post ); $force_plain_link = wp_force_plain_post_permalink( $post ); $parent_id = $post->post_parent; $parent = $parent_id ? get_post( $parent_id ) : false; $parent_valid = true; if ( $parent_id && ( $post->post_parent === $post->ID || ! $parent || ! is_post_type_viewable( get_post_type( $parent ) ) ) ) { $parent_valid = false; } if ( $force_plain_link || ! $parent_valid ) { $link = false; } elseif ( $wp_rewrite->using_permalinks() && $parent ) { if ( 'page' === $parent->post_type ) { $parentlink = _get_page_link( $post->post_parent ); } else { $parentlink = get_permalink( $post->post_parent ); } if ( is_numeric( $post->post_name ) || str_contains( get_option( 'permalink_structure' ), '%category%' ) ) { $name = 'attachment/' . $post->post_name; } else { $name = $post->post_name; } if ( ! str_contains( $parentlink, '?' ) ) { $link = user_trailingslashit( trailingslashit( $parentlink ) . '%postname%' ); } if ( ! $leavename ) { $link = str_replace( '%postname%', $name, $link ); } } elseif ( $wp_rewrite->using_permalinks() && ! $leavename ) { $link = home_url( user_trailingslashit( $post->post_name ) ); } if ( ! $link ) { $link = home_url( '/?attachment_id=' . $post->ID ); } return apply_filters( 'attachment_link', $link, $post->ID ); } function get_year_link( $year ) { global $wp_rewrite; if ( ! $year ) { $year = current_time( 'Y' ); } $yearlink = $wp_rewrite->get_year_permastruct(); if ( ! empty( $yearlink ) ) { $yearlink = str_replace( '%year%', $year, $yearlink ); $yearlink = home_url( user_trailingslashit( $yearlink, 'year' ) ); } else { $yearlink = home_url( '?m=' . $year ); } return apply_filters( 'year_link', $yearlink, $year ); } function get_month_link( $year, $month ) { global $wp_rewrite; if ( ! $year ) { $year = current_time( 'Y' ); } if ( ! $month ) { $month = current_time( 'm' ); } $monthlink = $wp_rewrite->get_month_permastruct(); if ( ! empty( $monthlink ) ) { $monthlink = str_replace( '%year%', $year, $monthlink ); $monthlink = str_replace( '%monthnum%', zeroise( (int) $month, 2 ), $monthlink ); $monthlink = home_url( user_trailingslashit( $monthlink, 'month' ) ); } else { $monthlink = home_url( '?m=' . $year . zeroise( $month, 2 ) ); } return apply_filters( 'month_link', $monthlink, $year, $month ); } function get_day_link( $year, $month, $day ) { global $wp_rewrite; if ( ! $year ) { $year = current_time( 'Y' ); } if ( ! $month ) { $month = current_time( 'm' ); } if ( ! $day ) { $day = current_time( 'j' ); } $daylink = $wp_rewrite->get_day_permastruct(); if ( ! empty( $daylink ) ) { $daylink = str_replace( '%year%', $year, $daylink ); $daylink = str_replace( '%monthnum%', zeroise( (int) $month, 2 ), $daylink ); $daylink = str_replace( '%day%', zeroise( (int) $day, 2 ), $daylink ); $daylink = home_url( user_trailingslashit( $daylink, 'day' ) ); } else { $daylink = home_url( '?m=' . $year . zeroise( $month, 2 ) . zeroise( $day, 2 ) ); } return apply_filters( 'day_link', $daylink, $year, $month, $day ); } function the_feed_link( $anchor, $feed = '' ) { $link = '<a href="' . esc_url( get_feed_link( $feed ) ) . '">' . $anchor . '</a>'; echo apply_filters( 'the_feed_link', $link, $feed ); } function get_feed_link( $feed = '' ) { global $wp_rewrite; $permalink = $wp_rewrite->get_feed_permastruct(); if ( $permalink ) { if ( str_contains( $feed, 'comments_' ) ) { $feed = str_replace( 'comments_', '', $feed ); $permalink = $wp_rewrite->get_comment_feed_permastruct(); } if ( get_default_feed() === $feed ) { $feed = ''; } $permalink = str_replace( '%feed%', $feed, $permalink ); $permalink = preg_replace( '#/+#', '/', "/$permalink" ); $output = home_url( user_trailingslashit( $permalink, 'feed' ) ); } else { if ( empty( $feed ) ) { $feed = get_default_feed(); } if ( str_contains( $feed, 'comments_' ) ) { $feed = str_replace( 'comments_', 'comments-', $feed ); } $output = home_url( "?feed={$feed}" ); } return apply_filters( 'feed_link', $output, $feed ); } function get_post_comments_feed_link( $post_id = 0, $feed = '' ) { $post_id = absint( $post_id ); if ( ! $post_id ) { $post_id = get_the_ID(); } if ( empty( $feed ) ) { $feed = get_default_feed(); } $post = get_post( $post_id ); if ( ! $post instanceof WP_Post ) { return ''; } $unattached = 'attachment' === $post->post_type && 0 === (int) $post->post_parent; if ( get_option( 'permalink_structure' ) ) { if ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post_id ) { $url = _get_page_link( $post_id ); } else { $url = get_permalink( $post_id ); } if ( $unattached ) { $url = home_url( '/feed/' ); if ( get_default_feed() !== $feed ) { $url .= "$feed/"; } $url = add_query_arg( 'attachment_id', $post_id, $url ); } else { $url = trailingslashit( $url ) . 'feed'; if ( get_default_feed() !== $feed ) { $url .= "/$feed"; } $url = user_trailingslashit( $url, 'single_feed' ); } } else { if ( $unattached ) { $url = add_query_arg( array( 'feed' => $feed, 'attachment_id' => $post_id, ), home_url( '/' ) ); } elseif ( 'page' === $post->post_type ) { $url = add_query_arg( array( 'feed' => $feed, 'page_id' => $post_id, ), home_url( '/' ) ); } else { $url = add_query_arg( array( 'feed' => $feed, 'p' => $post_id, ), home_url( '/' ) ); } } return apply_filters( 'post_comments_feed_link', $url ); } function post_comments_feed_link( $link_text = '', $post_id = 0, $feed = '' ) { $url = get_post_comments_feed_link( $post_id, $feed ); if ( empty( $link_text ) ) { $link_text = __( 'Comments Feed' ); } $link = '<a href="' . esc_url( $url ) . '">' . $link_text . '</a>'; echo apply_filters( 'post_comments_feed_link_html', $link, $post_id, $feed ); } function get_author_feed_link( $author_id, $feed = '' ) { $author_id = (int) $author_id; $permalink_structure = get_option( 'permalink_structure' ); if ( empty( $feed ) ) { $feed = get_default_feed(); } if ( ! $permalink_structure ) { $link = home_url( "?feed=$feed&author=" . $author_id ); } else { $link = get_author_posts_url( $author_id ); if ( get_default_feed() === $feed ) { $feed_link = 'feed'; } else { $feed_link = "feed/$feed"; } $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' ); } $link = apply_filters( 'author_feed_link', $link, $feed ); return $link; } function get_category_feed_link( $cat, $feed = '' ) { return get_term_feed_link( $cat, 'category', $feed ); } function get_term_feed_link( $term, $taxonomy = '', $feed = '' ) { if ( ! is_object( $term ) ) { $term = (int) $term; } $term = get_term( $term, $taxonomy ); if ( empty( $term ) || is_wp_error( $term ) ) { return false; } $taxonomy = $term->taxonomy; if ( empty( $feed ) ) { $feed = get_default_feed(); } $permalink_structure = get_option( 'permalink_structure' ); if ( ! $permalink_structure ) { if ( 'category' === $taxonomy ) { $link = home_url( "?feed=$feed&cat=$term->term_id" ); } elseif ( 'post_tag' === $taxonomy ) { $link = home_url( "?feed=$feed&tag=$term->slug" ); } else { $t = get_taxonomy( $taxonomy ); $link = home_url( "?feed=$feed&$t->query_var=$term->slug" ); } } else { $link = get_term_link( $term, $term->taxonomy ); if ( get_default_feed() === $feed ) { $feed_link = 'feed'; } else { $feed_link = "feed/$feed"; } $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' ); } if ( 'category' === $taxonomy ) { $link = apply_filters( 'category_feed_link', $link, $feed ); } elseif ( 'post_tag' === $taxonomy ) { $link = apply_filters( 'tag_feed_link', $link, $feed ); } else { $link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy ); } return $link; } function get_tag_feed_link( $tag, $feed = '' ) { return get_term_feed_link( $tag, 'post_tag', $feed ); } function get_edit_tag_link( $tag, $taxonomy = 'post_tag' ) { return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag, $taxonomy ) ); } function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) { $link = edit_term_link( $link, '', '', $tag, false ); echo $before . apply_filters( 'edit_tag_link', $link ) . $after; } function get_edit_term_link( $term, $taxonomy = '', $object_type = '' ) { $term = get_term( $term, $taxonomy ); if ( ! $term || is_wp_error( $term ) ) { return; } $tax = get_taxonomy( $term->taxonomy ); $term_id = $term->term_id; if ( ! $tax || ! current_user_can( 'edit_term', $term_id ) ) { return; } $args = array( 'taxonomy' => $tax->name, 'tag_ID' => $term_id, ); if ( $object_type ) { $args['post_type'] = $object_type; } elseif ( ! empty( $tax->object_type ) ) { $args['post_type'] = reset( $tax->object_type ); } if ( $tax->show_ui ) { $location = add_query_arg( $args, admin_url( 'term.php' ) ); } else { $location = ''; } return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type ); } function edit_term_link( $link = '', $before = '', $after = '', $term = null, $display = true ) { if ( is_null( $term ) ) { $term = get_queried_object(); } else { $term = get_term( $term ); } if ( ! $term ) { return; } $tax = get_taxonomy( $term->taxonomy ); if ( ! current_user_can( 'edit_term', $term->term_id ) ) { return; } if ( empty( $link ) ) { $link = __( 'Edit This' ); } $link = '<a href="' . get_edit_term_link( $term->term_id, $term->taxonomy ) . '">' . $link . '</a>'; $link = $before . apply_filters( 'edit_term_link', $link, $term->term_id ) . $after; if ( $display ) { echo $link; } else { return $link; } } function get_search_link( $query = '' ) { global $wp_rewrite; if ( empty( $query ) ) { $search = get_search_query( false ); } else { $search = stripslashes( $query ); } $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty( $permastruct ) ) { $link = home_url( '?s=' . urlencode( $search ) ); } else { $search = urlencode( $search ); $search = str_replace( '%2F', '/', $search ); $link = str_replace( '%search%', $search, $permastruct ); $link = home_url( user_trailingslashit( $link, 'search' ) ); } return apply_filters( 'search_link', $link, $search ); } function get_search_feed_link( $search_query = '', $feed = '' ) { global $wp_rewrite; $link = get_search_link( $search_query ); if ( empty( $feed ) ) { $feed = get_default_feed(); } $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty( $permastruct ) ) { $link = add_query_arg( 'feed', $feed, $link ); } else { $link = trailingslashit( $link ); $link .= "feed/$feed/"; } return apply_filters( 'search_feed_link', $link, $feed, 'posts' ); } function get_search_comments_feed_link( $search_query = '', $feed = '' ) { global $wp_rewrite; if ( empty( $feed ) ) { $feed = get_default_feed(); } $link = get_search_feed_link( $search_query, $feed ); $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty( $permastruct ) ) { $link = add_query_arg( 'feed', 'comments-' . $feed, $link ); } else { $link = add_query_arg( 'withcomments', 1, $link ); } return apply_filters( 'search_feed_link', $link, $feed, 'comments' ); } function get_post_type_archive_link( $post_type ) { global $wp_rewrite; $post_type_obj = get_post_type_object( $post_type ); if ( ! $post_type_obj ) { return false; } if ( 'post' === $post_type ) { $show_on_front = get_option( 'show_on_front' ); $page_for_posts = get_option( 'page_for_posts' ); if ( 'page' === $show_on_front && $page_for_posts ) { $link = get_permalink( $page_for_posts ); } else { $link = get_home_url(); } return apply_filters( 'post_type_archive_link', $link, $post_type ); } if ( ! $post_type_obj->has_archive ) { return false; } if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) ) { $struct = ( true === $post_type_obj->has_archive ) ? $post_type_obj->rewrite['slug'] : $post_type_obj->has_archive; if ( $post_type_obj->rewrite['with_front'] ) { $struct = $wp_rewrite->front . $struct; } else { $struct = $wp_rewrite->root . $struct; } $link = home_url( user_trailingslashit( $struct, 'post_type_archive' ) ); } else { $link = home_url( '?post_type=' . $post_type ); } return apply_filters( 'post_type_archive_link', $link, $post_type ); } function get_post_type_archive_feed_link( $post_type, $feed = '' ) { $default_feed = get_default_feed(); if ( empty( $feed ) ) { $feed = $default_feed; } $link = get_post_type_archive_link( $post_type ); if ( ! $link ) { return false; } $post_type_obj = get_post_type_object( $post_type ); if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) && $post_type_obj->rewrite['feeds'] ) { $link = trailingslashit( $link ); $link .= 'feed/'; if ( $feed !== $default_feed ) { $link .= "$feed/"; } } else { $link = add_query_arg( 'feed', $feed, $link ); } return apply_filters( 'post_type_archive_feed_link', $link, $feed ); } function get_preview_post_link( $post = null, $query_args = array(), $preview_link = '' ) { $post = get_post( $post ); if ( ! $post ) { return; } $post_type_object = get_post_type_object( $post->post_type ); if ( is_post_type_viewable( $post_type_object ) ) { if ( ! $preview_link ) { $preview_link = set_url_scheme( get_permalink( $post ) ); } $query_args['preview'] = 'true'; $preview_link = add_query_arg( $query_args, $preview_link ); } return apply_filters( 'preview_post_link', $preview_link, $post ); } function get_edit_post_link( $post = 0, $context = 'display' ) { $post = get_post( $post ); if ( ! $post ) { return; } if ( 'revision' === $post->post_type ) { $action = ''; } elseif ( 'display' === $context ) { $action = '&action=edit'; } else { $action = '&action=edit'; } $post_type_object = get_post_type_object( $post->post_type ); if ( ! $post_type_object ) { return; } if ( ! current_user_can( 'edit_post', $post->ID ) ) { return; } $link = ''; if ( 'wp_template' === $post->post_type || 'wp_template_part' === $post->post_type ) { $slug = urlencode( get_stylesheet() . '//' . $post->post_name ); $link = admin_url( sprintf( $post_type_object->_edit_link, $post->post_type, $slug ) ); } elseif ( 'wp_navigation' === $post->post_type ) { $link = admin_url( sprintf( $post_type_object->_edit_link, (string) $post->ID ) ); } elseif ( $post_type_object->_edit_link ) { $link = admin_url( sprintf( $post_type_object->_edit_link . $action, $post->ID ) ); } return apply_filters( 'get_edit_post_link', $link, $post->ID, $context ); } function edit_post_link( $text = null, $before = '', $after = '', $post = 0, $css_class = 'post-edit-link' ) { $post = get_post( $post ); if ( ! $post ) { return; } $url = get_edit_post_link( $post->ID ); if ( ! $url ) { return; } if ( null === $text ) { $text = __( 'Edit This' ); } $link = '<a class="' . esc_attr( $css_class ) . '" href="' . esc_url( $url ) . '">' . $text . '</a>'; echo $before . apply_filters( 'edit_post_link', $link, $post->ID, $text ) . $after; } function get_delete_post_link( $post = 0, $deprecated = '', $force_delete = false ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '3.0.0' ); } $post = get_post( $post ); if ( ! $post ) { return; } $post_type_object = get_post_type_object( $post->post_type ); if ( ! $post_type_object ) { return; } if ( ! current_user_can( 'delete_post', $post->ID ) ) { return; } $action = ( $force_delete || ! EMPTY_TRASH_DAYS ) ? 'delete' : 'trash'; $delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) ); return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-post_{$post->ID}" ), $post->ID, $force_delete ); } function get_edit_comment_link( $comment_id = 0, $context = 'display' ) { $comment = get_comment( $comment_id ); if ( ! is_object( $comment ) || ! current_user_can( 'edit_comment', $comment->comment_ID ) ) { return; } if ( 'display' === $context ) { $action = 'comment.php?action=editcomment&c='; } else { $action = 'comment.php?action=editcomment&c='; } $location = admin_url( $action ) . $comment->comment_ID; $comment_id = (int) $comment->comment_ID; return apply_filters( 'get_edit_comment_link', $location, $comment_id, $context ); } function edit_comment_link( $text = null, $before = '', $after = '' ) { $comment = get_comment(); if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) { return; } if ( null === $text ) { $text = __( 'Edit This' ); } $link = '<a class="comment-edit-link" href="' . esc_url( get_edit_comment_link( $comment ) ) . '">' . $text . '</a>'; echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID, $text ) . $after; } function get_edit_bookmark_link( $link = 0 ) { $link = get_bookmark( $link ); if ( ! current_user_can( 'manage_links' ) ) { return; } $location = admin_url( 'link.php?action=edit&link_id=' ) . $link->link_id; return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id ); } function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) { $bookmark = get_bookmark( $bookmark ); if ( ! current_user_can( 'manage_links' ) ) { return; } if ( empty( $link ) ) { $link = __( 'Edit This' ); } $link = '<a href="' . esc_url( get_edit_bookmark_link( $bookmark ) ) . '">' . $link . '</a>'; echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after; } function get_edit_user_link( $user_id = null ) { if ( ! $user_id ) { $user_id = get_current_user_id(); } if ( empty( $user_id ) || ! current_user_can( 'edit_user', $user_id ) ) { return ''; } $user = get_userdata( $user_id ); if ( ! $user ) { return ''; } if ( get_current_user_id() === $user->ID ) { $link = get_edit_profile_url( $user->ID ); } else { $link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) ); } return apply_filters( 'get_edit_user_link', $link, $user->ID ); } function get_previous_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { return get_adjacent_post( $in_same_term, $excluded_terms, true, $taxonomy ); } function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { return get_adjacent_post( $in_same_term, $excluded_terms, false, $taxonomy ); } function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { global $wpdb; $post = get_post(); if ( ! $post || ! taxonomy_exists( $taxonomy ) ) { return null; } $current_post_date = $post->post_date; $join = ''; $where = ''; $adjacent = $previous ? 'previous' : 'next'; if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) { if ( str_contains( $excluded_terms, ' and ' ) ) { _deprecated_argument( __FUNCTION__, '3.3.0', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) ); $excluded_terms = explode( ' and ', $excluded_terms ); } else { $excluded_terms = explode( ',', $excluded_terms ); } $excluded_terms = array_map( 'intval', $excluded_terms ); } $excluded_terms = apply_filters( "get_{$adjacent}_post_excluded_terms", $excluded_terms ); if ( $in_same_term || ! empty( $excluded_terms ) ) { if ( $in_same_term ) { $join .= " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"; $where .= $wpdb->prepare( 'AND tt.taxonomy = %s', $taxonomy ); if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) ) { return ''; } $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ); if ( is_wp_error( $term_array ) ) { return ''; } $term_array = array_diff( $term_array, (array) $excluded_terms ); if ( ! $term_array ) { return ''; } $term_array = array_map( 'intval', $term_array ); $where .= ' AND tt.term_id IN (' . implode( ',', $term_array ) . ')'; } if ( ! empty( $excluded_terms ) ) { $where .= " AND p.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships tr LEFT JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.term_id IN (" . implode( ',', array_map( 'intval', $excluded_terms ) ) . ') )'; } } if ( is_user_logged_in() ) { $user_id = get_current_user_id(); $post_type_object = get_post_type_object( $post->post_type ); if ( empty( $post_type_object ) ) { $post_type_cap = $post->post_type; $read_private_cap = 'read_private_' . $post_type_cap . 's'; } else { $read_private_cap = $post_type_object->cap->read_private_posts; } $private_states = get_post_stati( array( 'private' => true ) ); $where .= " AND ( p.post_status = 'publish'"; foreach ( $private_states as $state ) { if ( current_user_can( $read_private_cap ) ) { $where .= $wpdb->prepare( ' OR p.post_status = %s', $state ); } else { $where .= $wpdb->prepare( ' OR (p.post_author = %d AND p.post_status = %s)', $user_id, $state ); } } $where .= ' )'; } else { $where .= " AND p.post_status = 'publish'"; } $comparison_operator = $previous ? '<' : '>'; $order = $previous ? 'DESC' : 'ASC'; $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post ); $where_prepared = $wpdb->prepare( "WHERE (p.post_date $comparison_operator %s OR (p.post_date = %s AND p.ID $comparison_operator %d)) AND p.post_type = %s $where", $current_post_date, $current_post_date, $post->ID, $post->post_type ); $where = apply_filters( "get_{$adjacent}_post_where", $where_prepared, $in_same_term, $excluded_terms, $taxonomy, $post ); $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order, p.ID $order LIMIT 1", $post, $order ); $query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort"; $key = md5( $query ); $last_changed = (array) wp_cache_get_last_changed( 'posts' ); if ( $in_same_term || ! empty( $excluded_terms ) ) { $last_changed[] = wp_cache_get_last_changed( 'terms' ); } $cache_key = "adjacent_post:$key"; $result = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( false !== $result ) { if ( $result ) { $result = get_post( $result ); } return $result; } $result = $wpdb->get_var( $query ); if ( null === $result ) { $result = ''; } wp_cache_set_salted( $cache_key, $result, 'post-queries', $last_changed ); if ( $result ) { $result = get_post( $result ); } return $result; } function get_adjacent_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { $post = get_post(); if ( $previous && is_attachment() && $post ) { $post = get_post( $post->post_parent ); } else { $post = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy ); } if ( empty( $post ) ) { return; } $post_title = the_title_attribute( array( 'echo' => false, 'post' => $post, ) ); if ( empty( $post_title ) ) { $post_title = $previous ? __( 'Previous Post' ) : __( 'Next Post' ); } $date = mysql2date( get_option( 'date_format' ), $post->post_date ); $title = str_replace( '%title', $post_title, $title ); $title = str_replace( '%date', $date, $title ); $link = $previous ? "<link rel='prev' title='" : "<link rel='next' title='"; $link .= esc_attr( $title ); $link .= "' href='" . get_permalink( $post ) . "' />\n"; $adjacent = $previous ? 'previous' : 'next'; return apply_filters( "{$adjacent}_post_rel_link", $link ); } function adjacent_posts_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy ); echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy ); } function adjacent_posts_rel_link_wp_head() { if ( ! is_single() || is_attachment() ) { return; } adjacent_posts_rel_link(); } function next_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, false, $taxonomy ); } function prev_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms, true, $taxonomy ); } function get_boundary_post( $in_same_term = false, $excluded_terms = '', $start = true, $taxonomy = 'category' ) { $post = get_post(); if ( ! $post || ! is_single() || is_attachment() || ! taxonomy_exists( $taxonomy ) ) { return null; } $query_args = array( 'posts_per_page' => 1, 'order' => $start ? 'ASC' : 'DESC', 'update_post_term_cache' => false, 'update_post_meta_cache' => false, ); $term_array = array(); if ( ! is_array( $excluded_terms ) ) { if ( ! empty( $excluded_terms ) ) { $excluded_terms = explode( ',', $excluded_terms ); } else { $excluded_terms = array(); } } if ( $in_same_term || ! empty( $excluded_terms ) ) { if ( $in_same_term ) { $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ); } if ( ! empty( $excluded_terms ) ) { $excluded_terms = array_map( 'intval', $excluded_terms ); $excluded_terms = array_diff( $excluded_terms, $term_array ); $inverse_terms = array(); foreach ( $excluded_terms as $excluded_term ) { $inverse_terms[] = $excluded_term * -1; } $excluded_terms = $inverse_terms; } $query_args['tax_query'] = array( array( 'taxonomy' => $taxonomy, 'terms' => array_merge( $term_array, $excluded_terms ), ), ); } return get_posts( $query_args ); } function get_previous_post_link( $format = '« %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, true, $taxonomy ); } function previous_post_link( $format = '« %link', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { echo get_previous_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy ); } function get_next_post_link( $format = '%link »', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { return get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, false, $taxonomy ); } function next_post_link( $format = '%link »', $link = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { echo get_next_post_link( $format, $link, $in_same_term, $excluded_terms, $taxonomy ); } function get_adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { if ( $previous && is_attachment() ) { $post = get_post( get_post()->post_parent ); } else { $post = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy ); } if ( ! $post ) { $output = ''; } else { $title = $post->post_title; if ( empty( $post->post_title ) ) { $title = $previous ? __( 'Previous Post' ) : __( 'Next Post' ); } $title = apply_filters( 'the_title', $title, $post->ID ); $date = mysql2date( get_option( 'date_format' ), $post->post_date ); $rel = $previous ? 'prev' : 'next'; $string = '<a href="' . get_permalink( $post ) . '" rel="' . $rel . '">'; $inlink = str_replace( '%title', $title, $link ); $inlink = str_replace( '%date', $date, $inlink ); $inlink = $string . $inlink . '</a>'; $output = str_replace( '%link', $inlink, $format ); } $adjacent = $previous ? 'previous' : 'next'; return apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post, $adjacent ); } function adjacent_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { echo get_adjacent_post_link( $format, $link, $in_same_term, $excluded_terms, $previous, $taxonomy ); } function get_pagenum_link( $pagenum = 1, $escape = true ) { global $wp_rewrite; $pagenum = (int) $pagenum; $request = remove_query_arg( 'paged' ); $home_root = parse_url( home_url() ); $home_root = ( isset( $home_root['path'] ) ) ? $home_root['path'] : ''; $home_root = preg_quote( $home_root, '|' ); $request = preg_replace( '|^' . $home_root . '|i', '', $request ); $request = preg_replace( '|^/+|', '', $request ); if ( ! $wp_rewrite->using_permalinks() || is_admin() ) { $base = trailingslashit( get_bloginfo( 'url' ) ); if ( $pagenum > 1 ) { $result = add_query_arg( 'paged', $pagenum, $base . $request ); } else { $result = $base . $request; } } else { $qs_regex = '|\?.*?$|'; preg_match( $qs_regex, $request, $qs_match ); $parts = array(); $parts[] = untrailingslashit( get_bloginfo( 'url' ) ); if ( ! empty( $qs_match[0] ) ) { $query_string = $qs_match[0]; $request = preg_replace( $qs_regex, '', $request ); } else { $query_string = ''; } $request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request ); $request = preg_replace( '|^' . preg_quote( $wp_rewrite->index, '|' ) . '|i', '', $request ); $request = ltrim( $request, '/' ); if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' !== $request ) ) { $parts[] = $wp_rewrite->index; } $parts[] = untrailingslashit( $request ); if ( $pagenum > 1 ) { $parts[] = $wp_rewrite->pagination_base; $parts[] = $pagenum; } $result = user_trailingslashit( implode( '/', array_filter( $parts ) ), 'paged' ); if ( ! empty( $query_string ) ) { $result .= $query_string; } } $result = apply_filters( 'get_pagenum_link', $result, $pagenum ); if ( $escape ) { return esc_url( $result ); } else { return sanitize_url( $result ); } } function get_next_posts_page_link( $max_page = 0 ) { global $paged; if ( ! is_single() ) { if ( ! $paged ) { $paged = 1; } $next_page = (int) $paged + 1; if ( ! $max_page || $max_page >= $next_page ) { return get_pagenum_link( $next_page ); } } } function next_posts( $max_page = 0, $display = true ) { $link = get_next_posts_page_link( $max_page ); $output = $link ? esc_url( $link ) : ''; if ( $display ) { echo $output; } else { return $output; } } function get_next_posts_link( $label = null, $max_page = 0 ) { global $paged, $wp_query; if ( ! $max_page ) { $max_page = $wp_query->max_num_pages; } if ( ! $paged ) { $paged = 1; } $next_page = (int) $paged + 1; if ( null === $label ) { $label = __( 'Next Page »' ); } if ( ! is_single() && ( $next_page <= $max_page ) ) { $attr = apply_filters( 'next_posts_link_attributes', '' ); return sprintf( '<a href="%1$s" %2$s>%3$s</a>', next_posts( $max_page, false ), $attr, preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label ) ); } } function next_posts_link( $label = null, $max_page = 0 ) { echo get_next_posts_link( $label, $max_page ); } function get_previous_posts_page_link() { global $paged; if ( ! is_single() ) { $previous_page = (int) $paged - 1; if ( $previous_page < 1 ) { $previous_page = 1; } return get_pagenum_link( $previous_page ); } } function previous_posts( $display = true ) { $output = esc_url( get_previous_posts_page_link() ); if ( $display ) { echo $output; } else { return $output; } } function get_previous_posts_link( $label = null ) { global $paged; if ( null === $label ) { $label = __( '« Previous Page' ); } if ( ! is_single() && $paged > 1 ) { $attr = apply_filters( 'previous_posts_link_attributes', '' ); return sprintf( '<a href="%1$s" %2$s>%3$s</a>', previous_posts( false ), $attr, preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label ) ); } } function previous_posts_link( $label = null ) { echo get_previous_posts_link( $label ); } function get_posts_nav_link( $args = array() ) { global $wp_query; $return = ''; if ( ! is_singular() ) { $defaults = array( 'sep' => ' — ', 'prelabel' => __( '« Previous Page' ), 'nxtlabel' => __( 'Next Page »' ), ); $args = wp_parse_args( $args, $defaults ); $max_num_pages = $wp_query->max_num_pages; $paged = get_query_var( 'paged' ); if ( $paged < 2 || $paged >= $max_num_pages ) { $args['sep'] = ''; } if ( $max_num_pages > 1 ) { $return = get_previous_posts_link( $args['prelabel'] ); $return .= preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $args['sep'] ); $return .= get_next_posts_link( $args['nxtlabel'] ); } } return $return; } function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) { $args = array_filter( compact( 'sep', 'prelabel', 'nxtlabel' ) ); echo get_posts_nav_link( $args ); } function get_the_post_navigation( $args = array() ) { if ( ! empty( $args['screen_reader_text'] ) && empty( $args['aria_label'] ) ) { $args['aria_label'] = $args['screen_reader_text']; } $args = wp_parse_args( $args, array( 'prev_text' => '%title', 'next_text' => '%title', 'in_same_term' => false, 'excluded_terms' => '', 'taxonomy' => 'category', 'screen_reader_text' => __( 'Post navigation' ), 'aria_label' => __( 'Posts' ), 'class' => 'post-navigation', ) ); $navigation = ''; $previous = get_previous_post_link( '<div class="nav-previous">%link</div>', $args['prev_text'], $args['in_same_term'], $args['excluded_terms'], $args['taxonomy'] ); $next = get_next_post_link( '<div class="nav-next">%link</div>', $args['next_text'], $args['in_same_term'], $args['excluded_terms'], $args['taxonomy'] ); if ( $previous || $next ) { $navigation = _navigation_markup( $previous . $next, $args['class'], $args['screen_reader_text'], $args['aria_label'] ); } return $navigation; } function the_post_navigation( $args = array() ) { echo get_the_post_navigation( $args ); } function get_the_posts_navigation( $args = array() ) { global $wp_query; $navigation = ''; if ( $wp_query->max_num_pages > 1 ) { if ( ! empty( $args['screen_reader_text'] ) && empty( $args['aria_label'] ) ) { $args['aria_label'] = $args['screen_reader_text']; } $args = wp_parse_args( $args, array( 'prev_text' => __( 'Older posts' ), 'next_text' => __( 'Newer posts' ), 'screen_reader_text' => __( 'Posts navigation' ), 'aria_label' => __( 'Posts' ), 'class' => 'posts-navigation', ) ); $next_link = get_previous_posts_link( $args['next_text'] ); $prev_link = get_next_posts_link( $args['prev_text'] ); if ( $prev_link ) { $navigation .= '<div class="nav-previous">' . $prev_link . '</div>'; } if ( $next_link ) { $navigation .= '<div class="nav-next">' . $next_link . '</div>'; } $navigation = _navigation_markup( $navigation, $args['class'], $args['screen_reader_text'], $args['aria_label'] ); } return $navigation; } function the_posts_navigation( $args = array() ) { echo get_the_posts_navigation( $args ); } function get_the_posts_pagination( $args = array() ) { global $wp_query; $navigation = ''; if ( $wp_query->max_num_pages > 1 ) { if ( ! empty( $args['screen_reader_text'] ) && empty( $args['aria_label'] ) ) { $args['aria_label'] = $args['screen_reader_text']; } $args = wp_parse_args( $args, array( 'mid_size' => 1, 'prev_text' => _x( 'Previous', 'previous set of posts' ), 'next_text' => _x( 'Next', 'next set of posts' ), 'screen_reader_text' => __( 'Posts pagination' ), 'aria_label' => __( 'Posts pagination' ), 'class' => 'pagination', ) ); $args = apply_filters( 'the_posts_pagination_args', $args ); if ( isset( $args['type'] ) && 'array' === $args['type'] ) { $args['type'] = 'plain'; } $links = paginate_links( $args ); if ( $links ) { $navigation = _navigation_markup( $links, $args['class'], $args['screen_reader_text'], $args['aria_label'] ); } } return $navigation; } function the_posts_pagination( $args = array() ) { echo get_the_posts_pagination( $args ); } function _navigation_markup( $links, $css_class = 'posts-navigation', $screen_reader_text = '', $aria_label = '' ) { if ( empty( $screen_reader_text ) ) { $screen_reader_text = __( 'Posts navigation' ); } if ( empty( $aria_label ) ) { $aria_label = $screen_reader_text; } $template = '
<nav class="navigation %1$s" aria-label="%4$s">
<h2 class="screen-reader-text">%2$s</h2>
<div class="nav-links">%3$s</div>
</nav>'; $template = apply_filters( 'navigation_markup_template', $template, $css_class ); return sprintf( $template, sanitize_html_class( $css_class ), esc_html( $screen_reader_text ), $links, esc_attr( $aria_label ) ); } function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) { global $wp_rewrite; $pagenum = (int) $pagenum; $max_page = (int) $max_page; $result = get_permalink(); if ( 'newest' === get_option( 'default_comments_page' ) ) { if ( $pagenum !== $max_page ) { if ( $wp_rewrite->using_permalinks() ) { $result = user_trailingslashit( trailingslashit( $result ) . $wp_rewrite->comments_pagination_base . '-' . $pagenum, 'commentpaged' ); } else { $result = add_query_arg( 'cpage', $pagenum, $result ); } } } elseif ( $pagenum > 1 ) { if ( $wp_rewrite->using_permalinks() ) { $result = user_trailingslashit( trailingslashit( $result ) . $wp_rewrite->comments_pagination_base . '-' . $pagenum, 'commentpaged' ); } else { $result = add_query_arg( 'cpage', $pagenum, $result ); } } $result .= '#comments'; return apply_filters( 'get_comments_pagenum_link', $result ); } function get_next_comments_link( $label = '', $max_page = 0, $page = null ) { global $wp_query; if ( ! is_singular() ) { return; } if ( is_null( $page ) ) { $page = get_query_var( 'cpage' ); } if ( ! $page ) { $page = 1; } $next_page = (int) $page + 1; if ( empty( $max_page ) ) { $max_page = $wp_query->max_num_comment_pages; } if ( empty( $max_page ) ) { $max_page = get_comment_pages_count(); } if ( $next_page > $max_page ) { return; } if ( empty( $label ) ) { $label = __( 'Newer Comments »' ); } $attr = apply_filters( 'next_comments_link_attributes', '' ); return sprintf( '<a href="%1$s" %2$s>%3$s</a>', esc_url( get_comments_pagenum_link( $next_page, $max_page ) ), $attr, preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label ) ); } function next_comments_link( $label = '', $max_page = 0 ) { echo get_next_comments_link( $label, $max_page ); } function get_previous_comments_link( $label = '', $page = null ) { if ( ! is_singular() ) { return; } if ( is_null( $page ) ) { $page = get_query_var( 'cpage' ); } if ( (int) $page <= 1 ) { return; } $previous_page = (int) $page - 1; if ( empty( $label ) ) { $label = __( '« Older Comments' ); } $attr = apply_filters( 'previous_comments_link_attributes', '' ); return sprintf( '<a href="%1$s" %2$s>%3$s</a>', esc_url( get_comments_pagenum_link( $previous_page ) ), $attr, preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label ) ); } function previous_comments_link( $label = '' ) { echo get_previous_comments_link( $label ); } function paginate_comments_links( $args = array() ) { global $wp_rewrite; if ( ! is_singular() ) { return; } $page = get_query_var( 'cpage' ); if ( ! $page ) { $page = 1; } $max_page = get_comment_pages_count(); $defaults = array( 'base' => add_query_arg( 'cpage', '%#%' ), 'format' => '', 'total' => $max_page, 'current' => $page, 'echo' => true, 'type' => 'plain', 'add_fragment' => '#comments', ); if ( $wp_rewrite->using_permalinks() ) { $defaults['base'] = user_trailingslashit( trailingslashit( get_permalink() ) . $wp_rewrite->comments_pagination_base . '-%#%', 'commentpaged' ); } $args = wp_parse_args( $args, $defaults ); $page_links = paginate_links( $args ); if ( $args['echo'] && 'array' !== $args['type'] ) { echo $page_links; } else { return $page_links; } } function get_the_comments_navigation( $args = array() ) { $navigation = ''; if ( get_comment_pages_count() > 1 ) { if ( ! empty( $args['screen_reader_text'] ) && empty( $args['aria_label'] ) ) { $args['aria_label'] = $args['screen_reader_text']; } $args = wp_parse_args( $args, array( 'prev_text' => __( 'Older comments' ), 'next_text' => __( 'Newer comments' ), 'screen_reader_text' => __( 'Comments navigation' ), 'aria_label' => __( 'Comments' ), 'class' => 'comment-navigation', ) ); $prev_link = get_previous_comments_link( $args['prev_text'] ); $next_link = get_next_comments_link( $args['next_text'] ); if ( $prev_link ) { $navigation .= '<div class="nav-previous">' . $prev_link . '</div>'; } if ( $next_link ) { $navigation .= '<div class="nav-next">' . $next_link . '</div>'; } $navigation = _navigation_markup( $navigation, $args['class'], $args['screen_reader_text'], $args['aria_label'] ); } return $navigation; } function the_comments_navigation( $args = array() ) { echo get_the_comments_navigation( $args ); } function get_the_comments_pagination( $args = array() ) { $navigation = ''; if ( ! empty( $args['screen_reader_text'] ) && empty( $args['aria_label'] ) ) { $args['aria_label'] = $args['screen_reader_text']; } $args = wp_parse_args( $args, array( 'screen_reader_text' => __( 'Comments pagination' ), 'aria_label' => __( 'Comments pagination' ), 'class' => 'comments-pagination', ) ); $args['echo'] = false; if ( isset( $args['type'] ) && 'array' === $args['type'] ) { $args['type'] = 'plain'; } $links = paginate_comments_links( $args ); if ( $links ) { $navigation = _navigation_markup( $links, $args['class'], $args['screen_reader_text'], $args['aria_label'] ); } return $navigation; } function the_comments_pagination( $args = array() ) { echo get_the_comments_pagination( $args ); } function home_url( $path = '', $scheme = null ) { return get_home_url( null, $path, $scheme ); } function get_home_url( $blog_id = null, $path = '', $scheme = null ) { $orig_scheme = $scheme; if ( empty( $blog_id ) || ! is_multisite() ) { $url = get_option( 'home' ); } else { switch_to_blog( $blog_id ); $url = get_option( 'home' ); restore_current_blog(); } if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ), true ) ) { if ( is_ssl() ) { $scheme = 'https'; } else { $scheme = parse_url( $url, PHP_URL_SCHEME ); } } $url = set_url_scheme( $url, $scheme ); if ( $path && is_string( $path ) ) { $url .= '/' . ltrim( $path, '/' ); } return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id ); } function site_url( $path = '', $scheme = null ) { return get_site_url( null, $path, $scheme ); } function get_site_url( $blog_id = null, $path = '', $scheme = null ) { if ( empty( $blog_id ) || ! is_multisite() ) { $url = get_option( 'siteurl' ); } else { switch_to_blog( $blog_id ); $url = get_option( 'siteurl' ); restore_current_blog(); } $url = set_url_scheme( $url, $scheme ); if ( $path && is_string( $path ) ) { $url .= '/' . ltrim( $path, '/' ); } return apply_filters( 'site_url', $url, $path, $scheme, $blog_id ); } function admin_url( $path = '', $scheme = 'admin' ) { return get_admin_url( null, $path, $scheme ); } function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) { $url = get_site_url( $blog_id, 'wp-admin/', $scheme ); if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'admin_url', $url, $path, $blog_id, $scheme ); } function includes_url( $path = '', $scheme = null ) { $url = site_url( '/' . WPINC . '/', $scheme ); if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'includes_url', $url, $path, $scheme ); } function content_url( $path = '' ) { $url = set_url_scheme( WP_CONTENT_URL ); if ( $path && is_string( $path ) ) { $url .= '/' . ltrim( $path, '/' ); } return apply_filters( 'content_url', $url, $path ); } function plugins_url( $path = '', $plugin = '' ) { $path = wp_normalize_path( $path ); $plugin = wp_normalize_path( $plugin ); $mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR ); if ( ! empty( $plugin ) && str_starts_with( $plugin, $mu_plugin_dir ) ) { $url = WPMU_PLUGIN_URL; } else { $url = WP_PLUGIN_URL; } $url = set_url_scheme( $url ); if ( ! empty( $plugin ) && is_string( $plugin ) ) { $folder = dirname( plugin_basename( $plugin ) ); if ( '.' !== $folder ) { $url .= '/' . ltrim( $folder, '/' ); } } if ( $path && is_string( $path ) ) { $url .= '/' . ltrim( $path, '/' ); } return apply_filters( 'plugins_url', $url, $path, $plugin ); } function network_site_url( $path = '', $scheme = null ) { if ( ! is_multisite() ) { return site_url( $path, $scheme ); } $current_network = get_network(); if ( 'relative' === $scheme ) { $url = $current_network->path; } else { $url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $scheme ); } if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'network_site_url', $url, $path, $scheme ); } function network_home_url( $path = '', $scheme = null ) { if ( ! is_multisite() ) { return home_url( $path, $scheme ); } $current_network = get_network(); $orig_scheme = $scheme; if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ), true ) ) { $scheme = is_ssl() ? 'https' : 'http'; } if ( 'relative' === $scheme ) { $url = $current_network->path; } else { $url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $scheme ); } if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'network_home_url', $url, $path, $orig_scheme ); } function network_admin_url( $path = '', $scheme = 'admin' ) { if ( ! is_multisite() ) { return admin_url( $path, $scheme ); } $url = network_site_url( 'wp-admin/network/', $scheme ); if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'network_admin_url', $url, $path, $scheme ); } function user_admin_url( $path = '', $scheme = 'admin' ) { $url = network_site_url( 'wp-admin/user/', $scheme ); if ( $path && is_string( $path ) ) { $url .= ltrim( $path, '/' ); } return apply_filters( 'user_admin_url', $url, $path, $scheme ); } function self_admin_url( $path = '', $scheme = 'admin' ) { if ( is_network_admin() ) { $url = network_admin_url( $path, $scheme ); } elseif ( is_user_admin() ) { $url = user_admin_url( $path, $scheme ); } else { $url = admin_url( $path, $scheme ); } return apply_filters( 'self_admin_url', $url, $path, $scheme ); } function set_url_scheme( $url, $scheme = null ) { $orig_scheme = $scheme; if ( ! $scheme ) { $scheme = is_ssl() ? 'https' : 'http'; } elseif ( 'admin' === $scheme || 'login' === $scheme || 'login_post' === $scheme || 'rpc' === $scheme ) { $scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http'; } elseif ( 'http' !== $scheme && 'https' !== $scheme && 'relative' !== $scheme ) { $scheme = is_ssl() ? 'https' : 'http'; } $url = trim( $url ); if ( str_starts_with( $url, '//' ) ) { $url = 'http:' . $url; } if ( 'relative' === $scheme ) { $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) ); if ( '' !== $url && '/' === $url[0] ) { $url = '/' . ltrim( $url, "/ \t\n\r\0\x0B" ); } } else { $url = preg_replace( '#^\w+://#', $scheme . '://', $url ); } return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme ); } function get_dashboard_url( $user_id = 0, $path = '', $scheme = 'admin' ) { $user_id = $user_id ? (int) $user_id : get_current_user_id(); $blogs = get_blogs_of_user( $user_id ); if ( is_multisite() && ! user_can( $user_id, 'manage_network' ) && empty( $blogs ) ) { $url = user_admin_url( $path, $scheme ); } elseif ( ! is_multisite() ) { $url = admin_url( $path, $scheme ); } else { $current_blog = get_current_blog_id(); if ( $current_blog && ( user_can( $user_id, 'manage_network' ) || in_array( $current_blog, array_keys( $blogs ), true ) ) ) { $url = admin_url( $path, $scheme ); } else { $active = get_active_blog_for_user( $user_id ); if ( $active ) { $url = get_admin_url( $active->blog_id, $path, $scheme ); } else { $url = user_admin_url( $path, $scheme ); } } } return apply_filters( 'user_dashboard_url', $url, $user_id, $path, $scheme ); } function get_edit_profile_url( $user_id = 0, $scheme = 'admin' ) { $user_id = $user_id ? (int) $user_id : get_current_user_id(); if ( is_user_admin() ) { $url = user_admin_url( 'profile.php', $scheme ); } elseif ( is_network_admin() ) { $url = network_admin_url( 'profile.php', $scheme ); } else { $url = get_dashboard_url( $user_id, 'profile.php', $scheme ); } return apply_filters( 'edit_profile_url', $url, $user_id, $scheme ); } function wp_get_canonical_url( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } if ( 'publish' !== get_post_status( $post ) ) { return false; } $canonical_url = get_permalink( $post ); if ( get_queried_object_id() === $post->ID ) { $page = get_query_var( 'page', 0 ); if ( $page >= 2 ) { if ( ! get_option( 'permalink_structure' ) ) { $canonical_url = add_query_arg( 'page', $page, $canonical_url ); } else { $canonical_url = trailingslashit( $canonical_url ) . user_trailingslashit( $page, 'single_paged' ); } } $cpage = get_query_var( 'cpage', 0 ); if ( $cpage ) { $canonical_url = get_comments_pagenum_link( $cpage ); } } return apply_filters( 'get_canonical_url', $canonical_url, $post ); } function rel_canonical() { if ( ! is_singular() ) { return; } $id = get_queried_object_id(); if ( 0 === $id ) { return; } $url = wp_get_canonical_url( $id ); if ( ! empty( $url ) ) { echo '<link rel="canonical" href="' . esc_url( $url ) . '" />' . "\n"; } } function wp_get_shortlink( $id = 0, $context = 'post', $allow_slugs = true ) { $shortlink = apply_filters( 'pre_get_shortlink', false, $id, $context, $allow_slugs ); if ( false !== $shortlink ) { return $shortlink; } $post_id = 0; if ( 'query' === $context && is_singular() ) { $post_id = get_queried_object_id(); $post = get_post( $post_id ); } elseif ( 'post' === $context ) { $post = get_post( $id ); if ( ! empty( $post->ID ) ) { $post_id = $post->ID; } } $shortlink = ''; if ( ! empty( $post_id ) ) { $post_type = get_post_type_object( $post->post_type ); if ( 'page' === $post->post_type && 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID ) { $shortlink = home_url( '/' ); } elseif ( $post_type && $post_type->public ) { $shortlink = home_url( '?p=' . $post_id ); } } return apply_filters( 'get_shortlink', $shortlink, $id, $context, $allow_slugs ); } function wp_shortlink_wp_head() { $shortlink = wp_get_shortlink( 0, 'query' ); if ( empty( $shortlink ) ) { return; } echo "<link rel='shortlink' href='" . esc_url( $shortlink ) . "' />\n"; } function wp_shortlink_header() { if ( headers_sent() ) { return; } $shortlink = wp_get_shortlink( 0, 'query' ); if ( empty( $shortlink ) ) { return; } header( 'Link: <' . $shortlink . '>; rel=shortlink', false ); } function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) { $post = get_post(); if ( empty( $text ) ) { $text = __( 'This is the short link.' ); } $shortlink = wp_get_shortlink( $post->ID ); if ( ! empty( $shortlink ) ) { $link = '<a rel="shortlink" href="' . esc_url( $shortlink ) . '">' . $text . '</a>'; $link = apply_filters( 'the_shortlink', $link, $shortlink, $text, $title ); echo $before, $link, $after; } } function get_avatar_url( $id_or_email, $args = null ) { $args = get_avatar_data( $id_or_email, $args ); return $args['url']; } function is_avatar_comment_type( $comment_type ) { $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment', 'note' ) ); return in_array( $comment_type, (array) $allowed_comment_types, true ); } function get_avatar_data( $id_or_email, $args = null ) { $args = wp_parse_args( $args, array( 'size' => 96, 'height' => null, 'width' => null, 'default' => get_option( 'avatar_default', 'mystery' ), 'force_default' => false, 'rating' => get_option( 'avatar_rating' ), 'scheme' => null, 'processed_args' => null, 'extra_attr' => '', ) ); if ( is_numeric( $args['size'] ) ) { $args['size'] = absint( $args['size'] ); if ( ! $args['size'] ) { $args['size'] = 96; } } else { $args['size'] = 96; } if ( is_numeric( $args['height'] ) ) { $args['height'] = absint( $args['height'] ); if ( ! $args['height'] ) { $args['height'] = $args['size']; } } else { $args['height'] = $args['size']; } if ( is_numeric( $args['width'] ) ) { $args['width'] = absint( $args['width'] ); if ( ! $args['width'] ) { $args['width'] = $args['size']; } } else { $args['width'] = $args['size']; } if ( empty( $args['default'] ) ) { $args['default'] = get_option( 'avatar_default', 'mystery' ); } switch ( $args['default'] ) { case 'mm': case 'mystery': case 'mysteryman': $args['default'] = 'mm'; break; case 'gravatar_default': $args['default'] = false; break; } $args['force_default'] = (bool) $args['force_default']; $args['rating'] = strtolower( $args['rating'] ); $args['found_avatar'] = false; $args = apply_filters( 'pre_get_avatar_data', $args, $id_or_email ); if ( isset( $args['url'] ) ) { return apply_filters( 'get_avatar_data', $args, $id_or_email ); } $email_hash = ''; $user = false; $email = false; if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) { $id_or_email = get_comment( $id_or_email ); } if ( is_numeric( $id_or_email ) ) { $user = get_user_by( 'id', absint( $id_or_email ) ); } elseif ( is_string( $id_or_email ) ) { if ( str_contains( $id_or_email, '@sha256.gravatar.com' ) ) { list( $email_hash ) = explode( '@', $id_or_email ); } elseif ( str_contains( $id_or_email, '@md5.gravatar.com' ) ) { list( $email_hash ) = explode( '@', $id_or_email ); } else { $email = $id_or_email; } } elseif ( $id_or_email instanceof WP_User ) { $user = $id_or_email; } elseif ( $id_or_email instanceof WP_Post ) { $user = get_user_by( 'id', (int) $id_or_email->post_author ); } elseif ( $id_or_email instanceof WP_Comment ) { if ( ! is_avatar_comment_type( get_comment_type( $id_or_email ) ) ) { $args['url'] = false; return apply_filters( 'get_avatar_data', $args, $id_or_email ); } if ( ! empty( $id_or_email->user_id ) ) { $user = get_user_by( 'id', (int) $id_or_email->user_id ); } if ( ( ! $user || is_wp_error( $user ) ) && ! empty( $id_or_email->comment_author_email ) ) { $email = $id_or_email->comment_author_email; } } if ( ! $email_hash ) { if ( $user ) { $email = $user->user_email; } if ( $email ) { $email_hash = hash( 'sha256', strtolower( trim( $email ) ) ); } } if ( $email_hash ) { $args['found_avatar'] = true; } $url_args = array( 's' => $args['size'], 'd' => $args['default'], 'f' => $args['force_default'] ? 'y' : false, 'r' => $args['rating'], ); if ( 'initials' === $args['default'] ) { $name = ''; if ( $user ) { if ( '' !== $user->display_name ) { $name = $user->display_name; } elseif ( '' !== $user->first_name && '' !== $user->last_name ) { $name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $user->first_name, $user->last_name ); } else { $name = $user->user_login; } } elseif ( $id_or_email instanceof WP_Comment ) { $name = $id_or_email->comment_author; } elseif ( is_string( $id_or_email ) && false !== strpos( $id_or_email, '@' ) ) { $name = str_replace( array( '.', '_', '-' ), ' ', substr( $id_or_email, 0, strpos( $id_or_email, '@' ) ) ); } if ( '' !== $name ) { if ( ! str_contains( $name, ' ' ) || preg_match( '/\p{Han}|\p{Hiragana}|\p{Katakana}|\p{Hangul}/u', $name ) ) { $initials = mb_substr( $name, 0, min( 2, mb_strlen( $name, 'UTF-8' ) ), 'UTF-8' ); } else { $first = mb_substr( $name, 0, 1, 'UTF-8' ); $last = mb_substr( $name, strrpos( $name, ' ' ) + 1, 1, 'UTF-8' ); $initials = $first . $last; } $url_args['initials'] = $initials; } } $url = 'https://secure.gravatar.com/avatar/' . $email_hash; $url = add_query_arg( rawurlencode_deep( array_filter( $url_args ) ), $url ); $args['url'] = apply_filters( 'get_avatar_url', $url, $id_or_email, $args ); return apply_filters( 'get_avatar_data', $args, $id_or_email ); } function get_theme_file_uri( $file = '' ) { $file = ltrim( $file, '/' ); $stylesheet_directory = get_stylesheet_directory(); if ( empty( $file ) ) { $url = get_stylesheet_directory_uri(); } elseif ( get_template_directory() !== $stylesheet_directory && file_exists( $stylesheet_directory . '/' . $file ) ) { $url = get_stylesheet_directory_uri() . '/' . $file; } else { $url = get_template_directory_uri() . '/' . $file; } return apply_filters( 'theme_file_uri', $url, $file ); } function get_parent_theme_file_uri( $file = '' ) { $file = ltrim( $file, '/' ); if ( empty( $file ) ) { $url = get_template_directory_uri(); } else { $url = get_template_directory_uri() . '/' . $file; } return apply_filters( 'parent_theme_file_uri', $url, $file ); } function get_theme_file_path( $file = '' ) { $file = ltrim( $file, '/' ); $stylesheet_directory = get_stylesheet_directory(); $template_directory = get_template_directory(); if ( empty( $file ) ) { $path = $stylesheet_directory; } elseif ( $stylesheet_directory !== $template_directory && file_exists( $stylesheet_directory . '/' . $file ) ) { $path = $stylesheet_directory . '/' . $file; } else { $path = $template_directory . '/' . $file; } return apply_filters( 'theme_file_path', $path, $file ); } function get_parent_theme_file_path( $file = '' ) { $file = ltrim( $file, '/' ); if ( empty( $file ) ) { $path = get_template_directory(); } else { $path = get_template_directory() . '/' . $file; } return apply_filters( 'parent_theme_file_path', $path, $file ); } function get_privacy_policy_url() { $url = ''; $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); if ( ! empty( $policy_page_id ) && get_post_status( $policy_page_id ) === 'publish' ) { $url = (string) get_permalink( $policy_page_id ); } return apply_filters( 'privacy_policy_url', $url, $policy_page_id ); } function the_privacy_policy_link( $before = '', $after = '' ) { echo get_the_privacy_policy_link( $before, $after ); } function get_the_privacy_policy_link( $before = '', $after = '' ) { $link = ''; $privacy_policy_url = get_privacy_policy_url(); $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); $page_title = ( $policy_page_id ) ? get_the_title( $policy_page_id ) : ''; if ( $privacy_policy_url && $page_title ) { $link = sprintf( '<a class="privacy-policy-link" href="%s" rel="privacy-policy">%s</a>', esc_url( $privacy_policy_url ), esc_html( $page_title ) ); } $link = apply_filters( 'the_privacy_policy_link', $link, $privacy_policy_url ); if ( $link ) { return $before . $link . $after; } return ''; } function wp_internal_hosts() { static $internal_hosts; if ( empty( $internal_hosts ) ) { $internal_hosts = apply_filters( 'wp_internal_hosts', array( wp_parse_url( home_url(), PHP_URL_HOST ), ) ); $internal_hosts = array_unique( array_map( 'strtolower', (array) $internal_hosts ) ); } return $internal_hosts; } function wp_is_internal_link( $link ) { $link = strtolower( $link ); if ( in_array( wp_parse_url( $link, PHP_URL_SCHEME ), wp_allowed_protocols(), true ) ) { return in_array( wp_parse_url( $link, PHP_URL_HOST ), wp_internal_hosts(), true ); } return false; }
###require ABSPATH . WPINC . '/author-template.php';
function get_the_author( $deprecated = '' ) { global $authordata; if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.1.0' ); } return apply_filters( 'the_author', is_object( $authordata ) ? $authordata->display_name : '' ); } function the_author( $deprecated = '', $deprecated_echo = true ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.1.0' ); } if ( true !== $deprecated_echo ) { _deprecated_argument( __FUNCTION__, '1.5.0', sprintf( __( 'Use %s instead if you do not want the value echoed.' ), '<code>get_the_author()</code>' ) ); } if ( $deprecated_echo ) { echo get_the_author(); } return get_the_author(); } function get_the_modified_author( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return null; } $last_id = get_post_meta( $post->ID, '_edit_last', true ); if ( ! $last_id ) { return null; } $last_user = get_userdata( $last_id ); return apply_filters( 'the_modified_author', $last_user ? $last_user->display_name : '' ); } function the_modified_author() { echo get_the_modified_author(); } function get_the_author_meta( $field = '', $user_id = false ) { $original_user_id = $user_id; if ( ! $user_id ) { global $authordata; $user_id = isset( $authordata->ID ) ? $authordata->ID : 0; } else { $authordata = get_userdata( $user_id ); } if ( in_array( $field, array( 'login', 'pass', 'nicename', 'email', 'url', 'registered', 'activation_key', 'status' ), true ) ) { $field = 'user_' . $field; } $value = isset( $authordata->$field ) ? $authordata->$field : ''; return apply_filters( "get_the_author_{$field}", $value, $user_id, $original_user_id ); } function the_author_meta( $field = '', $user_id = false ) { $author_meta = get_the_author_meta( $field, $user_id ); echo apply_filters( "the_author_{$field}", $author_meta, $user_id ); } function get_the_author_link() { if ( get_the_author_meta( 'url' ) ) { global $authordata; $author_url = get_the_author_meta( 'url' ); $author_display_name = get_the_author(); $link = sprintf( '<a href="%1$s" title="%2$s" rel="author external">%3$s</a>', esc_url( $author_url ), esc_attr( sprintf( __( 'Visit %s’s website' ), $author_display_name ) ), $author_display_name ); return apply_filters( 'the_author_link', $link, $author_url, $authordata ); } else { return get_the_author(); } } function the_author_link() { echo get_the_author_link(); } function get_the_author_posts() { $post = get_post(); if ( ! $post ) { return 0; } return (int) count_user_posts( $post->post_author, $post->post_type ); } function the_author_posts() { echo get_the_author_posts(); } function get_the_author_posts_link() { global $authordata; if ( ! is_object( $authordata ) ) { return ''; } $link = sprintf( '<a href="%1$s" title="%2$s" rel="author">%3$s</a>', esc_url( get_author_posts_url( $authordata->ID, $authordata->user_nicename ) ), esc_attr( sprintf( __( 'Posts by %s' ), get_the_author() ) ), get_the_author() ); return apply_filters( 'the_author_posts_link', $link ); } function the_author_posts_link( $deprecated = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.1.0' ); } echo get_the_author_posts_link(); } function get_author_posts_url( $author_id, $author_nicename = '' ) { global $wp_rewrite; $author_id = (int) $author_id; $link = $wp_rewrite->get_author_permastruct(); if ( empty( $link ) ) { $file = home_url( '/' ); $link = $file . '?author=' . $author_id; } else { if ( '' === $author_nicename ) { $user = get_userdata( $author_id ); if ( ! empty( $user->user_nicename ) ) { $author_nicename = $user->user_nicename; } } $link = str_replace( '%author%', $author_nicename, $link ); $link = home_url( user_trailingslashit( $link ) ); } $link = apply_filters( 'author_link', $link, $author_id, $author_nicename ); return $link; } function wp_list_authors( $args = '' ) { global $wpdb; $defaults = array( 'orderby' => 'name', 'order' => 'ASC', 'number' => '', 'optioncount' => false, 'exclude_admin' => true, 'show_fullname' => false, 'hide_empty' => true, 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true, 'style' => 'list', 'html' => true, 'exclude' => '', 'include' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); $return = ''; $query_args = wp_array_slice_assoc( $parsed_args, array( 'orderby', 'order', 'number', 'exclude', 'include' ) ); $query_args['fields'] = 'ids'; $query_args = apply_filters( 'wp_list_authors_args', $query_args, $parsed_args ); $authors = get_users( $query_args ); $post_counts = array(); $post_counts = apply_filters( 'pre_wp_list_authors_post_counts_query', false, $parsed_args ); if ( ! is_array( $post_counts ) ) { $post_counts = array(); $post_counts_query = $wpdb->get_results( "SELECT DISTINCT post_author, COUNT(ID) AS count
FROM $wpdb->posts
WHERE " . get_private_posts_cap_sql( 'post' ) . '
GROUP BY post_author' ); foreach ( (array) $post_counts_query as $row ) { $post_counts[ $row->post_author ] = $row->count; } } foreach ( $authors as $author_id ) { $posts = isset( $post_counts[ $author_id ] ) ? $post_counts[ $author_id ] : 0; if ( ! $posts && $parsed_args['hide_empty'] ) { continue; } $author = get_userdata( $author_id ); if ( $parsed_args['exclude_admin'] && 'admin' === $author->display_name ) { continue; } if ( $parsed_args['show_fullname'] && $author->first_name && $author->last_name ) { $name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $author->first_name, $author->last_name ); } else { $name = $author->display_name; } if ( ! $parsed_args['html'] ) { $return .= $name . ', '; continue; } if ( 'list' === $parsed_args['style'] ) { $return .= '<li>'; } $link = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', esc_url( get_author_posts_url( $author->ID, $author->user_nicename ) ), esc_attr( sprintf( __( 'Posts by %s' ), $author->display_name ) ), $name ); if ( ! empty( $parsed_args['feed_image'] ) || ! empty( $parsed_args['feed'] ) ) { $link .= ' '; if ( empty( $parsed_args['feed_image'] ) ) { $link .= '('; } $link .= '<a href="' . get_author_feed_link( $author->ID, $parsed_args['feed_type'] ) . '"'; $alt = ''; if ( ! empty( $parsed_args['feed'] ) ) { $alt = ' alt="' . esc_attr( $parsed_args['feed'] ) . '"'; $name = $parsed_args['feed']; } $link .= '>'; if ( ! empty( $parsed_args['feed_image'] ) ) { $link .= '<img src="' . esc_url( $parsed_args['feed_image'] ) . '" style="border: none;"' . $alt . ' />'; } else { $link .= $name; } $link .= '</a>'; if ( empty( $parsed_args['feed_image'] ) ) { $link .= ')'; } } if ( $parsed_args['optioncount'] ) { $link .= ' (' . $posts . ')'; } $return .= $link; $return .= ( 'list' === $parsed_args['style'] ) ? '</li>' : ', '; } $return = rtrim( $return, ', ' ); if ( $parsed_args['echo'] ) { echo $return; } else { return $return; } } function is_multi_author() { global $wpdb; $is_multi_author = get_transient( 'is_multi_author' ); if ( false === $is_multi_author ) { $rows = (array) $wpdb->get_col( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 2" ); $is_multi_author = 1 < count( $rows ) ? 1 : 0; set_transient( 'is_multi_author', $is_multi_author ); } return apply_filters( 'is_multi_author', (bool) $is_multi_author ); } function __clear_multi_author_cache() { delete_transient( 'is_multi_author' ); }
###require ABSPATH . WPINC . '/robots-template.php';
function wp_robots() { $robots = apply_filters( 'wp_robots', array() ); $robots_strings = array(); foreach ( $robots as $directive => $value ) { if ( is_string( $value ) ) { $robots_strings[] = "{$directive}:{$value}"; } elseif ( $value ) { $robots_strings[] = $directive; } } if ( empty( $robots_strings ) ) { return; } echo "<meta name='robots' content='" . esc_attr( implode( ', ', $robots_strings ) ) . "' />\n"; } function wp_robots_noindex( array $robots ) { if ( ! get_option( 'blog_public' ) ) { return wp_robots_no_robots( $robots ); } return $robots; } function wp_robots_noindex_embeds( array $robots ) { if ( is_embed() ) { return wp_robots_no_robots( $robots ); } return $robots; } function wp_robots_noindex_search( array $robots ) { if ( is_search() ) { return wp_robots_no_robots( $robots ); } return $robots; } function wp_robots_no_robots( array $robots ) { $robots['noindex'] = true; if ( get_option( 'blog_public' ) ) { $robots['follow'] = true; } else { $robots['nofollow'] = true; } return $robots; } function wp_robots_sensitive_page( array $robots ) { $robots['noindex'] = true; $robots['noarchive'] = true; return $robots; } function wp_robots_max_image_preview_large( array $robots ) { if ( get_option( 'blog_public' ) ) { $robots['max-image-preview'] = 'large'; } return $robots; }
###require ABSPATH . WPINC . '/post.php';
function create_initial_post_types() { WP_Post_Type::reset_default_labels(); register_post_type( 'post', array( 'labels' => array( 'name_admin_bar' => _x( 'Post', 'add new from admin bar' ), ), 'public' => true, '_builtin' => true, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'map_meta_cap' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-admin-post', 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'delete_with_user' => true, 'supports' => array( 'title', 'editor' => array( 'notes' => true ), 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats', ), 'show_in_rest' => true, 'rest_base' => 'posts', 'rest_controller_class' => 'WP_REST_Posts_Controller', ) ); register_post_type( 'page', array( 'labels' => array( 'name_admin_bar' => _x( 'Page', 'add new from admin bar' ), ), 'public' => true, 'publicly_queryable' => false, '_builtin' => true, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'page', 'map_meta_cap' => true, 'menu_position' => 20, 'menu_icon' => 'dashicons-admin-page', 'hierarchical' => true, 'rewrite' => false, 'query_var' => false, 'delete_with_user' => true, 'supports' => array( 'title', 'editor' => array( 'notes' => true ), 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions', ), 'show_in_rest' => true, 'rest_base' => 'pages', 'rest_controller_class' => 'WP_REST_Posts_Controller', ) ); register_post_type( 'attachment', array( 'labels' => array( 'name' => _x( 'Media', 'post type general name' ), 'name_admin_bar' => _x( 'Media', 'add new from admin bar' ), 'add_new' => __( 'Add Media File' ), 'add_new_item' => __( 'Add Media File' ), 'edit_item' => __( 'Edit Media' ), 'view_item' => ( '1' === get_option( 'wp_attachment_pages_enabled' ) ) ? __( 'View Attachment Page' ) : __( 'View Media File' ), 'attributes' => __( 'Attachment Attributes' ), ), 'public' => true, 'show_ui' => true, '_builtin' => true, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'capabilities' => array( 'create_posts' => 'upload_files', ), 'map_meta_cap' => true, 'menu_icon' => 'dashicons-admin-media', 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'show_in_nav_menus' => false, 'delete_with_user' => true, 'supports' => array( 'title', 'author', 'comments' ), 'show_in_rest' => true, 'rest_base' => 'media', 'rest_controller_class' => 'WP_REST_Attachments_Controller', ) ); add_post_type_support( 'attachment:audio', 'thumbnail' ); add_post_type_support( 'attachment:video', 'thumbnail' ); register_post_type( 'revision', array( 'labels' => array( 'name' => __( 'Revisions' ), 'singular_name' => __( 'Revision' ), ), 'public' => false, '_builtin' => true, '_edit_link' => 'revision.php?revision=%d', 'capability_type' => 'post', 'map_meta_cap' => true, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'can_export' => false, 'delete_with_user' => true, 'supports' => array( 'author' ), ) ); register_post_type( 'nav_menu_item', array( 'labels' => array( 'name' => __( 'Navigation Menu Items' ), 'singular_name' => __( 'Navigation Menu Item' ), ), 'public' => false, '_builtin' => true, 'hierarchical' => false, 'rewrite' => false, 'delete_with_user' => false, 'query_var' => false, 'map_meta_cap' => true, 'capability_type' => array( 'edit_theme_options', 'edit_theme_options' ), 'capabilities' => array( 'edit_post' => 'edit_post', 'read_post' => 'read_post', 'delete_post' => 'delete_post', 'edit_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', 'read' => 'read', 'delete_private_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'edit_private_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', ), 'show_in_rest' => true, 'rest_base' => 'menu-items', 'rest_controller_class' => 'WP_REST_Menu_Items_Controller', ) ); register_post_type( 'custom_css', array( 'labels' => array( 'name' => __( 'Custom CSS' ), 'singular_name' => __( 'Custom CSS' ), ), 'public' => false, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'delete_with_user' => false, 'can_export' => true, '_builtin' => true, 'supports' => array( 'title', 'revisions' ), 'capabilities' => array( 'delete_posts' => 'edit_theme_options', 'delete_post' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'delete_private_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'edit_post' => 'edit_css', 'edit_posts' => 'edit_css', 'edit_others_posts' => 'edit_css', 'edit_published_posts' => 'edit_css', 'read_post' => 'read', 'read_private_posts' => 'read', 'publish_posts' => 'edit_theme_options', ), ) ); register_post_type( 'customize_changeset', array( 'labels' => array( 'name' => _x( 'Changesets', 'post type general name' ), 'singular_name' => _x( 'Changeset', 'post type singular name' ), 'add_new' => __( 'Add Changeset' ), 'add_new_item' => __( 'Add Changeset' ), 'new_item' => __( 'New Changeset' ), 'edit_item' => __( 'Edit Changeset' ), 'view_item' => __( 'View Changeset' ), 'all_items' => __( 'All Changesets' ), 'search_items' => __( 'Search Changesets' ), 'not_found' => __( 'No changesets found.' ), 'not_found_in_trash' => __( 'No changesets found in Trash.' ), ), 'public' => false, '_builtin' => true, 'map_meta_cap' => true, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'can_export' => false, 'delete_with_user' => false, 'supports' => array( 'title', 'author' ), 'capability_type' => 'customize_changeset', 'capabilities' => array( 'create_posts' => 'customize', 'delete_others_posts' => 'customize', 'delete_post' => 'customize', 'delete_posts' => 'customize', 'delete_private_posts' => 'customize', 'delete_published_posts' => 'customize', 'edit_others_posts' => 'customize', 'edit_post' => 'customize', 'edit_posts' => 'customize', 'edit_private_posts' => 'customize', 'edit_published_posts' => 'do_not_allow', 'publish_posts' => 'customize', 'read' => 'read', 'read_post' => 'customize', 'read_private_posts' => 'customize', ), ) ); register_post_type( 'oembed_cache', array( 'labels' => array( 'name' => __( 'oEmbed Responses' ), 'singular_name' => __( 'oEmbed Response' ), ), 'public' => false, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'delete_with_user' => false, 'can_export' => false, '_builtin' => true, 'supports' => array(), ) ); register_post_type( 'user_request', array( 'labels' => array( 'name' => __( 'User Requests' ), 'singular_name' => __( 'User Request' ), ), 'public' => false, '_builtin' => true, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'can_export' => false, 'delete_with_user' => false, 'supports' => array(), ) ); register_post_type( 'wp_block', array( 'labels' => array( 'name' => _x( 'Patterns', 'post type general name' ), 'singular_name' => _x( 'Pattern', 'post type singular name' ), 'add_new' => __( 'Add Pattern' ), 'add_new_item' => __( 'Add Pattern' ), 'new_item' => __( 'New Pattern' ), 'edit_item' => __( 'Edit Block Pattern' ), 'view_item' => __( 'View Pattern' ), 'view_items' => __( 'View Patterns' ), 'all_items' => __( 'All Patterns' ), 'search_items' => __( 'Search Patterns' ), 'not_found' => __( 'No patterns found.' ), 'not_found_in_trash' => __( 'No patterns found in Trash.' ), 'filter_items_list' => __( 'Filter patterns list' ), 'items_list_navigation' => __( 'Patterns list navigation' ), 'items_list' => __( 'Patterns list' ), 'item_published' => __( 'Pattern published.' ), 'item_published_privately' => __( 'Pattern published privately.' ), 'item_reverted_to_draft' => __( 'Pattern reverted to draft.' ), 'item_scheduled' => __( 'Pattern scheduled.' ), 'item_updated' => __( 'Pattern updated.' ), ), 'public' => false, '_builtin' => true, 'show_ui' => true, 'show_in_menu' => false, 'rewrite' => false, 'show_in_rest' => true, 'rest_base' => 'blocks', 'rest_controller_class' => 'WP_REST_Blocks_Controller', 'capability_type' => 'block', 'capabilities' => array( 'read' => 'edit_posts', 'create_posts' => 'publish_posts', 'edit_posts' => 'edit_posts', 'edit_published_posts' => 'edit_published_posts', 'delete_published_posts' => 'delete_published_posts', 'delete_posts' => 'delete_posts', 'edit_others_posts' => 'edit_others_posts', 'delete_others_posts' => 'delete_others_posts', ), 'map_meta_cap' => true, 'supports' => array( 'title', 'excerpt', 'editor', 'revisions', 'custom-fields', ), ) ); $template_edit_link = 'site-editor.php?' . build_query( array( 'postType' => '%s', 'postId' => '%s', 'canvas' => 'edit', ) ); register_post_type( 'wp_template', array( 'labels' => array( 'name' => _x( 'Templates', 'post type general name' ), 'singular_name' => _x( 'Template', 'post type singular name' ), 'add_new' => __( 'Add Template' ), 'add_new_item' => __( 'Add Template' ), 'new_item' => __( 'New Template' ), 'edit_item' => __( 'Edit Template' ), 'view_item' => __( 'View Template' ), 'all_items' => __( 'Templates' ), 'search_items' => __( 'Search Templates' ), 'parent_item_colon' => __( 'Parent Template:' ), 'not_found' => __( 'No templates found.' ), 'not_found_in_trash' => __( 'No templates found in Trash.' ), 'archives' => __( 'Template archives' ), 'insert_into_item' => __( 'Insert into template' ), 'uploaded_to_this_item' => __( 'Uploaded to this template' ), 'filter_items_list' => __( 'Filter templates list' ), 'items_list_navigation' => __( 'Templates list navigation' ), 'items_list' => __( 'Templates list' ), 'item_updated' => __( 'Template updated.' ), ), 'description' => __( 'Templates to include in your theme.' ), 'public' => false, '_builtin' => true, '_edit_link' => $template_edit_link, 'has_archive' => false, 'show_ui' => false, 'show_in_menu' => false, 'show_in_rest' => true, 'rewrite' => false, 'rest_base' => 'templates', 'rest_controller_class' => 'WP_REST_Templates_Controller', 'autosave_rest_controller_class' => 'WP_REST_Template_Autosaves_Controller', 'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller', 'late_route_registration' => true, 'capability_type' => array( 'template', 'templates' ), 'capabilities' => array( 'create_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'delete_private_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'edit_private_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'read' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', ), 'map_meta_cap' => true, 'supports' => array( 'title', 'slug', 'excerpt', 'editor', 'revisions', 'author', ), ) ); register_post_type( 'wp_template_part', array( 'labels' => array( 'name' => _x( 'Template Parts', 'post type general name' ), 'singular_name' => _x( 'Template Part', 'post type singular name' ), 'add_new' => __( 'Add Template Part' ), 'add_new_item' => __( 'Add Template Part' ), 'new_item' => __( 'New Template Part' ), 'edit_item' => __( 'Edit Template Part' ), 'view_item' => __( 'View Template Part' ), 'all_items' => __( 'Template Parts' ), 'search_items' => __( 'Search Template Parts' ), 'parent_item_colon' => __( 'Parent Template Part:' ), 'not_found' => __( 'No template parts found.' ), 'not_found_in_trash' => __( 'No template parts found in Trash.' ), 'archives' => __( 'Template part archives' ), 'insert_into_item' => __( 'Insert into template part' ), 'uploaded_to_this_item' => __( 'Uploaded to this template part' ), 'filter_items_list' => __( 'Filter template parts list' ), 'items_list_navigation' => __( 'Template parts list navigation' ), 'items_list' => __( 'Template parts list' ), 'item_updated' => __( 'Template part updated.' ), ), 'description' => __( 'Template parts to include in your templates.' ), 'public' => false, '_builtin' => true, '_edit_link' => $template_edit_link, 'has_archive' => false, 'show_ui' => false, 'show_in_menu' => false, 'show_in_rest' => true, 'rewrite' => false, 'rest_base' => 'template-parts', 'rest_controller_class' => 'WP_REST_Templates_Controller', 'autosave_rest_controller_class' => 'WP_REST_Template_Autosaves_Controller', 'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller', 'late_route_registration' => true, 'map_meta_cap' => true, 'capabilities' => array( 'create_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'delete_private_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'edit_private_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'read' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', ), 'supports' => array( 'title', 'slug', 'excerpt', 'editor', 'revisions', 'author', ), ) ); register_post_type( 'wp_global_styles', array( 'label' => _x( 'Global Styles', 'post type general name' ), 'description' => __( 'Global styles to include in themes.' ), 'public' => false, '_builtin' => true, '_edit_link' => '/site-editor.php?canvas=edit', 'show_ui' => false, 'show_in_rest' => true, 'rewrite' => false, 'rest_base' => 'global-styles', 'rest_controller_class' => 'WP_REST_Global_Styles_Controller', 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller', 'late_route_registration' => true, 'capabilities' => array( 'read' => 'edit_posts', 'create_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', ), 'map_meta_cap' => true, 'supports' => array( 'title', 'editor', 'revisions', ), ) ); remove_post_type_support( 'wp_global_styles', 'autosave' ); $navigation_post_edit_link = 'site-editor.php?' . build_query( array( 'postId' => '%s', 'postType' => 'wp_navigation', 'canvas' => 'edit', ) ); register_post_type( 'wp_navigation', array( 'labels' => array( 'name' => _x( 'Navigation Menus', 'post type general name' ), 'singular_name' => _x( 'Navigation Menu', 'post type singular name' ), 'add_new' => __( 'Add Navigation Menu' ), 'add_new_item' => __( 'Add Navigation Menu' ), 'new_item' => __( 'New Navigation Menu' ), 'edit_item' => __( 'Edit Navigation Menu' ), 'view_item' => __( 'View Navigation Menu' ), 'all_items' => __( 'Navigation Menus' ), 'search_items' => __( 'Search Navigation Menus' ), 'parent_item_colon' => __( 'Parent Navigation Menu:' ), 'not_found' => __( 'No Navigation Menu found.' ), 'not_found_in_trash' => __( 'No Navigation Menu found in Trash.' ), 'archives' => __( 'Navigation Menu archives' ), 'insert_into_item' => __( 'Insert into Navigation Menu' ), 'uploaded_to_this_item' => __( 'Uploaded to this Navigation Menu' ), 'filter_items_list' => __( 'Filter Navigation Menu list' ), 'items_list_navigation' => __( 'Navigation Menus list navigation' ), 'items_list' => __( 'Navigation Menus list' ), ), 'description' => __( 'Navigation menus that can be inserted into your site.' ), 'public' => false, '_builtin' => true, '_edit_link' => $navigation_post_edit_link, 'has_archive' => false, 'show_ui' => true, 'show_in_menu' => false, 'show_in_admin_bar' => false, 'show_in_rest' => true, 'rewrite' => false, 'map_meta_cap' => true, 'capabilities' => array( 'edit_others_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', 'delete_private_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'edit_private_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', ), 'rest_base' => 'navigation', 'rest_controller_class' => 'WP_REST_Posts_Controller', 'supports' => array( 'title', 'editor', 'revisions', ), ) ); register_post_type( 'wp_font_family', array( 'labels' => array( 'name' => __( 'Font Families' ), 'singular_name' => __( 'Font Family' ), ), 'public' => false, '_builtin' => true, 'hierarchical' => false, 'capabilities' => array( 'read' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', ), 'map_meta_cap' => true, 'query_var' => false, 'rewrite' => false, 'show_in_rest' => true, 'rest_base' => 'font-families', 'rest_controller_class' => 'WP_REST_Font_Families_Controller', 'supports' => array( 'title' ), ) ); register_post_type( 'wp_font_face', array( 'labels' => array( 'name' => __( 'Font Faces' ), 'singular_name' => __( 'Font Face' ), ), 'public' => false, '_builtin' => true, 'hierarchical' => false, 'capabilities' => array( 'read' => 'edit_theme_options', 'read_private_posts' => 'edit_theme_options', 'create_posts' => 'edit_theme_options', 'publish_posts' => 'edit_theme_options', 'edit_posts' => 'edit_theme_options', 'edit_others_posts' => 'edit_theme_options', 'edit_published_posts' => 'edit_theme_options', 'delete_posts' => 'edit_theme_options', 'delete_others_posts' => 'edit_theme_options', 'delete_published_posts' => 'edit_theme_options', ), 'map_meta_cap' => true, 'query_var' => false, 'rewrite' => false, 'show_in_rest' => true, 'rest_base' => 'font-families/(?P<font_family_id>[\d]+)/font-faces', 'rest_controller_class' => 'WP_REST_Font_Faces_Controller', 'supports' => array( 'title' ), ) ); register_post_status( 'publish', array( 'label' => _x( 'Published', 'post status' ), 'public' => true, '_builtin' => true, 'label_count' => _n_noop( 'Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>' ), ) ); register_post_status( 'future', array( 'label' => _x( 'Scheduled', 'post status' ), 'protected' => true, '_builtin' => true, 'label_count' => _n_noop( 'Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>' ), ) ); register_post_status( 'draft', array( 'label' => _x( 'Draft', 'post status' ), 'protected' => true, '_builtin' => true, 'label_count' => _n_noop( 'Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>' ), 'date_floating' => true, ) ); register_post_status( 'pending', array( 'label' => _x( 'Pending', 'post status' ), 'protected' => true, '_builtin' => true, 'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ), 'date_floating' => true, ) ); register_post_status( 'private', array( 'label' => _x( 'Private', 'post status' ), 'private' => true, '_builtin' => true, 'label_count' => _n_noop( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>' ), ) ); register_post_status( 'trash', array( 'label' => _x( 'Trash', 'post status' ), 'internal' => true, '_builtin' => true, 'label_count' => _n_noop( 'Trash <span class="count">(%s)</span>', 'Trash <span class="count">(%s)</span>' ), 'show_in_admin_status_list' => true, ) ); register_post_status( 'auto-draft', array( 'label' => 'auto-draft', 'internal' => true, '_builtin' => true, 'date_floating' => true, ) ); register_post_status( 'inherit', array( 'label' => 'inherit', 'internal' => true, '_builtin' => true, 'exclude_from_search' => false, ) ); register_post_status( 'request-pending', array( 'label' => _x( 'Pending', 'request status' ), 'internal' => true, '_builtin' => true, 'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ), 'exclude_from_search' => false, ) ); register_post_status( 'request-confirmed', array( 'label' => _x( 'Confirmed', 'request status' ), 'internal' => true, '_builtin' => true, 'label_count' => _n_noop( 'Confirmed <span class="count">(%s)</span>', 'Confirmed <span class="count">(%s)</span>' ), 'exclude_from_search' => false, ) ); register_post_status( 'request-failed', array( 'label' => _x( 'Failed', 'request status' ), 'internal' => true, '_builtin' => true, 'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>' ), 'exclude_from_search' => false, ) ); register_post_status( 'request-completed', array( 'label' => _x( 'Completed', 'request status' ), 'internal' => true, '_builtin' => true, 'label_count' => _n_noop( 'Completed <span class="count">(%s)</span>', 'Completed <span class="count">(%s)</span>' ), 'exclude_from_search' => false, ) ); } function get_attached_file( $attachment_id, $unfiltered = false ) { $file = get_post_meta( $attachment_id, '_wp_attached_file', true ); if ( $file && ! str_starts_with( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) { $uploads = wp_get_upload_dir(); if ( false === $uploads['error'] ) { $file = $uploads['basedir'] . "/$file"; } } if ( $unfiltered ) { return $file; } return apply_filters( 'get_attached_file', $file, $attachment_id ); } function update_attached_file( $attachment_id, $file ) { if ( ! get_post( $attachment_id ) ) { return false; } $file = apply_filters( 'update_attached_file', $file, $attachment_id ); $file = _wp_relative_upload_path( $file ); if ( $file ) { return update_post_meta( $attachment_id, '_wp_attached_file', $file ); } else { return delete_post_meta( $attachment_id, '_wp_attached_file' ); } } function _wp_relative_upload_path( $path ) { $new_path = $path; $uploads = wp_get_upload_dir(); if ( str_starts_with( $new_path, $uploads['basedir'] ) ) { $new_path = str_replace( $uploads['basedir'], '', $new_path ); $new_path = ltrim( $new_path, '/' ); } return apply_filters( '_wp_relative_upload_path', $new_path, $path ); } function get_children( $args = '', $output = OBJECT ) { $kids = array(); if ( empty( $args ) ) { if ( isset( $GLOBALS['post'] ) ) { $args = array( 'post_parent' => (int) $GLOBALS['post']->post_parent ); } else { return $kids; } } elseif ( is_object( $args ) ) { $args = array( 'post_parent' => (int) $args->post_parent ); } elseif ( is_numeric( $args ) ) { $args = array( 'post_parent' => (int) $args ); } $defaults = array( 'numberposts' => -1, 'post_type' => 'any', 'post_status' => 'any', 'post_parent' => 0, ); $parsed_args = wp_parse_args( $args, $defaults ); $children = get_posts( $parsed_args ); if ( ! $children ) { return $kids; } if ( ! empty( $parsed_args['fields'] ) ) { return $children; } update_post_cache( $children ); foreach ( $children as $key => $child ) { $kids[ $child->ID ] = $children[ $key ]; } if ( OBJECT === $output ) { return $kids; } elseif ( ARRAY_A === $output ) { $weeuns = array(); foreach ( (array) $kids as $kid ) { $weeuns[ $kid->ID ] = get_object_vars( $kids[ $kid->ID ] ); } return $weeuns; } elseif ( ARRAY_N === $output ) { $babes = array(); foreach ( (array) $kids as $kid ) { $babes[ $kid->ID ] = array_values( get_object_vars( $kids[ $kid->ID ] ) ); } return $babes; } else { return $kids; } } function get_extended( $post ) { if ( preg_match( '/<!--more(.*?)?-->/', $post, $matches ) ) { list($main, $extended) = explode( $matches[0], $post, 2 ); $more_text = $matches[1]; } else { $main = $post; $extended = ''; $more_text = ''; } $main = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $main ); $extended = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $extended ); $more_text = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $more_text ); return array( 'main' => $main, 'extended' => $extended, 'more_text' => $more_text, ); } function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) { if ( empty( $post ) && isset( $GLOBALS['post'] ) ) { $post = $GLOBALS['post']; } if ( $post instanceof WP_Post ) { $_post = $post; } elseif ( is_object( $post ) ) { if ( empty( $post->filter ) ) { $_post = sanitize_post( $post, 'raw' ); $_post = new WP_Post( $_post ); } elseif ( 'raw' === $post->filter ) { $_post = new WP_Post( $post ); } else { $_post = WP_Post::get_instance( $post->ID ); } } else { $_post = WP_Post::get_instance( $post ); } if ( ! $_post ) { return null; } $_post = $_post->filter( $filter ); if ( ARRAY_A === $output ) { return $_post->to_array(); } elseif ( ARRAY_N === $output ) { return array_values( $_post->to_array() ); } return $_post; } function get_post_ancestors( $post ) { $post = get_post( $post ); if ( ! $post || empty( $post->post_parent ) || $post->post_parent === $post->ID ) { return array(); } $ancestors = array(); $id = $post->post_parent; $ancestors[] = $id; while ( $ancestor = get_post( $id ) ) { if ( empty( $ancestor->post_parent ) || $ancestor->post_parent === $post->ID || in_array( $ancestor->post_parent, $ancestors, true ) ) { break; } $id = $ancestor->post_parent; $ancestors[] = $id; } return $ancestors; } function get_post_field( $field, $post = null, $context = 'display' ) { $post = get_post( $post ); if ( ! $post ) { return ''; } if ( ! isset( $post->$field ) ) { return ''; } return sanitize_post_field( $field, $post->$field, $post->ID, $context ); } function get_post_mime_type( $post = null ) { $post = get_post( $post ); if ( is_object( $post ) ) { return $post->post_mime_type; } return false; } function get_post_status( $post = null ) { if ( ! $post instanceof WP_Post || ! isset( $post->filter ) || 'sample' !== $post->filter ) { $post = get_post( $post ); } if ( ! is_object( $post ) ) { return false; } $post_status = $post->post_status; if ( 'attachment' === $post->post_type && 'inherit' === $post_status ) { if ( 0 === $post->post_parent || ! get_post( $post->post_parent ) || $post->ID === $post->post_parent ) { $post_status = 'publish'; } elseif ( 'trash' === get_post_status( $post->post_parent ) ) { $post_status = get_post_meta( $post->post_parent, '_wp_trash_meta_status', true ); if ( ! $post_status ) { $post_status = 'publish'; } } else { $post_status = get_post_status( $post->post_parent ); } } elseif ( 'attachment' === $post->post_type && ! in_array( $post_status, array( 'private', 'trash', 'auto-draft' ), true ) ) { $post_status = 'publish'; } return apply_filters( 'get_post_status', $post_status, $post ); } function get_post_statuses() { $status = array( 'draft' => __( 'Draft' ), 'pending' => __( 'Pending Review' ), 'private' => __( 'Private' ), 'publish' => __( 'Published' ), ); return $status; } function get_page_statuses() { $status = array( 'draft' => __( 'Draft' ), 'private' => __( 'Private' ), 'publish' => __( 'Published' ), ); return $status; } function _wp_privacy_statuses() { return array( 'request-pending' => _x( 'Pending', 'request status' ), 'request-confirmed' => _x( 'Confirmed', 'request status' ), 'request-failed' => _x( 'Failed', 'request status' ), 'request-completed' => _x( 'Completed', 'request status' ), ); } function register_post_status( $post_status, $args = array() ) { global $wp_post_statuses; if ( ! is_array( $wp_post_statuses ) ) { $wp_post_statuses = array(); } $defaults = array( 'label' => false, 'label_count' => false, 'exclude_from_search' => null, '_builtin' => false, 'public' => null, 'internal' => null, 'protected' => null, 'private' => null, 'publicly_queryable' => null, 'show_in_admin_status_list' => null, 'show_in_admin_all_list' => null, 'date_floating' => null, ); $args = wp_parse_args( $args, $defaults ); $args = (object) $args; $post_status = sanitize_key( $post_status ); $args->name = $post_status; if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private ) { $args->internal = true; } if ( null === $args->public ) { $args->public = false; } if ( null === $args->private ) { $args->private = false; } if ( null === $args->protected ) { $args->protected = false; } if ( null === $args->internal ) { $args->internal = false; } if ( null === $args->publicly_queryable ) { $args->publicly_queryable = $args->public; } if ( null === $args->exclude_from_search ) { $args->exclude_from_search = $args->internal; } if ( null === $args->show_in_admin_all_list ) { $args->show_in_admin_all_list = ! $args->internal; } if ( null === $args->show_in_admin_status_list ) { $args->show_in_admin_status_list = ! $args->internal; } if ( null === $args->date_floating ) { $args->date_floating = false; } if ( false === $args->label ) { $args->label = $post_status; } if ( false === $args->label_count ) { $args->label_count = _n_noop( $args->label, $args->label ); } $wp_post_statuses[ $post_status ] = $args; return $args; } function get_post_status_object( $post_status ) { global $wp_post_statuses; if ( ! is_string( $post_status ) || empty( $wp_post_statuses[ $post_status ] ) ) { return null; } return $wp_post_statuses[ $post_status ]; } function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) { global $wp_post_statuses; $field = ( 'names' === $output ) ? 'name' : false; return wp_filter_object_list( $wp_post_statuses, $args, $operator, $field ); } function is_post_type_hierarchical( $post_type ) { if ( ! post_type_exists( $post_type ) ) { return false; } $post_type = get_post_type_object( $post_type ); return $post_type->hierarchical; } function post_type_exists( $post_type ) { return (bool) get_post_type_object( $post_type ); } function get_post_type( $post = null ) { $post = get_post( $post ); if ( $post ) { return $post->post_type; } return false; } function get_post_type_object( $post_type ) { global $wp_post_types; if ( ! is_scalar( $post_type ) || empty( $wp_post_types[ $post_type ] ) ) { return null; } return $wp_post_types[ $post_type ]; } function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) { global $wp_post_types; $field = ( 'names' === $output ) ? 'name' : false; return wp_filter_object_list( $wp_post_types, $args, $operator, $field ); } function register_post_type( $post_type, $args = array() ) { global $wp_post_types; if ( ! is_array( $wp_post_types ) ) { $wp_post_types = array(); } $post_type = sanitize_key( $post_type ); if ( empty( $post_type ) || strlen( $post_type ) > 20 ) { _doing_it_wrong( __FUNCTION__, __( 'Post type names must be between 1 and 20 characters in length.' ), '4.2.0' ); return new WP_Error( 'post_type_length_invalid', __( 'Post type names must be between 1 and 20 characters in length.' ) ); } $post_type_object = new WP_Post_Type( $post_type, $args ); $post_type_object->add_supports(); $post_type_object->add_rewrite_rules(); $post_type_object->register_meta_boxes(); $wp_post_types[ $post_type ] = $post_type_object; $post_type_object->add_hooks(); $post_type_object->register_taxonomies(); do_action( 'registered_post_type', $post_type, $post_type_object ); do_action( "registered_post_type_{$post_type}", $post_type, $post_type_object ); return $post_type_object; } function unregister_post_type( $post_type ) { global $wp_post_types; if ( ! post_type_exists( $post_type ) ) { return new WP_Error( 'invalid_post_type', __( 'Invalid post type.' ) ); } $post_type_object = get_post_type_object( $post_type ); if ( $post_type_object->_builtin ) { return new WP_Error( 'invalid_post_type', __( 'Unregistering a built-in post type is not allowed' ) ); } $post_type_object->remove_supports(); $post_type_object->remove_rewrite_rules(); $post_type_object->unregister_meta_boxes(); $post_type_object->remove_hooks(); $post_type_object->unregister_taxonomies(); unset( $wp_post_types[ $post_type ] ); do_action( 'unregistered_post_type', $post_type ); return true; } function get_post_type_capabilities( $args ) { if ( ! is_array( $args->capability_type ) ) { $args->capability_type = array( $args->capability_type, $args->capability_type . 's' ); } list( $singular_base, $plural_base ) = $args->capability_type; $default_capabilities = array( 'edit_post' => 'edit_' . $singular_base, 'read_post' => 'read_' . $singular_base, 'delete_post' => 'delete_' . $singular_base, 'edit_posts' => 'edit_' . $plural_base, 'edit_others_posts' => 'edit_others_' . $plural_base, 'delete_posts' => 'delete_' . $plural_base, 'publish_posts' => 'publish_' . $plural_base, 'read_private_posts' => 'read_private_' . $plural_base, ); if ( $args->map_meta_cap ) { $default_capabilities_for_mapping = array( 'read' => 'read', 'delete_private_posts' => 'delete_private_' . $plural_base, 'delete_published_posts' => 'delete_published_' . $plural_base, 'delete_others_posts' => 'delete_others_' . $plural_base, 'edit_private_posts' => 'edit_private_' . $plural_base, 'edit_published_posts' => 'edit_published_' . $plural_base, ); $default_capabilities = array_merge( $default_capabilities, $default_capabilities_for_mapping ); } $capabilities = array_merge( $default_capabilities, $args->capabilities ); if ( ! isset( $capabilities['create_posts'] ) ) { $capabilities['create_posts'] = $capabilities['edit_posts']; } if ( $args->map_meta_cap ) { _post_type_meta_capabilities( $capabilities ); } return (object) $capabilities; } function _post_type_meta_capabilities( $capabilities = null ) { global $post_type_meta_caps; foreach ( $capabilities as $core => $custom ) { if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ), true ) ) { $post_type_meta_caps[ $custom ] = $core; } } } function get_post_type_labels( $post_type_object ) { $nohier_vs_hier_defaults = WP_Post_Type::get_default_labels(); $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name']; $labels = _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults ); if ( ! isset( $post_type_object->labels->template_name ) && isset( $post_type_object->labels->singular_name ) ) { $labels->template_name = sprintf( __( 'Single item: %s' ), $post_type_object->labels->singular_name ); } $post_type = $post_type_object->name; $default_labels = clone $labels; $labels = apply_filters( "post_type_labels_{$post_type}", $labels ); $labels = (object) array_merge( (array) $default_labels, (array) $labels ); return $labels; } function _get_custom_object_labels( $data_object, $nohier_vs_hier_defaults ) { $data_object->labels = (array) $data_object->labels; if ( isset( $data_object->label ) && empty( $data_object->labels['name'] ) ) { $data_object->labels['name'] = $data_object->label; } if ( ! isset( $data_object->labels['singular_name'] ) && isset( $data_object->labels['name'] ) ) { $data_object->labels['singular_name'] = $data_object->labels['name']; } if ( ! isset( $data_object->labels['name_admin_bar'] ) ) { $data_object->labels['name_admin_bar'] = isset( $data_object->labels['singular_name'] ) ? $data_object->labels['singular_name'] : $data_object->name; } if ( ! isset( $data_object->labels['menu_name'] ) && isset( $data_object->labels['name'] ) ) { $data_object->labels['menu_name'] = $data_object->labels['name']; } if ( ! isset( $data_object->labels['all_items'] ) && isset( $data_object->labels['menu_name'] ) ) { $data_object->labels['all_items'] = $data_object->labels['menu_name']; } if ( ! isset( $data_object->labels['archives'] ) && isset( $data_object->labels['all_items'] ) ) { $data_object->labels['archives'] = $data_object->labels['all_items']; } $defaults = array(); foreach ( $nohier_vs_hier_defaults as $key => $value ) { $defaults[ $key ] = $data_object->hierarchical ? $value[1] : $value[0]; } $labels = array_merge( $defaults, $data_object->labels ); $data_object->labels = (object) $data_object->labels; return (object) $labels; } function _add_post_type_submenus() { foreach ( get_post_types( array( 'show_ui' => true ) ) as $ptype ) { $ptype_obj = get_post_type_object( $ptype ); if ( ! $ptype_obj->show_in_menu || true === $ptype_obj->show_in_menu ) { continue; } add_submenu_page( $ptype_obj->show_in_menu, $ptype_obj->labels->name, $ptype_obj->labels->all_items, $ptype_obj->cap->edit_posts, "edit.php?post_type=$ptype" ); } } function add_post_type_support( $post_type, $feature, ...$args ) { global $_wp_post_type_features; $features = (array) $feature; foreach ( $features as $feature ) { if ( $args ) { $_wp_post_type_features[ $post_type ][ $feature ] = $args; } else { $_wp_post_type_features[ $post_type ][ $feature ] = true; } } } function remove_post_type_support( $post_type, $feature ) { global $_wp_post_type_features; unset( $_wp_post_type_features[ $post_type ][ $feature ] ); } function get_all_post_type_supports( $post_type ) { global $_wp_post_type_features; if ( isset( $_wp_post_type_features[ $post_type ] ) ) { return $_wp_post_type_features[ $post_type ]; } return array(); } function post_type_supports( $post_type, $feature ) { global $_wp_post_type_features; return ( isset( $_wp_post_type_features[ $post_type ][ $feature ] ) ); } function get_post_types_by_support( $feature, $operator = 'and' ) { global $_wp_post_type_features; $features = array_fill_keys( (array) $feature, true ); return array_keys( wp_filter_object_list( $_wp_post_type_features, $features, $operator ) ); } function set_post_type( $post_id = 0, $post_type = 'post' ) { global $wpdb; $post_type = sanitize_post_field( 'post_type', $post_type, $post_id, 'db' ); $return = $wpdb->update( $wpdb->posts, array( 'post_type' => $post_type ), array( 'ID' => $post_id ) ); clean_post_cache( $post_id ); return $return; } function is_post_type_viewable( $post_type ) { if ( is_scalar( $post_type ) ) { $post_type = get_post_type_object( $post_type ); if ( ! $post_type ) { return false; } } if ( ! is_object( $post_type ) ) { return false; } $is_viewable = $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public ); return true === apply_filters( 'is_post_type_viewable', $is_viewable, $post_type ); } function is_post_status_viewable( $post_status ) { if ( is_scalar( $post_status ) ) { if ( ! is_string( $post_status ) ) { return false; } $post_status = get_post_status_object( $post_status ); if ( ! $post_status ) { return false; } } if ( ! is_object( $post_status ) || $post_status->internal || $post_status->protected ) { return false; } $is_viewable = $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public ); return true === apply_filters( 'is_post_status_viewable', $is_viewable, $post_status ); } function is_post_publicly_viewable( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $post_type = get_post_type( $post ); $post_status = get_post_status( $post ); return is_post_type_viewable( $post_type ) && is_post_status_viewable( $post_status ); } function is_post_embeddable( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { return false; } $is_embeddable = $post_type->embeddable; return apply_filters( 'is_post_embeddable', $is_embeddable, $post ); } function get_posts( $args = null ) { $defaults = array( 'numberposts' => 5, 'category' => 0, 'orderby' => 'date', 'order' => 'DESC', 'include' => array(), 'exclude' => array(), 'meta_key' => '', 'meta_value' => '', 'post_type' => 'post', 'suppress_filters' => true, ); $parsed_args = wp_parse_args( $args, $defaults ); if ( empty( $parsed_args['post_status'] ) ) { $parsed_args['post_status'] = ( 'attachment' === $parsed_args['post_type'] ) ? 'inherit' : 'publish'; } if ( ! empty( $parsed_args['numberposts'] ) && empty( $parsed_args['posts_per_page'] ) ) { $parsed_args['posts_per_page'] = $parsed_args['numberposts']; } if ( ! empty( $parsed_args['category'] ) ) { $parsed_args['cat'] = $parsed_args['category']; } if ( ! empty( $parsed_args['include'] ) ) { $incposts = wp_parse_id_list( $parsed_args['include'] ); $parsed_args['posts_per_page'] = count( $incposts ); $parsed_args['post__in'] = $incposts; } elseif ( ! empty( $parsed_args['exclude'] ) ) { $parsed_args['post__not_in'] = wp_parse_id_list( $parsed_args['exclude'] ); } $parsed_args['ignore_sticky_posts'] = true; $parsed_args['no_found_rows'] = true; $get_posts = new WP_Query(); return $get_posts->query( $parsed_args ); } function add_post_meta( $post_id, $meta_key, $meta_value, $unique = false ) { $the_post = wp_is_post_revision( $post_id ); if ( $the_post ) { $post_id = $the_post; } return add_metadata( 'post', $post_id, $meta_key, $meta_value, $unique ); } function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) { $the_post = wp_is_post_revision( $post_id ); if ( $the_post ) { $post_id = $the_post; } return delete_metadata( 'post', $post_id, $meta_key, $meta_value ); } function get_post_meta( $post_id, $key = '', $single = false ) { return get_metadata( 'post', $post_id, $key, $single ); } function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) { $the_post = wp_is_post_revision( $post_id ); if ( $the_post ) { $post_id = $the_post; } return update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value ); } function delete_post_meta_by_key( $post_meta_key ) { return delete_metadata( 'post', null, $post_meta_key, '', true ); } function register_post_meta( $post_type, $meta_key, array $args ) { $args['object_subtype'] = $post_type; return register_meta( 'post', $meta_key, $args ); } function unregister_post_meta( $post_type, $meta_key ) { return unregister_meta_key( 'post', $meta_key, $post_type ); } function get_post_custom( $post_id = 0 ) { $post_id = absint( $post_id ); if ( ! $post_id ) { $post_id = get_the_ID(); } return get_post_meta( $post_id ); } function get_post_custom_keys( $post_id = 0 ) { $custom = get_post_custom( $post_id ); if ( ! is_array( $custom ) ) { return; } $keys = array_keys( $custom ); if ( $keys ) { return $keys; } } function get_post_custom_values( $key = '', $post_id = 0 ) { if ( ! $key ) { return null; } $custom = get_post_custom( $post_id ); return isset( $custom[ $key ] ) ? $custom[ $key ] : null; } function is_sticky( $post_id = 0 ) { $post_id = absint( $post_id ); if ( ! $post_id ) { $post_id = get_the_ID(); } $stickies = get_option( 'sticky_posts' ); if ( is_array( $stickies ) ) { $stickies = array_map( 'intval', $stickies ); $is_sticky = in_array( $post_id, $stickies, true ); } else { $is_sticky = false; } return apply_filters( 'is_sticky', $is_sticky, $post_id ); } function sanitize_post( $post, $context = 'display' ) { if ( is_object( $post ) ) { if ( isset( $post->filter ) && $context === $post->filter ) { return $post; } if ( ! isset( $post->ID ) ) { $post->ID = 0; } foreach ( array_keys( get_object_vars( $post ) ) as $field ) { $post->$field = sanitize_post_field( $field, $post->$field, $post->ID, $context ); } $post->filter = $context; } elseif ( is_array( $post ) ) { if ( isset( $post['filter'] ) && $context === $post['filter'] ) { return $post; } if ( ! isset( $post['ID'] ) ) { $post['ID'] = 0; } foreach ( array_keys( $post ) as $field ) { $post[ $field ] = sanitize_post_field( $field, $post[ $field ], $post['ID'], $context ); } $post['filter'] = $context; } return $post; } function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) { $int_fields = array( 'ID', 'post_parent', 'menu_order' ); if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } $array_int_fields = array( 'ancestors' ); if ( in_array( $field, $array_int_fields, true ) ) { $value = array_map( 'absint', $value ); return $value; } if ( 'raw' === $context ) { return $value; } $prefixed = false; if ( str_contains( $field, 'post_' ) ) { $prefixed = true; $field_no_prefix = str_replace( 'post_', '', $field ); } if ( 'edit' === $context ) { $format_to_edit = array( 'post_content', 'post_excerpt', 'post_title', 'post_password' ); if ( $prefixed ) { $value = apply_filters( "edit_{$field}", $value, $post_id ); $value = apply_filters( "{$field_no_prefix}_edit_pre", $value, $post_id ); } else { $value = apply_filters( "edit_post_{$field}", $value, $post_id ); } if ( in_array( $field, $format_to_edit, true ) ) { if ( 'post_content' === $field ) { $value = format_to_edit( $value, user_can_richedit() ); } else { $value = format_to_edit( $value ); } } else { $value = esc_attr( $value ); } } elseif ( 'db' === $context ) { if ( $prefixed ) { $value = apply_filters( "pre_{$field}", $value ); $value = apply_filters( "{$field_no_prefix}_save_pre", $value ); } else { $value = apply_filters( "pre_post_{$field}", $value ); $value = apply_filters( "{$field}_pre", $value ); } } else { if ( $prefixed ) { $value = apply_filters( "{$field}", $value, $post_id, $context ); } else { $value = apply_filters( "post_{$field}", $value, $post_id, $context ); } if ( 'attribute' === $context ) { $value = esc_attr( $value ); } elseif ( 'js' === $context ) { $value = esc_js( $value ); } } if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } return $value; } function stick_post( $post_id ) { $post_id = (int) $post_id; $stickies = get_option( 'sticky_posts' ); $updated = false; if ( ! is_array( $stickies ) ) { $stickies = array(); } else { $stickies = array_unique( array_map( 'intval', $stickies ) ); } if ( ! in_array( $post_id, $stickies, true ) ) { $stickies[] = $post_id; $updated = update_option( 'sticky_posts', array_values( $stickies ) ); } if ( $updated ) { do_action( 'post_stuck', $post_id ); } } function unstick_post( $post_id ) { $post_id = (int) $post_id; $stickies = get_option( 'sticky_posts' ); if ( ! is_array( $stickies ) ) { return; } $stickies = array_values( array_unique( array_map( 'intval', $stickies ) ) ); if ( ! in_array( $post_id, $stickies, true ) ) { return; } $offset = array_search( $post_id, $stickies, true ); if ( false === $offset ) { return; } array_splice( $stickies, $offset, 1 ); $updated = update_option( 'sticky_posts', $stickies ); if ( $updated ) { do_action( 'post_unstuck', $post_id ); } } function _count_posts_cache_key( $type = 'post', $perm = '' ) { $cache_key = 'posts-' . $type; if ( 'readable' === $perm && is_user_logged_in() ) { $post_type_object = get_post_type_object( $type ); if ( $post_type_object && ! current_user_can( $post_type_object->cap->read_private_posts ) ) { $cache_key .= '_' . $perm . '_' . get_current_user_id(); } } return $cache_key; } function wp_count_posts( $type = 'post', $perm = '' ) { global $wpdb; if ( ! post_type_exists( $type ) ) { return new stdClass(); } $cache_key = _count_posts_cache_key( $type, $perm ); $counts = wp_cache_get( $cache_key, 'counts' ); if ( false !== $counts ) { foreach ( get_post_stati() as $status ) { if ( ! isset( $counts->{$status} ) ) { $counts->{$status} = 0; } } return apply_filters( 'wp_count_posts', $counts, $type, $perm ); } if ( 'readable' === $perm && is_user_logged_in() && ! current_user_can( get_post_type_object( $type )->cap->read_private_posts ) ) { $query = "
SELECT post_status, COUNT(*) AS num_posts
FROM (
SELECT post_status
FROM {$wpdb->posts}
WHERE post_type = %s AND post_status != 'private'
UNION ALL
SELECT post_status
FROM {$wpdb->posts}
WHERE post_type = %s AND post_status = 'private' AND post_author = %d
) AS filtered_posts
"; $args = array( $type, $type, get_current_user_id() ); } else { $query = "
SELECT post_status, COUNT(*) AS num_posts
FROM {$wpdb->posts}
WHERE post_type = %s
"; $args = array( $type ); } $query .= ' GROUP BY post_status'; $results = (array) $wpdb->get_results( $wpdb->prepare( $query, ...$args ), ARRAY_A ); $counts = array_fill_keys( get_post_stati(), 0 ); foreach ( $results as $row ) { $counts[ $row['post_status'] ] = $row['num_posts']; } $counts = (object) $counts; wp_cache_set( $cache_key, $counts, 'counts' ); return apply_filters( 'wp_count_posts', $counts, $type, $perm ); } function wp_count_attachments( $mime_type = '' ) { global $wpdb; $cache_key = sprintf( 'attachments%s', ! empty( $mime_type ) ? ':' . str_replace( '/', '_', implode( '-', (array) $mime_type ) ) : '' ); $counts = wp_cache_get( $cache_key, 'counts' ); if ( false === $counts ) { $and = wp_post_mime_type_where( $mime_type ); $count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A ); $counts = array(); foreach ( (array) $count as $row ) { $counts[ $row['post_mime_type'] ] = $row['num_posts']; } $counts['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and" ); wp_cache_set( $cache_key, (object) $counts, 'counts' ); } return apply_filters( 'wp_count_attachments', (object) $counts, $mime_type ); } function get_post_mime_types() { $post_mime_types = array( 'image' => array( __( 'Images' ), __( 'Manage Images' ), _n_noop( 'Image <span class="count">(%s)</span>', 'Images <span class="count">(%s)</span>' ), ), 'audio' => array( _x( 'Audio', 'file type group' ), __( 'Manage Audio' ), _n_noop( 'Audio <span class="count">(%s)</span>', 'Audio <span class="count">(%s)</span>' ), ), 'video' => array( _x( 'Video', 'file type group' ), __( 'Manage Video' ), _n_noop( 'Video <span class="count">(%s)</span>', 'Video <span class="count">(%s)</span>' ), ), 'document' => array( __( 'Documents' ), __( 'Manage Documents' ), _n_noop( 'Document <span class="count">(%s)</span>', 'Documents <span class="count">(%s)</span>' ), ), 'spreadsheet' => array( __( 'Spreadsheets' ), __( 'Manage Spreadsheets' ), _n_noop( 'Spreadsheet <span class="count">(%s)</span>', 'Spreadsheets <span class="count">(%s)</span>' ), ), 'archive' => array( _x( 'Archives', 'file type group' ), __( 'Manage Archives' ), _n_noop( 'Archive <span class="count">(%s)</span>', 'Archives <span class="count">(%s)</span>' ), ), ); $ext_types = wp_get_ext_types(); $mime_types = wp_get_mime_types(); foreach ( $post_mime_types as $group => $labels ) { if ( in_array( $group, array( 'image', 'audio', 'video' ), true ) ) { continue; } if ( ! isset( $ext_types[ $group ] ) ) { unset( $post_mime_types[ $group ] ); continue; } $group_mime_types = array(); foreach ( $ext_types[ $group ] as $extension ) { foreach ( $mime_types as $exts => $mime ) { if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) { $group_mime_types[] = $mime; break; } } } $group_mime_types = implode( ',', array_unique( $group_mime_types ) ); $post_mime_types[ $group_mime_types ] = $labels; unset( $post_mime_types[ $group ] ); } return apply_filters( 'post_mime_types', $post_mime_types ); } function wp_match_mime_types( $wildcard_mime_types, $real_mime_types ) { $matches = array(); if ( is_string( $wildcard_mime_types ) ) { $wildcard_mime_types = array_map( 'trim', explode( ',', $wildcard_mime_types ) ); } if ( is_string( $real_mime_types ) ) { $real_mime_types = array_map( 'trim', explode( ',', $real_mime_types ) ); } $patternses = array(); $wild = '[-._a-z0-9]*'; foreach ( (array) $wildcard_mime_types as $type ) { $mimes = array_map( 'trim', explode( ',', $type ) ); foreach ( $mimes as $mime ) { $regex = str_replace( '__wildcard__', $wild, preg_quote( str_replace( '*', '__wildcard__', $mime ) ) ); $patternses[][ $type ] = "^$regex$"; if ( ! str_contains( $mime, '/' ) ) { $patternses[][ $type ] = "^$regex/"; $patternses[][ $type ] = $regex; } } } asort( $patternses ); foreach ( $patternses as $patterns ) { foreach ( $patterns as $type => $pattern ) { foreach ( (array) $real_mime_types as $real ) { if ( preg_match( "#$pattern#", $real ) && ( empty( $matches[ $type ] ) || false === array_search( $real, $matches[ $type ], true ) ) ) { $matches[ $type ][] = $real; } } } } return $matches; } function wp_post_mime_type_where( $post_mime_types, $table_alias = '' ) { $where = ''; $wildcards = array( '', '%', '%/%' ); if ( is_string( $post_mime_types ) ) { $post_mime_types = array_map( 'trim', explode( ',', $post_mime_types ) ); } $where_clauses = array(); foreach ( (array) $post_mime_types as $mime_type ) { $mime_type = preg_replace( '/\s/', '', $mime_type ); $slashpos = strpos( $mime_type, '/' ); if ( false !== $slashpos ) { $mime_group = preg_replace( '/[^-*.a-zA-Z0-9]/', '', substr( $mime_type, 0, $slashpos ) ); $mime_subgroup = preg_replace( '/[^-*.+a-zA-Z0-9]/', '', substr( $mime_type, $slashpos + 1 ) ); if ( empty( $mime_subgroup ) ) { $mime_subgroup = '*'; } else { $mime_subgroup = str_replace( '/', '', $mime_subgroup ); } $mime_pattern = "$mime_group/$mime_subgroup"; } else { $mime_pattern = preg_replace( '/[^-*.a-zA-Z0-9]/', '', $mime_type ); if ( ! str_contains( $mime_pattern, '*' ) ) { $mime_pattern .= '/*'; } } $mime_pattern = preg_replace( '/\*+/', '%', $mime_pattern ); if ( in_array( $mime_type, $wildcards, true ) ) { return ''; } if ( str_contains( $mime_pattern, '%' ) ) { $where_clauses[] = empty( $table_alias ) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'"; } else { $where_clauses[] = empty( $table_alias ) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'"; } } if ( ! empty( $where_clauses ) ) { $where = ' AND (' . implode( ' OR ', $where_clauses ) . ') '; } return $where; } function wp_delete_post( $post_id = 0, $force_delete = false ) { global $wpdb; $post_id = (int) $post_id; if ( $post_id <= 0 ) { _doing_it_wrong( __FUNCTION__, __( 'The post ID must be greater than 0.' ), '6.9.0' ); return false; } $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id ) ); if ( ! $post ) { return $post; } $post = get_post( $post ); if ( ! $force_delete && ( 'post' === $post->post_type || 'page' === $post->post_type ) && 'trash' !== get_post_status( $post_id ) && EMPTY_TRASH_DAYS ) { return wp_trash_post( $post_id ); } if ( 'attachment' === $post->post_type ) { return wp_delete_attachment( $post_id, $force_delete ); } $check = apply_filters( 'pre_delete_post', null, $post, $force_delete ); if ( null !== $check ) { return $check; } do_action( 'before_delete_post', $post_id, $post ); delete_post_meta( $post_id, '_wp_trash_meta_status' ); delete_post_meta( $post_id, '_wp_trash_meta_time' ); wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) ); $parent_data = array( 'post_parent' => $post->post_parent ); $parent_where = array( 'post_parent' => $post_id ); if ( is_post_type_hierarchical( $post->post_type ) ) { $children_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", $post_id, $post->post_type ); $children = $wpdb->get_results( $children_query ); if ( $children ) { $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => $post->post_type ) ); } } $revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $post_id ) ); foreach ( $revision_ids as $revision_id ) { wp_delete_post_revision( $revision_id ); } $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) ); wp_defer_comment_counting( true ); $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $post_id ) ); foreach ( $comment_ids as $comment_id ) { wp_delete_comment( $comment_id, true ); } wp_defer_comment_counting( false ); $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ) ); foreach ( $post_meta_ids as $mid ) { delete_metadata_by_mid( 'post', $mid ); } do_action( "delete_post_{$post->post_type}", $post_id, $post ); do_action( 'delete_post', $post_id, $post ); $result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) ); if ( ! $result ) { return false; } do_action( "deleted_post_{$post->post_type}", $post_id, $post ); do_action( 'deleted_post', $post_id, $post ); clean_post_cache( $post ); if ( is_post_type_hierarchical( $post->post_type ) && $children ) { foreach ( $children as $child ) { clean_post_cache( $child ); } } wp_clear_scheduled_hook( 'publish_future_post', array( $post_id ) ); do_action( 'after_delete_post', $post_id, $post ); return $post; } function _reset_front_page_settings_for_post( $post_id ) { $post = get_post( $post_id ); if ( 'page' === $post->post_type ) { if ( (int) get_option( 'page_on_front' ) === $post->ID ) { update_option( 'show_on_front', 'posts' ); update_option( 'page_on_front', 0 ); } if ( (int) get_option( 'page_for_posts' ) === $post->ID ) { update_option( 'page_for_posts', 0 ); } } unstick_post( $post->ID ); } function wp_trash_post( $post_id = 0 ) { if ( ! EMPTY_TRASH_DAYS ) { return wp_delete_post( $post_id, true ); } $post = get_post( $post_id ); if ( ! $post ) { return $post; } if ( 'trash' === $post->post_status ) { return false; } $previous_status = $post->post_status; $check = apply_filters( 'pre_trash_post', null, $post, $previous_status ); if ( null !== $check ) { return $check; } do_action( 'wp_trash_post', $post_id, $previous_status ); add_post_meta( $post_id, '_wp_trash_meta_status', $previous_status ); add_post_meta( $post_id, '_wp_trash_meta_time', time() ); $post_updated = wp_update_post( array( 'ID' => $post_id, 'post_status' => 'trash', ) ); if ( ! $post_updated ) { return false; } wp_trash_post_comments( $post_id ); do_action( 'trashed_post', $post_id, $previous_status ); return $post; } function wp_untrash_post( $post_id = 0 ) { $post = get_post( $post_id ); if ( ! $post ) { return $post; } $post_id = $post->ID; if ( 'trash' !== $post->post_status ) { return false; } $previous_status = get_post_meta( $post_id, '_wp_trash_meta_status', true ); $check = apply_filters( 'pre_untrash_post', null, $post, $previous_status ); if ( null !== $check ) { return $check; } do_action( 'untrash_post', $post_id, $previous_status ); $new_status = ( 'attachment' === $post->post_type ) ? 'inherit' : 'draft'; $post_status = apply_filters( 'wp_untrash_post_status', $new_status, $post_id, $previous_status ); delete_post_meta( $post_id, '_wp_trash_meta_status' ); delete_post_meta( $post_id, '_wp_trash_meta_time' ); $post_updated = wp_update_post( array( 'ID' => $post_id, 'post_status' => $post_status, ) ); if ( ! $post_updated ) { return false; } wp_untrash_post_comments( $post_id ); do_action( 'untrashed_post', $post_id, $previous_status ); return $post; } function wp_trash_post_comments( $post = null ) { global $wpdb; $post = get_post( $post ); if ( ! $post ) { return; } $post_id = $post->ID; do_action( 'trash_post_comments', $post_id ); $comments = $wpdb->get_results( $wpdb->prepare( "SELECT comment_ID, comment_approved FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ) ); if ( ! $comments ) { return; } $statuses = array(); foreach ( $comments as $comment ) { $statuses[ $comment->comment_ID ] = $comment->comment_approved; } add_post_meta( $post_id, '_wp_trash_meta_comments_status', $statuses ); $result = $wpdb->update( $wpdb->comments, array( 'comment_approved' => 'post-trashed' ), array( 'comment_post_ID' => $post_id ) ); clean_comment_cache( array_keys( $statuses ) ); do_action( 'trashed_post_comments', $post_id, $statuses ); return $result; } function wp_untrash_post_comments( $post = null ) { global $wpdb; $post = get_post( $post ); if ( ! $post ) { return; } $post_id = $post->ID; $statuses = get_post_meta( $post_id, '_wp_trash_meta_comments_status', true ); if ( ! $statuses ) { return true; } do_action( 'untrash_post_comments', $post_id ); $group_by_status = array(); foreach ( $statuses as $comment_id => $comment_status ) { $group_by_status[ $comment_status ][] = $comment_id; } foreach ( $group_by_status as $status => $comments ) { if ( 'post-trashed' === $status ) { $status = '0'; } $comments_in = implode( ', ', array_map( 'intval', $comments ) ); $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->comments SET comment_approved = %s WHERE comment_ID IN ($comments_in)", $status ) ); } clean_comment_cache( array_keys( $statuses ) ); delete_post_meta( $post_id, '_wp_trash_meta_comments_status' ); do_action( 'untrashed_post_comments', $post_id ); } function wp_get_post_categories( $post_id = 0, $args = array() ) { $post_id = (int) $post_id; $defaults = array( 'fields' => 'ids' ); $args = wp_parse_args( $args, $defaults ); $cats = wp_get_object_terms( $post_id, 'category', $args ); return $cats; } function wp_get_post_tags( $post_id = 0, $args = array() ) { return wp_get_post_terms( $post_id, 'post_tag', $args ); } function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) { $post_id = (int) $post_id; $defaults = array( 'fields' => 'all' ); $args = wp_parse_args( $args, $defaults ); $tags = wp_get_object_terms( $post_id, $taxonomy, $args ); return $tags; } function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) { if ( is_numeric( $args ) ) { _deprecated_argument( __FUNCTION__, '3.1.0', __( 'Passing an integer number of posts is deprecated. Pass an array of arguments instead.' ) ); $args = array( 'numberposts' => absint( $args ) ); } $defaults = array( 'numberposts' => 10, 'offset' => 0, 'category' => 0, 'orderby' => 'post_date', 'order' => 'DESC', 'include' => '', 'exclude' => '', 'meta_key' => '', 'meta_value' => '', 'post_type' => 'post', 'post_status' => 'draft, publish, future, pending, private', 'suppress_filters' => true, ); $parsed_args = wp_parse_args( $args, $defaults ); $results = get_posts( $parsed_args ); if ( ARRAY_A === $output ) { foreach ( $results as $key => $result ) { $results[ $key ] = get_object_vars( $result ); } return $results ? $results : array(); } return $results ? $results : false; } function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true ) { global $wpdb; $unsanitized_postarr = $postarr; $user_id = get_current_user_id(); $defaults = array( 'post_author' => $user_id, 'post_content' => '', 'post_content_filtered' => '', 'post_title' => '', 'post_excerpt' => '', 'post_status' => 'draft', 'post_type' => 'post', 'comment_status' => '', 'ping_status' => '', 'post_password' => '', 'to_ping' => '', 'pinged' => '', 'post_parent' => 0, 'menu_order' => 0, 'guid' => '', 'import_id' => 0, 'context' => '', 'post_date' => '', 'post_date_gmt' => '', ); $postarr = wp_parse_args( $postarr, $defaults ); unset( $postarr['filter'] ); $postarr = sanitize_post( $postarr, 'db' ); $post_id = 0; $update = false; $guid = $postarr['guid']; if ( ! empty( $postarr['ID'] ) ) { $update = true; $post_id = $postarr['ID']; $post_before = get_post( $post_id ); if ( is_null( $post_before ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) ); } return 0; } $guid = get_post_field( 'guid', $post_id ); $previous_status = get_post_field( 'post_status', $post_id ); } else { $previous_status = 'new'; $post_before = null; } $post_type = empty( $postarr['post_type'] ) ? 'post' : $postarr['post_type']; $post_title = $postarr['post_title']; $post_content = $postarr['post_content']; $post_excerpt = $postarr['post_excerpt']; if ( isset( $postarr['post_name'] ) ) { $post_name = $postarr['post_name']; } elseif ( $update ) { $post_name = $post_before->post_name; } $maybe_empty = 'attachment' !== $post_type && ! $post_content && ! $post_title && ! $post_excerpt && post_type_supports( $post_type, 'editor' ) && post_type_supports( $post_type, 'title' ) && post_type_supports( $post_type, 'excerpt' ); if ( apply_filters( 'wp_insert_post_empty_content', $maybe_empty, $postarr ) ) { if ( $wp_error ) { return new WP_Error( 'empty_content', __( 'Content, title, and excerpt are empty.' ) ); } else { return 0; } } $post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status']; if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) { $post_status = 'inherit'; } if ( ! empty( $postarr['post_category'] ) ) { $post_category = array_filter( $postarr['post_category'] ); } elseif ( $update && ! isset( $postarr['post_category'] ) ) { $post_category = $post_before->post_category; } if ( empty( $post_category ) || 0 === count( $post_category ) || ! is_array( $post_category ) ) { if ( 'post' === $post_type && 'auto-draft' !== $post_status ) { $post_category = array( get_option( 'default_category' ) ); } else { $post_category = array(); } } if ( 'pending' === $post_status ) { $post_type_object = get_post_type_object( $post_type ); if ( ! $update && $post_type_object && ! current_user_can( $post_type_object->cap->publish_posts ) ) { $post_name = ''; } elseif ( $update && ! current_user_can( 'publish_post', $post_id ) ) { $post_name = ''; } } if ( empty( $post_name ) ) { if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true ) ) { $post_name = sanitize_title( $post_title ); } else { $post_name = ''; } } else { $check_name = sanitize_title( $post_name, '', 'old-save' ); if ( $update && strtolower( urlencode( $post_name ) ) === $check_name && get_post_field( 'post_name', $post_id ) === $check_name ) { $post_name = $check_name; } else { $post_name = sanitize_title( $post_name ); } } $post_date = wp_resolve_post_date( $postarr['post_date'], $postarr['post_date_gmt'] ); if ( ! $post_date ) { if ( $wp_error ) { return new WP_Error( 'invalid_date', __( 'Invalid date.' ) ); } else { return 0; } } if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' === $postarr['post_date_gmt'] ) { if ( ! in_array( $post_status, get_post_stati( array( 'date_floating' => true ) ), true ) ) { $post_date_gmt = get_gmt_from_date( $post_date ); } else { $post_date_gmt = '0000-00-00 00:00:00'; } } else { $post_date_gmt = $postarr['post_date_gmt']; } if ( $update || '0000-00-00 00:00:00' === $post_date ) { $post_modified = current_time( 'mysql' ); $post_modified_gmt = current_time( 'mysql', true ); } else { $post_modified = $post_date; $post_modified_gmt = $post_date_gmt; } if ( 'attachment' !== $post_type ) { $now = gmdate( 'Y-m-d H:i:s' ); if ( 'publish' === $post_status ) { if ( strtotime( $post_date_gmt ) - strtotime( $now ) >= MINUTE_IN_SECONDS ) { $post_status = 'future'; } } elseif ( 'future' === $post_status ) { if ( strtotime( $post_date_gmt ) - strtotime( $now ) < MINUTE_IN_SECONDS ) { $post_status = 'publish'; } } } if ( empty( $postarr['comment_status'] ) ) { if ( $update ) { $comment_status = 'closed'; } else { $comment_status = get_default_comment_status( $post_type ); } } else { $comment_status = $postarr['comment_status']; } $post_content_filtered = $postarr['post_content_filtered']; $post_author = isset( $postarr['post_author'] ) ? $postarr['post_author'] : $user_id; $ping_status = empty( $postarr['ping_status'] ) ? get_default_comment_status( $post_type, 'pingback' ) : $postarr['ping_status']; $to_ping = isset( $postarr['to_ping'] ) ? sanitize_trackback_urls( $postarr['to_ping'] ) : ''; $pinged = isset( $postarr['pinged'] ) ? $postarr['pinged'] : ''; $import_id = isset( $postarr['import_id'] ) ? $postarr['import_id'] : 0; if ( isset( $postarr['menu_order'] ) ) { $menu_order = (int) $postarr['menu_order']; } else { $menu_order = 0; } $post_password = isset( $postarr['post_password'] ) ? $postarr['post_password'] : ''; if ( 'private' === $post_status ) { $post_password = ''; } if ( isset( $postarr['post_parent'] ) ) { $post_parent = (int) $postarr['post_parent']; } else { $post_parent = 0; } $new_postarr = array_merge( array( 'ID' => $post_id, ), compact( array_diff( array_keys( $defaults ), array( 'context', 'filter' ) ) ) ); $post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_id, $new_postarr, $postarr ); if ( 'trash' === $previous_status && 'trash' !== $post_status ) { $desired_post_slug = get_post_meta( $post_id, '_wp_desired_post_slug', true ); if ( $desired_post_slug ) { delete_post_meta( $post_id, '_wp_desired_post_slug' ); $post_name = $desired_post_slug; } } if ( 'trash' !== $post_status && $post_name ) { $add_trashed_suffix = apply_filters( 'add_trashed_suffix_to_trashed_posts', true, $post_name, $post_id ); if ( $add_trashed_suffix ) { wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_id ); } } if ( 'trash' === $post_status && 'trash' !== $previous_status && 'new' !== $previous_status ) { $post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_id ); } $post_name = wp_unique_post_slug( $post_name, $post_id, $post_status, $post_type, $post_parent ); $post_mime_type = isset( $postarr['post_mime_type'] ) ? $postarr['post_mime_type'] : ''; $data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' ); $emoji_fields = array( 'post_title', 'post_content', 'post_excerpt' ); foreach ( $emoji_fields as $emoji_field ) { if ( isset( $data[ $emoji_field ] ) ) { $charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field ); if ( 'utf8' === $charset || 'utf8mb3' === $charset ) { $data[ $emoji_field ] = wp_encode_emoji( $data[ $emoji_field ] ); } } } if ( 'attachment' === $post_type ) { $data = apply_filters( 'wp_insert_attachment_data', $data, $postarr, $unsanitized_postarr, $update ); } else { $data = apply_filters( 'wp_insert_post_data', $data, $postarr, $unsanitized_postarr, $update ); } $data = wp_unslash( $data ); $where = array( 'ID' => $post_id ); if ( $update ) { do_action( 'pre_post_update', $post_id, $data ); if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) { if ( $wp_error ) { if ( 'attachment' === $post_type ) { $message = __( 'Could not update attachment in the database.' ); } else { $message = __( 'Could not update post in the database.' ); } return new WP_Error( 'db_update_error', $message, $wpdb->last_error ); } else { return 0; } } } else { if ( ! empty( $import_id ) ) { $import_id = (int) $import_id; if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id ) ) ) { $data['ID'] = $import_id; } } do_action( 'pre_post_insert', $data ); if ( false === $wpdb->insert( $wpdb->posts, $data ) ) { if ( $wp_error ) { if ( 'attachment' === $post_type ) { $message = __( 'Could not insert attachment into the database.' ); } else { $message = __( 'Could not insert post into the database.' ); } return new WP_Error( 'db_insert_error', $message, $wpdb->last_error ); } else { return 0; } } $post_id = (int) $wpdb->insert_id; $where = array( 'ID' => $post_id ); } if ( empty( $data['post_name'] ) && ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ), true ) ) { $data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'], $post_id ), $post_id, $data['post_status'], $post_type, $post_parent ); $wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where ); clean_post_cache( $post_id ); } if ( is_object_in_taxonomy( $post_type, 'category' ) ) { wp_set_post_categories( $post_id, $post_category ); } if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $post_type, 'post_tag' ) ) { wp_set_post_tags( $post_id, $postarr['tags_input'] ); } if ( 'auto-draft' !== $post_status ) { foreach ( get_object_taxonomies( $post_type, 'object' ) as $taxonomy => $tax_object ) { if ( ! empty( $tax_object->default_term ) ) { if ( isset( $postarr['tax_input'][ $taxonomy ] ) && is_array( $postarr['tax_input'][ $taxonomy ] ) ) { $postarr['tax_input'][ $taxonomy ] = array_filter( $postarr['tax_input'][ $taxonomy ] ); } $terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) ); if ( ! empty( $terms ) && empty( $postarr['tax_input'][ $taxonomy ] ) ) { $postarr['tax_input'][ $taxonomy ] = $terms; } if ( empty( $postarr['tax_input'][ $taxonomy ] ) ) { $default_term_id = get_option( 'default_term_' . $taxonomy ); if ( ! empty( $default_term_id ) ) { $postarr['tax_input'][ $taxonomy ] = array( (int) $default_term_id ); } } } } } if ( ! empty( $postarr['tax_input'] ) ) { foreach ( $postarr['tax_input'] as $taxonomy => $tags ) { $taxonomy_obj = get_taxonomy( $taxonomy ); if ( ! $taxonomy_obj ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' ); continue; } if ( is_array( $tags ) ) { $tags = array_filter( $tags ); } if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) { wp_set_post_terms( $post_id, $tags, $taxonomy ); } } } if ( ! empty( $postarr['meta_input'] ) ) { foreach ( $postarr['meta_input'] as $field => $value ) { update_post_meta( $post_id, $field, $value ); } } $current_guid = get_post_field( 'guid', $post_id ); if ( ! $update && '' === $current_guid ) { $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_id ) ), $where ); } if ( 'attachment' === $postarr['post_type'] ) { if ( ! empty( $postarr['file'] ) ) { update_attached_file( $post_id, $postarr['file'] ); } if ( ! empty( $postarr['context'] ) ) { add_post_meta( $post_id, '_wp_attachment_context', $postarr['context'], true ); } } if ( isset( $postarr['_thumbnail_id'] ) ) { $thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) || 'revision' === $post_type; if ( ! $thumbnail_support && 'attachment' === $post_type && $post_mime_type ) { if ( wp_attachment_is( 'audio', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ); } elseif ( wp_attachment_is( 'video', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ); } } if ( $thumbnail_support ) { $thumbnail_id = (int) $postarr['_thumbnail_id']; if ( -1 === $thumbnail_id ) { delete_post_thumbnail( $post_id ); } else { set_post_thumbnail( $post_id, $thumbnail_id ); } } } clean_post_cache( $post_id ); $post = get_post( $post_id ); if ( ! empty( $postarr['page_template'] ) ) { $post->page_template = $postarr['page_template']; $page_templates = wp_get_theme()->get_page_templates( $post ); if ( 'default' !== $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) ); } update_post_meta( $post_id, '_wp_page_template', 'default' ); } else { update_post_meta( $post_id, '_wp_page_template', $postarr['page_template'] ); } } if ( 'attachment' !== $postarr['post_type'] ) { wp_transition_post_status( $data['post_status'], $previous_status, $post ); } else { if ( $update ) { do_action( 'edit_attachment', $post_id ); $post_after = get_post( $post_id ); do_action( 'attachment_updated', $post_id, $post_after, $post_before ); } else { do_action( 'add_attachment', $post_id ); } return $post_id; } if ( $update ) { do_action( "edit_post_{$post->post_type}", $post_id, $post ); do_action( 'edit_post', $post_id, $post ); $post_after = get_post( $post_id ); do_action( 'post_updated', $post_id, $post_after, $post_before ); } do_action( "save_post_{$post->post_type}", $post_id, $post, $update ); do_action( 'save_post', $post_id, $post, $update ); do_action( 'wp_insert_post', $post_id, $post, $update ); if ( $fire_after_hooks ) { wp_after_insert_post( $post, $update, $post_before ); } return $post_id; } function wp_update_post( $postarr = array(), $wp_error = false, $fire_after_hooks = true ) { if ( is_object( $postarr ) ) { $postarr = get_object_vars( $postarr ); $postarr = wp_slash( $postarr ); } $post = get_post( $postarr['ID'], ARRAY_A ); if ( is_null( $post ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) ); } return 0; } $post = wp_slash( $post ); if ( isset( $postarr['post_category'] ) && is_array( $postarr['post_category'] ) && count( $postarr['post_category'] ) > 0 ) { $post_cats = $postarr['post_category']; } else { $post_cats = $post['post_category']; } if ( isset( $post['post_status'] ) && in_array( $post['post_status'], array( 'draft', 'pending', 'auto-draft' ), true ) && empty( $postarr['edit_date'] ) && ( '0000-00-00 00:00:00' === $post['post_date_gmt'] ) ) { $clear_date = true; } else { $clear_date = false; } $postarr = array_merge( $post, $postarr ); $postarr['post_category'] = $post_cats; if ( $clear_date ) { $postarr['post_date'] = current_time( 'mysql' ); $postarr['post_date_gmt'] = ''; } if ( 'attachment' === $postarr['post_type'] ) { return wp_insert_attachment( $postarr, false, 0, $wp_error ); } if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $postarr['post_type'], 'post_tag' ) ) { $tags = get_the_terms( $postarr['ID'], 'post_tag' ); $tag_names = array(); if ( $tags && ! is_wp_error( $tags ) ) { $tag_names = wp_list_pluck( $tags, 'name' ); } if ( $postarr['tags_input'] === $tag_names ) { unset( $postarr['tags_input'] ); } } return wp_insert_post( $postarr, $wp_error, $fire_after_hooks ); } function wp_publish_post( $post ) { global $wpdb; $post = get_post( $post ); if ( ! $post ) { return; } if ( 'publish' === $post->post_status ) { return; } $post_before = get_post( $post->ID ); foreach ( get_object_taxonomies( $post->post_type, 'object' ) as $taxonomy => $tax_object ) { if ( 'category' !== $taxonomy && empty( $tax_object->default_term ) ) { continue; } if ( ! empty( get_the_terms( $post, $taxonomy ) ) ) { continue; } if ( 'category' === $taxonomy ) { $default_term_id = (int) get_option( 'default_category', 0 ); } else { $default_term_id = (int) get_option( 'default_term_' . $taxonomy, 0 ); } if ( ! $default_term_id ) { continue; } wp_set_post_terms( $post->ID, array( $default_term_id ), $taxonomy ); } $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post->ID ) ); clean_post_cache( $post->ID ); $old_status = $post->post_status; $post->post_status = 'publish'; wp_transition_post_status( 'publish', $old_status, $post ); do_action( "edit_post_{$post->post_type}", $post->ID, $post ); do_action( 'edit_post', $post->ID, $post ); do_action( "save_post_{$post->post_type}", $post->ID, $post, true ); do_action( 'save_post', $post->ID, $post, true ); do_action( 'wp_insert_post', $post->ID, $post, true ); wp_after_insert_post( $post, true, $post_before ); } function check_and_publish_future_post( $post ) { $post = get_post( $post ); if ( ! $post ) { return; } if ( 'future' !== $post->post_status ) { return; } $time = strtotime( $post->post_date_gmt . ' GMT' ); if ( $time > time() ) { wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) ); wp_schedule_single_event( $time, 'publish_future_post', array( $post->ID ) ); return; } wp_publish_post( $post->ID ); } function wp_resolve_post_date( $post_date = '', $post_date_gmt = '' ) { if ( empty( $post_date ) || '0000-00-00 00:00:00' === $post_date ) { if ( empty( $post_date_gmt ) || '0000-00-00 00:00:00' === $post_date_gmt ) { $post_date = current_time( 'mysql' ); } else { $post_date = get_date_from_gmt( $post_date_gmt ); } } preg_match( '/^(\d{4})-(\d{1,2})-(\d{1,2})/', $post_date, $matches ); if ( empty( $matches ) || ! is_array( $matches ) || count( $matches ) < 4 ) { return false; } $valid_date = wp_checkdate( $matches[2], $matches[3], $matches[1], $post_date ); if ( ! $valid_date ) { return false; } return $post_date; } function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_parent ) { if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true ) || ( 'inherit' === $post_status && 'revision' === $post_type ) || 'user_request' === $post_type ) { return $slug; } $override_slug = apply_filters( 'pre_wp_unique_post_slug', null, $slug, $post_id, $post_status, $post_type, $post_parent ); if ( null !== $override_slug ) { return $override_slug; } global $wpdb, $wp_rewrite; $original_slug = $slug; $feeds = $wp_rewrite->feeds; if ( ! is_array( $feeds ) ) { $feeds = array(); } if ( 'attachment' === $post_type ) { $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_id ) ); $is_bad_attachment_slug = apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ); if ( $post_name_check || in_array( $slug, $feeds, true ) || 'embed' === $slug || $is_bad_attachment_slug ) { $suffix = 2; do { $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_id ) ); ++$suffix; } while ( $post_name_check ); $slug = $alt_post_name; } } elseif ( is_post_type_hierarchical( $post_type ) ) { if ( 'nav_menu_item' === $post_type ) { return $slug; } $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id, $post_parent ) ); $is_bad_hierarchical_slug = apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ); if ( $post_name_check || in_array( $slug, $feeds, true ) || 'embed' === $slug || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) || $is_bad_hierarchical_slug ) { $suffix = 2; do { $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_id, $post_parent ) ); ++$suffix; } while ( $post_name_check ); $slug = $alt_post_name; } } else { $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id ) ); $post = get_post( $post_id ); $conflicts_with_date_archive = false; if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) ) { $slug_num = (int) $slug; if ( $slug_num ) { $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) ); $postname_index = array_search( '%postname%', $permastructs, true ); if ( 0 === $postname_index || ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num ) || ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num ) ) { $conflicts_with_date_archive = true; } } } $is_bad_flat_slug = apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ); if ( $post_name_check || in_array( $slug, $feeds, true ) || 'embed' === $slug || $conflicts_with_date_archive || $is_bad_flat_slug ) { $suffix = 2; do { $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_id ) ); ++$suffix; } while ( $post_name_check ); $slug = $alt_post_name; } } return apply_filters( 'wp_unique_post_slug', $slug, $post_id, $post_status, $post_type, $post_parent, $original_slug ); } function _truncate_post_slug( $slug, $length = 200 ) { if ( strlen( $slug ) > $length ) { $decoded_slug = urldecode( $slug ); if ( $decoded_slug === $slug ) { $slug = substr( $slug, 0, $length ); } else { $slug = utf8_uri_encode( $decoded_slug, $length, true ); } } return rtrim( $slug, '-' ); } function wp_add_post_tags( $post_id = 0, $tags = '' ) { return wp_set_post_tags( $post_id, $tags, true ); } function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) { return wp_set_post_terms( $post_id, $tags, 'post_tag', $append ); } function wp_set_post_terms( $post_id = 0, $terms = '', $taxonomy = 'post_tag', $append = false ) { $post_id = (int) $post_id; if ( ! $post_id ) { return false; } if ( empty( $terms ) ) { $terms = array(); } if ( ! is_array( $terms ) ) { $comma = _x( ',', 'tag delimiter' ); if ( ',' !== $comma ) { $terms = str_replace( $comma, ',', $terms ); } $terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) ); } if ( is_taxonomy_hierarchical( $taxonomy ) ) { $terms = array_unique( array_map( 'intval', $terms ) ); } return wp_set_object_terms( $post_id, $terms, $taxonomy, $append ); } function wp_set_post_categories( $post_id = 0, $post_categories = array(), $append = false ) { $post_id = (int) $post_id; $post_type = get_post_type( $post_id ); $post_status = get_post_status( $post_id ); $post_categories = (array) $post_categories; if ( empty( $post_categories ) ) { $default_category_post_types = apply_filters( 'default_category_post_types', array() ); $default_category_post_types = array_merge( $default_category_post_types, array( 'post' ) ); if ( in_array( $post_type, $default_category_post_types, true ) && is_object_in_taxonomy( $post_type, 'category' ) && 'auto-draft' !== $post_status ) { $post_categories = array( get_option( 'default_category' ) ); $append = false; } else { $post_categories = array(); } } elseif ( 1 === count( $post_categories ) && '' === reset( $post_categories ) ) { return true; } return wp_set_post_terms( $post_id, $post_categories, 'category', $append ); } function wp_transition_post_status( $new_status, $old_status, $post ) { do_action( 'transition_post_status', $new_status, $old_status, $post ); do_action( "{$old_status}_to_{$new_status}", $post ); do_action( "{$new_status}_{$post->post_type}", $post->ID, $post, $old_status ); } function wp_after_insert_post( $post, $update, $post_before ) { $post = get_post( $post ); if ( ! $post ) { return; } $post_id = $post->ID; do_action( 'wp_after_insert_post', $post_id, $post, $update, $post_before ); } function add_ping( $post, $uri ) { global $wpdb; $post = get_post( $post ); if ( ! $post ) { return false; } $pung = trim( $post->pinged ); $pung = preg_split( '/\s/', $pung ); if ( is_array( $uri ) ) { $pung = array_merge( $pung, $uri ); } else { $pung[] = $uri; } $new = implode( "\n", $pung ); $new = apply_filters( 'add_ping', $new ); $return = $wpdb->update( $wpdb->posts, array( 'pinged' => $new ), array( 'ID' => $post->ID ) ); clean_post_cache( $post->ID ); return $return; } function get_enclosed( $post_id ) { $custom_fields = get_post_custom( $post_id ); $pung = array(); if ( ! is_array( $custom_fields ) ) { return $pung; } foreach ( $custom_fields as $key => $val ) { if ( 'enclosure' !== $key || ! is_array( $val ) ) { continue; } foreach ( $val as $enc ) { $enclosure = explode( "\n", $enc ); $pung[] = trim( $enclosure[0] ); } } return apply_filters( 'get_enclosed', $pung, $post_id ); } function get_pung( $post ) { $post = get_post( $post ); if ( ! $post ) { return false; } $pung = trim( $post->pinged ); $pung = preg_split( '/\s/', $pung ); return apply_filters( 'get_pung', $pung ); } function get_to_ping( $post ) { $post = get_post( $post ); if ( ! $post ) { return false; } $to_ping = sanitize_trackback_urls( $post->to_ping ); $to_ping = preg_split( '/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY ); return apply_filters( 'get_to_ping', $to_ping ); } function trackback_url_list( $tb_list, $post_id ) { if ( ! empty( $tb_list ) ) { $postdata = get_post( $post_id, ARRAY_A ); $excerpt = strip_tags( $postdata['post_excerpt'] ? $postdata['post_excerpt'] : $postdata['post_content'] ); if ( strlen( $excerpt ) > 255 ) { $excerpt = substr( $excerpt, 0, 252 ) . '…'; } $trackback_urls = explode( ',', $tb_list ); foreach ( (array) $trackback_urls as $tb_url ) { $tb_url = trim( $tb_url ); trackback( $tb_url, wp_unslash( $postdata['post_title'] ), $excerpt, $post_id ); } } } function get_all_page_ids() { global $wpdb; $page_ids = wp_cache_get( 'all_page_ids', 'posts' ); if ( ! is_array( $page_ids ) ) { $page_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type = 'page'" ); wp_cache_add( 'all_page_ids', $page_ids, 'posts' ); } return $page_ids; } function get_page( $page, $output = OBJECT, $filter = 'raw' ) { return get_post( $page, $output, $filter ); } function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $last_changed = wp_cache_get_last_changed( 'posts' ); $hash = md5( $page_path . serialize( $post_type ) ); $cache_key = "get_page_by_path:$hash"; $cached = wp_cache_get_salted( $cache_key, 'post-queries', $last_changed ); if ( false !== $cached ) { if ( '0' === $cached || 0 === $cached ) { return null; } else { return get_post( $cached, $output ); } } $page_path = rawurlencode( urldecode( $page_path ) ); $page_path = str_replace( '%2F', '/', $page_path ); $page_path = str_replace( '%20', ' ', $page_path ); $parts = explode( '/', trim( $page_path, '/' ) ); $parts = array_map( 'sanitize_title_for_query', $parts ); $escaped_parts = esc_sql( $parts ); $in_string = "'" . implode( "','", $escaped_parts ) . "'"; if ( is_array( $post_type ) ) { $post_types = $post_type; } else { $post_types = array( $post_type, 'attachment' ); } $post_types = esc_sql( $post_types ); $post_type_in_string = "'" . implode( "','", $post_types ) . "'"; $sql = "
SELECT ID, post_name, post_parent, post_type
FROM $wpdb->posts
WHERE post_name IN ($in_string)
AND post_type IN ($post_type_in_string)
"; $pages = $wpdb->get_results( $sql, OBJECT_K ); $revparts = array_reverse( $parts ); $found_id = 0; foreach ( (array) $pages as $page ) { if ( $page->post_name === $revparts[0] ) { $count = 0; $p = $page; while ( 0 !== (int) $p->post_parent && isset( $pages[ $p->post_parent ] ) ) { ++$count; $parent = $pages[ $p->post_parent ]; if ( ! isset( $revparts[ $count ] ) || $parent->post_name !== $revparts[ $count ] ) { break; } $p = $parent; } if ( 0 === (int) $p->post_parent && count( $revparts ) === $count + 1 && $p->post_name === $revparts[ $count ] ) { $found_id = $page->ID; if ( $page->post_type === $post_type ) { break; } } } } wp_cache_set_salted( $cache_key, $found_id, 'post-queries', $last_changed ); if ( $found_id ) { return get_post( $found_id, $output ); } return null; } function get_page_children( $page_id, $pages ) { $children = array(); foreach ( (array) $pages as $page ) { $children[ (int) $page->post_parent ][] = $page; } $page_list = array(); if ( isset( $children[ $page_id ] ) ) { $to_look = array_reverse( $children[ $page_id ] ); while ( $to_look ) { $p = array_pop( $to_look ); $page_list[] = $p; if ( isset( $children[ $p->ID ] ) ) { foreach ( array_reverse( $children[ $p->ID ] ) as $child ) { $to_look[] = $child; } } } } return $page_list; } function get_page_hierarchy( &$pages, $page_id = 0 ) { if ( empty( $pages ) ) { return array(); } $children = array(); foreach ( (array) $pages as $p ) { $parent_id = (int) $p->post_parent; $children[ $parent_id ][] = $p; } $result = array(); _page_traverse_name( $page_id, $children, $result ); return $result; } function _page_traverse_name( $page_id, &$children, &$result ) { if ( isset( $children[ $page_id ] ) ) { foreach ( (array) $children[ $page_id ] as $child ) { $result[ $child->ID ] = $child->post_name; _page_traverse_name( $child->ID, $children, $result ); } } } function get_page_uri( $page = 0 ) { if ( ! $page instanceof WP_Post ) { $page = get_post( $page ); } if ( ! $page ) { return false; } $uri = $page->post_name; foreach ( $page->ancestors as $parent ) { $parent = get_post( $parent ); if ( $parent && $parent->post_name ) { $uri = $parent->post_name . '/' . $uri; } } return apply_filters( 'get_page_uri', $uri, $page ); } function get_pages( $args = array() ) { $defaults = array( 'child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => array(), 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', ); $parsed_args = wp_parse_args( $args, $defaults ); $number = (int) $parsed_args['number']; $offset = (int) $parsed_args['offset']; $child_of = (int) $parsed_args['child_of']; $hierarchical = $parsed_args['hierarchical']; $exclude = $parsed_args['exclude']; $meta_key = $parsed_args['meta_key']; $meta_value = $parsed_args['meta_value']; $parent = $parsed_args['parent']; $post_status = $parsed_args['post_status']; $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) ); if ( ! in_array( $parsed_args['post_type'], $hierarchical_post_types, true ) ) { return false; } if ( $parent > 0 && ! $child_of ) { $hierarchical = false; } if ( ! is_array( $post_status ) ) { $post_status = explode( ',', $post_status ); } if ( array_diff( $post_status, get_post_stati() ) ) { return false; } $query_args = array( 'orderby' => 'post_title', 'order' => 'ASC', 'post__not_in' => wp_parse_id_list( $exclude ), 'meta_key' => $meta_key, 'meta_value' => $meta_value, 'posts_per_page' => -1, 'offset' => $offset, 'post_type' => $parsed_args['post_type'], 'post_status' => $post_status, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'ignore_sticky_posts' => true, 'no_found_rows' => true, ); if ( ! empty( $parsed_args['include'] ) ) { $child_of = 0; $parent = -1; unset( $query_args['post__not_in'], $query_args['meta_key'], $query_args['meta_value'] ); $hierarchical = false; $query_args['post__in'] = wp_parse_id_list( $parsed_args['include'] ); } if ( ! empty( $parsed_args['authors'] ) ) { $post_authors = wp_parse_list( $parsed_args['authors'] ); if ( ! empty( $post_authors ) ) { $query_args['author__in'] = array(); foreach ( $post_authors as $post_author ) { if ( 0 === (int) $post_author ) { $post_author = get_user_by( 'login', $post_author ); if ( empty( $post_author ) ) { continue; } if ( empty( $post_author->ID ) ) { continue; } $post_author = $post_author->ID; } $query_args['author__in'][] = (int) $post_author; } } } if ( is_array( $parent ) ) { $post_parent__in = array_map( 'absint', (array) $parent ); if ( ! empty( $post_parent__in ) ) { $query_args['post_parent__in'] = $post_parent__in; } } elseif ( $parent >= 0 ) { $query_args['post_parent'] = $parent; } $orderby = wp_parse_list( $parsed_args['sort_column'] ); $orderby = array_map( static function ( $orderby_field ) { $orderby_field = trim( $orderby_field ); if ( 'post_modified_gmt' === $orderby_field || 'modified_gmt' === $orderby_field ) { $orderby_field = str_replace( '_gmt', '', $orderby_field ); } return $orderby_field; }, $orderby ); if ( $orderby ) { $query_args['orderby'] = array_fill_keys( $orderby, $parsed_args['sort_order'] ); } $order = $parsed_args['sort_order']; if ( $order ) { $query_args['order'] = $order; } if ( ! empty( $number ) ) { $query_args['posts_per_page'] = $number; } $query_args = apply_filters( 'get_pages_query_args', $query_args, $parsed_args ); $pages = new WP_Query(); $pages = $pages->query( $query_args ); if ( $child_of || $hierarchical ) { $pages = get_page_children( $child_of, $pages ); } if ( ! empty( $parsed_args['exclude_tree'] ) ) { $exclude = wp_parse_id_list( $parsed_args['exclude_tree'] ); foreach ( $exclude as $id ) { $children = get_page_children( $id, $pages ); foreach ( $children as $child ) { $exclude[] = $child->ID; } } $num_pages = count( $pages ); for ( $i = 0; $i < $num_pages; $i++ ) { if ( in_array( $pages[ $i ]->ID, $exclude, true ) ) { unset( $pages[ $i ] ); } } } return apply_filters( 'get_pages', $pages, $parsed_args ); } function is_local_attachment( $url ) { if ( ! str_contains( $url, home_url() ) ) { return false; } if ( str_contains( $url, home_url( '/?attachment_id=' ) ) ) { return true; } $id = url_to_postid( $url ); if ( $id ) { $post = get_post( $id ); if ( 'attachment' === $post->post_type ) { return true; } } return false; } function wp_insert_attachment( $args, $file = false, $parent_post_id = 0, $wp_error = false, $fire_after_hooks = true ) { $defaults = array( 'file' => $file, 'post_parent' => 0, ); $data = wp_parse_args( $args, $defaults ); if ( ! empty( $parent_post_id ) ) { $data['post_parent'] = $parent_post_id; } $data['post_type'] = 'attachment'; return wp_insert_post( $data, $wp_error, $fire_after_hooks ); } function wp_delete_attachment( $post_id, $force_delete = false ) { global $wpdb; $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id ) ); if ( ! $post ) { return $post; } $post = get_post( $post ); if ( 'attachment' !== $post->post_type ) { return false; } if ( ! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status ) { return wp_trash_post( $post_id ); } $check = apply_filters( 'pre_delete_attachment', null, $post, $force_delete ); if ( null !== $check ) { return $check; } delete_post_meta( $post_id, '_wp_trash_meta_status' ); delete_post_meta( $post_id, '_wp_trash_meta_time' ); $meta = wp_get_attachment_metadata( $post_id ); $backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true ); $file = get_attached_file( $post_id ); if ( is_multisite() && is_string( $file ) && ! empty( $file ) ) { clean_dirsize_cache( $file ); } do_action( 'delete_attachment', $post_id, $post ); wp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) ); wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) ); delete_metadata( 'post', null, '_thumbnail_id', $post_id, true ); wp_defer_comment_counting( true ); $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $post_id ) ); foreach ( $comment_ids as $comment_id ) { wp_delete_comment( $comment_id, true ); } wp_defer_comment_counting( false ); $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ) ); foreach ( $post_meta_ids as $mid ) { delete_metadata_by_mid( 'post', $mid ); } do_action( 'delete_post', $post_id, $post ); $result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) ); if ( ! $result ) { return false; } do_action( 'deleted_post', $post_id, $post ); wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file ); clean_post_cache( $post ); return $post; } function wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file ) { global $wpdb; $uploadpath = wp_get_upload_dir(); $deleted = true; if ( ! empty( $meta['thumb'] ) ) { if ( ! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id ) ) ) { $thumbfile = str_replace( wp_basename( $file ), $meta['thumb'], $file ); if ( ! empty( $thumbfile ) ) { $thumbfile = path_join( $uploadpath['basedir'], $thumbfile ); $thumbdir = path_join( $uploadpath['basedir'], dirname( $file ) ); if ( ! wp_delete_file_from_directory( $thumbfile, $thumbdir ) ) { $deleted = false; } } } } if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) { $intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) ); foreach ( $meta['sizes'] as $size => $sizeinfo ) { $intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file ); if ( ! empty( $intermediate_file ) ) { $intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file ); if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) { $deleted = false; } } } } if ( ! empty( $meta['original_image'] ) ) { if ( empty( $intermediate_dir ) ) { $intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) ); } $original_image = str_replace( wp_basename( $file ), $meta['original_image'], $file ); if ( ! empty( $original_image ) ) { $original_image = path_join( $uploadpath['basedir'], $original_image ); if ( ! wp_delete_file_from_directory( $original_image, $intermediate_dir ) ) { $deleted = false; } } } if ( is_array( $backup_sizes ) ) { $del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) ); foreach ( $backup_sizes as $size ) { $del_file = path_join( dirname( $meta['file'] ), $size['file'] ); if ( ! empty( $del_file ) ) { $del_file = path_join( $uploadpath['basedir'], $del_file ); if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) { $deleted = false; } } } } if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) { $deleted = false; } return $deleted; } function wp_get_attachment_metadata( $attachment_id = 0, $unfiltered = false ) { $attachment_id = (int) $attachment_id; if ( ! $attachment_id ) { $post = get_post(); if ( ! $post ) { return false; } $attachment_id = $post->ID; } $data = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); if ( ! $data ) { return false; } if ( $unfiltered ) { return $data; } return apply_filters( 'wp_get_attachment_metadata', $data, $attachment_id ); } function wp_update_attachment_metadata( $attachment_id, $data ) { $attachment_id = (int) $attachment_id; $post = get_post( $attachment_id ); if ( ! $post ) { return false; } $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ); if ( $data ) { return update_post_meta( $post->ID, '_wp_attachment_metadata', $data ); } else { return delete_post_meta( $post->ID, '_wp_attachment_metadata' ); } } function wp_get_attachment_url( $attachment_id = 0 ) { global $pagenow; $attachment_id = (int) $attachment_id; $post = get_post( $attachment_id ); if ( ! $post ) { return false; } if ( 'attachment' !== $post->post_type ) { return false; } $url = ''; $file = get_post_meta( $post->ID, '_wp_attached_file', true ); if ( $file ) { $uploads = wp_get_upload_dir(); if ( $uploads && false === $uploads['error'] ) { if ( str_starts_with( $file, $uploads['basedir'] ) ) { $url = str_replace( $uploads['basedir'], $uploads['baseurl'], $file ); } elseif ( str_contains( $file, 'wp-content/uploads' ) ) { $url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $file ) ) . wp_basename( $file ); } else { $url = $uploads['baseurl'] . "/$file"; } } } if ( ! $url ) { $url = get_the_guid( $post->ID ); } if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $pagenow ) { $url = set_url_scheme( $url ); } $url = apply_filters( 'wp_get_attachment_url', $url, $post->ID ); if ( ! $url ) { return false; } return $url; } function wp_get_attachment_caption( $post_id = 0 ) { $post_id = (int) $post_id; $post = get_post( $post_id ); if ( ! $post ) { return false; } if ( 'attachment' !== $post->post_type ) { return false; } $caption = $post->post_excerpt; return apply_filters( 'wp_get_attachment_caption', $caption, $post->ID ); } function wp_get_attachment_thumb_url( $post_id = 0 ) { $post_id = (int) $post_id; $thumbnail_url = wp_get_attachment_image_url( $post_id, 'thumbnail' ); if ( empty( $thumbnail_url ) ) { return false; } return apply_filters( 'wp_get_attachment_thumb_url', $thumbnail_url, $post_id ); } function wp_attachment_is( $type, $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $file = get_attached_file( $post->ID ); if ( ! $file ) { return false; } if ( str_starts_with( $post->post_mime_type, $type . '/' ) ) { return true; } $check = wp_check_filetype( $file ); if ( empty( $check['ext'] ) ) { return false; } $ext = $check['ext']; if ( 'import' !== $post->post_mime_type ) { return $type === $ext; } switch ( $type ) { case 'image': $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif', 'heic' ); return in_array( $ext, $image_exts, true ); case 'audio': return in_array( $ext, wp_get_audio_extensions(), true ); case 'video': return in_array( $ext, wp_get_video_extensions(), true ); default: return $type === $ext; } } function wp_attachment_is_image( $post = null ) { return wp_attachment_is( 'image', $post ); } function wp_mime_type_icon( $mime = 0, $preferred_ext = '.png' ) { if ( ! is_numeric( $mime ) ) { $icon = wp_cache_get( "mime_type_icon_$mime" ); } if ( ! empty( $preferred_ext ) && is_string( $preferred_ext ) && ! str_starts_with( $preferred_ext, '.' ) ) { $preferred_ext = '.' . strtolower( $preferred_ext ); } $post_id = 0; if ( empty( $icon ) ) { $post_mimes = array(); if ( is_numeric( $mime ) ) { $mime = (int) $mime; $post = get_post( $mime ); if ( $post ) { $post_id = (int) $post->ID; $file = get_attached_file( $post_id ); $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $file ); if ( ! empty( $ext ) ) { $post_mimes[] = $ext; $ext_type = wp_ext2type( $ext ); if ( $ext_type ) { $post_mimes[] = $ext_type; } } $mime = $post->post_mime_type; } else { $mime = 0; } } else { $post_mimes[] = $mime; } $icon_files = wp_cache_get( 'icon_files' ); if ( ! is_array( $icon_files ) ) { $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); $icon_dir_uri = apply_filters( 'icon_dir_uri', includes_url( 'images/media' ) ); $dirs = apply_filters( 'icon_dirs', array( $icon_dir => $icon_dir_uri ) ); $icon_files = array(); $all_icons = array(); while ( $dirs ) { $keys = array_keys( $dirs ); $dir = array_shift( $keys ); $uri = array_shift( $dirs ); $dh = opendir( $dir ); if ( $dh ) { while ( false !== $file = readdir( $dh ) ) { $file = wp_basename( $file ); if ( str_starts_with( $file, '.' ) ) { continue; } $ext = strtolower( substr( $file, -4 ) ); if ( ! in_array( $ext, array( '.svg', '.png', '.gif', '.jpg' ), true ) ) { if ( is_dir( "$dir/$file" ) ) { $dirs[ "$dir/$file" ] = "$uri/$file"; } continue; } $all_icons[ "$dir/$file" ] = "$uri/$file"; if ( $ext === $preferred_ext ) { $icon_files[ "$dir/$file" ] = "$uri/$file"; } } closedir( $dh ); } } if ( empty( $icon_files ) ) { $icon_files = $all_icons; } wp_cache_add( 'icon_files', $icon_files, 'default', 600 ); } $types = array(); foreach ( $icon_files as $file => $uri ) { $types[ preg_replace( '/^([^.]*).*$/', '$1', wp_basename( $file ) ) ] =& $icon_files[ $file ]; } if ( ! empty( $mime ) ) { $post_mimes[] = substr( $mime, 0, strpos( $mime, '/' ) ); $post_mimes[] = substr( $mime, strpos( $mime, '/' ) + 1 ); $post_mimes[] = str_replace( '/', '_', $mime ); } $matches = wp_match_mime_types( array_keys( $types ), $post_mimes ); $matches['default'] = array( 'default' ); foreach ( $matches as $match => $wilds ) { foreach ( $wilds as $wild ) { if ( ! isset( $types[ $wild ] ) ) { continue; } $icon = $types[ $wild ]; if ( ! is_numeric( $mime ) ) { wp_cache_add( "mime_type_icon_$mime", $icon ); } break 2; } } } return apply_filters( 'wp_mime_type_icon', $icon, $mime, $post_id ); } function wp_check_for_changed_slugs( $post_id, $post, $post_before ) { if ( $post->post_name === $post_before->post_name ) { return; } if ( ! ( 'publish' === $post->post_status || ( 'attachment' === $post->post_type && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical( $post->post_type ) ) { return; } $old_slugs = (array) get_post_meta( $post_id, '_wp_old_slug' ); if ( ! empty( $post_before->post_name ) && ! in_array( $post_before->post_name, $old_slugs, true ) ) { add_post_meta( $post_id, '_wp_old_slug', $post_before->post_name ); } if ( in_array( $post->post_name, $old_slugs, true ) ) { delete_post_meta( $post_id, '_wp_old_slug', $post->post_name ); } } function wp_check_for_changed_dates( $post_id, $post, $post_before ) { $previous_date = gmdate( 'Y-m-d', strtotime( $post_before->post_date ) ); $new_date = gmdate( 'Y-m-d', strtotime( $post->post_date ) ); if ( $new_date === $previous_date ) { return; } if ( ! ( 'publish' === $post->post_status || ( 'attachment' === $post->post_type && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical( $post->post_type ) ) { return; } $old_dates = (array) get_post_meta( $post_id, '_wp_old_date' ); if ( ! empty( $previous_date ) && ! in_array( $previous_date, $old_dates, true ) ) { add_post_meta( $post_id, '_wp_old_date', $previous_date ); } if ( in_array( $new_date, $old_dates, true ) ) { delete_post_meta( $post_id, '_wp_old_date', $new_date ); } } function get_private_posts_cap_sql( $post_type ) { return get_posts_by_author_sql( $post_type, false ); } function get_posts_by_author_sql( $post_type, $full = true, $post_author = null, $public_only = false ) { global $wpdb; if ( is_array( $post_type ) ) { $post_types = $post_type; } else { $post_types = array( $post_type ); } $post_type_clauses = array(); foreach ( $post_types as $post_type ) { $post_type_obj = get_post_type_object( $post_type ); if ( ! $post_type_obj ) { continue; } $cap = apply_filters_deprecated( 'pub_priv_sql_capability', array( '' ), '3.2.0' ); if ( ! $cap ) { $cap = current_user_can( $post_type_obj->cap->read_private_posts ); } $post_status_sql = "post_status = 'publish'"; if ( false === $public_only ) { if ( $cap ) { $post_status_sql .= " OR post_status = 'private'"; } elseif ( is_user_logged_in() ) { $id = get_current_user_id(); if ( null === $post_author || ! $full ) { $post_status_sql .= " OR post_status = 'private' AND post_author = $id"; } elseif ( $id === (int) $post_author ) { $post_status_sql .= " OR post_status = 'private'"; } } } $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( $post_status_sql ) )"; } if ( empty( $post_type_clauses ) ) { return $full ? 'WHERE 1 = 0' : '1 = 0'; } $sql = '( ' . implode( ' OR ', $post_type_clauses ) . ' )'; if ( null !== $post_author ) { $sql .= $wpdb->prepare( ' AND post_author = %d', $post_author ); } if ( $full ) { $sql = 'WHERE ' . $sql; } return $sql; } function get_lastpostdate( $timezone = 'server', $post_type = 'any' ) { $lastpostdate = _get_last_post_time( $timezone, 'date', $post_type ); return apply_filters( 'get_lastpostdate', $lastpostdate, $timezone, $post_type ); } function get_lastpostmodified( $timezone = 'server', $post_type = 'any' ) { $lastpostmodified = apply_filters( 'pre_get_lastpostmodified', false, $timezone, $post_type ); if ( false !== $lastpostmodified ) { return $lastpostmodified; } $lastpostmodified = _get_last_post_time( $timezone, 'modified', $post_type ); $lastpostdate = get_lastpostdate( $timezone, $post_type ); if ( $lastpostdate > $lastpostmodified ) { $lastpostmodified = $lastpostdate; } return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone, $post_type ); } function _get_last_post_time( $timezone, $field, $post_type = 'any' ) { global $wpdb; if ( ! in_array( $field, array( 'date', 'modified' ), true ) ) { return false; } $timezone = strtolower( $timezone ); $key = "lastpost{$field}:$timezone"; if ( 'any' !== $post_type ) { $key .= ':' . sanitize_key( $post_type ); } $date = wp_cache_get( $key, 'timeinfo' ); if ( false !== $date ) { return $date; } if ( 'any' === $post_type ) { $post_types = get_post_types( array( 'public' => true ) ); array_walk( $post_types, array( $wpdb, 'escape_by_ref' ) ); $post_types = "'" . implode( "', '", $post_types ) . "'"; } else { $post_types = "'" . sanitize_key( $post_type ) . "'"; } switch ( $timezone ) { case 'gmt': $date = $wpdb->get_var( "SELECT post_{$field}_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" ); break; case 'blog': $date = $wpdb->get_var( "SELECT post_{$field} FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" ); break; case 'server': $add_seconds_server = gmdate( 'Z' ); $date = $wpdb->get_var( "SELECT DATE_ADD(post_{$field}_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" ); break; } if ( $date ) { wp_cache_set( $key, $date, 'timeinfo' ); return $date; } return false; } function update_post_cache( &$posts ) { if ( ! $posts ) { return; } $data = array(); foreach ( $posts as $post ) { if ( empty( $post->filter ) || 'raw' !== $post->filter ) { $post = sanitize_post( $post, 'raw' ); } $data[ $post->ID ] = $post; } wp_cache_add_multiple( $data, 'posts' ); } function clean_post_cache( $post ) { global $_wp_suspend_cache_invalidation; if ( ! empty( $_wp_suspend_cache_invalidation ) ) { return; } $post = get_post( $post ); if ( ! $post ) { return; } wp_cache_delete( $post->ID, 'posts' ); wp_cache_delete( 'post_parent:' . (string) $post->ID, 'posts' ); wp_cache_delete( $post->ID, 'post_meta' ); clean_object_term_cache( $post->ID, $post->post_type ); wp_cache_delete( 'wp_get_archives', 'general' ); do_action( 'clean_post_cache', $post->ID, $post ); if ( 'page' === $post->post_type ) { wp_cache_delete( 'all_page_ids', 'posts' ); do_action( 'clean_page_cache', $post->ID ); } wp_cache_set_posts_last_changed(); } function update_post_caches( &$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true ) { if ( ! $posts ) { return; } update_post_cache( $posts ); $post_ids = array(); foreach ( $posts as $post ) { $post_ids[] = $post->ID; } if ( ! $post_type ) { $post_type = 'any'; } if ( $update_term_cache ) { if ( is_array( $post_type ) ) { $ptypes = $post_type; } elseif ( 'any' === $post_type ) { $ptypes = array(); foreach ( $posts as $post ) { $ptypes[] = $post->post_type; } $ptypes = array_unique( $ptypes ); } else { $ptypes = array( $post_type ); } if ( ! empty( $ptypes ) ) { update_object_term_cache( $post_ids, $ptypes ); } } if ( $update_meta_cache ) { update_postmeta_cache( $post_ids ); } } function update_post_author_caches( $posts ) { if ( ! function_exists( 'cache_users' ) ) { return; } $author_ids = wp_list_pluck( $posts, 'post_author' ); $author_ids = array_map( 'absint', $author_ids ); $author_ids = array_unique( array_filter( $author_ids ) ); cache_users( $author_ids ); } function update_post_parent_caches( $posts ) { $parent_ids = wp_list_pluck( $posts, 'post_parent' ); $parent_ids = array_map( 'absint', $parent_ids ); $parent_ids = array_unique( array_filter( $parent_ids ) ); if ( ! empty( $parent_ids ) ) { _prime_post_caches( $parent_ids, false ); } } function update_postmeta_cache( $post_ids ) { return update_meta_cache( 'post', $post_ids ); } function clean_attachment_cache( $id, $clean_terms = false ) { global $_wp_suspend_cache_invalidation; if ( ! empty( $_wp_suspend_cache_invalidation ) ) { return; } $id = (int) $id; wp_cache_delete( $id, 'posts' ); wp_cache_delete( $id, 'post_meta' ); if ( $clean_terms ) { clean_object_term_cache( $id, 'attachment' ); } do_action( 'clean_attachment_cache', $id ); } function _transition_post_status( $new_status, $old_status, $post ) { global $wpdb; if ( 'publish' !== $old_status && 'publish' === $new_status ) { if ( '' === get_the_guid( $post->ID ) ) { $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) ); } do_action_deprecated( 'private_to_published', array( $post->ID ), '2.3.0', 'private_to_publish' ); } if ( 'publish' === $new_status || 'publish' === $old_status ) { foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' ); wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' ); wp_cache_delete( "lastpostdate:$timezone:{$post->post_type}", 'timeinfo' ); } } if ( $new_status !== $old_status ) { wp_cache_delete( _count_posts_cache_key( $post->post_type ), 'counts' ); wp_cache_delete( _count_posts_cache_key( $post->post_type, 'readable' ), 'counts' ); } wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) ); } function _future_post_hook( $deprecated, $post ) { wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) ); wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT' ), 'publish_future_post', array( $post->ID ) ); } function _publish_post_hook( $post_id ) { if ( defined( 'XMLRPC_REQUEST' ) ) { do_action( 'xmlrpc_publish_post', $post_id ); } if ( defined( 'WP_IMPORTING' ) ) { return; } if ( get_option( 'default_pingback_flag' ) ) { add_post_meta( $post_id, '_pingme', '1', true ); } add_post_meta( $post_id, '_encloseme', '1', true ); $to_ping = get_to_ping( $post_id ); if ( ! empty( $to_ping ) ) { add_post_meta( $post_id, '_trackbackme', '1' ); } if ( ! wp_next_scheduled( 'do_pings' ) ) { wp_schedule_single_event( time(), 'do_pings' ); } } function wp_get_post_parent_id( $post = null ) { $post = get_post( $post ); if ( ! $post || is_wp_error( $post ) ) { return false; } return (int) $post->post_parent; } function wp_check_post_hierarchy_for_loops( $post_parent, $post_id ) { if ( ! $post_parent ) { return 0; } if ( ! $post_id ) { return $post_parent; } if ( $post_parent === $post_id ) { return 0; } $loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_id, $post_parent ); if ( ! $loop ) { return $post_parent; } if ( isset( $loop[ $post_id ] ) ) { return 0; } foreach ( array_keys( $loop ) as $loop_member ) { wp_update_post( array( 'ID' => $loop_member, 'post_parent' => 0, ) ); } return $post_parent; } function set_post_thumbnail( $post, $thumbnail_id ) { $post = get_post( $post ); $thumbnail_id = absint( $thumbnail_id ); if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) { if ( wp_get_attachment_image( $thumbnail_id, 'thumbnail' ) ) { return update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id ); } else { return delete_post_meta( $post->ID, '_thumbnail_id' ); } } return false; } function delete_post_thumbnail( $post ) { $post = get_post( $post ); if ( $post ) { return delete_post_meta( $post->ID, '_thumbnail_id' ); } return false; } function wp_delete_auto_drafts() { global $wpdb; $old_posts = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_status = 'auto-draft' AND DATE_SUB( NOW(), INTERVAL 7 DAY ) > post_date" ); foreach ( (array) $old_posts as $delete ) { wp_delete_post( $delete, true ); } } function wp_queue_posts_for_term_meta_lazyload( $posts ) { $post_type_taxonomies = array(); $prime_post_terms = array(); foreach ( $posts as $post ) { if ( ! ( $post instanceof WP_Post ) ) { continue; } if ( ! isset( $post_type_taxonomies[ $post->post_type ] ) ) { $post_type_taxonomies[ $post->post_type ] = get_object_taxonomies( $post->post_type ); } foreach ( $post_type_taxonomies[ $post->post_type ] as $taxonomy ) { $prime_post_terms[ $taxonomy ][] = $post->ID; } } $term_ids = array(); if ( $prime_post_terms ) { foreach ( $prime_post_terms as $taxonomy => $post_ids ) { $cached_term_ids = wp_cache_get_multiple( $post_ids, "{$taxonomy}_relationships" ); if ( is_array( $cached_term_ids ) ) { $cached_term_ids = array_filter( $cached_term_ids ); foreach ( $cached_term_ids as $_term_ids ) { foreach ( $_term_ids as $term_id ) { if ( is_numeric( $term_id ) ) { $term_ids[] = (int) $term_id; } elseif ( isset( $term_id->term_id ) ) { $term_ids[] = (int) $term_id->term_id; } } } } } $term_ids = array_unique( $term_ids ); } wp_lazyload_term_meta( $term_ids ); } function _update_term_count_on_transition_post_status( $new_status, $old_status, $post ) { if ( $new_status === $old_status ) { return; } foreach ( (array) get_object_taxonomies( $post->post_type, 'objects' ) as $taxonomy ) { $counted_statuses = apply_filters( 'update_post_term_count_statuses', array( 'publish' ), $taxonomy ); if ( ! in_array( $old_status, $counted_statuses, true ) && ! in_array( $new_status, $counted_statuses, true ) ) { continue; } if ( in_array( $old_status, $counted_statuses, true ) && in_array( $new_status, $counted_statuses, true ) ) { continue; } $tt_ids = wp_get_object_terms( $post->ID, $taxonomy->name, array( 'fields' => 'tt_ids' ) ); wp_update_term_count( $tt_ids, $taxonomy->name ); } } function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache = true ) { global $wpdb; $non_cached_ids = _get_non_cached_ids( $ids, 'posts' ); if ( ! empty( $non_cached_ids ) ) { $fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", implode( ',', $non_cached_ids ) ) ); if ( $fresh_posts ) { update_post_cache( $fresh_posts ); } } if ( $update_meta_cache ) { update_postmeta_cache( $ids ); } if ( $update_term_cache ) { $post_types = array_map( 'get_post_type', $ids ); $post_types = array_unique( $post_types ); update_object_term_cache( $ids, $post_types ); } } function _prime_post_parent_id_caches( array $ids ) { global $wpdb; $ids = array_filter( $ids, '_validate_cache_id' ); $ids = array_unique( array_map( 'intval', $ids ), SORT_NUMERIC ); if ( empty( $ids ) ) { return; } $cache_keys = array(); foreach ( $ids as $id ) { $cache_keys[ $id ] = 'post_parent:' . (string) $id; } $cached_data = wp_cache_get_multiple( array_values( $cache_keys ), 'posts' ); $non_cached_ids = array(); foreach ( $cache_keys as $id => $cache_key ) { if ( false === $cached_data[ $cache_key ] ) { $non_cached_ids[] = $id; } } if ( ! empty( $non_cached_ids ) ) { $fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.ID, $wpdb->posts.post_parent FROM $wpdb->posts WHERE ID IN (%s)", implode( ',', $non_cached_ids ) ) ); if ( $fresh_posts ) { $post_parent_data = array(); foreach ( $fresh_posts as $fresh_post ) { $post_parent_data[ 'post_parent:' . (string) $fresh_post->ID ] = (int) $fresh_post->post_parent; } wp_cache_add_multiple( $post_parent_data, 'posts' ); } } } function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_id = 0 ) { $trashed_posts_with_desired_slug = get_posts( array( 'name' => $post_name, 'post_status' => 'trash', 'post_type' => 'any', 'nopaging' => true, 'post__not_in' => array( $post_id ), ) ); if ( ! empty( $trashed_posts_with_desired_slug ) ) { foreach ( $trashed_posts_with_desired_slug as $_post ) { wp_add_trashed_suffix_to_post_name_for_post( $_post ); } } } function wp_add_trashed_suffix_to_post_name_for_post( $post ) { global $wpdb; $post = get_post( $post ); if ( str_ends_with( $post->post_name, '__trashed' ) ) { return $post->post_name; } add_post_meta( $post->ID, '_wp_desired_post_slug', $post->post_name ); $post_name = _truncate_post_slug( $post->post_name, 191 ) . '__trashed'; $wpdb->update( $wpdb->posts, array( 'post_name' => $post_name ), array( 'ID' => $post->ID ) ); clean_post_cache( $post->ID ); return $post_name; } function wp_cache_set_posts_last_changed() { wp_cache_set_last_changed( 'posts' ); } function get_available_post_mime_types( $type = 'attachment' ) { global $wpdb; $mime_types = apply_filters( 'pre_get_available_post_mime_types', null, $type ); if ( ! is_array( $mime_types ) ) { $mime_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s AND post_mime_type != ''", $type ) ); } return array_values( array_filter( $mime_types ) ); } function wp_get_original_image_path( $attachment_id, $unfiltered = false ) { if ( ! wp_attachment_is_image( $attachment_id ) ) { return false; } $image_meta = wp_get_attachment_metadata( $attachment_id ); $image_file = get_attached_file( $attachment_id, $unfiltered ); if ( empty( $image_meta['original_image'] ) ) { $original_image = $image_file; } else { $original_image = path_join( dirname( $image_file ), $image_meta['original_image'] ); } return apply_filters( 'wp_get_original_image_path', $original_image, $attachment_id ); } function wp_get_original_image_url( $attachment_id ) { if ( ! wp_attachment_is_image( $attachment_id ) ) { return false; } $image_url = wp_get_attachment_url( $attachment_id ); if ( ! $image_url ) { return false; } $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( empty( $image_meta['original_image'] ) ) { $original_image_url = $image_url; } else { $original_image_url = path_join( dirname( $image_url ), $image_meta['original_image'] ); } return apply_filters( 'wp_get_original_image_url', $original_image_url, $attachment_id ); } function wp_untrash_post_set_previous_status( $new_status, $post_id, $previous_status ) { return $previous_status; } function use_block_editor_for_post( $post ) { $post = get_post( $post ); if ( ! $post ) { return false; } if ( is_admin() && isset( $_GET['meta-box-loader'] ) ) { check_admin_referer( 'meta-box-loader', 'meta-box-loader-nonce' ); return false; } $use_block_editor = use_block_editor_for_post_type( $post->post_type ); return apply_filters( 'use_block_editor_for_post', $use_block_editor, $post ); } function use_block_editor_for_post_type( $post_type ) { if ( ! post_type_exists( $post_type ) ) { return false; } if ( ! post_type_supports( $post_type, 'editor' ) ) { return false; } $post_type_object = get_post_type_object( $post_type ); if ( $post_type_object && ! $post_type_object->show_in_rest ) { return false; } return apply_filters( 'use_block_editor_for_post_type', true, $post_type ); } function wp_create_initial_post_meta() { register_post_meta( 'wp_block', 'wp_pattern_sync_status', array( 'sanitize_callback' => 'sanitize_text_field', 'single' => true, 'type' => 'string', 'show_in_rest' => array( 'schema' => array( 'type' => 'string', 'enum' => array( 'partial', 'unsynced' ), ), ), ) ); }
###require ABSPATH . WPINC . '/class-walker-page.php';
class Walker_Page extends Walker { public $tree_type = 'page'; public $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID', ); public function start_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); $output .= "{$n}{$indent}<ul class='children'>{$n}"; } public function end_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); $output .= "{$indent}</ul>{$n}"; } public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { $page = $data_object; $current_page_id = $current_object_id; if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page_id ) ) { $_current_page = get_post( $current_page_id ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors, true ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID === (int) $current_page_id ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID === $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( (int) get_option( 'page_for_posts' ) === $page->ID ) { $css_class[] = 'current_page_parent'; } $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page_id ) ); $css_classes = $css_classes ? ' class="' . esc_attr( $css_classes ) . '"' : ''; if ( '' === $page->post_title ) { $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); $atts['aria-current'] = ( $page->ID === (int) $current_page_id ) ? 'page' : ''; $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page_id ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } $output .= $indent . sprintf( '<li%s><a%s>%s%s%s</a>', $css_classes, $attributes, $args['link_before'], apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' === $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= ' ' . mysql2date( $date_format, $time ); } } public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $output .= "</li>{$n}"; } }
###require ABSPATH . WPINC . '/class-walker-page-dropdown.php';
class Walker_PageDropdown extends Walker { public $tree_type = 'page'; public $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID', ); public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { $page = $data_object; $pad = str_repeat( ' ', $depth * 3 ); if ( ! isset( $args['value_field'] ) || ! isset( $page->{$args['value_field']} ) ) { $args['value_field'] = 'ID'; } $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $page->{$args['value_field']} ) . '"'; if ( $page->ID === (int) $args['selected'] ) { $output .= ' selected="selected"'; } $output .= '>'; $title = $page->post_title; if ( '' === $title ) { $title = sprintf( __( '#%d (no title)' ), $page->ID ); } $title = apply_filters( 'list_pages', $title, $page ); $output .= $pad . esc_html( $title ); $output .= "</option>\n"; } }
###require ABSPATH . WPINC . '/class-wp-post-type.php';
final class WP_Post_Type { public $name; public $label; public $labels; protected static $default_labels = array(); public $description = ''; public $public = false; public $hierarchical = false; public $exclude_from_search = null; public $publicly_queryable = null; public $embeddable = null; public $show_ui = null; public $show_in_menu = null; public $show_in_nav_menus = null; public $show_in_admin_bar = null; public $menu_position = null; public $menu_icon = null; public $capability_type = 'post'; public $map_meta_cap = false; public $register_meta_box_cb = null; public $taxonomies = array(); public $has_archive = false; public $query_var; public $can_export = true; public $delete_with_user = null; public $template = array(); public $template_lock = false; public $_builtin = false; public $_edit_link = 'post.php?post=%d'; public $cap; public $rewrite; public $supports; public $show_in_rest; public $rest_base; public $rest_namespace; public $rest_controller_class; public $rest_controller; public $revisions_rest_controller_class; public $revisions_rest_controller; public $autosave_rest_controller_class; public $autosave_rest_controller; public $late_route_registration; public function __construct( $post_type, $args = array() ) { $this->name = $post_type; $this->set_props( $args ); } public function set_props( $args ) { $args = wp_parse_args( $args ); $args = apply_filters( 'register_post_type_args', $args, $this->name ); $post_type = $this->name; $args = apply_filters( "register_{$post_type}_post_type_args", $args, $this->name ); $has_edit_link = ! empty( $args['_edit_link'] ); $defaults = array( 'labels' => array(), 'description' => '', 'public' => false, 'hierarchical' => false, 'exclude_from_search' => null, 'publicly_queryable' => null, 'embeddable' => null, 'show_ui' => null, 'show_in_menu' => null, 'show_in_nav_menus' => null, 'show_in_admin_bar' => null, 'menu_position' => null, 'menu_icon' => null, 'capability_type' => 'post', 'capabilities' => array(), 'map_meta_cap' => null, 'supports' => array(), 'register_meta_box_cb' => null, 'taxonomies' => array(), 'has_archive' => false, 'rewrite' => true, 'query_var' => true, 'can_export' => true, 'delete_with_user' => null, 'show_in_rest' => false, 'rest_base' => false, 'rest_namespace' => false, 'rest_controller_class' => false, 'autosave_rest_controller_class' => false, 'revisions_rest_controller_class' => false, 'late_route_registration' => false, 'template' => array(), 'template_lock' => false, '_builtin' => false, '_edit_link' => 'post.php?post=%d', ); $args = array_merge( $defaults, $args ); $args['name'] = $this->name; if ( null === $args['publicly_queryable'] ) { $args['publicly_queryable'] = $args['public']; } if ( null === $args['show_ui'] ) { $args['show_ui'] = $args['public']; } if ( null === $args['embeddable'] ) { $args['embeddable'] = $args['public']; } if ( false === $args['rest_namespace'] && ! empty( $args['show_in_rest'] ) ) { $args['rest_namespace'] = 'wp/v2'; } if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { $args['show_in_menu'] = $args['show_ui']; } if ( null === $args['show_in_admin_bar'] ) { $args['show_in_admin_bar'] = (bool) $args['show_in_menu']; } if ( null === $args['show_in_nav_menus'] ) { $args['show_in_nav_menus'] = $args['public']; } if ( null === $args['exclude_from_search'] ) { $args['exclude_from_search'] = ! $args['public']; } if ( empty( $args['capabilities'] ) && null === $args['map_meta_cap'] && in_array( $args['capability_type'], array( 'post', 'page' ), true ) ) { $args['map_meta_cap'] = true; } if ( null === $args['map_meta_cap'] ) { $args['map_meta_cap'] = false; } if ( ! $args['show_ui'] && ! $has_edit_link ) { $args['_edit_link'] = ''; } $this->cap = get_post_type_capabilities( (object) $args ); unset( $args['capabilities'] ); if ( is_array( $args['capability_type'] ) ) { $args['capability_type'] = $args['capability_type'][0]; } if ( false !== $args['query_var'] ) { if ( true === $args['query_var'] ) { $args['query_var'] = $this->name; } else { $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] ); } } if ( false !== $args['rewrite'] && ( is_admin() || get_option( 'permalink_structure' ) ) ) { if ( ! is_array( $args['rewrite'] ) ) { $args['rewrite'] = array(); } if ( empty( $args['rewrite']['slug'] ) ) { $args['rewrite']['slug'] = $this->name; } if ( ! isset( $args['rewrite']['with_front'] ) ) { $args['rewrite']['with_front'] = true; } if ( ! isset( $args['rewrite']['pages'] ) ) { $args['rewrite']['pages'] = true; } if ( ! isset( $args['rewrite']['feeds'] ) || ! $args['has_archive'] ) { $args['rewrite']['feeds'] = (bool) $args['has_archive']; } if ( ! isset( $args['rewrite']['ep_mask'] ) ) { if ( isset( $args['permalink_epmask'] ) ) { $args['rewrite']['ep_mask'] = $args['permalink_epmask']; } else { $args['rewrite']['ep_mask'] = EP_PERMALINK; } } } foreach ( $args as $property_name => $property_value ) { $this->$property_name = $property_value; } $this->labels = get_post_type_labels( $this ); $this->label = $this->labels->name; } public function add_supports() { if ( ! empty( $this->supports ) ) { foreach ( $this->supports as $feature => $args ) { if ( is_array( $args ) ) { add_post_type_support( $this->name, $feature, $args ); } else { add_post_type_support( $this->name, $args ); } } unset( $this->supports ); if ( post_type_supports( $this->name, 'editor' ) && ! post_type_supports( $this->name, 'autosave' ) ) { add_post_type_support( $this->name, 'autosave' ); } } elseif ( false !== $this->supports ) { add_post_type_support( $this->name, array( 'title', 'editor', 'autosave' ) ); } } public function add_rewrite_rules() { global $wp_rewrite, $wp; if ( false !== $this->query_var && $wp && is_post_type_viewable( $this ) ) { $wp->add_query_var( $this->query_var ); } if ( false !== $this->rewrite && ( is_admin() || get_option( 'permalink_structure' ) ) ) { if ( $this->hierarchical ) { add_rewrite_tag( "%$this->name%", '(.+?)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&pagename=" ); } else { add_rewrite_tag( "%$this->name%", '([^/]+)', $this->query_var ? "{$this->query_var}=" : "post_type=$this->name&name=" ); } if ( $this->has_archive ) { $archive_slug = true === $this->has_archive ? $this->rewrite['slug'] : $this->has_archive; if ( $this->rewrite['with_front'] ) { $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; } else { $archive_slug = $wp_rewrite->root . $archive_slug; } add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$this->name", 'top' ); if ( $this->rewrite['feeds'] && $wp_rewrite->feeds ) { $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$this->name" . '&feed=$matches[1]', 'top' ); } if ( $this->rewrite['pages'] ) { add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$this->name" . '&paged=$matches[1]', 'top' ); } } $permastruct_args = $this->rewrite; $permastruct_args['feed'] = $permastruct_args['feeds']; add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $permastruct_args ); } } public function register_meta_boxes() { if ( $this->register_meta_box_cb ) { add_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10, 1 ); } } public function add_hooks() { add_action( 'future_' . $this->name, '_future_post_hook', 5, 2 ); } public function register_taxonomies() { foreach ( $this->taxonomies as $taxonomy ) { register_taxonomy_for_object_type( $taxonomy, $this->name ); } } public function remove_supports() { global $_wp_post_type_features; unset( $_wp_post_type_features[ $this->name ] ); } public function remove_rewrite_rules() { global $wp, $wp_rewrite, $post_type_meta_caps; if ( false !== $this->query_var ) { $wp->remove_query_var( $this->query_var ); } if ( false !== $this->rewrite ) { remove_rewrite_tag( "%$this->name%" ); remove_permastruct( $this->name ); foreach ( $wp_rewrite->extra_rules_top as $regex => $query ) { if ( str_contains( $query, "index.php?post_type=$this->name" ) ) { unset( $wp_rewrite->extra_rules_top[ $regex ] ); } } } foreach ( $this->cap as $cap ) { unset( $post_type_meta_caps[ $cap ] ); } } public function unregister_meta_boxes() { if ( $this->register_meta_box_cb ) { remove_action( 'add_meta_boxes_' . $this->name, $this->register_meta_box_cb, 10 ); } } public function unregister_taxonomies() { foreach ( get_object_taxonomies( $this->name ) as $taxonomy ) { unregister_taxonomy_for_object_type( $taxonomy, $this->name ); } } public function remove_hooks() { remove_action( 'future_' . $this->name, '_future_post_hook', 5 ); } public function get_rest_controller() { if ( ! $this->show_in_rest ) { return null; } $class = $this->rest_controller_class ? $this->rest_controller_class : WP_REST_Posts_Controller::class; if ( ! class_exists( $class ) ) { return null; } if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) { return null; } if ( ! $this->rest_controller ) { $this->rest_controller = new $class( $this->name ); } if ( ! ( $this->rest_controller instanceof $class ) ) { return null; } return $this->rest_controller; } public function get_revisions_rest_controller() { if ( ! $this->show_in_rest ) { return null; } if ( ! post_type_supports( $this->name, 'revisions' ) ) { return null; } $class = $this->revisions_rest_controller_class ? $this->revisions_rest_controller_class : WP_REST_Revisions_Controller::class; if ( ! class_exists( $class ) ) { return null; } if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) { return null; } if ( ! $this->revisions_rest_controller ) { $this->revisions_rest_controller = new $class( $this->name ); } if ( ! ( $this->revisions_rest_controller instanceof $class ) ) { return null; } return $this->revisions_rest_controller; } public function get_autosave_rest_controller() { if ( ! $this->show_in_rest ) { return null; } if ( ! post_type_supports( $this->name, 'autosave' ) ) { return null; } $class = $this->autosave_rest_controller_class ? $this->autosave_rest_controller_class : WP_REST_Autosaves_Controller::class; if ( ! class_exists( $class ) ) { return null; } if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) { return null; } if ( ! $this->autosave_rest_controller ) { $this->autosave_rest_controller = new $class( $this->name ); } if ( ! ( $this->autosave_rest_controller instanceof $class ) ) { return null; } return $this->autosave_rest_controller; } public static function get_default_labels() { if ( ! empty( self::$default_labels ) ) { return self::$default_labels; } self::$default_labels = array( 'name' => array( _x( 'Posts', 'post type general name' ), _x( 'Pages', 'post type general name' ) ), 'singular_name' => array( _x( 'Post', 'post type singular name' ), _x( 'Page', 'post type singular name' ) ), 'add_new' => array( __( 'Add' ), __( 'Add' ) ), 'add_new_item' => array( __( 'Add Post' ), __( 'Add Page' ) ), 'edit_item' => array( __( 'Edit Post' ), __( 'Edit Page' ) ), 'new_item' => array( __( 'New Post' ), __( 'New Page' ) ), 'view_item' => array( __( 'View Post' ), __( 'View Page' ) ), 'view_items' => array( __( 'View Posts' ), __( 'View Pages' ) ), 'search_items' => array( __( 'Search Posts' ), __( 'Search Pages' ) ), 'not_found' => array( __( 'No posts found.' ), __( 'No pages found.' ) ), 'not_found_in_trash' => array( __( 'No posts found in Trash.' ), __( 'No pages found in Trash.' ) ), 'parent_item_colon' => array( null, __( 'Parent Page:' ) ), 'all_items' => array( __( 'All Posts' ), __( 'All Pages' ) ), 'archives' => array( __( 'Post Archives' ), __( 'Page Archives' ) ), 'attributes' => array( __( 'Post Attributes' ), __( 'Page Attributes' ) ), 'insert_into_item' => array( __( 'Insert into post' ), __( 'Insert into page' ) ), 'uploaded_to_this_item' => array( __( 'Uploaded to this post' ), __( 'Uploaded to this page' ) ), 'featured_image' => array( _x( 'Featured image', 'post' ), _x( 'Featured image', 'page' ) ), 'set_featured_image' => array( _x( 'Set featured image', 'post' ), _x( 'Set featured image', 'page' ) ), 'remove_featured_image' => array( _x( 'Remove featured image', 'post' ), _x( 'Remove featured image', 'page' ) ), 'use_featured_image' => array( _x( 'Use as featured image', 'post' ), _x( 'Use as featured image', 'page' ) ), 'filter_items_list' => array( __( 'Filter posts list' ), __( 'Filter pages list' ) ), 'filter_by_date' => array( __( 'Filter by date' ), __( 'Filter by date' ) ), 'items_list_navigation' => array( __( 'Posts list navigation' ), __( 'Pages list navigation' ) ), 'items_list' => array( __( 'Posts list' ), __( 'Pages list' ) ), 'item_published' => array( __( 'Post published.' ), __( 'Page published.' ) ), 'item_published_privately' => array( __( 'Post published privately.' ), __( 'Page published privately.' ) ), 'item_reverted_to_draft' => array( __( 'Post reverted to draft.' ), __( 'Page reverted to draft.' ) ), 'item_trashed' => array( __( 'Post trashed.' ), __( 'Page trashed.' ) ), 'item_scheduled' => array( __( 'Post scheduled.' ), __( 'Page scheduled.' ) ), 'item_updated' => array( __( 'Post updated.' ), __( 'Page updated.' ) ), 'item_link' => array( _x( 'Post Link', 'navigation link block title' ), _x( 'Page Link', 'navigation link block title' ), ), 'item_link_description' => array( _x( 'A link to a post.', 'navigation link block description' ), _x( 'A link to a page.', 'navigation link block description' ), ), ); return self::$default_labels; } public static function reset_default_labels() { self::$default_labels = array(); } }
###require ABSPATH . WPINC . '/class-wp-post.php';
final class WP_Post { public $ID; public $post_author = '0'; public $post_date = '0000-00-00 00:00:00'; public $post_date_gmt = '0000-00-00 00:00:00'; public $post_content = ''; public $post_title = ''; public $post_excerpt = ''; public $post_status = 'publish'; public $comment_status = 'open'; public $ping_status = 'open'; public $post_password = ''; public $post_name = ''; public $to_ping = ''; public $pinged = ''; public $post_modified = '0000-00-00 00:00:00'; public $post_modified_gmt = '0000-00-00 00:00:00'; public $post_content_filtered = ''; public $post_parent = 0; public $guid = ''; public $menu_order = 0; public $post_type = 'post'; public $post_mime_type = ''; public $comment_count = '0'; public $filter; public static function get_instance( $post_id ) { global $wpdb; $post_id = (int) $post_id; if ( $post_id <= 0 ) { return false; } $_post = wp_cache_get( $post_id, 'posts' ); if ( ! $_post ) { $_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id ) ); if ( ! $_post ) { return false; } $_post = sanitize_post( $_post, 'raw' ); wp_cache_add( $_post->ID, $_post, 'posts' ); } elseif ( empty( $_post->filter ) || 'raw' !== $_post->filter ) { $_post = sanitize_post( $_post, 'raw' ); } return new WP_Post( $_post ); } public function __construct( $post ) { foreach ( get_object_vars( $post ) as $key => $value ) { $this->$key = $value; } } public function __isset( $key ) { if ( 'ancestors' === $key ) { return true; } if ( 'page_template' === $key ) { return true; } if ( 'post_category' === $key ) { return true; } if ( 'tags_input' === $key ) { return true; } return metadata_exists( 'post', $this->ID, $key ); } public function __get( $key ) { if ( 'page_template' === $key && $this->__isset( $key ) ) { return get_post_meta( $this->ID, '_wp_page_template', true ); } if ( 'post_category' === $key ) { if ( is_object_in_taxonomy( $this->post_type, 'category' ) ) { $terms = get_the_terms( $this, 'category' ); } if ( empty( $terms ) ) { return array(); } return wp_list_pluck( $terms, 'term_id' ); } if ( 'tags_input' === $key ) { if ( is_object_in_taxonomy( $this->post_type, 'post_tag' ) ) { $terms = get_the_terms( $this, 'post_tag' ); } if ( empty( $terms ) ) { return array(); } return wp_list_pluck( $terms, 'name' ); } if ( 'ancestors' === $key ) { $value = get_post_ancestors( $this ); } else { $value = get_post_meta( $this->ID, $key, true ); } if ( $this->filter ) { $value = sanitize_post_field( $key, $value, $this->ID, $this->filter ); } return $value; } public function filter( $filter ) { if ( $this->filter === $filter ) { return $this; } if ( 'raw' === $filter ) { return self::get_instance( $this->ID ); } return sanitize_post( $this, $filter ); } public function to_array() { $post = get_object_vars( $this ); foreach ( array( 'ancestors', 'page_template', 'post_category', 'tags_input' ) as $key ) { if ( $this->__isset( $key ) ) { $post[ $key ] = $this->__get( $key ); } } return $post; } }
###require ABSPATH . WPINC . '/post-template.php';
function the_ID() { echo get_the_ID(); } function get_the_ID() { $post = get_post(); return ! empty( $post ) ? $post->ID : false; } function the_title( $before = '', $after = '', $display = true ) { $title = get_the_title(); if ( strlen( $title ) === 0 ) { return; } $title = $before . $title . $after; if ( $display ) { echo $title; } else { return $title; } } function the_title_attribute( $args = '' ) { $defaults = array( 'before' => '', 'after' => '', 'echo' => true, 'post' => get_post(), ); $parsed_args = wp_parse_args( $args, $defaults ); $title = get_the_title( $parsed_args['post'] ); if ( strlen( $title ) === 0 ) { return; } $title = $parsed_args['before'] . $title . $parsed_args['after']; $title = esc_attr( strip_tags( $title ) ); if ( $parsed_args['echo'] ) { echo $title; } else { return $title; } } function get_the_title( $post = 0 ) { $post = get_post( $post ); $post_title = isset( $post->post_title ) ? $post->post_title : ''; $post_id = isset( $post->ID ) ? $post->ID : 0; if ( ! is_admin() ) { if ( ! empty( $post->post_password ) ) { $prepend = __( 'Protected: %s' ); $protected_title_format = apply_filters( 'protected_title_format', $prepend, $post ); $post_title = sprintf( $protected_title_format, $post_title ); } elseif ( isset( $post->post_status ) && 'private' === $post->post_status ) { $prepend = __( 'Private: %s' ); $private_title_format = apply_filters( 'private_title_format', $prepend, $post ); $post_title = sprintf( $private_title_format, $post_title ); } } return apply_filters( 'the_title', $post_title, $post_id ); } function the_guid( $post = 0 ) { $post = get_post( $post ); $post_guid = isset( $post->guid ) ? get_the_guid( $post ) : ''; $post_id = isset( $post->ID ) ? $post->ID : 0; echo apply_filters( 'the_guid', $post_guid, $post_id ); } function get_the_guid( $post = 0 ) { $post = get_post( $post ); $post_guid = isset( $post->guid ) ? $post->guid : ''; $post_id = isset( $post->ID ) ? $post->ID : 0; return apply_filters( 'get_the_guid', $post_guid, $post_id ); } function the_content( $more_link_text = null, $strip_teaser = false ) { $content = get_the_content( $more_link_text, $strip_teaser ); $content = apply_filters( 'the_content', $content ); $content = str_replace( ']]>', ']]>', $content ); echo $content; } function get_the_content( $more_link_text = null, $strip_teaser = false, $post = null ) { global $page, $more, $preview, $pages, $multipage; $_post = get_post( $post ); if ( ! ( $_post instanceof WP_Post ) ) { return ''; } if ( null === $post && did_action( 'the_post' ) ) { $elements = compact( 'page', 'more', 'preview', 'pages', 'multipage' ); } else { $elements = generate_postdata( $_post ); } if ( null === $more_link_text ) { $more_link_text = sprintf( '<span aria-label="%1$s">%2$s</span>', sprintf( __( 'Continue reading %s' ), the_title_attribute( array( 'echo' => false, 'post' => $_post, ) ) ), __( '(more…)' ) ); } $output = ''; $has_teaser = false; if ( post_password_required( $_post ) ) { return get_the_password_form( $_post ); } if ( $elements['page'] > count( $elements['pages'] ) ) { $elements['page'] = count( $elements['pages'] ); } $page_no = $elements['page']; $content = $elements['pages'][ $page_no - 1 ]; if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) { if ( has_block( 'more', $content ) ) { $content = preg_replace( '/<!-- \/?wp:more(.*?) -->/', '', $content ); } $content = explode( $matches[0], $content, 2 ); if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) ) { $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) ); } $has_teaser = true; } else { $content = array( $content ); } if ( str_contains( $_post->post_content, '<!--noteaser-->' ) && ( ! $elements['multipage'] || 1 === $elements['page'] ) ) { $strip_teaser = true; } $teaser = $content[0]; if ( $elements['more'] && $strip_teaser && $has_teaser ) { $teaser = ''; } $output .= $teaser; if ( count( $content ) > 1 ) { if ( $elements['more'] ) { $output .= '<span id="more-' . $_post->ID . '"></span>' . $content[1]; } else { if ( ! empty( $more_link_text ) ) { $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink( $_post ) . "#more-{$_post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text ); } $output = force_balance_tags( $output ); } } return $output; } function the_excerpt() { echo apply_filters( 'the_excerpt', get_the_excerpt() ); } function get_the_excerpt( $post = null ) { if ( is_bool( $post ) ) { _deprecated_argument( __FUNCTION__, '2.3.0' ); } $post = get_post( $post ); if ( empty( $post ) ) { return ''; } if ( post_password_required( $post ) ) { return __( 'There is no excerpt because this is a protected post.' ); } return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); } function has_excerpt( $post = 0 ) { $post = get_post( $post ); return ( ! empty( $post->post_excerpt ) ); } function post_class( $css_class = '', $post = null ) { echo 'class="' . esc_attr( implode( ' ', get_post_class( $css_class, $post ) ) ) . '"'; } function get_post_class( $css_class = '', $post = null ) { $post = get_post( $post ); $classes = array(); if ( $css_class ) { if ( ! is_array( $css_class ) ) { $css_class = preg_split( '#\s+#', $css_class ); } $classes = array_map( 'esc_attr', $css_class ); } else { $css_class = array(); } if ( ! $post ) { return $classes; } $classes[] = 'post-' . $post->ID; if ( ! is_admin() ) { $classes[] = $post->post_type; } $classes[] = 'type-' . $post->post_type; $classes[] = 'status-' . $post->post_status; if ( post_type_supports( $post->post_type, 'post-formats' ) ) { $post_format = get_post_format( $post->ID ); if ( $post_format && ! is_wp_error( $post_format ) ) { $classes[] = 'format-' . sanitize_html_class( $post_format ); } else { $classes[] = 'format-standard'; } } $post_password_required = post_password_required( $post->ID ); if ( $post_password_required ) { $classes[] = 'post-password-required'; } elseif ( ! empty( $post->post_password ) ) { $classes[] = 'post-password-protected'; } if ( current_theme_supports( 'post-thumbnails' ) && has_post_thumbnail( $post->ID ) && ! is_attachment( $post ) && ! $post_password_required ) { $classes[] = 'has-post-thumbnail'; } if ( is_sticky( $post->ID ) ) { if ( is_home() && ! is_paged() ) { $classes[] = 'sticky'; } elseif ( is_admin() ) { $classes[] = 'status-sticky'; } } $classes[] = 'hentry'; $taxonomies = get_taxonomies( array( 'public' => true ) ); $taxonomies = apply_filters( 'post_class_taxonomies', $taxonomies, $post->ID, $classes, $css_class ); foreach ( (array) $taxonomies as $taxonomy ) { if ( is_object_in_taxonomy( $post->post_type, $taxonomy ) ) { foreach ( (array) get_the_terms( $post->ID, $taxonomy ) as $term ) { if ( empty( $term->slug ) ) { continue; } $term_class = sanitize_html_class( $term->slug, $term->term_id ); if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) { $term_class = $term->term_id; } if ( 'post_tag' === $taxonomy ) { $classes[] = 'tag-' . $term_class; } else { $classes[] = sanitize_html_class( $taxonomy . '-' . $term_class, $taxonomy . '-' . $term->term_id ); } } } } $classes = array_map( 'esc_attr', $classes ); $classes = apply_filters( 'post_class', $classes, $css_class, $post->ID ); return array_unique( $classes ); } function body_class( $css_class = '' ) { echo 'class="' . esc_attr( implode( ' ', get_body_class( $css_class ) ) ) . '"'; } function get_body_class( $css_class = '' ) { global $wp_query; $classes = array(); if ( is_rtl() ) { $classes[] = 'rtl'; } if ( is_front_page() ) { $classes[] = 'home'; } if ( is_home() ) { $classes[] = 'blog'; } if ( is_privacy_policy() ) { $classes[] = 'privacy-policy'; } if ( is_archive() ) { $classes[] = 'archive'; } if ( is_date() ) { $classes[] = 'date'; } if ( is_search() ) { $classes[] = 'search'; $classes[] = $wp_query->posts ? 'search-results' : 'search-no-results'; } if ( is_paged() ) { $classes[] = 'paged'; } if ( is_attachment() ) { $classes[] = 'attachment'; } if ( is_404() ) { $classes[] = 'error404'; } if ( is_singular() ) { $post = $wp_query->get_queried_object(); $post_id = $post->ID; $post_type = $post->post_type; $classes[] = 'wp-singular'; if ( is_page_template() ) { $classes[] = "{$post_type}-template"; $template_slug = get_page_template_slug( $post_id ); $template_parts = explode( '/', $template_slug ); foreach ( $template_parts as $part ) { $classes[] = "{$post_type}-template-" . sanitize_html_class( str_replace( array( '.', '/' ), '-', basename( $part, '.php' ) ) ); } $classes[] = "{$post_type}-template-" . sanitize_html_class( str_replace( '.', '-', $template_slug ) ); } else { $classes[] = "{$post_type}-template-default"; } if ( is_single() ) { $classes[] = 'single'; if ( isset( $post->post_type ) ) { $classes[] = 'single-' . sanitize_html_class( $post->post_type, $post_id ); $classes[] = 'postid-' . $post_id; if ( post_type_supports( $post->post_type, 'post-formats' ) ) { $post_format = get_post_format( $post->ID ); if ( $post_format && ! is_wp_error( $post_format ) ) { $classes[] = 'single-format-' . sanitize_html_class( $post_format ); } else { $classes[] = 'single-format-standard'; } } } } if ( is_attachment() ) { $mime_type = get_post_mime_type( $post_id ); $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' ); $classes[] = 'attachmentid-' . $post_id; $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type ); } elseif ( is_page() ) { $classes[] = 'page'; $classes[] = 'page-id-' . $post_id; if ( get_pages( array( 'parent' => $post_id, 'number' => 1, ) ) ) { $classes[] = 'page-parent'; } if ( $post->post_parent ) { $classes[] = 'page-child'; $classes[] = 'parent-pageid-' . $post->post_parent; } } } elseif ( is_archive() ) { if ( is_post_type_archive() ) { $classes[] = 'post-type-archive'; $post_type = get_query_var( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $classes[] = 'post-type-archive-' . sanitize_html_class( $post_type ); } elseif ( is_author() ) { $author = $wp_query->get_queried_object(); $classes[] = 'author'; if ( isset( $author->user_nicename ) ) { $classes[] = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID ); $classes[] = 'author-' . $author->ID; } } elseif ( is_category() ) { $cat = $wp_query->get_queried_object(); $classes[] = 'category'; if ( isset( $cat->term_id ) ) { $cat_class = sanitize_html_class( $cat->slug, $cat->term_id ); if ( is_numeric( $cat_class ) || ! trim( $cat_class, '-' ) ) { $cat_class = $cat->term_id; } $classes[] = 'category-' . $cat_class; $classes[] = 'category-' . $cat->term_id; } } elseif ( is_tag() ) { $tag = $wp_query->get_queried_object(); $classes[] = 'tag'; if ( isset( $tag->term_id ) ) { $tag_class = sanitize_html_class( $tag->slug, $tag->term_id ); if ( is_numeric( $tag_class ) || ! trim( $tag_class, '-' ) ) { $tag_class = $tag->term_id; } $classes[] = 'tag-' . $tag_class; $classes[] = 'tag-' . $tag->term_id; } } elseif ( is_tax() ) { $term = $wp_query->get_queried_object(); if ( isset( $term->term_id ) ) { $term_class = sanitize_html_class( $term->slug, $term->term_id ); if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) { $term_class = $term->term_id; } $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy ); $classes[] = 'term-' . $term_class; $classes[] = 'term-' . $term->term_id; } } } if ( is_user_logged_in() ) { $classes[] = 'logged-in'; } if ( is_admin_bar_showing() ) { $classes[] = 'admin-bar'; $classes[] = 'no-customize-support'; } if ( current_theme_supports( 'custom-background' ) && ( get_background_color() !== get_theme_support( 'custom-background', 'default-color' ) || get_background_image() ) ) { $classes[] = 'custom-background'; } if ( has_custom_logo() ) { $classes[] = 'wp-custom-logo'; } if ( current_theme_supports( 'responsive-embeds' ) ) { $classes[] = 'wp-embed-responsive'; } $page = $wp_query->get( 'page' ); if ( ! $page || $page < 2 ) { $page = $wp_query->get( 'paged' ); } if ( $page && $page > 1 && ! is_404() ) { $classes[] = 'paged-' . $page; if ( is_single() ) { $classes[] = 'single-paged-' . $page; } elseif ( is_page() ) { $classes[] = 'page-paged-' . $page; } elseif ( is_category() ) { $classes[] = 'category-paged-' . $page; } elseif ( is_tag() ) { $classes[] = 'tag-paged-' . $page; } elseif ( is_date() ) { $classes[] = 'date-paged-' . $page; } elseif ( is_author() ) { $classes[] = 'author-paged-' . $page; } elseif ( is_search() ) { $classes[] = 'search-paged-' . $page; } elseif ( is_post_type_archive() ) { $classes[] = 'post-type-paged-' . $page; } } $classes[] = 'wp-theme-' . sanitize_html_class( get_template() ); if ( is_child_theme() ) { $classes[] = 'wp-child-theme-' . sanitize_html_class( get_stylesheet() ); } if ( ! empty( $css_class ) ) { if ( ! is_array( $css_class ) ) { $css_class = preg_split( '#\s+#', $css_class ); } $classes = array_merge( $classes, $css_class ); } else { $css_class = array(); } $classes = array_map( 'esc_attr', $classes ); $classes = apply_filters( 'body_class', $classes, $css_class ); return array_unique( $classes ); } function post_password_required( $post = null ) { $post = get_post( $post ); if ( empty( $post->post_password ) ) { return apply_filters( 'post_password_required', false, $post ); } if ( ! isset( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) ) { return apply_filters( 'post_password_required', true, $post ); } require_once ABSPATH . WPINC . '/class-phpass.php'; $hasher = new PasswordHash( 8, true ); $hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ); if ( ! str_starts_with( $hash, '$P$B' ) ) { $required = true; } else { $required = ! $hasher->CheckPassword( $post->post_password, $hash ); } return apply_filters( 'post_password_required', $required, $post ); } function wp_link_pages( $args = '' ) { global $page, $numpages, $multipage, $more; $defaults = array( 'before' => '<p class="post-nav-links">' . __( 'Pages:' ), 'after' => '</p>', 'link_before' => '', 'link_after' => '', 'aria_current' => 'page', 'next_or_number' => 'number', 'separator' => ' ', 'nextpagelink' => __( 'Next page' ), 'previouspagelink' => __( 'Previous page' ), 'pagelink' => '%', 'echo' => 1, ); $parsed_args = wp_parse_args( $args, $defaults ); $parsed_args = apply_filters( 'wp_link_pages_args', $parsed_args ); $output = ''; if ( $multipage ) { if ( 'number' === $parsed_args['next_or_number'] ) { $output .= $parsed_args['before']; for ( $i = 1; $i <= $numpages; $i++ ) { $link = $parsed_args['link_before'] . str_replace( '%', $i, $parsed_args['pagelink'] ) . $parsed_args['link_after']; if ( $i !== $page || ! $more && 1 === $page ) { $link = _wp_link_page( $i ) . $link . '</a>'; } elseif ( $i === $page ) { $link = '<span class="post-page-numbers current" aria-current="' . esc_attr( $parsed_args['aria_current'] ) . '">' . $link . '</span>'; } $link = apply_filters( 'wp_link_pages_link', $link, $i ); $output .= ( 1 === $i ) ? ' ' : $parsed_args['separator']; $output .= $link; } $output .= $parsed_args['after']; } elseif ( $more ) { $output .= $parsed_args['before']; $prev = $page - 1; if ( $prev > 0 ) { $link = _wp_link_page( $prev ) . $parsed_args['link_before'] . $parsed_args['previouspagelink'] . $parsed_args['link_after'] . '</a>'; $output .= apply_filters( 'wp_link_pages_link', $link, $prev ); } $next = $page + 1; if ( $next <= $numpages ) { if ( $prev ) { $output .= $parsed_args['separator']; } $link = _wp_link_page( $next ) . $parsed_args['link_before'] . $parsed_args['nextpagelink'] . $parsed_args['link_after'] . '</a>'; $output .= apply_filters( 'wp_link_pages_link', $link, $next ); } $output .= $parsed_args['after']; } } $html = apply_filters( 'wp_link_pages', $output, $args ); if ( $parsed_args['echo'] ) { echo $html; } return $html; } function _wp_link_page( $i ) { global $wp_rewrite; $post = get_post(); $query_args = array(); if ( 1 === $i ) { $url = get_permalink(); } else { if ( ! get_option( 'permalink_structure' ) || in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) { $url = add_query_arg( 'page', $i, get_permalink() ); } elseif ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID ) { $url = trailingslashit( get_permalink() ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . $i, 'single_paged' ); } else { $url = trailingslashit( get_permalink() ) . user_trailingslashit( $i, 'single_paged' ); } } if ( is_preview() ) { if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) { $query_args['preview_id'] = wp_unslash( $_GET['preview_id'] ); $query_args['preview_nonce'] = wp_unslash( $_GET['preview_nonce'] ); } $url = get_preview_post_link( $post, $query_args, $url ); } return '<a href="' . esc_url( $url ) . '" class="post-page-numbers">'; } function post_custom( $key = '' ) { $custom = get_post_custom(); if ( ! isset( $custom[ $key ] ) ) { return false; } elseif ( 1 === count( $custom[ $key ] ) ) { return $custom[ $key ][0]; } else { return $custom[ $key ]; } } function the_meta() { _deprecated_function( __FUNCTION__, '6.0.2', 'get_post_meta()' ); $keys = get_post_custom_keys(); if ( $keys ) { $li_html = ''; foreach ( (array) $keys as $key ) { $keyt = trim( $key ); if ( is_protected_meta( $keyt, 'post' ) ) { continue; } $values = array_map( 'trim', get_post_custom_values( $key ) ); $value = implode( ', ', $values ); $html = sprintf( "<li><span class='post-meta-key'>%s</span> %s</li>\n", esc_html( sprintf( _x( '%s:', 'Post custom field name' ), $key ) ), esc_html( $value ) ); $li_html .= apply_filters( 'the_meta_key', $html, $key, $value ); } if ( $li_html ) { echo "<ul class='post-meta'>\n{$li_html}</ul>\n"; } } } function wp_dropdown_pages( $args = '' ) { $defaults = array( 'depth' => 0, 'child_of' => 0, 'selected' => 0, 'echo' => 1, 'name' => 'page_id', 'id' => '', 'class' => '', 'show_option_none' => '', 'show_option_no_change' => '', 'option_none_value' => '', 'value_field' => 'ID', ); $parsed_args = wp_parse_args( $args, $defaults ); $pages = get_pages( $parsed_args ); $output = ''; if ( empty( $parsed_args['id'] ) ) { $parsed_args['id'] = $parsed_args['name']; } if ( ! empty( $pages ) ) { $class = ''; if ( ! empty( $parsed_args['class'] ) ) { $class = " class='" . esc_attr( $parsed_args['class'] ) . "'"; } $output = "<select name='" . esc_attr( $parsed_args['name'] ) . "'" . $class . " id='" . esc_attr( $parsed_args['id'] ) . "'>\n"; if ( $parsed_args['show_option_no_change'] ) { $output .= "\t<option value=\"-1\">" . $parsed_args['show_option_no_change'] . "</option>\n"; } if ( $parsed_args['show_option_none'] ) { $output .= "\t<option value=\"" . esc_attr( $parsed_args['option_none_value'] ) . '">' . $parsed_args['show_option_none'] . "</option>\n"; } $output .= walk_page_dropdown_tree( $pages, $parsed_args['depth'], $parsed_args ); $output .= "</select>\n"; } $html = apply_filters( 'wp_dropdown_pages', $output, $parsed_args, $pages ); if ( $parsed_args['echo'] ) { echo $html; } return $html; } function wp_list_pages( $args = '' ) { $defaults = array( 'depth' => 0, 'show_date' => '', 'date_format' => get_option( 'date_format' ), 'child_of' => 0, 'exclude' => '', 'title_li' => __( 'Pages' ), 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order, post_title', 'link_before' => '', 'link_after' => '', 'item_spacing' => 'preserve', 'walker' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); if ( ! in_array( $parsed_args['item_spacing'], array( 'preserve', 'discard' ), true ) ) { $parsed_args['item_spacing'] = $defaults['item_spacing']; } $output = ''; $current_page = 0; $parsed_args['exclude'] = preg_replace( '/[^0-9,]/', '', $parsed_args['exclude'] ); $exclude_array = ( $parsed_args['exclude'] ) ? explode( ',', $parsed_args['exclude'] ) : array(); $parsed_args['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) ); $parsed_args['hierarchical'] = 0; $pages = get_pages( $parsed_args ); if ( ! empty( $pages ) ) { if ( $parsed_args['title_li'] ) { $output .= '<li class="pagenav">' . $parsed_args['title_li'] . '<ul>'; } global $wp_query; if ( is_page() || is_attachment() || $wp_query->is_posts_page ) { $current_page = get_queried_object_id(); } elseif ( is_singular() ) { $queried_object = get_queried_object(); if ( is_post_type_hierarchical( $queried_object->post_type ) ) { $current_page = $queried_object->ID; } } $output .= walk_page_tree( $pages, $parsed_args['depth'], $current_page, $parsed_args ); if ( $parsed_args['title_li'] ) { $output .= '</ul></li>'; } } $html = apply_filters( 'wp_list_pages', $output, $parsed_args, $pages ); if ( $parsed_args['echo'] ) { echo $html; } else { return $html; } } function wp_page_menu( $args = array() ) { $defaults = array( 'sort_column' => 'menu_order, post_title', 'menu_id' => '', 'menu_class' => 'menu', 'container' => 'div', 'echo' => true, 'link_before' => '', 'link_after' => '', 'before' => '<ul>', 'after' => '</ul>', 'item_spacing' => 'discard', 'walker' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ), true ) ) { $args['item_spacing'] = $defaults['item_spacing']; } if ( 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $args = apply_filters( 'wp_page_menu_args', $args ); $menu = ''; $list_args = $args; if ( ! empty( $args['show_home'] ) ) { if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] ) { $text = __( 'Home' ); } else { $text = $args['show_home']; } $class = ''; if ( is_front_page() && ! is_paged() ) { $class = 'class="current_page_item"'; } $menu .= '<li ' . $class . '><a href="' . esc_url( home_url( '/' ) ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>'; if ( 'page' === get_option( 'show_on_front' ) ) { if ( ! empty( $list_args['exclude'] ) ) { $list_args['exclude'] .= ','; } else { $list_args['exclude'] = ''; } $list_args['exclude'] .= get_option( 'page_on_front' ); } } $list_args['echo'] = false; $list_args['title_li'] = ''; $menu .= wp_list_pages( $list_args ); $container = sanitize_text_field( $args['container'] ); if ( empty( $container ) ) { $container = 'div'; } if ( $menu ) { if ( isset( $args['fallback_cb'] ) && 'wp_page_menu' === $args['fallback_cb'] && 'ul' !== $container ) { $args['before'] = "<ul>{$n}"; $args['after'] = '</ul>'; } $menu = $args['before'] . $menu . $args['after']; } $attrs = ''; if ( ! empty( $args['menu_id'] ) ) { $attrs .= ' id="' . esc_attr( $args['menu_id'] ) . '"'; } if ( ! empty( $args['menu_class'] ) ) { $attrs .= ' class="' . esc_attr( $args['menu_class'] ) . '"'; } $menu = "<{$container}{$attrs}>" . $menu . "</{$container}>{$n}"; $menu = apply_filters( 'wp_page_menu', $menu, $args ); if ( $args['echo'] ) { echo $menu; } else { return $menu; } } function walk_page_tree( $pages, $depth, $current_page, $args ) { if ( empty( $args['walker'] ) ) { $walker = new Walker_Page(); } else { $walker = $args['walker']; } foreach ( (array) $pages as $page ) { if ( $page->post_parent ) { $args['pages_with_children'][ $page->post_parent ] = true; } } return $walker->walk( $pages, $depth, $args, $current_page ); } function walk_page_dropdown_tree( ...$args ) { if ( empty( $args[2]['walker'] ) ) { $walker = new Walker_PageDropdown(); } else { $walker = $args[2]['walker']; } return $walker->walk( ...$args ); } function the_attachment_link( $post = 0, $fullsize = false, $deprecated = false, $permalink = false ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.5.0' ); } if ( $fullsize ) { echo wp_get_attachment_link( $post, 'full', $permalink ); } else { echo wp_get_attachment_link( $post, 'thumbnail', $permalink ); } } function wp_get_attachment_link( $post = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) { $_post = get_post( $post ); if ( empty( $_post ) || ( 'attachment' !== $_post->post_type ) || ! wp_get_attachment_url( $_post->ID ) ) { return __( 'Missing Attachment' ); } $url = wp_get_attachment_url( $_post->ID ); if ( $permalink ) { $url = get_attachment_link( $_post->ID ); } if ( $text ) { $link_text = $text; } elseif ( $size && 'none' !== $size ) { $link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr ); } else { $link_text = ''; } if ( '' === trim( $link_text ) ) { $link_text = $_post->post_title; } if ( '' === trim( $link_text ) ) { $link_text = esc_html( pathinfo( get_attached_file( $_post->ID ), PATHINFO_FILENAME ) ); } $attributes = apply_filters( 'wp_get_attachment_link_attributes', array( 'href' => $url ), $_post->ID ); $link_attributes = ''; foreach ( $attributes as $name => $value ) { $value = 'href' === $name ? esc_url( $value ) : esc_attr( $value ); $link_attributes .= ' ' . esc_attr( $name ) . "='" . $value . "'"; } $link_html = "<a$link_attributes>$link_text</a>"; return apply_filters( 'wp_get_attachment_link', $link_html, $post, $size, $permalink, $icon, $text, $attr ); } function prepend_attachment( $content ) { $post = get_post(); if ( empty( $post->post_type ) || 'attachment' !== $post->post_type ) { return $content; } if ( wp_attachment_is( 'video', $post ) ) { $meta = wp_get_attachment_metadata( get_the_ID() ); $atts = array( 'src' => wp_get_attachment_url() ); if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $atts['width'] = (int) $meta['width']; $atts['height'] = (int) $meta['height']; } if ( has_post_thumbnail() ) { $atts['poster'] = wp_get_attachment_url( get_post_thumbnail_id() ); } $p = wp_video_shortcode( $atts ); } elseif ( wp_attachment_is( 'audio', $post ) ) { $p = wp_audio_shortcode( array( 'src' => wp_get_attachment_url() ) ); } else { $p = '<p class="attachment">'; $p .= wp_get_attachment_link( 0, 'medium', false ); $p .= '</p>'; } $p = apply_filters( 'prepend_attachment', $p ); return "$p\n$content"; } function get_the_password_form( $post = 0 ) { $post = get_post( $post ); $field_id = 'pwbox-' . ( empty( $post->ID ) ? wp_rand() : $post->ID ); $invalid_password = ''; $invalid_password_html = ''; $aria = ''; $class = ''; $redirect_field = ''; if ( ! empty( $post->ID ) && wp_get_raw_referer() === get_permalink( $post->ID ) && isset( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) ) { $invalid_password = apply_filters( 'the_password_form_incorrect_password', __( 'Invalid password.' ), $post ); $invalid_password_html = '<div class="post-password-form-invalid-password" role="alert"><p id="error-' . $field_id . '">' . $invalid_password . '</p></div>'; $aria = ' aria-describedby="error-' . $field_id . '"'; $class = ' password-form-error'; } if ( ! empty( $post->ID ) ) { $redirect_field = sprintf( '<input type="hidden" name="redirect_to" value="%s" />', esc_attr( get_permalink( $post->ID ) ) ); } $output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form' . $class . '" method="post">' . $redirect_field . $invalid_password_html . '
<p>' . __( 'This content is password-protected. To view it, please enter the password below.' ) . '</p>
<p><label for="' . $field_id . '">' . __( 'Password:' ) . ' <input name="post_password" id="' . $field_id . '" type="password" spellcheck="false" required size="20"' . $aria . ' /></label> <input type="submit" name="Submit" value="' . esc_attr_x( 'Enter', 'post password form' ) . '" /></p></form>
'; return apply_filters( 'the_password_form', $output, $post, $invalid_password ); } function is_page_template( $template = '' ) { if ( ! is_singular() ) { return false; } $page_template = get_page_template_slug( get_queried_object_id() ); if ( empty( $template ) ) { return (bool) $page_template; } if ( $template === $page_template ) { return true; } if ( is_array( $template ) ) { if ( ( in_array( 'default', $template, true ) && ! $page_template ) || in_array( $page_template, $template, true ) ) { return true; } } return ( 'default' === $template && ! $page_template ); } function get_page_template_slug( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $template = get_post_meta( $post->ID, '_wp_page_template', true ); if ( ! $template || 'default' === $template ) { return ''; } return $template; } function wp_post_revision_title( $revision, $link = true ) { $revision = get_post( $revision ); if ( ! $revision ) { return $revision; } if ( ! in_array( $revision->post_type, array( 'post', 'page', 'revision' ), true ) ) { return false; } $datef = _x( 'F j, Y @ H:i:s', 'revision date format' ); $autosavef = __( '%s [Autosave]' ); $currentf = __( '%s [Current Revision]' ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); $edit_link = get_edit_post_link( $revision->ID ); if ( $link && current_user_can( 'edit_post', $revision->ID ) && $edit_link ) { $date = "<a href='$edit_link'>$date</a>"; } if ( ! wp_is_post_revision( $revision ) ) { $date = sprintf( $currentf, $date ); } elseif ( wp_is_post_autosave( $revision ) ) { $date = sprintf( $autosavef, $date ); } return $date; } function wp_post_revision_title_expanded( $revision, $link = true ) { $revision = get_post( $revision ); if ( ! $revision ) { return $revision; } if ( ! in_array( $revision->post_type, array( 'post', 'page', 'revision' ), true ) ) { return false; } $author = get_the_author_meta( 'display_name', $revision->post_author ); $datef = _x( 'F j, Y @ H:i:s', 'revision date format' ); $gravatar = get_avatar( $revision->post_author, 24 ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); $edit_link = get_edit_post_link( $revision->ID ); if ( $link && current_user_can( 'edit_post', $revision->ID ) && $edit_link ) { $date = "<a href='$edit_link'>$date</a>"; } $revision_date_author = sprintf( __( '%1$s %2$s, %3$s ago (%4$s)' ), $gravatar, $author, human_time_diff( strtotime( $revision->post_modified_gmt ) ), $date ); $autosavef = __( '%s [Autosave]' ); $currentf = __( '%s [Current Revision]' ); if ( ! wp_is_post_revision( $revision ) ) { $revision_date_author = sprintf( $currentf, $revision_date_author ); } elseif ( wp_is_post_autosave( $revision ) ) { $revision_date_author = sprintf( $autosavef, $revision_date_author ); } return apply_filters( 'wp_post_revision_title_expanded', $revision_date_author, $revision, $link ); } function wp_list_post_revisions( $post = 0, $type = 'all' ) { $post = get_post( $post ); if ( ! $post ) { return; } if ( is_array( $type ) ) { $type = ! empty( $type['type'] ) ? $type['type'] : $type; _deprecated_argument( __FUNCTION__, '3.6.0' ); } $revisions = wp_get_post_revisions( $post->ID ); if ( ! $revisions ) { return; } $rows = ''; foreach ( $revisions as $revision ) { if ( ! current_user_can( 'read_post', $revision->ID ) ) { continue; } $is_autosave = wp_is_post_autosave( $revision ); if ( ( 'revision' === $type && $is_autosave ) || ( 'autosave' === $type && ! $is_autosave ) ) { continue; } $rows .= "\t<li>" . wp_post_revision_title_expanded( $revision ) . "</li>\n"; } echo "<div class='hide-if-js'><p>" . __( 'JavaScript must be enabled to use this feature.' ) . "</p></div>\n"; echo "<ul class='post-revisions hide-if-no-js'>\n"; echo $rows; echo '</ul>'; } function get_post_parent( $post = null ) { $wp_post = get_post( $post ); return ! empty( $wp_post->post_parent ) ? get_post( $wp_post->post_parent ) : null; } function has_post_parent( $post = null ) { return (bool) get_post_parent( $post ); }
###require ABSPATH . WPINC . '/revision.php';
function _wp_post_revision_fields( $post = array(), $deprecated = false ) { static $fields = null; if ( ! is_array( $post ) ) { $post = get_post( $post, ARRAY_A ); } if ( is_null( $fields ) ) { $fields = array( 'post_title' => __( 'Title' ), 'post_content' => __( 'Content' ), 'post_excerpt' => __( 'Excerpt' ), ); } $fields = apply_filters( '_wp_post_revision_fields', $fields, $post ); foreach ( array( 'ID', 'post_name', 'post_parent', 'post_date', 'post_date_gmt', 'post_status', 'post_type', 'comment_count', 'post_author' ) as $protect ) { unset( $fields[ $protect ] ); } return $fields; } function _wp_post_revision_data( $post = array(), $autosave = false ) { if ( ! is_array( $post ) ) { $post = get_post( $post, ARRAY_A ); } $fields = _wp_post_revision_fields( $post ); $revision_data = array(); foreach ( array_intersect( array_keys( $post ), array_keys( $fields ) ) as $field ) { $revision_data[ $field ] = $post[ $field ]; } $revision_data['post_parent'] = $post['ID']; $revision_data['post_status'] = 'inherit'; $revision_data['post_type'] = 'revision'; $revision_data['post_name'] = $autosave ? "$post[ID]-autosave-v1" : "$post[ID]-revision-v1"; $revision_data['post_date'] = isset( $post['post_modified'] ) ? $post['post_modified'] : ''; $revision_data['post_date_gmt'] = isset( $post['post_modified_gmt'] ) ? $post['post_modified_gmt'] : ''; return $revision_data; } function wp_save_post_revision_on_insert( $post_id, $post, $update ) { if ( ! $update ) { return; } if ( ! has_action( 'post_updated', 'wp_save_post_revision' ) ) { return; } wp_save_post_revision( $post_id ); } function wp_save_post_revision( $post_id ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( doing_action( 'post_updated' ) && has_action( 'wp_after_insert_post', 'wp_save_post_revision_on_insert' ) ) { return; } $post = get_post( $post_id ); if ( ! $post ) { return; } if ( ! post_type_supports( $post->post_type, 'revisions' ) ) { return; } if ( 'auto-draft' === $post->post_status ) { return; } if ( ! wp_revisions_enabled( $post ) ) { return; } $revisions = wp_get_post_revisions( $post_id ); if ( $revisions ) { foreach ( $revisions as $revision ) { if ( str_contains( $revision->post_name, "{$revision->post_parent}-revision" ) ) { $latest_revision = $revision; break; } } if ( isset( $latest_revision ) && apply_filters( 'wp_save_post_revision_check_for_changes', true, $latest_revision, $post ) ) { $post_has_changed = false; foreach ( array_keys( _wp_post_revision_fields( $post ) ) as $field ) { if ( normalize_whitespace( $post->$field ) !== normalize_whitespace( $latest_revision->$field ) ) { $post_has_changed = true; break; } } $post_has_changed = (bool) apply_filters( 'wp_save_post_revision_post_has_changed', $post_has_changed, $latest_revision, $post ); if ( ! $post_has_changed ) { return; } } } $return = _wp_put_post_revision( $post ); $revisions_to_keep = wp_revisions_to_keep( $post ); if ( $revisions_to_keep < 0 ) { return $return; } $revisions = wp_get_post_revisions( $post_id, array( 'order' => 'ASC' ) ); $revisions = apply_filters( 'wp_save_post_revision_revisions_before_deletion', $revisions, $post_id ); $delete = count( $revisions ) - $revisions_to_keep; if ( $delete < 1 ) { return $return; } $revisions = array_slice( $revisions, 0, $delete ); for ( $i = 0; isset( $revisions[ $i ] ); $i++ ) { if ( str_contains( $revisions[ $i ]->post_name, 'autosave' ) ) { continue; } wp_delete_post_revision( $revisions[ $i ]->ID ); } return $return; } function wp_get_post_autosave( $post_id, $user_id = 0 ) { $args = array( 'post_type' => 'revision', 'post_status' => 'inherit', 'post_parent' => $post_id, 'name' => $post_id . '-autosave-v1', 'posts_per_page' => 1, 'orderby' => 'date', 'order' => 'DESC', 'fields' => 'ids', 'no_found_rows' => true, ); if ( 0 !== $user_id ) { $args['author'] = $user_id; } $query = new WP_Query( $args ); if ( ! $query->have_posts() ) { return false; } return get_post( $query->posts[0] ); } function wp_is_post_revision( $post ) { $post = wp_get_post_revision( $post ); if ( ! $post ) { return false; } return (int) $post->post_parent; } function wp_is_post_autosave( $post ) { $post = wp_get_post_revision( $post ); if ( ! $post ) { return false; } if ( str_contains( $post->post_name, "{$post->post_parent}-autosave" ) ) { return (int) $post->post_parent; } return false; } function _wp_put_post_revision( $post = null, $autosave = false ) { if ( is_object( $post ) ) { $post = get_object_vars( $post ); } elseif ( ! is_array( $post ) ) { $post = get_post( $post, ARRAY_A ); } if ( ! $post || empty( $post['ID'] ) ) { return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) ); } if ( isset( $post['post_type'] ) && 'revision' === $post['post_type'] ) { return new WP_Error( 'post_type', __( 'Cannot create a revision of a revision' ) ); } $post = _wp_post_revision_data( $post, $autosave ); $post = wp_slash( $post ); $revision_id = wp_insert_post( $post, true ); if ( is_wp_error( $revision_id ) ) { return $revision_id; } if ( $revision_id ) { do_action( '_wp_put_post_revision', $revision_id, $post['post_parent'] ); } return $revision_id; } function wp_save_revisioned_meta_fields( $revision_id, $post_id ) { $post_type = get_post_type( $post_id ); if ( ! $post_type ) { return; } foreach ( wp_post_revision_meta_keys( $post_type ) as $meta_key ) { if ( metadata_exists( 'post', $post_id, $meta_key ) ) { _wp_copy_post_meta( $post_id, $revision_id, $meta_key ); } } } function wp_get_post_revision( &$post, $output = OBJECT, $filter = 'raw' ) { $revision = get_post( $post, OBJECT, $filter ); if ( ! $revision ) { return $revision; } if ( 'revision' !== $revision->post_type ) { return null; } if ( OBJECT === $output ) { return $revision; } elseif ( ARRAY_A === $output ) { $_revision = get_object_vars( $revision ); return $_revision; } elseif ( ARRAY_N === $output ) { $_revision = array_values( get_object_vars( $revision ) ); return $_revision; } return $revision; } function wp_restore_post_revision( $revision, $fields = null ) { $revision = wp_get_post_revision( $revision, ARRAY_A ); if ( ! $revision ) { return $revision; } if ( ! is_array( $fields ) ) { $fields = array_keys( _wp_post_revision_fields( $revision ) ); } $update = array(); foreach ( array_intersect( array_keys( $revision ), $fields ) as $field ) { $update[ $field ] = $revision[ $field ]; } if ( ! $update ) { return false; } $update['ID'] = $revision['post_parent']; $update = wp_slash( $update ); $post_id = wp_update_post( $update ); if ( ! $post_id || is_wp_error( $post_id ) ) { return $post_id; } update_post_meta( $post_id, '_edit_last', get_current_user_id() ); do_action( 'wp_restore_post_revision', $post_id, $revision['ID'] ); return $post_id; } function wp_restore_post_revision_meta( $post_id, $revision_id ) { $post_type = get_post_type( $post_id ); if ( ! $post_type ) { return; } foreach ( wp_post_revision_meta_keys( $post_type ) as $meta_key ) { delete_post_meta( $post_id, $meta_key ); _wp_copy_post_meta( $revision_id, $post_id, $meta_key ); } } function _wp_copy_post_meta( $source_post_id, $target_post_id, $meta_key ) { foreach ( get_post_meta( $source_post_id, $meta_key ) as $meta_value ) { add_metadata( 'post', $target_post_id, $meta_key, wp_slash( $meta_value ) ); } } function wp_post_revision_meta_keys( $post_type ) { $registered_meta = array_merge( get_registered_meta_keys( 'post' ), get_registered_meta_keys( 'post', $post_type ) ); $wp_revisioned_meta_keys = array(); foreach ( $registered_meta as $name => $args ) { if ( $args['revisions_enabled'] ) { $wp_revisioned_meta_keys[ $name ] = true; } } $wp_revisioned_meta_keys = array_keys( $wp_revisioned_meta_keys ); return apply_filters( 'wp_post_revision_meta_keys', $wp_revisioned_meta_keys, $post_type ); } function wp_check_revisioned_meta_fields_have_changed( $post_has_changed, WP_Post $last_revision, WP_Post $post ) { foreach ( wp_post_revision_meta_keys( $post->post_type ) as $meta_key ) { if ( get_post_meta( $post->ID, $meta_key ) !== get_post_meta( $last_revision->ID, $meta_key ) ) { $post_has_changed = true; break; } } return $post_has_changed; } function wp_delete_post_revision( $revision ) { $revision = wp_get_post_revision( $revision ); if ( ! $revision ) { return $revision; } $delete = wp_delete_post( $revision->ID ); if ( $delete ) { do_action( 'wp_delete_post_revision', $revision->ID, $revision ); } return $delete; } function wp_get_post_revisions( $post = 0, $args = null ) { $post = get_post( $post ); if ( ! $post || empty( $post->ID ) ) { return array(); } $defaults = array( 'order' => 'DESC', 'orderby' => 'date ID', 'check_enabled' => true, ); $args = wp_parse_args( $args, $defaults ); if ( $args['check_enabled'] && ! wp_revisions_enabled( $post ) ) { return array(); } $args = array_merge( $args, array( 'post_parent' => $post->ID, 'post_type' => 'revision', 'post_status' => 'inherit', ) ); $revisions = get_children( $args ); if ( ! $revisions ) { return array(); } return $revisions; } function wp_get_latest_revision_id_and_total_count( $post = 0 ) { $post = get_post( $post ); if ( ! $post ) { return new WP_Error( 'invalid_post', __( 'Invalid post.' ) ); } if ( ! wp_revisions_enabled( $post ) ) { return new WP_Error( 'revisions_not_enabled', __( 'Revisions not enabled.' ) ); } $args = array( 'post_parent' => $post->ID, 'fields' => 'ids', 'post_type' => 'revision', 'post_status' => 'inherit', 'order' => 'DESC', 'orderby' => 'date ID', 'posts_per_page' => 1, 'ignore_sticky_posts' => true, ); $revision_query = new WP_Query(); $revisions = $revision_query->query( $args ); if ( ! $revisions ) { return array( 'latest_id' => 0, 'count' => 0, ); } return array( 'latest_id' => $revisions[0], 'count' => $revision_query->found_posts, ); } function wp_get_post_revisions_url( $post = 0 ) { $post = get_post( $post ); if ( ! $post instanceof WP_Post ) { return null; } if ( 'revision' === $post->post_type ) { return get_edit_post_link( $post ); } if ( ! wp_revisions_enabled( $post ) ) { return null; } $revisions = wp_get_latest_revision_id_and_total_count( $post->ID ); if ( is_wp_error( $revisions ) || 0 === $revisions['count'] ) { return null; } return get_edit_post_link( $revisions['latest_id'] ); } function wp_revisions_enabled( $post ) { return wp_revisions_to_keep( $post ) !== 0; } function wp_revisions_to_keep( $post ) { $num = WP_POST_REVISIONS; if ( true === $num ) { $num = -1; } else { $num = (int) $num; } if ( ! post_type_supports( $post->post_type, 'revisions' ) ) { $num = 0; } $num = apply_filters( 'wp_revisions_to_keep', $num, $post ); $num = apply_filters( "wp_{$post->post_type}_revisions_to_keep", $num, $post ); return (int) $num; } function _set_preview( $post ) { if ( ! is_object( $post ) ) { return $post; } $preview = wp_get_post_autosave( $post->ID ); if ( is_object( $preview ) ) { $preview = sanitize_post( $preview ); $post->post_content = $preview->post_content; $post->post_title = $preview->post_title; $post->post_excerpt = $preview->post_excerpt; } add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); add_filter( 'get_post_metadata', '_wp_preview_post_thumbnail_filter', 10, 3 ); add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); return $post; } function _show_post_preview() { if ( isset( $_GET['preview_id'] ) && isset( $_GET['preview_nonce'] ) ) { $id = (int) $_GET['preview_id']; if ( false === wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . $id ) ) { wp_die( __( 'Sorry, you are not allowed to preview drafts.' ), 403 ); } add_filter( 'the_preview', '_set_preview' ); } } function _wp_preview_terms_filter( $terms, $post_id, $taxonomy ) { $post = get_post(); if ( ! $post ) { return $terms; } if ( empty( $_REQUEST['post_format'] ) || $post->ID !== $post_id || 'post_format' !== $taxonomy || 'revision' === $post->post_type ) { return $terms; } if ( 'standard' === $_REQUEST['post_format'] ) { $terms = array(); } else { $term = get_term_by( 'slug', 'post-format-' . sanitize_key( $_REQUEST['post_format'] ), 'post_format' ); if ( $term ) { $terms = array( $term ); } } return $terms; } function _wp_preview_post_thumbnail_filter( $value, $post_id, $meta_key ) { $post = get_post(); if ( ! $post ) { return $value; } if ( empty( $_REQUEST['_thumbnail_id'] ) || empty( $_REQUEST['preview_id'] ) || $post->ID !== $post_id || $post_id !== (int) $_REQUEST['preview_id'] || '_thumbnail_id' !== $meta_key || 'revision' === $post->post_type ) { return $value; } $thumbnail_id = (int) $_REQUEST['_thumbnail_id']; if ( $thumbnail_id <= 0 ) { return ''; } return (string) $thumbnail_id; } function _wp_get_post_revision_version( $revision ) { if ( is_object( $revision ) ) { $revision = get_object_vars( $revision ); } elseif ( ! is_array( $revision ) ) { return false; } if ( preg_match( '/^\d+-(?:autosave|revision)-v(\d+)$/', $revision['post_name'], $matches ) ) { return (int) $matches[1]; } return 0; } function _wp_upgrade_revisions_of_post( $post, $revisions ) { global $wpdb; $lock = "revision-upgrade-{$post->ID}"; $now = time(); $result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'off') /* LOCK */", $lock, $now ) ); if ( ! $result ) { $locked = get_option( $lock ); if ( ! $locked ) { return false; } if ( $locked > $now - HOUR_IN_SECONDS ) { return false; } } update_option( $lock, $now ); reset( $revisions ); $add_last = true; do { $this_revision = current( $revisions ); $prev_revision = next( $revisions ); $this_revision_version = _wp_get_post_revision_version( $this_revision ); if ( false === $this_revision_version ) { continue; } if ( 0 < $this_revision_version ) { $add_last = false; continue; } $update = array( 'post_name' => preg_replace( '/^(\d+-(?:autosave|revision))[\d-]*$/', '$1-v1', $this_revision->post_name ), ); if ( $prev_revision ) { $prev_revision_version = _wp_get_post_revision_version( $prev_revision ); if ( $prev_revision_version < 1 ) { $update['post_author'] = $prev_revision->post_author; } } $result = $wpdb->update( $wpdb->posts, $update, array( 'ID' => $this_revision->ID ) ); if ( $result ) { wp_cache_delete( $this_revision->ID, 'posts' ); } } while ( $prev_revision ); delete_option( $lock ); if ( $add_last ) { wp_save_post_revision( $post->ID ); } return true; } function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { $post = get_post(); if ( empty( $post ) || $post->ID !== $object_id || ! in_array( $meta_key, wp_post_revision_meta_keys( $post->post_type ), true ) || 'revision' === $post->post_type ) { return $value; } $preview = wp_get_post_autosave( $post->ID ); if ( false === $preview ) { return $value; } return get_post_meta( $preview->ID, $meta_key, $single ); }
###require ABSPATH . WPINC . '/post-formats.php';
function get_post_format( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } if ( ! post_type_supports( $post->post_type, 'post-formats' ) ) { return false; } $_format = get_the_terms( $post->ID, 'post_format' ); if ( empty( $_format ) ) { return false; } $format = reset( $_format ); return str_replace( 'post-format-', '', $format->slug ); } function has_post_format( $format = array(), $post = null ) { $prefixed = array(); if ( $format ) { foreach ( (array) $format as $single ) { $prefixed[] = 'post-format-' . sanitize_key( $single ); } } return has_term( $prefixed, 'post_format', $post ); } function set_post_format( $post, $format ) { $post = get_post( $post ); if ( ! $post ) { return new WP_Error( 'invalid_post', __( 'Invalid post.' ) ); } if ( ! empty( $format ) ) { $format = sanitize_key( $format ); if ( 'standard' === $format || ! in_array( $format, get_post_format_slugs(), true ) ) { $format = ''; } else { $format = 'post-format-' . $format; } } return wp_set_post_terms( $post->ID, $format, 'post_format' ); } function get_post_format_strings() { $strings = array( 'standard' => _x( 'Standard', 'Post format' ), 'aside' => _x( 'Aside', 'Post format' ), 'chat' => _x( 'Chat', 'Post format' ), 'gallery' => _x( 'Gallery', 'Post format' ), 'link' => _x( 'Link', 'Post format' ), 'image' => _x( 'Image', 'Post format' ), 'quote' => _x( 'Quote', 'Post format' ), 'status' => _x( 'Status', 'Post format' ), 'video' => _x( 'Video', 'Post format' ), 'audio' => _x( 'Audio', 'Post format' ), ); return $strings; } function get_post_format_slugs() { $slugs = array_keys( get_post_format_strings() ); return array_combine( $slugs, $slugs ); } function get_post_format_string( $slug ) { $strings = get_post_format_strings(); if ( ! $slug ) { return $strings['standard']; } else { return ( isset( $strings[ $slug ] ) ) ? $strings[ $slug ] : ''; } } function get_post_format_link( $format ) { $term = get_term_by( 'slug', 'post-format-' . $format, 'post_format' ); if ( ! $term || is_wp_error( $term ) ) { return false; } return get_term_link( $term ); } function _post_format_request( $qvs ) { if ( ! isset( $qvs['post_format'] ) ) { return $qvs; } $slugs = get_post_format_slugs(); if ( isset( $slugs[ $qvs['post_format'] ] ) ) { $qvs['post_format'] = 'post-format-' . $slugs[ $qvs['post_format'] ]; } $tax = get_taxonomy( 'post_format' ); if ( ! is_admin() ) { $qvs['post_type'] = $tax->object_type; } return $qvs; } function _post_format_link( $link, $term, $taxonomy ) { global $wp_rewrite; if ( 'post_format' !== $taxonomy ) { return $link; } if ( $wp_rewrite->get_extra_permastruct( $taxonomy ) ) { return str_replace( "/{$term->slug}", '/' . str_replace( 'post-format-', '', $term->slug ), $link ); } else { $link = remove_query_arg( 'post_format', $link ); return add_query_arg( 'post_format', str_replace( 'post-format-', '', $term->slug ), $link ); } } function _post_format_get_term( $term ) { if ( isset( $term->slug ) ) { $term->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); } return $term; } function _post_format_get_terms( $terms, $taxonomies, $args ) { if ( in_array( 'post_format', (array) $taxonomies, true ) ) { if ( isset( $args['fields'] ) && 'names' === $args['fields'] ) { foreach ( $terms as $order => $name ) { $terms[ $order ] = get_post_format_string( str_replace( 'post-format-', '', $name ) ); } } else { foreach ( (array) $terms as $order => $term ) { if ( isset( $term->taxonomy ) && 'post_format' === $term->taxonomy ) { $terms[ $order ]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); } } } } return $terms; } function _post_format_wp_get_object_terms( $terms ) { foreach ( (array) $terms as $order => $term ) { if ( isset( $term->taxonomy ) && 'post_format' === $term->taxonomy ) { $terms[ $order ]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); } } return $terms; }
###require ABSPATH . WPINC . '/post-thumbnail-template.php';
function has_post_thumbnail( $post = null ) { $thumbnail_id = get_post_thumbnail_id( $post ); $has_thumbnail = (bool) $thumbnail_id; return (bool) apply_filters( 'has_post_thumbnail', $has_thumbnail, $post, $thumbnail_id ); } function get_post_thumbnail_id( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $thumbnail_id = (int) get_post_meta( $post->ID, '_thumbnail_id', true ); return (int) apply_filters( 'post_thumbnail_id', $thumbnail_id, $post ); } function the_post_thumbnail( $size = 'post-thumbnail', $attr = '' ) { echo get_the_post_thumbnail( null, $size, $attr ); } function update_post_thumbnail_cache( $wp_query = null ) { if ( ! $wp_query ) { $wp_query = $GLOBALS['wp_query']; } if ( $wp_query->thumbnails_cached ) { return; } $thumb_ids = array(); $parent_post_ids = array(); foreach ( $wp_query->posts as $post ) { if ( $post instanceof WP_Post ) { $parent_post_ids[] = $post->ID; } elseif ( is_int( $post ) ) { $parent_post_ids[] = $post; } } _prime_post_caches( $parent_post_ids, false, true ); foreach ( $wp_query->posts as $post ) { $id = get_post_thumbnail_id( $post ); if ( $id ) { $thumb_ids[] = $id; } } if ( ! empty( $thumb_ids ) ) { _prime_post_caches( $thumb_ids, false, true ); } $wp_query->thumbnails_cached = true; } function get_the_post_thumbnail( $post = null, $size = 'post-thumbnail', $attr = '' ) { $post = get_post( $post ); if ( ! $post ) { return ''; } $post_thumbnail_id = get_post_thumbnail_id( $post ); $size = apply_filters( 'post_thumbnail_size', $size, $post->ID ); if ( $post_thumbnail_id ) { do_action( 'begin_fetch_post_thumbnail_html', $post->ID, $post_thumbnail_id, $size ); if ( in_the_loop() ) { update_post_thumbnail_cache(); } $html = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr ); do_action( 'end_fetch_post_thumbnail_html', $post->ID, $post_thumbnail_id, $size ); } else { $html = ''; } return apply_filters( 'post_thumbnail_html', $html, $post->ID, $post_thumbnail_id, $size, $attr ); } function get_the_post_thumbnail_url( $post = null, $size = 'post-thumbnail' ) { $post_thumbnail_id = get_post_thumbnail_id( $post ); if ( ! $post_thumbnail_id ) { return false; } $thumbnail_url = wp_get_attachment_image_url( $post_thumbnail_id, $size ); return apply_filters( 'post_thumbnail_url', $thumbnail_url, $post, $size ); } function the_post_thumbnail_url( $size = 'post-thumbnail' ) { $url = get_the_post_thumbnail_url( null, $size ); if ( $url ) { echo esc_url( $url ); } } function get_the_post_thumbnail_caption( $post = null ) { $post_thumbnail_id = get_post_thumbnail_id( $post ); if ( ! $post_thumbnail_id ) { return ''; } $caption = wp_get_attachment_caption( $post_thumbnail_id ); if ( ! $caption ) { $caption = ''; } return $caption; } function the_post_thumbnail_caption( $post = null ) { echo apply_filters( 'the_post_thumbnail_caption', get_the_post_thumbnail_caption( $post ) ); }
###require ABSPATH . WPINC . '/category.php';
function get_categories( $args = '' ) { $defaults = array( 'taxonomy' => 'category' ); $args = wp_parse_args( $args, $defaults ); $args['taxonomy'] = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args ); if ( isset( $args['type'] ) && 'link' === $args['type'] ) { _deprecated_argument( __FUNCTION__, '3.0.0', sprintf( __( '%1$s is deprecated. Use %2$s instead.' ), '<code>type => link</code>', '<code>taxonomy => link_category</code>' ) ); $args['taxonomy'] = 'link_category'; } $categories = get_terms( $args ); if ( is_wp_error( $categories ) ) { $categories = array(); } else { $categories = (array) $categories; foreach ( array_keys( $categories ) as $k ) { _make_cat_compat( $categories[ $k ] ); } } return $categories; } function get_category( $category, $output = OBJECT, $filter = 'raw' ) { $category = get_term( $category, 'category', $output, $filter ); if ( is_wp_error( $category ) ) { return $category; } _make_cat_compat( $category ); return $category; } function get_category_by_path( $category_path, $full_match = true, $output = OBJECT ) { $category_path = rawurlencode( urldecode( $category_path ) ); $category_path = str_replace( '%2F', '/', $category_path ); $category_path = str_replace( '%20', ' ', $category_path ); $category_paths = '/' . trim( $category_path, '/' ); $leaf_path = sanitize_title( basename( $category_paths ) ); $category_paths = explode( '/', $category_paths ); $full_path = ''; foreach ( (array) $category_paths as $pathdir ) { $full_path .= ( '' !== $pathdir ? '/' : '' ) . sanitize_title( $pathdir ); } $categories = get_terms( array( 'taxonomy' => 'category', 'get' => 'all', 'slug' => $leaf_path, ) ); if ( empty( $categories ) ) { return; } foreach ( $categories as $category ) { $path = '/' . $leaf_path; $curcategory = $category; while ( ( 0 !== $curcategory->parent ) && ( $curcategory->parent !== $curcategory->term_id ) ) { $curcategory = get_term( $curcategory->parent, 'category' ); if ( is_wp_error( $curcategory ) ) { return $curcategory; } $path = '/' . $curcategory->slug . $path; } if ( $path === $full_path ) { $category = get_term( $category->term_id, 'category', $output ); _make_cat_compat( $category ); return $category; } } if ( ! $full_match ) { $category = get_term( reset( $categories )->term_id, 'category', $output ); _make_cat_compat( $category ); return $category; } } function get_category_by_slug( $slug ) { $category = get_term_by( 'slug', $slug, 'category' ); if ( $category ) { _make_cat_compat( $category ); } return $category; } function get_cat_ID( $cat_name ) { $cat = get_term_by( 'name', $cat_name, 'category' ); if ( $cat ) { return $cat->term_id; } return 0; } function get_cat_name( $cat_id ) { $cat_id = (int) $cat_id; $category = get_term( $cat_id, 'category' ); if ( ! $category || is_wp_error( $category ) ) { return ''; } return $category->name; } function cat_is_ancestor_of( $cat1, $cat2 ) { return term_is_ancestor_of( $cat1, $cat2, 'category' ); } function sanitize_category( $category, $context = 'display' ) { return sanitize_term( $category, 'category', $context ); } function sanitize_category_field( $field, $value, $cat_id, $context ) { return sanitize_term_field( $field, $value, $cat_id, 'category', $context ); } function get_tags( $args = '' ) { $defaults = array( 'taxonomy' => 'post_tag' ); $args = wp_parse_args( $args, $defaults ); $tags = get_terms( $args ); if ( empty( $tags ) ) { $tags = array(); } else { $tags = apply_filters( 'get_tags', $tags, $args ); } return $tags; } function get_tag( $tag, $output = OBJECT, $filter = 'raw' ) { return get_term( $tag, 'post_tag', $output, $filter ); } function clean_category_cache( $id ) { clean_term_cache( $id, 'category' ); } function _make_cat_compat( &$category ) { if ( is_object( $category ) && ! is_wp_error( $category ) ) { $category->cat_ID = $category->term_id; $category->category_count = $category->count; $category->category_description = $category->description; $category->cat_name = $category->name; $category->category_nicename = $category->slug; $category->category_parent = $category->parent; } elseif ( is_array( $category ) && isset( $category['term_id'] ) ) { $category['cat_ID'] = &$category['term_id']; $category['category_count'] = &$category['count']; $category['category_description'] = &$category['description']; $category['cat_name'] = &$category['name']; $category['category_nicename'] = &$category['slug']; $category['category_parent'] = &$category['parent']; } }
###require ABSPATH . WPINC . '/class-walker-category.php';
class Walker_Category extends Walker { public $tree_type = 'category'; public $db_fields = array( 'parent' => 'parent', 'id' => 'term_id', ); public function start_lvl( &$output, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $indent = str_repeat( "\t", $depth ); $output .= "$indent<ul class='children'>\n"; } public function end_lvl( &$output, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $indent = str_repeat( "\t", $depth ); $output .= "$indent</ul>\n"; } public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { $category = $data_object; $cat_name = apply_filters( 'list_cats', esc_attr( $category->name ), $category ); if ( '' === $cat_name ) { return; } $atts = array(); $atts['href'] = get_term_link( $category ); if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) { $atts['title'] = strip_tags( apply_filters( 'category_description', $category->description, $category ) ); } $atts = apply_filters( 'category_list_link_attributes', $atts, $category, $depth, $args, $current_object_id ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } $link = sprintf( '<a%s>%s</a>', $attributes, $cat_name ); if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) { $link .= ' '; if ( empty( $args['feed_image'] ) ) { $link .= '('; } $link .= '<a href="' . esc_url( get_term_feed_link( $category, $category->taxonomy, $args['feed_type'] ) ) . '"'; if ( empty( $args['feed'] ) ) { $alt = ' alt="' . sprintf( __( 'Feed for all posts filed under %s' ), $cat_name ) . '"'; } else { $alt = ' alt="' . $args['feed'] . '"'; $name = $args['feed']; $link .= empty( $args['title'] ) ? '' : $args['title']; } $link .= '>'; if ( empty( $args['feed_image'] ) ) { $link .= $name; } else { $link .= "<img src='" . esc_url( $args['feed_image'] ) . "'$alt" . ' />'; } $link .= '</a>'; if ( empty( $args['feed_image'] ) ) { $link .= ')'; } } if ( ! empty( $args['show_count'] ) ) { $link .= ' (' . number_format_i18n( $category->count ) . ')'; } if ( 'list' === $args['style'] ) { $output .= "\t<li"; $css_classes = array( 'cat-item', 'cat-item-' . $category->term_id, ); if ( ! empty( $args['current_category'] ) ) { $_current_terms = get_terms( array( 'taxonomy' => $category->taxonomy, 'include' => $args['current_category'], 'hide_empty' => false, ) ); foreach ( $_current_terms as $_current_term ) { if ( $category->term_id === $_current_term->term_id ) { $css_classes[] = 'current-cat'; $link = str_replace( '<a', '<a aria-current="page"', $link ); } elseif ( $category->term_id === $_current_term->parent ) { $css_classes[] = 'current-cat-parent'; } while ( $_current_term->parent ) { if ( $category->term_id === $_current_term->parent ) { $css_classes[] = 'current-cat-ancestor'; break; } $_current_term = get_term( $_current_term->parent, $category->taxonomy ); } } } $css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) ); $css_classes = $css_classes ? ' class="' . esc_attr( $css_classes ) . '"' : ''; $output .= $css_classes; $output .= ">$link\n"; } elseif ( isset( $args['separator'] ) ) { $output .= "\t$link" . $args['separator'] . "\n"; } else { $output .= "\t$link<br />\n"; } } public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $output .= "</li>\n"; } }
###require ABSPATH . WPINC . '/class-walker-category-dropdown.php';
class Walker_CategoryDropdown extends Walker { public $tree_type = 'category'; public $db_fields = array( 'parent' => 'parent', 'id' => 'term_id', ); public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { $category = $data_object; $pad = str_repeat( ' ', $depth * 3 ); $cat_name = apply_filters( 'list_cats', $category->name, $category ); if ( isset( $args['value_field'] ) && isset( $category->{$args['value_field']} ) ) { $value_field = $args['value_field']; } else { $value_field = 'term_id'; } $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $category->{$value_field} ) . '"'; if ( (string) $category->{$value_field} === (string) $args['selected'] ) { $output .= ' selected="selected"'; } $output .= '>'; $output .= $pad . $cat_name; if ( $args['show_count'] ) { $output .= ' (' . number_format_i18n( $category->count ) . ')'; } $output .= "</option>\n"; } }
###require ABSPATH . WPINC . '/category-template.php';
function get_category_link( $category ) { if ( ! is_object( $category ) ) { $category = (int) $category; } $category = get_term_link( $category ); if ( is_wp_error( $category ) ) { return ''; } return $category; } function get_category_parents( $category_id, $link = false, $separator = '/', $nicename = false, $deprecated = array() ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '4.8.0' ); } $format = $nicename ? 'slug' : 'name'; $args = array( 'separator' => $separator, 'link' => $link, 'format' => $format, ); return get_term_parents_list( $category_id, 'category', $args ); } function get_the_category( $post_id = false ) { $categories = get_the_terms( $post_id, 'category' ); if ( ! $categories || is_wp_error( $categories ) ) { $categories = array(); } $categories = array_values( $categories ); foreach ( array_keys( $categories ) as $key ) { _make_cat_compat( $categories[ $key ] ); } return apply_filters( 'get_the_categories', $categories, $post_id ); } function get_the_category_by_ID( $cat_id ) { $cat_id = (int) $cat_id; $category = get_term( $cat_id ); if ( is_wp_error( $category ) ) { return $category; } return ( $category ) ? $category->name : ''; } function get_the_category_list( $separator = '', $parents = '', $post_id = false ) { global $wp_rewrite; if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) { return apply_filters( 'the_category', '', $separator, $parents ); } $categories = apply_filters( 'the_category_list', get_the_category( $post_id ), $post_id ); if ( empty( $categories ) ) { return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents ); } $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"'; $thelist = ''; if ( '' === $separator ) { $thelist .= '<ul class="post-categories">'; foreach ( $categories as $category ) { $thelist .= "\n\t<li>"; switch ( strtolower( $parents ) ) { case 'multiple': if ( $category->parent ) { $thelist .= get_category_parents( $category->parent, true, $separator ); } $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>'; break; case 'single': $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>'; if ( $category->parent ) { $thelist .= get_category_parents( $category->parent, false, $separator ); } $thelist .= $category->name . '</a></li>'; break; case '': default: $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>'; } } $thelist .= '</ul>'; } else { $i = 0; foreach ( $categories as $category ) { if ( 0 < $i ) { $thelist .= $separator; } switch ( strtolower( $parents ) ) { case 'multiple': if ( $category->parent ) { $thelist .= get_category_parents( $category->parent, true, $separator ); } $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>'; break; case 'single': $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>'; if ( $category->parent ) { $thelist .= get_category_parents( $category->parent, false, $separator ); } $thelist .= "$category->name</a>"; break; case '': default: $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>'; } ++$i; } } return apply_filters( 'the_category', $thelist, $separator, $parents ); } function in_category( $category, $post = null ) { if ( empty( $category ) ) { return false; } return has_category( $category, $post ); } function the_category( $separator = '', $parents = '', $post_id = false ) { echo get_the_category_list( $separator, $parents, $post_id ); } function category_description( $category = 0 ) { return term_description( $category ); } function wp_dropdown_categories( $args = '' ) { $defaults = array( 'show_option_all' => '', 'show_option_none' => '', 'orderby' => 'id', 'order' => 'ASC', 'show_count' => 0, 'hide_empty' => 1, 'child_of' => 0, 'exclude' => '', 'echo' => 1, 'selected' => 0, 'hierarchical' => 0, 'name' => 'cat', 'id' => '', 'class' => 'postform', 'depth' => 0, 'tab_index' => 0, 'taxonomy' => 'category', 'hide_if_empty' => false, 'option_none_value' => -1, 'value_field' => 'term_id', 'required' => false, 'aria_describedby' => '', ); $defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0; if ( isset( $args['type'] ) && 'link' === $args['type'] ) { _deprecated_argument( __FUNCTION__, '3.0.0', sprintf( __( '%1$s is deprecated. Use %2$s instead.' ), '<code>type => link</code>', '<code>taxonomy => link_category</code>' ) ); $args['taxonomy'] = 'link_category'; } $parsed_args = wp_parse_args( $args, $defaults ); $option_none_value = $parsed_args['option_none_value']; if ( ! isset( $parsed_args['pad_counts'] ) && $parsed_args['show_count'] && $parsed_args['hierarchical'] ) { $parsed_args['pad_counts'] = true; } $tab_index = $parsed_args['tab_index']; $tab_index_attribute = ''; if ( (int) $tab_index > 0 ) { $tab_index_attribute = " tabindex=\"$tab_index\""; } $get_terms_args = $parsed_args; unset( $get_terms_args['name'] ); $categories = get_terms( $get_terms_args ); $name = esc_attr( $parsed_args['name'] ); $class = esc_attr( $parsed_args['class'] ); $id = $parsed_args['id'] ? esc_attr( $parsed_args['id'] ) : $name; $required = $parsed_args['required'] ? 'required' : ''; $aria_describedby_attribute = $parsed_args['aria_describedby'] ? ' aria-describedby="' . esc_attr( $parsed_args['aria_describedby'] ) . '"' : ''; if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) { $output = "<select $required name='$name' id='$id' class='$class'$tab_index_attribute$aria_describedby_attribute>\n"; } else { $output = ''; } if ( empty( $categories ) && ! $parsed_args['hide_if_empty'] && ! empty( $parsed_args['show_option_none'] ) ) { $show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null ); $output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n"; } if ( ! empty( $categories ) ) { if ( $parsed_args['show_option_all'] ) { $show_option_all = apply_filters( 'list_cats', $parsed_args['show_option_all'], null ); $selected = ( '0' === (string) $parsed_args['selected'] ) ? " selected='selected'" : ''; $output .= "\t<option value='0'$selected>$show_option_all</option>\n"; } if ( $parsed_args['show_option_none'] ) { $show_option_none = apply_filters( 'list_cats', $parsed_args['show_option_none'], null ); $selected = selected( $option_none_value, $parsed_args['selected'], false ); $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n"; } if ( $parsed_args['hierarchical'] ) { $depth = $parsed_args['depth']; } else { $depth = -1; } $output .= walk_category_dropdown_tree( $categories, $depth, $parsed_args ); } if ( ! $parsed_args['hide_if_empty'] || ! empty( $categories ) ) { $output .= "</select>\n"; } $output = apply_filters( 'wp_dropdown_cats', $output, $parsed_args ); if ( $parsed_args['echo'] ) { echo $output; } return $output; } function wp_list_categories( $args = '' ) { $defaults = array( 'child_of' => 0, 'current_category' => 0, 'depth' => 0, 'echo' => 1, 'exclude' => '', 'exclude_tree' => '', 'feed' => '', 'feed_image' => '', 'feed_type' => '', 'hide_empty' => 1, 'hide_title_if_empty' => false, 'hierarchical' => true, 'order' => 'ASC', 'orderby' => 'name', 'separator' => '<br />', 'show_count' => 0, 'show_option_all' => '', 'show_option_none' => __( 'No categories' ), 'style' => 'list', 'taxonomy' => 'category', 'title_li' => __( 'Categories' ), 'use_desc_for_title' => 0, ); $parsed_args = wp_parse_args( $args, $defaults ); if ( ! isset( $parsed_args['pad_counts'] ) && $parsed_args['show_count'] && $parsed_args['hierarchical'] ) { $parsed_args['pad_counts'] = true; } if ( $parsed_args['hierarchical'] ) { $exclude_tree = array(); if ( $parsed_args['exclude_tree'] ) { $exclude_tree = array_merge( $exclude_tree, wp_parse_id_list( $parsed_args['exclude_tree'] ) ); } if ( $parsed_args['exclude'] ) { $exclude_tree = array_merge( $exclude_tree, wp_parse_id_list( $parsed_args['exclude'] ) ); } $parsed_args['exclude_tree'] = $exclude_tree; $parsed_args['exclude'] = ''; } if ( ! isset( $parsed_args['class'] ) ) { $parsed_args['class'] = ( 'category' === $parsed_args['taxonomy'] ) ? 'categories' : $parsed_args['taxonomy']; } if ( ! taxonomy_exists( $parsed_args['taxonomy'] ) ) { return false; } $show_option_all = $parsed_args['show_option_all']; $show_option_none = $parsed_args['show_option_none']; $categories = get_categories( $parsed_args ); $output = ''; if ( $parsed_args['title_li'] && 'list' === $parsed_args['style'] && ( ! empty( $categories ) || ! $parsed_args['hide_title_if_empty'] ) ) { $output = '<li class="' . esc_attr( $parsed_args['class'] ) . '">' . $parsed_args['title_li'] . '<ul>'; } if ( empty( $categories ) ) { if ( ! empty( $show_option_none ) ) { if ( 'list' === $parsed_args['style'] ) { $output .= '<li class="cat-item-none">' . $show_option_none . '</li>'; } else { $output .= $show_option_none; } } } else { if ( ! empty( $show_option_all ) ) { $posts_page = ''; $taxonomy_object = get_taxonomy( $parsed_args['taxonomy'] ); if ( ! in_array( 'post', $taxonomy_object->object_type, true ) && ! in_array( 'page', $taxonomy_object->object_type, true ) ) { foreach ( $taxonomy_object->object_type as $object_type ) { $_object_type = get_post_type_object( $object_type ); if ( ! empty( $_object_type->has_archive ) ) { $posts_page = get_post_type_archive_link( $object_type ); break; } } } if ( ! $posts_page ) { if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ) { $posts_page = get_permalink( get_option( 'page_for_posts' ) ); } else { $posts_page = home_url( '/' ); } } $posts_page = esc_url( $posts_page ); if ( 'list' === $parsed_args['style'] ) { $output .= "<li class='cat-item-all'><a href='$posts_page'>$show_option_all</a></li>"; } else { $output .= "<a href='$posts_page'>$show_option_all</a>"; } } if ( empty( $parsed_args['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) { $current_term_object = get_queried_object(); if ( $current_term_object && $parsed_args['taxonomy'] === $current_term_object->taxonomy ) { $parsed_args['current_category'] = get_queried_object_id(); } } if ( $parsed_args['hierarchical'] ) { $depth = $parsed_args['depth']; } else { $depth = -1; } $output .= walk_category_tree( $categories, $depth, $parsed_args ); } if ( $parsed_args['title_li'] && 'list' === $parsed_args['style'] && ( ! empty( $categories ) || ! $parsed_args['hide_title_if_empty'] ) ) { $output .= '</ul></li>'; } $html = apply_filters( 'wp_list_categories', $output, $args ); if ( $parsed_args['echo'] ) { echo $html; } else { return $html; } } function wp_tag_cloud( $args = '' ) { $defaults = array( 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45, 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC', 'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true, 'show_count' => 0, ); $args = wp_parse_args( $args, $defaults ); $tags = get_terms( array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC', ) ) ); if ( empty( $tags ) || is_wp_error( $tags ) ) { return; } foreach ( $tags as $key => $tag ) { if ( 'edit' === $args['link'] ) { $link = get_edit_term_link( $tag, $tag->taxonomy, $args['post_type'] ); } else { $link = get_term_link( $tag, $tag->taxonomy ); } if ( is_wp_error( $link ) ) { return; } $tags[ $key ]->link = $link; $tags[ $key ]->id = $tag->term_id; } $return = wp_generate_tag_cloud( $tags, $args ); $return = apply_filters( 'wp_tag_cloud', $return, $args ); if ( 'array' === $args['format'] || empty( $args['echo'] ) ) { return $return; } echo $return; } function default_topic_count_scale( $count ) { return (int) round( log10( $count + 1 ) * 100 ); } function wp_generate_tag_cloud( $tags, $args = '' ) { $defaults = array( 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 0, 'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC', 'topic_count_text' => null, 'topic_count_text_callback' => null, 'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1, 'show_count' => 0, ); $args = wp_parse_args( $args, $defaults ); $return = ( 'array' === $args['format'] ) ? array() : ''; if ( empty( $tags ) ) { return $return; } if ( isset( $args['topic_count_text'] ) ) { $translate_nooped_plural = $args['topic_count_text']; } elseif ( ! empty( $args['topic_count_text_callback'] ) ) { if ( 'default_topic_count_text' === $args['topic_count_text_callback'] ) { $translate_nooped_plural = _n_noop( '%s item', '%s items' ); } else { $translate_nooped_plural = false; } } elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) { $translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] ); } else { $translate_nooped_plural = _n_noop( '%s item', '%s items' ); } $tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args ); if ( empty( $tags_sorted ) ) { return $return; } if ( $tags_sorted !== $tags ) { $tags = $tags_sorted; unset( $tags_sorted ); } else { if ( 'RAND' === $args['order'] ) { shuffle( $tags ); } else { if ( 'name' === $args['orderby'] ) { uasort( $tags, '_wp_object_name_sort_cb' ); } else { uasort( $tags, '_wp_object_count_sort_cb' ); } if ( 'DESC' === $args['order'] ) { $tags = array_reverse( $tags, true ); } } } if ( $args['number'] > 0 ) { $tags = array_slice( $tags, 0, $args['number'] ); } $counts = array(); $real_counts = array(); foreach ( (array) $tags as $key => $tag ) { $real_counts[ $key ] = $tag->count; $counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count ); } $min_count = min( $counts ); $spread = max( $counts ) - $min_count; if ( $spread <= 0 ) { $spread = 1; } $font_spread = $args['largest'] - $args['smallest']; if ( $font_spread < 0 ) { $font_spread = 1; } $font_step = $font_spread / $spread; $aria_label = false; if ( $args['show_count'] || 0 !== $font_spread ) { $aria_label = true; } $tags_data = array(); foreach ( $tags as $key => $tag ) { $tag_id = isset( $tag->id ) ? $tag->id : $key; $count = $counts[ $key ]; $real_count = $real_counts[ $key ]; if ( $translate_nooped_plural ) { $formatted_count = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) ); } else { $formatted_count = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args ); } $tags_data[] = array( 'id' => $tag_id, 'url' => ( '#' !== $tag->link ) ? $tag->link : '#', 'role' => ( '#' !== $tag->link ) ? '' : ' role="button"', 'name' => $tag->name, 'formatted_count' => $formatted_count, 'slug' => $tag->slug, 'real_count' => $real_count, 'class' => 'tag-cloud-link tag-link-' . $tag_id, 'font_size' => $args['smallest'] + ( $count - $min_count ) * $font_step, 'aria_label' => $aria_label ? sprintf( ' aria-label="%1$s (%2$s)"', esc_attr( $tag->name ), esc_attr( $formatted_count ) ) : '', 'show_count' => $args['show_count'] ? '<span class="tag-link-count"> (' . $real_count . ')</span>' : '', ); } $tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data ); $a = array(); foreach ( $tags_data as $key => $tag_data ) { $class = $tag_data['class'] . ' tag-link-position-' . ( $key + 1 ); $a[] = sprintf( '<a href="%1$s"%2$s class="%3$s" style="font-size: %4$s;"%5$s>%6$s%7$s</a>', esc_url( $tag_data['url'] ), $tag_data['role'], esc_attr( $class ), esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ), $tag_data['aria_label'], esc_html( $tag_data['name'] ), $tag_data['show_count'] ); } switch ( $args['format'] ) { case 'array': $return =& $a; break; case 'list': $return = "<ul class='wp-tag-cloud' role='list'>\n\t<li>"; $return .= implode( "</li>\n\t<li>", $a ); $return .= "</li>\n</ul>\n"; break; default: $return = implode( $args['separator'], $a ); break; } if ( $args['filter'] ) { return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args ); } else { return $return; } } function _wp_object_name_sort_cb( $a, $b ) { return strnatcasecmp( $a->name, $b->name ); } function _wp_object_count_sort_cb( $a, $b ) { return ( $a->count - $b->count ); } function walk_category_tree( ...$args ) { if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) { $walker = new Walker_Category(); } else { $walker = $args[2]['walker']; } return $walker->walk( ...$args ); } function walk_category_dropdown_tree( ...$args ) { if ( empty( $args[2]['walker'] ) || ! ( $args[2]['walker'] instanceof Walker ) ) { $walker = new Walker_CategoryDropdown(); } else { $walker = $args[2]['walker']; } return $walker->walk( ...$args ); } function get_tag_link( $tag ) { return get_category_link( $tag ); } function get_the_tags( $post = 0 ) { $terms = get_the_terms( $post, 'post_tag' ); return apply_filters( 'get_the_tags', $terms ); } function get_the_tag_list( $before = '', $sep = '', $after = '', $post_id = 0 ) { $tag_list = get_the_term_list( $post_id, 'post_tag', $before, $sep, $after ); return apply_filters( 'the_tags', $tag_list, $before, $sep, $after, $post_id ); } function the_tags( $before = null, $sep = ', ', $after = '' ) { if ( null === $before ) { $before = __( 'Tags: ' ); } $the_tags = get_the_tag_list( $before, $sep, $after ); if ( ! is_wp_error( $the_tags ) ) { echo $the_tags; } } function tag_description( $tag = 0 ) { return term_description( $tag ); } function term_description( $term = 0, $deprecated = null ) { if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) { $term = get_queried_object(); if ( $term ) { $term = $term->term_id; } } $description = get_term_field( 'description', $term ); return is_wp_error( $description ) ? '' : $description; } function get_the_terms( $post, $taxonomy ) { $post = get_post( $post ); if ( ! $post ) { return false; } $terms = get_object_term_cache( $post->ID, $taxonomy ); if ( false === $terms ) { $terms = wp_get_object_terms( $post->ID, $taxonomy ); if ( ! is_wp_error( $terms ) ) { $term_ids = wp_list_pluck( $terms, 'term_id' ); wp_cache_add( $post->ID, $term_ids, $taxonomy . '_relationships' ); } } $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy ); if ( empty( $terms ) ) { return false; } return $terms; } function get_the_term_list( $post_id, $taxonomy, $before = '', $sep = '', $after = '' ) { $terms = get_the_terms( $post_id, $taxonomy ); if ( is_wp_error( $terms ) ) { return $terms; } if ( empty( $terms ) ) { return false; } $links = array(); foreach ( $terms as $term ) { $link = get_term_link( $term, $taxonomy ); if ( is_wp_error( $link ) ) { return $link; } $links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>'; } $term_links = apply_filters( "term_links-{$taxonomy}", $links ); return $before . implode( $sep, $term_links ) . $after; } function get_term_parents_list( $term_id, $taxonomy, $args = array() ) { $list = ''; $term = get_term( $term_id, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } if ( ! $term ) { return $list; } $term_id = $term->term_id; $defaults = array( 'format' => 'name', 'separator' => '/', 'link' => true, 'inclusive' => true, ); $args = wp_parse_args( $args, $defaults ); foreach ( array( 'link', 'inclusive' ) as $bool ) { $args[ $bool ] = wp_validate_boolean( $args[ $bool ] ); } $parents = get_ancestors( $term_id, $taxonomy, 'taxonomy' ); if ( $args['inclusive'] ) { array_unshift( $parents, $term_id ); } foreach ( array_reverse( $parents ) as $term_id ) { $parent = get_term( $term_id, $taxonomy ); $name = ( 'slug' === $args['format'] ) ? $parent->slug : $parent->name; if ( $args['link'] ) { $list .= '<a href="' . esc_url( get_term_link( $parent->term_id, $taxonomy ) ) . '">' . $name . '</a>' . $args['separator']; } else { $list .= $name . $args['separator']; } } return $list; } function the_terms( $post_id, $taxonomy, $before = '', $sep = ', ', $after = '' ) { $term_list = get_the_term_list( $post_id, $taxonomy, $before, $sep, $after ); if ( is_wp_error( $term_list ) ) { return false; } echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after ); } function has_category( $category = '', $post = null ) { return has_term( $category, 'category', $post ); } function has_tag( $tag = '', $post = null ) { return has_term( $tag, 'post_tag', $post ); } function has_term( $term = '', $taxonomy = '', $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $r = is_object_in_term( $post->ID, $taxonomy, $term ); if ( is_wp_error( $r ) ) { return false; } return $r; }
###require ABSPATH . WPINC . '/comment.php';
function check_comment( $author, $email, $url, $comment, $user_ip, $user_agent, $comment_type ) { global $wpdb; if ( '1' === get_option( 'comment_moderation' ) ) { return false; } $comment = apply_filters( 'comment_text', $comment, null, array() ); $max_links = get_option( 'comment_max_links' ); if ( $max_links ) { $num_links = preg_match_all( '/<a [^>]*href/i', $comment, $out ); $num_links = apply_filters( 'comment_max_links_url', $num_links, $url, $comment ); if ( $num_links >= $max_links ) { return false; } } $mod_keys = trim( get_option( 'moderation_keys' ) ); if ( ! empty( $mod_keys ) ) { $words = explode( "\n", $mod_keys ); foreach ( (array) $words as $word ) { $word = trim( $word ); if ( empty( $word ) ) { continue; } $word = preg_quote( $word, '#' ); $pattern = "#$word#iu"; if ( preg_match( $pattern, $author ) ) { return false; } if ( preg_match( $pattern, $email ) ) { return false; } if ( preg_match( $pattern, $url ) ) { return false; } if ( preg_match( $pattern, $comment ) ) { return false; } if ( preg_match( $pattern, $user_ip ) ) { return false; } if ( preg_match( $pattern, $user_agent ) ) { return false; } } } if ( '1' === get_option( 'comment_previously_approved' ) ) { if ( 'trackback' !== $comment_type && 'pingback' !== $comment_type && '' !== $author && '' !== $email ) { $comment_user = get_user_by( 'email', wp_unslash( $email ) ); if ( ! empty( $comment_user->ID ) ) { $ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved
FROM $wpdb->comments
WHERE user_id = %d
AND comment_approved = '1'
LIMIT 1", $comment_user->ID ) ); } else { $ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved
FROM $wpdb->comments
WHERE comment_author = %s
AND comment_author_email = %s
AND comment_approved = '1'
LIMIT 1", $author, $email ) ); } if ( '1' === $ok_to_comment && ( empty( $mod_keys ) || ! str_contains( $email, $mod_keys ) ) ) { return true; } else { return false; } } else { return false; } } return true; } function get_approved_comments( $post_id, $args = array() ) { if ( ! $post_id ) { return array(); } $defaults = array( 'status' => 1, 'post_id' => $post_id, 'order' => 'ASC', ); $parsed_args = wp_parse_args( $args, $defaults ); $query = new WP_Comment_Query(); return $query->query( $parsed_args ); } function get_comment( $comment = null, $output = OBJECT ) { if ( empty( $comment ) && isset( $GLOBALS['comment'] ) ) { $comment = $GLOBALS['comment']; } if ( $comment instanceof WP_Comment ) { $_comment = $comment; } elseif ( is_object( $comment ) ) { $_comment = new WP_Comment( $comment ); } else { $_comment = WP_Comment::get_instance( $comment ); } if ( ! $_comment ) { return null; } $_comment = apply_filters( 'get_comment', $_comment ); if ( OBJECT === $output ) { return $_comment; } elseif ( ARRAY_A === $output ) { return $_comment->to_array(); } elseif ( ARRAY_N === $output ) { return array_values( $_comment->to_array() ); } return $_comment; } function get_comments( $args = '' ) { $query = new WP_Comment_Query(); return $query->query( $args ); } function get_comment_statuses() { $status = array( 'hold' => __( 'Unapproved' ), 'approve' => _x( 'Approved', 'comment status' ), 'spam' => _x( 'Spam', 'comment status' ), 'trash' => _x( 'Trash', 'comment status' ), ); return $status; } function get_default_comment_status( $post_type = 'post', $comment_type = 'comment' ) { switch ( $comment_type ) { case 'pingback': case 'trackback': $supports = 'trackbacks'; $option = 'ping'; break; default: $supports = 'comments'; $option = 'comment'; break; } if ( 'page' === $post_type ) { $status = 'closed'; } elseif ( post_type_supports( $post_type, $supports ) ) { $status = get_option( "default_{$option}_status" ); } else { $status = 'closed'; } return apply_filters( 'get_default_comment_status', $status, $post_type, $comment_type ); } function get_lastcommentmodified( $timezone = 'server' ) { global $wpdb; $timezone = strtolower( $timezone ); $key = "lastcommentmodified:$timezone"; $comment_modified_date = wp_cache_get( $key, 'timeinfo' ); if ( false !== $comment_modified_date ) { return $comment_modified_date; } switch ( $timezone ) { case 'gmt': $comment_modified_date = $wpdb->get_var( "SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" ); break; case 'blog': $comment_modified_date = $wpdb->get_var( "SELECT comment_date FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" ); break; case 'server': $add_seconds_server = gmdate( 'Z' ); $comment_modified_date = $wpdb->get_var( $wpdb->prepare( "SELECT DATE_ADD(comment_date_gmt, INTERVAL %s SECOND) FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1", $add_seconds_server ) ); break; } if ( $comment_modified_date ) { wp_cache_set( $key, $comment_modified_date, 'timeinfo' ); return $comment_modified_date; } return false; } function get_comment_count( $post_id = 0 ) { $post_id = (int) $post_id; $comment_count = array( 'approved' => 0, 'awaiting_moderation' => 0, 'spam' => 0, 'trash' => 0, 'post-trashed' => 0, 'total_comments' => 0, 'all' => 0, ); $args = array( 'count' => true, 'update_comment_meta_cache' => false, 'orderby' => 'none', ); if ( $post_id > 0 ) { $args['post_id'] = $post_id; } $mapping = array( 'approved' => 'approve', 'awaiting_moderation' => 'hold', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed', ); $comment_count = array(); foreach ( $mapping as $key => $value ) { $comment_count[ $key ] = get_comments( array_merge( $args, array( 'status' => $value ) ) ); } $comment_count['all'] = $comment_count['approved'] + $comment_count['awaiting_moderation']; $comment_count['total_comments'] = $comment_count['all'] + $comment_count['spam']; return array_map( 'intval', $comment_count ); } function add_comment_meta( $comment_id, $meta_key, $meta_value, $unique = false ) { return add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique ); } function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) { return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value ); } function get_comment_meta( $comment_id, $key = '', $single = false ) { return get_metadata( 'comment', $comment_id, $key, $single ); } function wp_lazyload_comment_meta( array $comment_ids ) { if ( empty( $comment_ids ) ) { return; } $lazyloader = wp_metadata_lazyloader(); $lazyloader->queue_objects( 'comment', $comment_ids ); } function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) { return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value ); } function wp_set_comment_cookies( $comment, $user, $cookies_consent = true ) { if ( $user->exists() ) { return; } if ( false === $cookies_consent ) { $past = time() - YEAR_IN_SECONDS; setcookie( 'comment_author_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); setcookie( 'comment_author_email_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); setcookie( 'comment_author_url_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); return; } $comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', YEAR_IN_SECONDS ); $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ); setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); setcookie( 'comment_author_url_' . COOKIEHASH, esc_url( $comment->comment_author_url ), $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); } function sanitize_comment_cookies() { if ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) { $comment_author = apply_filters( 'pre_comment_author_name', $_COOKIE[ 'comment_author_' . COOKIEHASH ] ); $comment_author = wp_unslash( $comment_author ); $comment_author = esc_attr( $comment_author ); $_COOKIE[ 'comment_author_' . COOKIEHASH ] = $comment_author; } if ( isset( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) { $comment_author_email = apply_filters( 'pre_comment_author_email', $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ); $comment_author_email = wp_unslash( $comment_author_email ); $comment_author_email = esc_attr( $comment_author_email ); $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] = $comment_author_email; } if ( isset( $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] ) ) { $comment_author_url = apply_filters( 'pre_comment_author_url', $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] ); $comment_author_url = wp_unslash( $comment_author_url ); $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] = $comment_author_url; } } function wp_allow_comment( $commentdata, $wp_error = false ) { global $wpdb; $dupe = $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ", wp_unslash( $commentdata['comment_post_ID'] ), wp_unslash( $commentdata['comment_parent'] ), wp_unslash( $commentdata['comment_author'] ) ); if ( $commentdata['comment_author_email'] ) { $dupe .= $wpdb->prepare( 'AND comment_author_email = %s ', wp_unslash( $commentdata['comment_author_email'] ) ); } $dupe .= $wpdb->prepare( ') AND comment_content = %s LIMIT 1', wp_unslash( $commentdata['comment_content'] ) ); $dupe_id = $wpdb->get_var( $dupe ); $dupe_id = apply_filters( 'duplicate_comment_id', $dupe_id, $commentdata ); if ( $dupe_id ) { do_action( 'comment_duplicate_trigger', $commentdata ); $comment_duplicate_message = apply_filters( 'comment_duplicate_message', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ) ); if ( $wp_error ) { return new WP_Error( 'comment_duplicate', $comment_duplicate_message, 409 ); } else { if ( wp_doing_ajax() ) { die( $comment_duplicate_message ); } wp_die( $comment_duplicate_message, 409 ); } } do_action( 'check_comment_flood', $commentdata['comment_author_IP'], $commentdata['comment_author_email'], $commentdata['comment_date_gmt'], $wp_error ); $is_flood = apply_filters( 'wp_is_comment_flood', false, $commentdata['comment_author_IP'], $commentdata['comment_author_email'], $commentdata['comment_date_gmt'], $wp_error ); if ( $is_flood ) { $comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) ); return new WP_Error( 'comment_flood', $comment_flood_message, 429 ); } return wp_check_comment_data( $commentdata ); } function check_comment_flood_db() { add_filter( 'wp_is_comment_flood', 'wp_check_comment_flood', 10, 5 ); } function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) { global $wpdb; if ( true === $is_flood ) { return $is_flood; } if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) { return false; } $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); if ( is_user_logged_in() ) { $user = get_current_user_id(); $check_column = '`user_id`'; } else { $user = $ip; $check_column = '`comment_author_IP`'; } $sql = $wpdb->prepare( "SELECT `comment_date_gmt` FROM `$wpdb->comments` WHERE `comment_date_gmt` >= %s AND ( $check_column = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1", $hour_ago, $user, $email ); $lasttime = $wpdb->get_var( $sql ); if ( $lasttime ) { $time_lastcomment = mysql2date( 'U', $lasttime, false ); $time_newcomment = mysql2date( 'U', $date, false ); $flood_die = apply_filters( 'comment_flood_filter', false, $time_lastcomment, $time_newcomment ); if ( $flood_die ) { do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment ); if ( $avoid_die ) { return true; } else { $comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) ); if ( wp_doing_ajax() ) { die( $comment_flood_message ); } wp_die( $comment_flood_message, 429 ); } } } return false; } function separate_comments( &$comments ) { $comments_by_type = array( 'comment' => array(), 'trackback' => array(), 'pingback' => array(), 'pings' => array(), ); $count = count( $comments ); for ( $i = 0; $i < $count; $i++ ) { $type = $comments[ $i ]->comment_type; if ( empty( $type ) ) { $type = 'comment'; } $comments_by_type[ $type ][] = &$comments[ $i ]; if ( 'trackback' === $type || 'pingback' === $type ) { $comments_by_type['pings'][] = &$comments[ $i ]; } } return $comments_by_type; } function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) { global $wp_query; if ( null === $comments && null === $per_page && null === $threaded && ! empty( $wp_query->max_num_comment_pages ) ) { return $wp_query->max_num_comment_pages; } if ( ( ! $comments || ! is_array( $comments ) ) && ! empty( $wp_query->comments ) ) { $comments = $wp_query->comments; } if ( empty( $comments ) ) { return 0; } if ( ! get_option( 'page_comments' ) ) { return 1; } if ( ! isset( $per_page ) ) { $per_page = (int) get_query_var( 'comments_per_page' ); } if ( 0 === $per_page ) { $per_page = (int) get_option( 'comments_per_page' ); } if ( 0 === $per_page ) { return 1; } if ( ! isset( $threaded ) ) { $threaded = get_option( 'thread_comments' ); } if ( $threaded ) { $walker = new Walker_Comment(); $count = ceil( $walker->get_number_of_root_elements( $comments ) / $per_page ); } else { $count = ceil( count( $comments ) / $per_page ); } return (int) $count; } function get_page_of_comment( $comment_id, $args = array() ) { global $wpdb; $page = null; $comment = get_comment( $comment_id ); if ( ! $comment ) { return null; } $defaults = array( 'type' => 'all', 'page' => '', 'per_page' => '', 'max_depth' => '', ); $args = wp_parse_args( $args, $defaults ); $original_args = $args; if ( get_option( 'page_comments' ) ) { if ( '' === $args['per_page'] ) { $args['per_page'] = get_query_var( 'comments_per_page' ); } if ( '' === $args['per_page'] ) { $args['per_page'] = get_option( 'comments_per_page' ); } } if ( empty( $args['per_page'] ) ) { $args['per_page'] = 0; $args['page'] = 0; } if ( $args['per_page'] < 1 ) { $page = 1; } if ( null === $page ) { if ( '' === $args['max_depth'] ) { if ( get_option( 'thread_comments' ) ) { $args['max_depth'] = get_option( 'thread_comments_depth' ); } else { $args['max_depth'] = -1; } } if ( $args['max_depth'] > 1 && '0' !== $comment->comment_parent ) { return get_page_of_comment( $comment->comment_parent, $args ); } $comment_args = array( 'type' => $args['type'], 'post_id' => $comment->comment_post_ID, 'fields' => 'ids', 'count' => true, 'status' => 'approve', 'orderby' => 'none', 'parent' => 0, 'date_query' => array( array( 'column' => "$wpdb->comments.comment_date_gmt", 'before' => $comment->comment_date_gmt, ), ), ); if ( is_user_logged_in() ) { $comment_args['include_unapproved'] = array( get_current_user_id() ); } else { $unapproved_email = wp_get_unapproved_comment_author_email(); if ( $unapproved_email ) { $comment_args['include_unapproved'] = array( $unapproved_email ); } } $comment_args = apply_filters( 'get_page_of_comment_query_args', $comment_args ); $comment_query = new WP_Comment_Query(); $older_comment_count = $comment_query->query( $comment_args ); if ( 0 === $older_comment_count ) { $page = 1; } else { $page = (int) ceil( ( $older_comment_count + 1 ) / $args['per_page'] ); } } return apply_filters( 'get_page_of_comment', (int) $page, $args, $original_args, $comment_id ); } function wp_get_comment_fields_max_lengths() { global $wpdb; $lengths = array( 'comment_author' => 245, 'comment_author_email' => 100, 'comment_author_url' => 200, 'comment_content' => 65525, ); if ( $wpdb->is_mysql ) { foreach ( $lengths as $column => $length ) { $col_length = $wpdb->get_col_length( $wpdb->comments, $column ); $max_length = 0; if ( is_wp_error( $col_length ) ) { break; } if ( ! is_array( $col_length ) && (int) $col_length > 0 ) { $max_length = (int) $col_length; } elseif ( is_array( $col_length ) && isset( $col_length['length'] ) && (int) $col_length['length'] > 0 ) { $max_length = (int) $col_length['length']; if ( ! empty( $col_length['type'] ) && 'byte' === $col_length['type'] ) { $max_length = $max_length - 10; } } if ( $max_length > 0 ) { $lengths[ $column ] = $max_length; } } } return apply_filters( 'wp_get_comment_fields_max_lengths', $lengths ); } function wp_check_comment_data_max_lengths( $comment_data ) { $max_lengths = wp_get_comment_fields_max_lengths(); if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) { return new WP_Error( 'comment_author_column_length', __( '<strong>Error:</strong> Your name is too long.' ), 200 ); } if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) { return new WP_Error( 'comment_author_email_column_length', __( '<strong>Error:</strong> Your email address is too long.' ), 200 ); } if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) { return new WP_Error( 'comment_author_url_column_length', __( '<strong>Error:</strong> Your URL is too long.' ), 200 ); } if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) { return new WP_Error( 'comment_content_column_length', __( '<strong>Error:</strong> Your comment is too long.' ), 200 ); } return true; } function wp_check_comment_data( $comment_data ) { global $wpdb; if ( ! empty( $comment_data['user_id'] ) ) { $user = get_userdata( $comment_data['user_id'] ); $post_author = (int) $wpdb->get_var( $wpdb->prepare( "SELECT post_author FROM $wpdb->posts WHERE ID = %d LIMIT 1", $comment_data['comment_post_ID'] ) ); } if ( isset( $user ) && ( $comment_data['user_id'] === $post_author || $user->has_cap( 'moderate_comments' ) ) ) { $approved = 1; } else { if ( check_comment( $comment_data['comment_author'], $comment_data['comment_author_email'], $comment_data['comment_author_url'], $comment_data['comment_content'], $comment_data['comment_author_IP'], $comment_data['comment_agent'], $comment_data['comment_type'] ) ) { $approved = 1; } else { $approved = 0; } if ( wp_check_comment_disallowed_list( $comment_data['comment_author'], $comment_data['comment_author_email'], $comment_data['comment_author_url'], $comment_data['comment_content'], $comment_data['comment_author_IP'], $comment_data['comment_agent'] ) ) { $approved = EMPTY_TRASH_DAYS ? 'trash' : 'spam'; } } return apply_filters( 'pre_comment_approved', $approved, $comment_data ); } function wp_check_comment_disallowed_list( $author, $email, $url, $comment, $user_ip, $user_agent ) { do_action_deprecated( 'wp_blacklist_check', array( $author, $email, $url, $comment, $user_ip, $user_agent ), '5.5.0', 'wp_check_comment_disallowed_list', __( 'Please consider writing more inclusive code.' ) ); do_action( 'wp_check_comment_disallowed_list', $author, $email, $url, $comment, $user_ip, $user_agent ); $mod_keys = trim( get_option( 'disallowed_keys' ) ); if ( '' === $mod_keys ) { return false; } $comment_without_html = wp_strip_all_tags( $comment ); $words = explode( "\n", $mod_keys ); foreach ( (array) $words as $word ) { $word = trim( $word ); if ( empty( $word ) ) { continue; } $word = preg_quote( $word, '#' ); $pattern = "#$word#iu"; if ( preg_match( $pattern, $author ) || preg_match( $pattern, $email ) || preg_match( $pattern, $url ) || preg_match( $pattern, $comment ) || preg_match( $pattern, $comment_without_html ) || preg_match( $pattern, $user_ip ) || preg_match( $pattern, $user_agent ) ) { return true; } } return false; } function wp_count_comments( $post_id = 0 ) { $post_id = (int) $post_id; $filtered = apply_filters( 'wp_count_comments', array(), $post_id ); if ( ! empty( $filtered ) ) { return $filtered; } $count = wp_cache_get( "comments-{$post_id}", 'counts' ); if ( false !== $count ) { return $count; } $stats = get_comment_count( $post_id ); $stats['moderated'] = $stats['awaiting_moderation']; unset( $stats['awaiting_moderation'] ); $stats_object = (object) $stats; wp_cache_set( "comments-{$post_id}", $stats_object, 'counts' ); return $stats_object; } function wp_delete_comment( $comment_id, $force_delete = false ) { global $wpdb; $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } if ( ! $force_delete && EMPTY_TRASH_DAYS && ! in_array( wp_get_comment_status( $comment ), array( 'trash', 'spam' ), true ) ) { return wp_trash_comment( $comment_id ); } do_action( 'delete_comment', $comment->comment_ID, $comment ); $children = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent = %d", $comment->comment_ID ) ); if ( ! empty( $children ) ) { $wpdb->update( $wpdb->comments, array( 'comment_parent' => $comment->comment_parent ), array( 'comment_parent' => $comment->comment_ID ) ); clean_comment_cache( $children ); } $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->commentmeta WHERE comment_id = %d", $comment->comment_ID ) ); foreach ( $meta_ids as $mid ) { delete_metadata_by_mid( 'comment', $mid ); } if ( ! $wpdb->delete( $wpdb->comments, array( 'comment_ID' => $comment->comment_ID ) ) ) { return false; } do_action( 'deleted_comment', $comment->comment_ID, $comment ); $post_id = $comment->comment_post_ID; if ( $post_id && '1' === $comment->comment_approved ) { wp_update_comment_count( $post_id ); } clean_comment_cache( $comment->comment_ID ); do_action( 'wp_set_comment_status', $comment->comment_ID, 'delete' ); wp_transition_comment_status( 'delete', $comment->comment_approved, $comment ); return true; } function wp_trash_comment( $comment_id ) { if ( ! EMPTY_TRASH_DAYS ) { $comment = get_comment( $comment_id ); $success = wp_delete_comment( $comment_id, true ); if ( ! $success ) { return false; } if ( $comment && 'note' === $comment->comment_type && 0 === (int) $comment->comment_parent ) { $children = $comment->get_children( array( 'fields' => 'ids', 'status' => 'all', 'type' => 'note', ) ); foreach ( $children as $child_id ) { if ( ! wp_delete_comment( $child_id, true ) ) { $success = false; } } } return $success; } $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } do_action( 'trash_comment', $comment->comment_ID, $comment ); if ( wp_set_comment_status( $comment, 'trash' ) ) { delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); do_action( 'trashed_comment', $comment->comment_ID, $comment ); if ( 'note' === $comment->comment_type && 0 === (int) $comment->comment_parent ) { $children = $comment->get_children( array( 'fields' => 'ids', 'status' => 'all', 'type' => 'note', ) ); $success = true; foreach ( $children as $child_id ) { if ( ! wp_trash_comment( $child_id ) ) { $success = false; } } return $success; } return true; } return false; } function wp_untrash_comment( $comment_id ) { $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } do_action( 'untrash_comment', $comment->comment_ID, $comment ); $status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ); if ( empty( $status ) ) { $status = '0'; } if ( wp_set_comment_status( $comment, $status ) ) { delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); do_action( 'untrashed_comment', $comment->comment_ID, $comment ); return true; } return false; } function wp_spam_comment( $comment_id ) { $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } do_action( 'spam_comment', $comment->comment_ID, $comment ); if ( wp_set_comment_status( $comment, 'spam' ) ) { delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); do_action( 'spammed_comment', $comment->comment_ID, $comment ); return true; } return false; } function wp_unspam_comment( $comment_id ) { $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } do_action( 'unspam_comment', $comment->comment_ID, $comment ); $status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ); if ( empty( $status ) ) { $status = '0'; } if ( wp_set_comment_status( $comment, $status ) ) { delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); do_action( 'unspammed_comment', $comment->comment_ID, $comment ); return true; } return false; } function wp_get_comment_status( $comment_id ) { $comment = get_comment( $comment_id ); if ( ! $comment ) { return false; } $approved = $comment->comment_approved; if ( null === $approved ) { return false; } elseif ( '1' === $approved ) { return 'approved'; } elseif ( '0' === $approved ) { return 'unapproved'; } elseif ( 'spam' === $approved ) { return 'spam'; } elseif ( 'trash' === $approved ) { return 'trash'; } else { return false; } } function wp_transition_comment_status( $new_status, $old_status, $comment ) { $comment_statuses = array( 0 => 'unapproved', 'hold' => 'unapproved', 1 => 'approved', 'approve' => 'approved', ); if ( isset( $comment_statuses[ $new_status ] ) ) { $new_status = $comment_statuses[ $new_status ]; } if ( isset( $comment_statuses[ $old_status ] ) ) { $old_status = $comment_statuses[ $old_status ]; } if ( $new_status !== $old_status ) { do_action( 'transition_comment_status', $new_status, $old_status, $comment ); do_action( "comment_{$old_status}_to_{$new_status}", $comment ); } do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment ); } function _clear_modified_cache_on_transition_comment_status( $new_status, $old_status ) { if ( 'approved' === $new_status || 'approved' === $old_status ) { $data = array(); foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { $data[] = "lastcommentmodified:$timezone"; } wp_cache_delete_multiple( $data, 'timeinfo' ); } } function wp_get_current_commenter() { $comment_author = ''; if ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) { $comment_author = $_COOKIE[ 'comment_author_' . COOKIEHASH ]; } $comment_author_email = ''; if ( isset( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) { $comment_author_email = $_COOKIE[ 'comment_author_email_' . COOKIEHASH ]; } $comment_author_url = ''; if ( isset( $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] ) ) { $comment_author_url = $_COOKIE[ 'comment_author_url_' . COOKIEHASH ]; } return apply_filters( 'wp_get_current_commenter', compact( 'comment_author', 'comment_author_email', 'comment_author_url' ) ); } function wp_get_unapproved_comment_author_email() { $commenter_email = ''; if ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) { $comment_id = (int) $_GET['unapproved']; $comment = get_comment( $comment_id ); if ( $comment && hash_equals( $_GET['moderation-hash'], wp_hash( $comment->comment_date_gmt ) ) ) { $comment_preview_expires = strtotime( $comment->comment_date_gmt . '+10 minutes' ); if ( time() < $comment_preview_expires ) { $commenter_email = $comment->comment_author_email; } } } if ( ! $commenter_email ) { $commenter = wp_get_current_commenter(); $commenter_email = $commenter['comment_author_email']; } return $commenter_email; } function wp_insert_comment( $commentdata ) { global $wpdb; $data = wp_unslash( $commentdata ); $comment_author = ! isset( $data['comment_author'] ) ? '' : $data['comment_author']; $comment_author_email = ! isset( $data['comment_author_email'] ) ? '' : $data['comment_author_email']; $comment_author_url = ! isset( $data['comment_author_url'] ) ? '' : $data['comment_author_url']; $comment_author_ip = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP']; $comment_date = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date']; $comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt']; $comment_post_id = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID']; $comment_content = ! isset( $data['comment_content'] ) ? '' : $data['comment_content']; $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; $comment_type = empty( $data['comment_type'] ) ? 'comment' : $data['comment_type']; $comment_parent = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent']; $user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id']; $compacted = array( 'comment_post_ID' => $comment_post_id, 'comment_author_IP' => $comment_author_ip, ); $compacted += compact( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id' ); if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) { return false; } $id = (int) $wpdb->insert_id; if ( 1 === (int) $comment_approved ) { wp_update_comment_count( $comment_post_id ); $data = array(); foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { $data[] = "lastcommentmodified:$timezone"; } wp_cache_delete_multiple( $data, 'timeinfo' ); } clean_comment_cache( $id ); $comment = get_comment( $id ); if ( isset( $commentdata['comment_meta'] ) && is_array( $commentdata['comment_meta'] ) ) { foreach ( $commentdata['comment_meta'] as $meta_key => $meta_value ) { add_comment_meta( $comment->comment_ID, $meta_key, $meta_value, true ); } } do_action( 'wp_insert_comment', $id, $comment ); return $id; } function wp_filter_comment( $commentdata ) { if ( isset( $commentdata['user_ID'] ) ) { $commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_ID'] ); } elseif ( isset( $commentdata['user_id'] ) ) { $commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_id'] ); } $commentdata['comment_agent'] = apply_filters( 'pre_comment_user_agent', ( isset( $commentdata['comment_agent'] ) ? $commentdata['comment_agent'] : '' ) ); $commentdata['comment_author'] = apply_filters( 'pre_comment_author_name', $commentdata['comment_author'] ); $commentdata['comment_content'] = apply_filters( 'pre_comment_content', $commentdata['comment_content'] ); $commentdata['comment_author_IP'] = apply_filters( 'pre_comment_user_ip', $commentdata['comment_author_IP'] ); $commentdata['comment_author_url'] = apply_filters( 'pre_comment_author_url', $commentdata['comment_author_url'] ); $commentdata['comment_author_email'] = apply_filters( 'pre_comment_author_email', $commentdata['comment_author_email'] ); $commentdata['filtered'] = true; return $commentdata; } function wp_throttle_comment_flood( $block, $time_lastcomment, $time_newcomment ) { if ( $block ) { return $block; } if ( ( $time_newcomment - $time_lastcomment ) < 15 ) { return true; } return false; } function wp_new_comment( $commentdata, $wp_error = false ) { global $wpdb; if ( isset( $commentdata['user_ID'] ) ) { $commentdata['user_ID'] = (int) $commentdata['user_ID']; $commentdata['user_id'] = $commentdata['user_ID']; } elseif ( isset( $commentdata['user_id'] ) ) { $commentdata['user_id'] = (int) $commentdata['user_id']; $commentdata['user_ID'] = $commentdata['user_id']; } $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; if ( ! isset( $commentdata['comment_author_IP'] ) ) { $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; } if ( ! isset( $commentdata['comment_agent'] ) ) { $commentdata['comment_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : ''; } $commentdata = apply_filters( 'preprocess_comment', $commentdata ); $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID']; if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) { $commentdata['user_ID'] = (int) $commentdata['user_ID']; $commentdata['user_id'] = $commentdata['user_ID']; } elseif ( isset( $commentdata['user_id'] ) ) { $commentdata['user_id'] = (int) $commentdata['user_id']; $commentdata['user_ID'] = $commentdata['user_id']; } $commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0; $parent_status = ( $commentdata['comment_parent'] > 0 ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : ''; $commentdata['comment_parent'] = ( 'approved' === $parent_status || 'unapproved' === $parent_status ) ? $commentdata['comment_parent'] : 0; $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); $commentdata['comment_agent'] = substr( $commentdata['comment_agent'], 0, 254 ); if ( empty( $commentdata['comment_date'] ) ) { $commentdata['comment_date'] = current_time( 'mysql' ); } if ( empty( $commentdata['comment_date_gmt'] ) ) { $commentdata['comment_date_gmt'] = current_time( 'mysql', true ); } if ( empty( $commentdata['comment_type'] ) ) { $commentdata['comment_type'] = 'comment'; } $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $commentdata = wp_filter_comment( $commentdata ); if ( ! in_array( $commentdata['comment_approved'], array( 'trash', 'spam' ), true ) ) { $commentdata['comment_approved'] = wp_check_comment_data( $commentdata ); } if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $comment_id = wp_insert_comment( $commentdata ); if ( ! $comment_id ) { $fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); foreach ( $fields as $field ) { if ( isset( $commentdata[ $field ] ) ) { $commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] ); } } $commentdata = wp_filter_comment( $commentdata ); $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $comment_id = wp_insert_comment( $commentdata ); if ( ! $comment_id ) { return false; } } do_action( 'comment_post', $comment_id, $commentdata['comment_approved'], $commentdata ); return $comment_id; } function wp_new_comment_notify_moderator( $comment_id ) { $comment = get_comment( $comment_id ); $maybe_notify = ( '0' === $comment->comment_approved ); $maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id ); if ( ! $maybe_notify ) { return false; } return wp_notify_moderator( $comment_id ); } function wp_new_comment_notify_postauthor( $comment_id ) { $comment = get_comment( $comment_id ); $is_note = ( $comment && 'note' === $comment->comment_type ); $maybe_notify = $is_note ? get_option( 'wp_notes_notify', 1 ) : get_option( 'comments_notify' ); $maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_id ); if ( ! $maybe_notify ) { return false; } if ( ! isset( $comment->comment_approved ) || ( '1' !== $comment->comment_approved && ! $is_note ) ) { return false; } return wp_notify_postauthor( $comment_id ); } function wp_new_comment_via_rest_notify_postauthor( $comment ) { if ( $comment instanceof WP_Comment && 'note' === $comment->comment_type ) { wp_new_comment_notify_postauthor( (int) $comment->comment_ID ); } } function wp_set_comment_status( $comment_id, $comment_status, $wp_error = false ) { global $wpdb; switch ( $comment_status ) { case 'hold': case '0': $status = '0'; break; case 'approve': case '1': $status = '1'; add_action( 'wp_set_comment_status', 'wp_new_comment_notify_postauthor' ); break; case 'spam': $status = 'spam'; break; case 'trash': $status = 'trash'; break; default: return false; } $comment_old = clone get_comment( $comment_id ); if ( ! $wpdb->update( $wpdb->comments, array( 'comment_approved' => $status ), array( 'comment_ID' => $comment_old->comment_ID ) ) ) { if ( $wp_error ) { return new WP_Error( 'db_update_error', __( 'Could not update comment status.' ), $wpdb->last_error ); } else { return false; } } clean_comment_cache( $comment_old->comment_ID ); $comment = get_comment( $comment_old->comment_ID ); do_action( 'wp_set_comment_status', $comment->comment_ID, $comment_status ); wp_transition_comment_status( $comment_status, $comment_old->comment_approved, $comment ); wp_update_comment_count( $comment->comment_post_ID ); return true; } function wp_update_comment( $commentarr, $wp_error = false ) { global $wpdb; $comment = get_comment( $commentarr['comment_ID'], ARRAY_A ); if ( empty( $comment ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_comment_id', __( 'Invalid comment ID.' ) ); } else { return false; } } if ( ! empty( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_post_id', __( 'Invalid post ID.' ) ); } else { return false; } } $filter_comment = false; if ( ! has_filter( 'pre_comment_content', 'wp_filter_kses' ) ) { $filter_comment = ! user_can( isset( $comment['user_id'] ) ? $comment['user_id'] : 0, 'unfiltered_html' ); } if ( $filter_comment ) { add_filter( 'pre_comment_content', 'wp_filter_kses' ); } $comment = wp_slash( $comment ); $old_status = $comment['comment_approved']; $commentarr = array_merge( $comment, $commentarr ); $commentarr = wp_filter_comment( $commentarr ); if ( $filter_comment ) { remove_filter( 'pre_comment_content', 'wp_filter_kses' ); } $data = wp_unslash( $commentarr ); $data['comment_content'] = apply_filters( 'comment_save_pre', $data['comment_content'] ); $data['comment_date_gmt'] = get_gmt_from_date( $data['comment_date'] ); if ( ! isset( $data['comment_approved'] ) ) { $data['comment_approved'] = 1; } elseif ( 'hold' === $data['comment_approved'] ) { $data['comment_approved'] = 0; } elseif ( 'approve' === $data['comment_approved'] ) { $data['comment_approved'] = 1; } $comment_id = $data['comment_ID']; $comment_post_id = $data['comment_post_ID']; $data = apply_filters( 'wp_update_comment_data', $data, $comment, $commentarr ); if ( is_wp_error( $data ) ) { if ( $wp_error ) { return $data; } else { return false; } } $keys = array( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id', ); $data = wp_array_slice_assoc( $data, $keys ); $result = $wpdb->update( $wpdb->comments, $data, array( 'comment_ID' => $comment_id ) ); if ( false === $result ) { if ( $wp_error ) { return new WP_Error( 'db_update_error', __( 'Could not update comment in the database.' ), $wpdb->last_error ); } else { return false; } } if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) { foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) { update_comment_meta( $comment_id, $meta_key, $meta_value ); } } clean_comment_cache( $comment_id ); wp_update_comment_count( $comment_post_id ); do_action( 'edit_comment', $comment_id, $data ); $comment = get_comment( $comment_id ); wp_transition_comment_status( $comment->comment_approved, $old_status, $comment ); return $result; } function wp_defer_comment_counting( $defer = null ) { static $_defer = false; if ( is_bool( $defer ) ) { $_defer = $defer; if ( ! $defer ) { wp_update_comment_count( null, true ); } } return $_defer; } function wp_update_comment_count( $post_id, $do_deferred = false ) { static $_deferred = array(); if ( empty( $post_id ) && ! $do_deferred ) { return false; } if ( $do_deferred ) { $_deferred = array_unique( $_deferred ); foreach ( $_deferred as $i => $_post_id ) { wp_update_comment_count_now( $_post_id ); unset( $_deferred[ $i ] ); } } if ( wp_defer_comment_counting() ) { $_deferred[] = $post_id; return true; } elseif ( $post_id ) { return wp_update_comment_count_now( $post_id ); } } function wp_update_comment_count_now( $post_id ) { global $wpdb; $post_id = (int) $post_id; if ( ! $post_id ) { return false; } wp_cache_delete( 'comments-0', 'counts' ); wp_cache_delete( "comments-{$post_id}", 'counts' ); $post = get_post( $post_id ); if ( ! $post ) { return false; } $old = (int) $post->comment_count; $new = apply_filters( 'pre_wp_update_comment_count_now', null, $old, $post_id ); if ( is_null( $new ) ) { $new = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type != 'note'", $post_id ) ); } else { $new = (int) $new; } $wpdb->update( $wpdb->posts, array( 'comment_count' => $new ), array( 'ID' => $post_id ) ); clean_post_cache( $post ); do_action( 'wp_update_comment_count', $post_id, $new, $old ); do_action( "edit_post_{$post->post_type}", $post_id, $post ); do_action( 'edit_post', $post_id, $post ); return true; } function discover_pingback_server_uri( $url, $deprecated = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.7.0' ); } $pingback_str_dquote = 'rel="pingback"'; $pingback_str_squote = 'rel=\'pingback\''; $parsed_url = parse_url( $url ); if ( ! isset( $parsed_url['host'] ) ) { return false; } $uploads_dir = wp_get_upload_dir(); if ( str_starts_with( $url, $uploads_dir['baseurl'] ) ) { return false; } $response = wp_safe_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0', ) ); if ( is_wp_error( $response ) ) { return false; } if ( wp_remote_retrieve_header( $response, 'X-Pingback' ) ) { return wp_remote_retrieve_header( $response, 'X-Pingback' ); } if ( preg_match( '#(image|audio|video|model)/#is', wp_remote_retrieve_header( $response, 'Content-Type' ) ) ) { return false; } $response = wp_safe_remote_get( $url, array( 'timeout' => 2, 'httpversion' => '1.0', ) ); if ( is_wp_error( $response ) ) { return false; } $contents = wp_remote_retrieve_body( $response ); $pingback_link_offset_dquote = strpos( $contents, $pingback_str_dquote ); $pingback_link_offset_squote = strpos( $contents, $pingback_str_squote ); if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) { $quote = ( $pingback_link_offset_dquote ) ? '"' : '\''; $pingback_link_offset = ( '"' === $quote ) ? $pingback_link_offset_dquote : $pingback_link_offset_squote; $pingback_href_pos = strpos( $contents, 'href=', $pingback_link_offset ); $pingback_href_start = $pingback_href_pos + 6; $pingback_href_end = strpos( $contents, $quote, $pingback_href_start ); $pingback_server_url_len = $pingback_href_end - $pingback_href_start; $pingback_server_url = substr( $contents, $pingback_href_start, $pingback_server_url_len ); if ( $pingback_server_url_len > 0 ) { return $pingback_server_url; } } return false; } function do_all_pings() { do_action( 'do_all_pings' ); } function do_all_pingbacks() { $pings = get_posts( array( 'post_type' => get_post_types(), 'suppress_filters' => false, 'nopaging' => true, 'meta_key' => '_pingme', 'fields' => 'ids', ) ); foreach ( $pings as $ping ) { delete_post_meta( $ping, '_pingme' ); pingback( null, $ping ); } } function do_all_enclosures() { $enclosures = get_posts( array( 'post_type' => get_post_types(), 'suppress_filters' => false, 'nopaging' => true, 'meta_key' => '_encloseme', 'fields' => 'ids', ) ); foreach ( $enclosures as $enclosure ) { delete_post_meta( $enclosure, '_encloseme' ); do_enclose( null, $enclosure ); } } function do_all_trackbacks() { $trackbacks = get_posts( array( 'post_type' => get_post_types(), 'suppress_filters' => false, 'nopaging' => true, 'meta_key' => '_trackbackme', 'fields' => 'ids', ) ); foreach ( $trackbacks as $trackback ) { delete_post_meta( $trackback, '_trackbackme' ); do_trackbacks( $trackback ); } } function do_trackbacks( $post ) { global $wpdb; $post = get_post( $post ); if ( ! $post ) { return false; } $to_ping = get_to_ping( $post ); $pinged = get_pung( $post ); if ( empty( $to_ping ) ) { $wpdb->update( $wpdb->posts, array( 'to_ping' => '' ), array( 'ID' => $post->ID ) ); return; } if ( empty( $post->post_excerpt ) ) { $excerpt = apply_filters( 'the_content', $post->post_content, $post->ID ); } else { $excerpt = apply_filters( 'the_excerpt', $post->post_excerpt ); } $excerpt = str_replace( ']]>', ']]>', $excerpt ); $excerpt = wp_html_excerpt( $excerpt, 252, '…' ); $post_title = apply_filters( 'the_title', $post->post_title, $post->ID ); $post_title = strip_tags( $post_title ); foreach ( (array) $to_ping as $tb_ping ) { $tb_ping = trim( $tb_ping ); if ( ! in_array( $tb_ping, $pinged, true ) ) { trackback( $tb_ping, $post_title, $excerpt, $post->ID ); $pinged[] = $tb_ping; } else { $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $tb_ping, $post->ID ) ); } } } function generic_ping( $post_id = 0 ) { $services = get_option( 'ping_sites' ); $services = explode( "\n", $services ); foreach ( (array) $services as $service ) { $service = trim( $service ); if ( '' !== $service ) { weblog_ping( $service ); } } return $post_id; } function pingback( $content, $post ) { require_once ABSPATH . WPINC . '/class-IXR.php'; require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php'; $post_links = array(); $post = get_post( $post ); if ( ! $post ) { return array(); } $pung = get_pung( $post ); if ( empty( $content ) ) { $content = $post->post_content; } $post_links_temp = wp_extract_urls( $content ); $ping_status = array(); foreach ( (array) $post_links_temp as $link_test ) { if ( ! in_array( $link_test, $pung, true ) && ( url_to_postid( $link_test ) !== $post->ID ) && ! is_local_attachment( $link_test ) ) { $test = parse_url( $link_test ); if ( $test ) { if ( isset( $test['query'] ) ) { $post_links[] = $link_test; } elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) { $post_links[] = $link_test; } } } } $post_links = array_unique( $post_links ); do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) ); foreach ( (array) $post_links as $pagelinkedto ) { $pingback_server_url = discover_pingback_server_uri( $pagelinkedto ); if ( $pingback_server_url ) { if ( function_exists( 'set_time_limit' ) ) { set_time_limit( 60 ); } $pagelinkedfrom = get_permalink( $post ); $client = new WP_HTTP_IXR_Client( $pingback_server_url ); $client->timeout = 3; $client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom ); $client->debug = false; $status = $client->query( 'pingback.ping', $pagelinkedfrom, $pagelinkedto ); if ( $status || ( isset( $client->error->code ) && 48 === $client->error->code ) ) { add_ping( $post, $pagelinkedto ); } $ping_status[ $pagelinkedto ] = $status; } } return $ping_status; } function privacy_ping_filter( $sites ) { if ( '0' !== get_option( 'blog_public' ) ) { return $sites; } else { return ''; } } function trackback( $trackback_url, $title, $excerpt, $post_id ) { global $wpdb; if ( empty( $trackback_url ) ) { return; } $options = array(); $options['timeout'] = 10; $options['body'] = array( 'title' => $title, 'url' => get_permalink( $post_id ), 'blog_name' => get_option( 'blogname' ), 'excerpt' => $excerpt, ); $response = wp_safe_remote_post( $trackback_url, $options ); if ( is_wp_error( $response ) ) { return; } $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET pinged = CONCAT(pinged, '\n', %s) WHERE ID = %d", $trackback_url, $post_id ) ); return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $trackback_url, $post_id ) ); } function weblog_ping( $server = '', $path = '' ) { require_once ABSPATH . WPINC . '/class-IXR.php'; require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php'; $client = new WP_HTTP_IXR_Client( $server, ( ( ! strlen( trim( $path ) ) || ( '/' === $path ) ) ? false : $path ) ); $client->timeout = 3; $client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' ); $client->debug = false; $home = trailingslashit( home_url() ); if ( ! $client->query( 'weblogUpdates.extendedPing', get_option( 'blogname' ), $home, get_bloginfo( 'rss2_url' ) ) ) { $client->query( 'weblogUpdates.ping', get_option( 'blogname' ), $home ); } } function pingback_ping_source_uri( $source_uri ) { return (string) wp_http_validate_url( $source_uri ); } function xmlrpc_pingback_error( $ixr_error ) { if ( 48 === $ixr_error->code ) { return $ixr_error; } return new IXR_Error( 0, '' ); } function clean_comment_cache( $ids ) { $comment_ids = (array) $ids; wp_cache_delete_multiple( $comment_ids, 'comment' ); foreach ( $comment_ids as $id ) { do_action( 'clean_comment_cache', $id ); } wp_cache_set_comments_last_changed(); } function update_comment_cache( $comments, $update_meta_cache = true ) { $data = array(); foreach ( (array) $comments as $comment ) { $data[ $comment->comment_ID ] = $comment; } wp_cache_add_multiple( $data, 'comment' ); if ( $update_meta_cache ) { $comment_ids = array(); foreach ( $comments as $comment ) { $comment_ids[] = $comment->comment_ID; } update_meta_cache( 'comment', $comment_ids ); } } function _prime_comment_caches( $comment_ids, $update_meta_cache = true ) { global $wpdb; $non_cached_ids = _get_non_cached_ids( $comment_ids, 'comment' ); if ( ! empty( $non_cached_ids ) ) { $fresh_comments = $wpdb->get_results( sprintf( "SELECT $wpdb->comments.* FROM $wpdb->comments WHERE comment_ID IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); update_comment_cache( $fresh_comments, false ); } if ( $update_meta_cache ) { wp_lazyload_comment_meta( $comment_ids ); } } function _close_comments_for_old_posts( $posts, $query ) { if ( empty( $posts ) || ! $query->is_singular() || ! get_option( 'close_comments_for_old_posts' ) ) { return $posts; } $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) ); if ( ! in_array( $posts[0]->post_type, $post_types, true ) ) { return $posts; } $days_old = (int) get_option( 'close_comments_days_old' ); if ( ! $days_old ) { return $posts; } if ( time() - strtotime( $posts[0]->post_date_gmt ) > ( $days_old * DAY_IN_SECONDS ) ) { $posts[0]->comment_status = 'closed'; $posts[0]->ping_status = 'closed'; } return $posts; } function _close_comments_for_old_post( $open, $post_id ) { if ( ! $open ) { return $open; } if ( ! get_option( 'close_comments_for_old_posts' ) ) { return $open; } $days_old = (int) get_option( 'close_comments_days_old' ); if ( ! $days_old ) { return $open; } $post = get_post( $post_id ); $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) ); if ( ! in_array( $post->post_type, $post_types, true ) ) { return $open; } if ( '0000-00-00 00:00:00' === $post->post_date_gmt ) { return $open; } if ( time() - strtotime( $post->post_date_gmt ) > ( $days_old * DAY_IN_SECONDS ) ) { return false; } return $open; } function wp_handle_comment_submission( $comment_data ) { $comment_post_id = 0; $comment_author = ''; $comment_author_email = ''; $comment_author_url = ''; $comment_content = ''; $comment_parent = 0; $user_id = 0; if ( isset( $comment_data['comment_post_ID'] ) ) { $comment_post_id = (int) $comment_data['comment_post_ID']; } if ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) ) { $comment_author = trim( strip_tags( $comment_data['author'] ) ); } if ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) ) { $comment_author_email = trim( $comment_data['email'] ); } if ( isset( $comment_data['url'] ) && is_string( $comment_data['url'] ) ) { $comment_author_url = trim( $comment_data['url'] ); } if ( isset( $comment_data['comment'] ) && is_string( $comment_data['comment'] ) ) { $comment_content = trim( $comment_data['comment'] ); } if ( isset( $comment_data['comment_parent'] ) ) { $comment_parent = absint( $comment_data['comment_parent'] ); $comment_parent_object = get_comment( $comment_parent ); if ( 0 !== $comment_parent && ( ! $comment_parent_object instanceof WP_Comment || 0 === (int) $comment_parent_object->comment_approved ) ) { do_action( 'comment_reply_to_unapproved_comment', $comment_post_id, $comment_parent ); return new WP_Error( 'comment_reply_to_unapproved_comment', __( 'Sorry, replies to unapproved comments are not allowed.' ), 403 ); } } $post = get_post( $comment_post_id ); if ( empty( $post->comment_status ) ) { do_action( 'comment_id_not_found', $comment_post_id ); return new WP_Error( 'comment_id_not_found' ); } $status = get_post_status( $post ); if ( ( 'private' === $status ) && ! current_user_can( 'read_post', $comment_post_id ) ) { return new WP_Error( 'comment_id_not_found' ); } $status_obj = get_post_status_object( $status ); if ( ! comments_open( $comment_post_id ) ) { do_action( 'comment_closed', $comment_post_id ); return new WP_Error( 'comment_closed', __( 'Sorry, comments are closed for this item.' ), 403 ); } elseif ( 'trash' === $status ) { do_action( 'comment_on_trash', $comment_post_id ); return new WP_Error( 'comment_on_trash' ); } elseif ( ! $status_obj->public && ! $status_obj->private ) { do_action( 'comment_on_draft', $comment_post_id ); if ( current_user_can( 'read_post', $comment_post_id ) ) { return new WP_Error( 'comment_on_draft', __( 'Sorry, comments are not allowed for this item.' ), 403 ); } else { return new WP_Error( 'comment_on_draft' ); } } elseif ( post_password_required( $comment_post_id ) ) { do_action( 'comment_on_password_protected', $comment_post_id ); return new WP_Error( 'comment_on_password_protected' ); } else { do_action( 'pre_comment_on_post', $comment_post_id ); } $user = wp_get_current_user(); if ( $user->exists() ) { if ( empty( $user->display_name ) ) { $user->display_name = $user->user_login; } $comment_author = $user->display_name; $comment_author_email = $user->user_email; $comment_author_url = $user->user_url; $user_id = $user->ID; if ( current_user_can( 'unfiltered_html' ) ) { if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] ) || ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_id ) ) { kses_remove_filters(); kses_init_filters(); remove_filter( 'pre_comment_content', 'wp_filter_post_kses' ); add_filter( 'pre_comment_content', 'wp_filter_kses' ); } } } else { if ( get_option( 'comment_registration' ) ) { return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to comment.' ), 403 ); } } $comment_type = 'comment'; if ( get_option( 'require_name_email' ) && ! $user->exists() ) { if ( '' === $comment_author_email || '' === $comment_author ) { return new WP_Error( 'require_name_email', __( '<strong>Error:</strong> Please fill the required fields.' ), 200 ); } elseif ( ! is_email( $comment_author_email ) ) { return new WP_Error( 'require_valid_email', __( '<strong>Error:</strong> Please enter a valid email address.' ), 200 ); } } $commentdata = array( 'comment_post_ID' => $comment_post_id, ); $commentdata += compact( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_id' ); $allow_empty_comment = apply_filters( 'allow_empty_comment', false, $commentdata ); if ( '' === $comment_content && ! $allow_empty_comment ) { return new WP_Error( 'require_valid_comment', __( '<strong>Error:</strong> Please type your comment text.' ), 200 ); } $check_max_lengths = wp_check_comment_data_max_lengths( $commentdata ); if ( is_wp_error( $check_max_lengths ) ) { return $check_max_lengths; } $comment_id = wp_new_comment( wp_slash( $commentdata ), true ); if ( is_wp_error( $comment_id ) ) { return $comment_id; } if ( ! $comment_id ) { return new WP_Error( 'comment_save_error', __( '<strong>Error:</strong> The comment could not be saved. Please try again later.' ), 500 ); } return get_comment( $comment_id ); } function wp_register_comment_personal_data_exporter( $exporters ) { $exporters['wordpress-comments'] = array( 'exporter_friendly_name' => __( 'WordPress Comments' ), 'callback' => 'wp_comments_personal_data_exporter', ); return $exporters; } function wp_comments_personal_data_exporter( $email_address, $page = 1 ) { $number = 500; $page = (int) $page; $data_to_export = array(); $comments = get_comments( array( 'author_email' => $email_address, 'number' => $number, 'paged' => $page, 'orderby' => 'comment_ID', 'order' => 'ASC', 'update_comment_meta_cache' => false, ) ); $comment_prop_to_export = array( 'comment_author' => __( 'Comment Author' ), 'comment_author_email' => __( 'Comment Author Email' ), 'comment_author_url' => __( 'Comment Author URL' ), 'comment_author_IP' => __( 'Comment Author IP' ), 'comment_agent' => __( 'Comment Author User Agent' ), 'comment_date' => __( 'Comment Date' ), 'comment_content' => __( 'Comment Content' ), 'comment_link' => __( 'Comment URL' ), ); foreach ( (array) $comments as $comment ) { $comment_data_to_export = array(); foreach ( $comment_prop_to_export as $key => $name ) { $value = ''; switch ( $key ) { case 'comment_author': case 'comment_author_email': case 'comment_author_url': case 'comment_author_IP': case 'comment_agent': case 'comment_date': $value = $comment->{$key}; break; case 'comment_content': $value = get_comment_text( $comment->comment_ID ); break; case 'comment_link': $value = get_comment_link( $comment->comment_ID ); $value = sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $value ), esc_html( $value ) ); break; } if ( ! empty( $value ) ) { $comment_data_to_export[] = array( 'name' => $name, 'value' => $value, ); } } $data_to_export[] = array( 'group_id' => 'comments', 'group_label' => __( 'Comments' ), 'group_description' => __( 'User’s comment data.' ), 'item_id' => "comment-{$comment->comment_ID}", 'data' => $comment_data_to_export, ); } $done = count( $comments ) < $number; return array( 'data' => $data_to_export, 'done' => $done, ); } function wp_register_comment_personal_data_eraser( $erasers ) { $erasers['wordpress-comments'] = array( 'eraser_friendly_name' => __( 'WordPress Comments' ), 'callback' => 'wp_comments_personal_data_eraser', ); return $erasers; } function wp_comments_personal_data_eraser( $email_address, $page = 1 ) { global $wpdb; if ( empty( $email_address ) ) { return array( 'items_removed' => false, 'items_retained' => false, 'messages' => array(), 'done' => true, ); } $number = 500; $page = (int) $page; $items_removed = false; $items_retained = false; $comments = get_comments( array( 'author_email' => $email_address, 'number' => $number, 'paged' => $page, 'orderby' => 'comment_ID', 'order' => 'ASC', 'include_unapproved' => true, ) ); $anon_author = __( 'Anonymous' ); $messages = array(); foreach ( (array) $comments as $comment ) { $anonymized_comment = array(); $anonymized_comment['comment_agent'] = ''; $anonymized_comment['comment_author'] = $anon_author; $anonymized_comment['comment_author_email'] = ''; $anonymized_comment['comment_author_IP'] = wp_privacy_anonymize_data( 'ip', $comment->comment_author_IP ); $anonymized_comment['comment_author_url'] = ''; $anonymized_comment['user_id'] = 0; $comment_id = (int) $comment->comment_ID; $anon_message = apply_filters( 'wp_anonymize_comment', true, $comment, $anonymized_comment ); if ( true !== $anon_message ) { if ( $anon_message && is_string( $anon_message ) ) { $messages[] = esc_html( $anon_message ); } else { $messages[] = sprintf( __( 'Comment %d contains personal data but could not be anonymized.' ), $comment_id ); } $items_retained = true; continue; } $args = array( 'comment_ID' => $comment_id, ); $updated = $wpdb->update( $wpdb->comments, $anonymized_comment, $args ); if ( $updated ) { $items_removed = true; clean_comment_cache( $comment_id ); } else { $items_retained = true; } } $done = count( $comments ) < $number; return array( 'items_removed' => $items_removed, 'items_retained' => $items_retained, 'messages' => $messages, 'done' => $done, ); } function wp_cache_set_comments_last_changed() { wp_cache_set_last_changed( 'comment' ); } function _wp_batch_update_comment_type() { global $wpdb; $lock_name = 'update_comment_type.lock'; $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) ); if ( ! $lock_result ) { $lock_result = get_option( $lock_name ); if ( ! $lock_result || ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) ) { wp_schedule_single_event( time() + ( 5 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); return; } } update_option( $lock_name, time() ); $empty_comment_type = $wpdb->get_var( "SELECT comment_ID FROM $wpdb->comments
WHERE comment_type = ''
LIMIT 1" ); if ( ! $empty_comment_type ) { update_option( 'finished_updating_comment_type', true ); delete_option( $lock_name ); return; } wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); $comment_batch_size = (int) apply_filters( 'wp_update_comment_type_batch_size', 100 ); $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID
FROM {$wpdb->comments}
WHERE comment_type = ''
ORDER BY comment_ID DESC
LIMIT %d", $comment_batch_size ) ); if ( $comment_ids ) { $comment_id_list = implode( ',', $comment_ids ); $wpdb->query( "UPDATE {$wpdb->comments}
SET comment_type = 'comment'
WHERE comment_type = ''
AND comment_ID IN ({$comment_id_list})" ); clean_comment_cache( $comment_ids ); } delete_option( $lock_name ); } function _wp_check_for_scheduled_update_comment_type() { if ( ! get_option( 'finished_updating_comment_type' ) && ! wp_next_scheduled( 'wp_update_comment_type_batch' ) ) { wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'wp_update_comment_type_batch' ); } } function wp_create_initial_comment_meta() { register_meta( 'comment', '_wp_note_status', array( 'type' => 'string', 'description' => __( 'Note resolution status' ), 'single' => true, 'show_in_rest' => array( 'schema' => array( 'type' => 'string', 'enum' => array( 'resolved', 'reopen' ), ), ), 'auth_callback' => function ( $allowed, $meta_key, $object_id ) { return current_user_can( 'edit_comment', $object_id ); }, ) ); }
###require ABSPATH . WPINC . '/class-wp-comment.php';
final class WP_Comment { public $comment_ID; public $comment_post_ID = '0'; public $comment_author = ''; public $comment_author_email = ''; public $comment_author_url = ''; public $comment_author_IP = ''; public $comment_date = '0000-00-00 00:00:00'; public $comment_date_gmt = '0000-00-00 00:00:00'; public $comment_content; public $comment_karma = '0'; public $comment_approved = '1'; public $comment_agent = ''; public $comment_type = 'comment'; public $comment_parent = '0'; public $user_id = '0'; protected $children; protected $populated_children = false; protected $post_fields = array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_content_filtered', 'post_parent', 'guid', 'menu_order', 'post_type', 'post_mime_type', 'comment_count' ); public static function get_instance( $id ) { global $wpdb; $comment_id = (int) $id; if ( ! $comment_id ) { return false; } $_comment = wp_cache_get( $comment_id, 'comment' ); if ( ! $_comment ) { $_comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_ID = %d LIMIT 1", $comment_id ) ); if ( ! $_comment ) { return false; } wp_cache_add( $_comment->comment_ID, $_comment, 'comment' ); } return new WP_Comment( $_comment ); } public function __construct( $comment ) { foreach ( get_object_vars( $comment ) as $key => $value ) { $this->$key = $value; } } public function to_array() { return get_object_vars( $this ); } public function get_children( $args = array() ) { $defaults = array( 'format' => 'tree', 'status' => 'all', 'hierarchical' => 'threaded', 'orderby' => '', ); $_args = wp_parse_args( $args, $defaults ); $_args['parent'] = $this->comment_ID; if ( is_null( $this->children ) ) { if ( $this->populated_children ) { $this->children = array(); } else { $this->children = get_comments( $_args ); } } if ( 'flat' === $_args['format'] ) { $children = array(); foreach ( $this->children as $child ) { $child_args = $_args; $child_args['format'] = 'flat'; unset( $child_args['parent'] ); $children = array_merge( $children, array( $child ), $child->get_children( $child_args ) ); } } else { $children = $this->children; } return $children; } public function add_child( WP_Comment $child ) { $this->children[ $child->comment_ID ] = $child; } public function get_child( $child_id ) { if ( isset( $this->children[ $child_id ] ) ) { return $this->children[ $child_id ]; } return false; } public function populated_children( $set ) { $this->populated_children = (bool) $set; } public function __isset( $name ) { if ( in_array( $name, $this->post_fields, true ) && 0 !== (int) $this->comment_post_ID ) { $post = get_post( $this->comment_post_ID ); return property_exists( $post, $name ); } return false; } public function __get( $name ) { if ( in_array( $name, $this->post_fields, true ) ) { $post = get_post( $this->comment_post_ID ); return $post->$name; } } }
###require ABSPATH . WPINC . '/class-wp-comment-query.php';
class WP_Comment_Query { public $request; public $meta_query = false; protected $meta_query_clauses; protected $sql_clauses = array( 'select' => '', 'from' => '', 'where' => array(), 'groupby' => '', 'orderby' => '', 'limits' => '', ); protected $filtered_where_clause; public $date_query = false; public $query_vars; public $query_var_defaults; public $comments; public $found_comments = 0; public $max_num_pages = 0; public function __call( $name, $arguments ) { if ( 'get_search_sql' === $name ) { return $this->get_search_sql( ...$arguments ); } return false; } public function __construct( $query = '' ) { $this->query_var_defaults = array( 'author_email' => '', 'author_url' => '', 'author__in' => '', 'author__not_in' => '', 'include_unapproved' => '', 'fields' => '', 'ID' => '', 'comment__in' => '', 'comment__not_in' => '', 'karma' => '', 'number' => '', 'offset' => '', 'no_found_rows' => true, 'orderby' => '', 'order' => 'DESC', 'paged' => 1, 'parent' => '', 'parent__in' => '', 'parent__not_in' => '', 'post_author__in' => '', 'post_author__not_in' => '', 'post_ID' => '', 'post_id' => 0, 'post__in' => '', 'post__not_in' => '', 'post_author' => '', 'post_name' => '', 'post_parent' => '', 'post_status' => '', 'post_type' => '', 'status' => 'all', 'type' => '', 'type__in' => '', 'type__not_in' => '', 'user_id' => '', 'search' => '', 'count' => false, 'meta_key' => '', 'meta_value' => '', 'meta_query' => '', 'date_query' => null, 'hierarchical' => false, 'cache_domain' => 'core', 'update_comment_meta_cache' => true, 'update_comment_post_cache' => false, ); if ( ! empty( $query ) ) { $this->query( $query ); } } public function parse_query( $query = '' ) { if ( empty( $query ) ) { $query = $this->query_vars; } $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); do_action_ref_array( 'parse_comment_query', array( &$this ) ); } public function query( $query ) { $this->query_vars = wp_parse_args( $query ); return $this->get_comments(); } public function get_comments() { global $wpdb; $this->parse_query(); $this->meta_query = new WP_Meta_Query(); $this->meta_query->parse_query_vars( $this->query_vars ); do_action_ref_array( 'pre_get_comments', array( &$this ) ); $this->meta_query->parse_query_vars( $this->query_vars ); if ( ! empty( $this->meta_query->queries ) ) { $this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this ); } $comment_data = null; $comment_data = apply_filters_ref_array( 'comments_pre_query', array( $comment_data, &$this ) ); if ( null !== $comment_data ) { if ( is_array( $comment_data ) && ! $this->query_vars['count'] ) { $this->comments = $comment_data; } return $comment_data; } $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); unset( $_args['fields'], $_args['update_comment_meta_cache'], $_args['update_comment_post_cache'] ); $key = md5( serialize( $_args ) ); $last_changed = wp_cache_get_last_changed( 'comment' ); $cache_key = "get_comments:$key"; $cache_value = wp_cache_get_salted( $cache_key, 'comment-queries', $last_changed ); if ( false === $cache_value ) { $comment_ids = $this->get_comment_ids(); if ( $comment_ids ) { $this->set_found_comments(); } $cache_value = array( 'comment_ids' => $comment_ids, 'found_comments' => $this->found_comments, ); wp_cache_set_salted( $cache_key, $cache_value, 'comment-queries', $last_changed ); } else { $comment_ids = $cache_value['comment_ids']; $this->found_comments = $cache_value['found_comments']; } if ( $this->found_comments && $this->query_vars['number'] ) { $this->max_num_pages = (int) ceil( $this->found_comments / $this->query_vars['number'] ); } if ( $this->query_vars['count'] ) { return (int) $comment_ids; } $comment_ids = array_map( 'intval', $comment_ids ); if ( $this->query_vars['update_comment_meta_cache'] ) { wp_lazyload_comment_meta( $comment_ids ); } if ( 'ids' === $this->query_vars['fields'] ) { $this->comments = $comment_ids; return $this->comments; } _prime_comment_caches( $comment_ids, false ); $_comments = array(); foreach ( $comment_ids as $comment_id ) { $_comment = get_comment( $comment_id ); if ( $_comment ) { $_comments[] = $_comment; } } if ( $this->query_vars['update_comment_post_cache'] ) { $comment_post_ids = array(); foreach ( $_comments as $_comment ) { $comment_post_ids[] = $_comment->comment_post_ID; } _prime_post_caches( $comment_post_ids, false, false ); } $_comments = apply_filters_ref_array( 'the_comments', array( $_comments, &$this ) ); $comments = array_map( 'get_comment', $_comments ); if ( $this->query_vars['hierarchical'] ) { $comments = $this->fill_descendants( $comments ); } $this->comments = $comments; return $this->comments; } protected function get_comment_ids() { global $wpdb; $approved_clauses = array(); $status_clauses = array(); $statuses = wp_parse_list( $this->query_vars['status'] ); if ( empty( $statuses ) ) { $statuses = array( 'all' ); } if ( ! in_array( 'any', $statuses, true ) ) { foreach ( $statuses as $status ) { switch ( $status ) { case 'hold': $status_clauses[] = "comment_approved = '0'"; break; case 'approve': $status_clauses[] = "comment_approved = '1'"; break; case 'all': case '': $status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )"; break; default: $status_clauses[] = $wpdb->prepare( 'comment_approved = %s', $status ); break; } } $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; } if ( ! empty( $this->query_vars['include_unapproved'] ) ) { $include_unapproved = wp_parse_list( $this->query_vars['include_unapproved'] ); foreach ( $include_unapproved as $unapproved_identifier ) { if ( is_numeric( $unapproved_identifier ) ) { $approved_clauses[] = $wpdb->prepare( "( user_id = %d AND comment_approved = '0' )", $unapproved_identifier ); } else { if ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) { $approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' AND {$wpdb->comments}.comment_ID = %d )", $unapproved_identifier, (int) $_GET['unapproved'] ); } else { $approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier ); } } } } if ( ! empty( $approved_clauses ) ) { if ( 1 === count( $approved_clauses ) ) { $this->sql_clauses['where']['approved'] = $approved_clauses[0]; } else { $this->sql_clauses['where']['approved'] = '( ' . implode( ' OR ', $approved_clauses ) . ' )'; } } $order = ( 'ASC' === strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC'; if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) { $orderby = ''; } elseif ( ! empty( $this->query_vars['orderby'] ) ) { $ordersby = is_array( $this->query_vars['orderby'] ) ? $this->query_vars['orderby'] : preg_split( '/[,\s]/', $this->query_vars['orderby'] ); $orderby_array = array(); $found_orderby_comment_id = false; foreach ( $ordersby as $_key => $_value ) { if ( ! $_value ) { continue; } if ( is_int( $_key ) ) { $_orderby = $_value; $_order = $order; } else { $_orderby = $_key; $_order = $_value; } if ( ! $found_orderby_comment_id && in_array( $_orderby, array( 'comment_ID', 'comment__in' ), true ) ) { $found_orderby_comment_id = true; } $parsed = $this->parse_orderby( $_orderby ); if ( ! $parsed ) { continue; } if ( 'comment__in' === $_orderby ) { $orderby_array[] = $parsed; continue; } $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); } if ( empty( $orderby_array ) ) { $orderby_array[] = "$wpdb->comments.comment_date_gmt $order"; } if ( ! $found_orderby_comment_id ) { $comment_id_order = ''; foreach ( $orderby_array as $orderby_clause ) { if ( preg_match( '/comment_date(?:_gmt)*\ (ASC|DESC)/', $orderby_clause, $match ) ) { $comment_id_order = $match[1]; break; } } if ( ! $comment_id_order ) { foreach ( $orderby_array as $orderby_clause ) { if ( str_contains( 'ASC', $orderby_clause ) ) { $comment_id_order = 'ASC'; } else { $comment_id_order = 'DESC'; } break; } } if ( ! $comment_id_order ) { $comment_id_order = 'DESC'; } $orderby_array[] = "$wpdb->comments.comment_ID $comment_id_order"; } $orderby = implode( ', ', $orderby_array ); } else { $orderby = "$wpdb->comments.comment_date_gmt $order"; } $number = absint( $this->query_vars['number'] ); $offset = absint( $this->query_vars['offset'] ); $paged = absint( $this->query_vars['paged'] ); $limits = ''; if ( ! empty( $number ) ) { if ( $offset ) { $limits = 'LIMIT ' . $offset . ',' . $number; } else { $limits = 'LIMIT ' . ( $number * ( $paged - 1 ) ) . ',' . $number; } } if ( $this->query_vars['count'] ) { $fields = 'COUNT(*)'; } else { $fields = "$wpdb->comments.comment_ID"; } $post_id = absint( $this->query_vars['post_id'] ); if ( ! empty( $post_id ) ) { $this->sql_clauses['where']['post_id'] = $wpdb->prepare( 'comment_post_ID = %d', $post_id ); } if ( ! empty( $this->query_vars['comment__in'] ) ) { $this->sql_clauses['where']['comment__in'] = "$wpdb->comments.comment_ID IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['comment__not_in'] ) ) { $this->sql_clauses['where']['comment__not_in'] = "$wpdb->comments.comment_ID NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['parent__in'] ) ) { $this->sql_clauses['where']['parent__in'] = 'comment_parent IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['parent__not_in'] ) ) { $this->sql_clauses['where']['parent__not_in'] = 'comment_parent NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__not_in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['post__in'] ) ) { $this->sql_clauses['where']['post__in'] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['post__not_in'] ) ) { $this->sql_clauses['where']['post__not_in'] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )'; } if ( '' !== $this->query_vars['author_email'] ) { $this->sql_clauses['where']['author_email'] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] ); } if ( '' !== $this->query_vars['author_url'] ) { $this->sql_clauses['where']['author_url'] = $wpdb->prepare( 'comment_author_url = %s', $this->query_vars['author_url'] ); } if ( '' !== $this->query_vars['karma'] ) { $this->sql_clauses['where']['karma'] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] ); } $raw_types = array( 'IN' => array_merge( (array) $this->query_vars['type'], (array) $this->query_vars['type__in'] ), 'NOT IN' => (array) $this->query_vars['type__not_in'], ); if ( ! in_array( 'all', $raw_types['IN'], true ) && ! in_array( 'note', $raw_types['IN'], true ) && ! in_array( 'note', $raw_types['NOT IN'], true ) ) { $raw_types['NOT IN'][] = 'note'; } $comment_types = array(); foreach ( $raw_types as $operator => $_raw_types ) { $_raw_types = array_unique( $_raw_types ); foreach ( $_raw_types as $type ) { switch ( $type ) { case '': case 'all': break; case 'comment': case 'comments': $comment_types[ $operator ][] = "''"; $comment_types[ $operator ][] = "'comment'"; break; case 'pings': $comment_types[ $operator ][] = "'pingback'"; $comment_types[ $operator ][] = "'trackback'"; break; default: $comment_types[ $operator ][] = $wpdb->prepare( '%s', $type ); break; } } if ( ! empty( $comment_types[ $operator ] ) ) { $types_sql = implode( ', ', $comment_types[ $operator ] ); $this->sql_clauses['where'][ 'comment_type__' . strtolower( str_replace( ' ', '_', $operator ) ) ] = "comment_type $operator ($types_sql)"; } } $parent = $this->query_vars['parent']; if ( $this->query_vars['hierarchical'] && ! $parent ) { $parent = 0; } if ( '' !== $parent ) { $this->sql_clauses['where']['parent'] = $wpdb->prepare( 'comment_parent = %d', $parent ); } if ( is_array( $this->query_vars['user_id'] ) ) { $this->sql_clauses['where']['user_id'] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')'; } elseif ( '' !== $this->query_vars['user_id'] ) { $this->sql_clauses['where']['user_id'] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] ); } if ( isset( $this->query_vars['search'] ) && strlen( $this->query_vars['search'] ) ) { $search_sql = $this->get_search_sql( $this->query_vars['search'], array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' ) ); $this->sql_clauses['where']['search'] = preg_replace( '/^\s*AND\s*/', '', $search_sql ); } $join_posts_table = false; $plucked = wp_array_slice_assoc( $this->query_vars, array( 'post_author', 'post_name', 'post_parent' ) ); $post_fields = array_filter( $plucked ); if ( ! empty( $post_fields ) ) { $join_posts_table = true; foreach ( $post_fields as $field_name => $field_value ) { $esses = array_fill( 0, count( (array) $field_value ), '%s' ); $this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $field_value ); } } foreach ( array( 'post_status', 'post_type' ) as $field_name ) { $q_values = array(); if ( ! empty( $this->query_vars[ $field_name ] ) ) { $q_values = $this->query_vars[ $field_name ]; if ( ! is_array( $q_values ) ) { $q_values = explode( ',', $q_values ); } if ( in_array( 'any', $q_values, true ) || empty( $q_values ) ) { continue; } $join_posts_table = true; $esses = array_fill( 0, count( $q_values ), '%s' ); $this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $q_values ); } } if ( ! empty( $this->query_vars['author__in'] ) ) { $this->sql_clauses['where']['author__in'] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['author__not_in'] ) ) { $this->sql_clauses['where']['author__not_in'] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['post_author__in'] ) ) { $join_posts_table = true; $this->sql_clauses['where']['post_author__in'] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )'; } if ( ! empty( $this->query_vars['post_author__not_in'] ) ) { $join_posts_table = true; $this->sql_clauses['where']['post_author__not_in'] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )'; } $join = ''; $groupby = ''; if ( $join_posts_table ) { $join .= "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID"; } if ( ! empty( $this->meta_query_clauses ) ) { $join .= $this->meta_query_clauses['join']; $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] ); if ( ! $this->query_vars['count'] ) { $groupby = "{$wpdb->comments}.comment_ID"; } } if ( ! empty( $this->query_vars['date_query'] ) && is_array( $this->query_vars['date_query'] ) ) { $this->date_query = new WP_Date_Query( $this->query_vars['date_query'], 'comment_date' ); $this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() ); } $where = implode( ' AND ', $this->sql_clauses['where'] ); $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); $clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) ); $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; $this->filtered_where_clause = $where; if ( $where ) { $where = 'WHERE ' . $where; } if ( $groupby ) { $groupby = 'GROUP BY ' . $groupby; } if ( $orderby ) { $orderby = "ORDER BY $orderby"; } $found_rows = ''; if ( ! $this->query_vars['no_found_rows'] ) { $found_rows = 'SQL_CALC_FOUND_ROWS'; } $this->sql_clauses['select'] = "SELECT $found_rows $fields"; $this->sql_clauses['from'] = "FROM $wpdb->comments $join"; $this->sql_clauses['groupby'] = $groupby; $this->sql_clauses['orderby'] = $orderby; $this->sql_clauses['limits'] = $limits; $this->request = "{$this->sql_clauses['select']}
{$this->sql_clauses['from']}
{$where}
{$this->sql_clauses['groupby']}
{$this->sql_clauses['orderby']}
{$this->sql_clauses['limits']}"; if ( $this->query_vars['count'] ) { return (int) $wpdb->get_var( $this->request ); } else { $comment_ids = $wpdb->get_col( $this->request ); return array_map( 'intval', $comment_ids ); } } private function set_found_comments() { global $wpdb; if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) { $found_comments_query = apply_filters( 'found_comments_query', 'SELECT FOUND_ROWS()', $this ); $this->found_comments = (int) $wpdb->get_var( $found_comments_query ); } } protected function fill_descendants( $comments ) { $levels = array( 0 => wp_list_pluck( $comments, 'comment_ID' ), ); $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) ); $last_changed = wp_cache_get_last_changed( 'comment' ); $level = 0; $exclude_keys = array( 'parent', 'parent__in', 'parent__not_in' ); do { $child_ids = array(); $uncached_parent_ids = array(); $_parent_ids = $levels[ $level ]; if ( $_parent_ids ) { $cache_keys = array(); foreach ( $_parent_ids as $parent_id ) { $cache_keys[ $parent_id ] = "get_comment_child_ids:$parent_id:$key"; } $cache_data = wp_cache_get_multiple_salted( array_values( $cache_keys ), 'comment-queries', $last_changed ); foreach ( $_parent_ids as $parent_id ) { $parent_child_ids = $cache_data[ $cache_keys[ $parent_id ] ]; if ( false !== $parent_child_ids ) { $child_ids = array_merge( $child_ids, $parent_child_ids ); } else { $uncached_parent_ids[] = $parent_id; } } } if ( $uncached_parent_ids ) { $parent_query_args = $this->query_vars; foreach ( $exclude_keys as $exclude_key ) { $parent_query_args[ $exclude_key ] = ''; } $parent_query_args['parent__in'] = $uncached_parent_ids; $parent_query_args['no_found_rows'] = true; $parent_query_args['hierarchical'] = false; $parent_query_args['offset'] = 0; $parent_query_args['number'] = 0; $level_comments = get_comments( $parent_query_args ); $parent_map = array_fill_keys( $uncached_parent_ids, array() ); foreach ( $level_comments as $level_comment ) { $parent_map[ $level_comment->comment_parent ][] = $level_comment->comment_ID; $child_ids[] = $level_comment->comment_ID; } $data = array(); foreach ( $parent_map as $parent_id => $children ) { $cache_key = "get_comment_child_ids:$parent_id:$key"; $data[ $cache_key ] = $children; } wp_cache_set_multiple_salted( $data, 'comment-queries', $last_changed ); } ++$level; $levels[ $level ] = $child_ids; } while ( $child_ids ); $descendant_ids = array(); for ( $i = 1, $c = count( $levels ); $i < $c; $i++ ) { $descendant_ids = array_merge( $descendant_ids, $levels[ $i ] ); } _prime_comment_caches( $descendant_ids, $this->query_vars['update_comment_meta_cache'] ); $all_comments = $comments; foreach ( $descendant_ids as $descendant_id ) { $all_comments[] = get_comment( $descendant_id ); } if ( 'threaded' === $this->query_vars['hierarchical'] ) { $threaded_comments = array(); $ref = array(); foreach ( $all_comments as $k => $c ) { $_c = get_comment( $c->comment_ID ); if ( ! isset( $ref[ $c->comment_parent ] ) ) { $threaded_comments[ $_c->comment_ID ] = $_c; $ref[ $_c->comment_ID ] = $threaded_comments[ $_c->comment_ID ]; } else { $ref[ $_c->comment_parent ]->add_child( $_c ); $ref[ $_c->comment_ID ] = $ref[ $_c->comment_parent ]->get_child( $_c->comment_ID ); } } foreach ( $ref as $_ref ) { $_ref->populated_children( true ); } $comments = $threaded_comments; } else { $comments = $all_comments; } return $comments; } protected function get_search_sql( $search, $columns ) { global $wpdb; $like = '%' . $wpdb->esc_like( $search ) . '%'; $searches = array(); foreach ( $columns as $column ) { $searches[] = $wpdb->prepare( "$column LIKE %s", $like ); } return ' AND (' . implode( ' OR ', $searches ) . ')'; } protected function parse_orderby( $orderby ) { global $wpdb; $allowed_keys = array( 'comment_agent', 'comment_approved', 'comment_author', 'comment_author_email', 'comment_author_IP', 'comment_author_url', 'comment_content', 'comment_date', 'comment_date_gmt', 'comment_ID', 'comment_karma', 'comment_parent', 'comment_post_ID', 'comment_type', 'user_id', ); if ( ! empty( $this->query_vars['meta_key'] ) ) { $allowed_keys[] = $this->query_vars['meta_key']; $allowed_keys[] = 'meta_value'; $allowed_keys[] = 'meta_value_num'; } $meta_query_clauses = $this->meta_query->get_clauses(); if ( $meta_query_clauses ) { $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_query_clauses ) ); } $parsed = false; if ( $this->query_vars['meta_key'] === $orderby || 'meta_value' === $orderby ) { $parsed = "$wpdb->commentmeta.meta_value"; } elseif ( 'meta_value_num' === $orderby ) { $parsed = "$wpdb->commentmeta.meta_value+0"; } elseif ( 'comment__in' === $orderby ) { $comment__in = implode( ',', array_map( 'absint', $this->query_vars['comment__in'] ) ); $parsed = "FIELD( {$wpdb->comments}.comment_ID, $comment__in )"; } elseif ( in_array( $orderby, $allowed_keys, true ) ) { if ( isset( $meta_query_clauses[ $orderby ] ) ) { $meta_clause = $meta_query_clauses[ $orderby ]; $parsed = sprintf( 'CAST(%s.meta_value AS %s)', esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) ); } else { $parsed = "$wpdb->comments.$orderby"; } } return $parsed; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'DESC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } }
###require ABSPATH . WPINC . '/class-walker-comment.php';
class Walker_Comment extends Walker { public $tree_type = 'comment'; public $db_fields = array( 'parent' => 'comment_parent', 'id' => 'comment_ID', ); public function start_lvl( &$output, $depth = 0, $args = array() ) { $GLOBALS['comment_depth'] = $depth + 1; switch ( $args['style'] ) { case 'div': break; case 'ol': $output .= '<ol class="children">' . "\n"; break; case 'ul': default: $output .= '<ul class="children">' . "\n"; break; } } public function end_lvl( &$output, $depth = 0, $args = array() ) { $GLOBALS['comment_depth'] = $depth + 1; switch ( $args['style'] ) { case 'div': break; case 'ol': $output .= "</ol><!-- .children -->\n"; break; case 'ul': default: $output .= "</ul><!-- .children -->\n"; break; } } public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { if ( ! $element ) { return; } $id_field = $this->db_fields['id']; $id = $element->$id_field; parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); if ( $max_depth <= $depth + 1 && isset( $children_elements[ $id ] ) ) { foreach ( $children_elements[ $id ] as $child ) { $this->display_element( $child, $children_elements, $max_depth, $depth, $args, $output ); } unset( $children_elements[ $id ] ); } } public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { $comment = $data_object; ++$depth; $GLOBALS['comment_depth'] = $depth; $GLOBALS['comment'] = $comment; if ( ! empty( $args['callback'] ) ) { ob_start(); call_user_func( $args['callback'], $comment, $args, $depth ); $output .= ob_get_clean(); return; } if ( 'comment' === $comment->comment_type ) { add_filter( 'comment_text', array( $this, 'filter_comment_text' ), 40, 2 ); } if ( ( 'pingback' === $comment->comment_type || 'trackback' === $comment->comment_type ) && $args['short_ping'] ) { ob_start(); $this->ping( $comment, $depth, $args ); $output .= ob_get_clean(); } elseif ( 'html5' === $args['format'] ) { ob_start(); $this->html5_comment( $comment, $depth, $args ); $output .= ob_get_clean(); } else { ob_start(); $this->comment( $comment, $depth, $args ); $output .= ob_get_clean(); } if ( 'comment' === $comment->comment_type ) { remove_filter( 'comment_text', array( $this, 'filter_comment_text' ), 40 ); } } public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { if ( ! empty( $args['end-callback'] ) ) { ob_start(); call_user_func( $args['end-callback'], $data_object, $args, $depth ); $output .= ob_get_clean(); return; } if ( 'div' === $args['style'] ) { $output .= "</div><!-- #comment-## -->\n"; } else { $output .= "</li><!-- #comment-## -->\n"; } } protected function ping( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?>
<<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( '', $comment ); ?>>
<div class="comment-body">
<?php _e( 'Pingback:' ); ?> <?php comment_author_link( $comment ); ?> <?php edit_comment_link( __( 'Edit' ), '<span class="edit-link">', '</span>' ); ?>
</div>
<?php
} public function filter_comment_text( $comment_text, $comment ) { $commenter = wp_get_current_commenter(); $show_pending_links = ! empty( $commenter['comment_author'] ); if ( $comment && '0' === $comment->comment_approved && ! $show_pending_links ) { $comment_text = wp_kses( $comment_text, array() ); } return $comment_text; } protected function comment( $comment, $depth, $args ) { if ( 'div' === $args['style'] ) { $tag = 'div'; $add_below = 'comment'; } else { $tag = 'li'; $add_below = 'div-comment'; } $commenter = wp_get_current_commenter(); $show_pending_links = isset( $commenter['comment_author'] ) && $commenter['comment_author']; if ( $commenter['comment_author_email'] ) { $moderation_note = __( 'Your comment is awaiting moderation.' ); } else { $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' ); } ?>
<<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?> id="comment-<?php comment_ID(); ?>">
<?php if ( 'div' !== $args['style'] ) : ?>
<div id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<?php endif; ?>
<div class="comment-author vcard">
<?php
if ( 0 !== $args['avatar_size'] ) { echo get_avatar( $comment, $args['avatar_size'] ); } ?>
<?php
$comment_author = get_comment_author_link( $comment ); if ( '0' === $comment->comment_approved && ! $show_pending_links ) { $comment_author = get_comment_author( $comment ); } printf( __( '%s <span class="says">says:</span>' ), sprintf( '<cite class="fn">%s</cite>', $comment_author ) ); ?>
</div>
<?php if ( '0' === $comment->comment_approved ) : ?>
<em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em>
<br />
<?php endif; ?>
<div class="comment-meta commentmetadata">
<?php
printf( '<a href="%s">%s</a>', esc_url( get_comment_link( $comment, $args ) ), sprintf( __( '%1$s at %2$s' ), get_comment_date( '', $comment ), get_comment_time() ) ); edit_comment_link( __( '(Edit)' ), ' ', '' ); ?>
</div>
<?php
comment_text( $comment, array_merge( $args, array( 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth'], ) ) ); ?>
<?php
comment_reply_link( array_merge( $args, array( 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>', ) ) ); ?>
<?php if ( 'div' !== $args['style'] ) : ?>
</div>
<?php endif; ?>
<?php
} protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; $commenter = wp_get_current_commenter(); $show_pending_links = ! empty( $commenter['comment_author'] ); if ( $commenter['comment_author_email'] ) { $moderation_note = __( 'Your comment is awaiting moderation.' ); } else { $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' ); } ?>
<<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>>
<article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<footer class="comment-meta">
<div class="comment-author vcard">
<?php
if ( 0 !== $args['avatar_size'] ) { echo get_avatar( $comment, $args['avatar_size'] ); } ?>
<?php
$comment_author = get_comment_author_link( $comment ); if ( '0' === $comment->comment_approved && ! $show_pending_links ) { $comment_author = get_comment_author( $comment ); } printf( __( '%s <span class="says">says:</span>' ), sprintf( '<b class="fn">%s</b>', $comment_author ) ); ?>
</div><!-- .comment-author -->
<div class="comment-metadata">
<?php
printf( '<a href="%s"><time datetime="%s">%s</time></a>', esc_url( get_comment_link( $comment, $args ) ), get_comment_time( 'c' ), sprintf( __( '%1$s at %2$s' ), get_comment_date( '', $comment ), get_comment_time() ) ); edit_comment_link( __( 'Edit' ), ' <span class="edit-link">', '</span>' ); ?>
</div><!-- .comment-metadata -->
<?php if ( '0' === $comment->comment_approved ) : ?>
<em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em>
<?php endif; ?>
</footer><!-- .comment-meta -->
<div class="comment-content">
<?php comment_text(); ?>
</div><!-- .comment-content -->
<?php
if ( '1' === $comment->comment_approved || $show_pending_links ) { comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>', ) ) ); } ?>
</article><!-- .comment-body -->
<?php
} }
###require ABSPATH . WPINC . '/comment-template.php';
function get_comment_author( $comment_id = 0 ) { $comment = get_comment( $comment_id ); if ( ! empty( $comment->comment_ID ) ) { $comment_id = $comment->comment_ID; } elseif ( is_scalar( $comment_id ) ) { $comment_id = (string) $comment_id; } else { $comment_id = '0'; } if ( empty( $comment->comment_author ) ) { $user = ! empty( $comment->user_id ) ? get_userdata( $comment->user_id ) : false; if ( $user ) { $comment_author = $user->display_name; } else { $comment_author = __( 'Anonymous' ); } } else { $comment_author = $comment->comment_author; } return apply_filters( 'get_comment_author', $comment_author, $comment_id, $comment ); } function comment_author( $comment_id = 0 ) { $comment = get_comment( $comment_id ); $comment_author = get_comment_author( $comment ); echo apply_filters( 'comment_author', $comment_author, $comment->comment_ID ); } function get_comment_author_email( $comment_id = 0 ) { $comment = get_comment( $comment_id ); return apply_filters( 'get_comment_author_email', $comment->comment_author_email, $comment->comment_ID, $comment ); } function comment_author_email( $comment_id = 0 ) { $comment = get_comment( $comment_id ); $comment_author_email = get_comment_author_email( $comment ); echo apply_filters( 'author_email', $comment_author_email, $comment->comment_ID ); } function comment_author_email_link( $link_text = '', $before = '', $after = '', $comment = null ) { $link = get_comment_author_email_link( $link_text, $before, $after, $comment ); if ( $link ) { echo $link; } } function get_comment_author_email_link( $link_text = '', $before = '', $after = '', $comment = null ) { $comment = get_comment( $comment ); $comment_author_email = apply_filters( 'comment_email', $comment->comment_author_email, $comment ); if ( ( ! empty( $comment_author_email ) ) && ( '@' !== $comment_author_email ) ) { $display = ( '' !== $link_text ) ? $link_text : $comment_author_email; $comment_author_email_link = $before . sprintf( '<a href="%1$s">%2$s</a>', esc_url( 'mailto:' . $comment_author_email ), esc_html( $display ) ) . $after; return $comment_author_email_link; } else { return ''; } } function get_comment_author_link( $comment_id = 0 ) { $comment = get_comment( $comment_id ); if ( ! empty( $comment->comment_ID ) ) { $comment_id = $comment->comment_ID; } elseif ( is_scalar( $comment_id ) ) { $comment_id = (string) $comment_id; } else { $comment_id = '0'; } $comment_author_url = get_comment_author_url( $comment ); $comment_author = get_comment_author( $comment ); if ( empty( $comment_author_url ) || 'http://' === $comment_author_url ) { $comment_author_link = $comment_author; } else { $rel_parts = array( 'ugc' ); if ( ! wp_is_internal_link( $comment_author_url ) ) { $rel_parts = array_merge( $rel_parts, array( 'external', 'nofollow' ) ); } $rel_parts = apply_filters( 'comment_author_link_rel', $rel_parts, $comment ); $rel = implode( ' ', $rel_parts ); $rel = esc_attr( $rel ); $rel = ! empty( $rel ) ? sprintf( ' rel="%s"', $rel ) : ''; $comment_author_link = sprintf( '<a href="%1$s" class="url"%2$s>%3$s</a>', $comment_author_url, $rel, $comment_author ); } return apply_filters( 'get_comment_author_link', $comment_author_link, $comment_author, $comment_id ); } function comment_author_link( $comment_id = 0 ) { echo get_comment_author_link( $comment_id ); } function get_comment_author_IP( $comment_id = 0 ) { $comment = get_comment( $comment_id ); return apply_filters( 'get_comment_author_IP', $comment->comment_author_IP, $comment->comment_ID, $comment ); } function comment_author_IP( $comment_id = 0 ) { echo esc_html( get_comment_author_IP( $comment_id ) ); } function get_comment_author_url( $comment_id = 0 ) { $comment = get_comment( $comment_id ); $comment_author_url = ''; $comment_id = 0; if ( ! empty( $comment ) ) { $comment_author_url = ( 'http://' === $comment->comment_author_url ) ? '' : $comment->comment_author_url; $comment_author_url = esc_url( $comment_author_url, array( 'http', 'https' ) ); $comment_id = $comment->comment_ID; } return apply_filters( 'get_comment_author_url', $comment_author_url, $comment_id, $comment ); } function comment_author_url( $comment_id = 0 ) { $comment = get_comment( $comment_id ); $comment_author_url = get_comment_author_url( $comment ); echo apply_filters( 'comment_url', $comment_author_url, $comment->comment_ID ); } function get_comment_author_url_link( $link_text = '', $before = '', $after = '', $comment = 0 ) { $comment_author_url = get_comment_author_url( $comment ); $display = ( '' !== $link_text ) ? $link_text : $comment_author_url; $display = str_replace( 'http://www.', '', $display ); $display = str_replace( 'http://', '', $display ); if ( str_ends_with( $display, '/' ) ) { $display = substr( $display, 0, -1 ); } $comment_author_url_link = $before . sprintf( '<a href="%1$s" rel="external">%2$s</a>', $comment_author_url, $display ) . $after; return apply_filters( 'get_comment_author_url_link', $comment_author_url_link ); } function comment_author_url_link( $link_text = '', $before = '', $after = '', $comment = 0 ) { echo get_comment_author_url_link( $link_text, $before, $after, $comment ); } function comment_class( $css_class = '', $comment = null, $post = null, $display = true ) { $css_class = 'class="' . implode( ' ', get_comment_class( $css_class, $comment, $post ) ) . '"'; if ( $display ) { echo $css_class; } else { return $css_class; } } function get_comment_class( $css_class = '', $comment_id = null, $post = null ) { global $comment_alt, $comment_depth, $comment_thread_alt; $classes = array(); $comment = get_comment( $comment_id ); if ( ! $comment ) { return $classes; } $classes[] = ( empty( $comment->comment_type ) ) ? 'comment' : $comment->comment_type; $user = $comment->user_id ? get_userdata( $comment->user_id ) : false; if ( $user ) { $classes[] = 'byuser'; $classes[] = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id ); $_post = get_post( $post ); if ( $_post ) { if ( $comment->user_id === $_post->post_author ) { $classes[] = 'bypostauthor'; } } } if ( empty( $comment_alt ) ) { $comment_alt = 0; } if ( empty( $comment_depth ) ) { $comment_depth = 1; } if ( empty( $comment_thread_alt ) ) { $comment_thread_alt = 0; } if ( $comment_alt % 2 ) { $classes[] = 'odd'; $classes[] = 'alt'; } else { $classes[] = 'even'; } ++$comment_alt; if ( 1 === $comment_depth ) { if ( $comment_thread_alt % 2 ) { $classes[] = 'thread-odd'; $classes[] = 'thread-alt'; } else { $classes[] = 'thread-even'; } ++$comment_thread_alt; } $classes[] = "depth-$comment_depth"; if ( ! empty( $css_class ) ) { if ( ! is_array( $css_class ) ) { $css_class = preg_split( '#\s+#', $css_class ); } $classes = array_merge( $classes, $css_class ); } $classes = array_map( 'esc_attr', $classes ); return apply_filters( 'comment_class', $classes, $css_class, $comment->comment_ID, $comment, $post ); } function get_comment_date( $format = '', $comment_id = 0 ) { $comment = get_comment( $comment_id ); $_format = ! empty( $format ) ? $format : get_option( 'date_format' ); $comment_date = mysql2date( $_format, $comment->comment_date ); return apply_filters( 'get_comment_date', $comment_date, $format, $comment ); } function comment_date( $format = '', $comment_id = 0 ) { echo get_comment_date( $format, $comment_id ); } function get_comment_excerpt( $comment_id = 0 ) { $comment = get_comment( $comment_id ); if ( ! post_password_required( $comment->comment_post_ID ) ) { $comment_text = strip_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) ); } else { $comment_text = __( 'Password protected' ); } $comment_excerpt_length = (int) _x( '20', 'comment_excerpt_length' ); $comment_excerpt_length = apply_filters( 'comment_excerpt_length', $comment_excerpt_length ); $comment_excerpt = wp_trim_words( $comment_text, $comment_excerpt_length, '…' ); return apply_filters( 'get_comment_excerpt', $comment_excerpt, $comment->comment_ID, $comment ); } function comment_excerpt( $comment_id = 0 ) { $comment = get_comment( $comment_id ); $comment_excerpt = get_comment_excerpt( $comment ); echo apply_filters( 'comment_excerpt', $comment_excerpt, $comment->comment_ID ); } function get_comment_ID() { $comment = get_comment(); $comment_id = ! empty( $comment->comment_ID ) ? $comment->comment_ID : '0'; return apply_filters( 'get_comment_ID', $comment_id, $comment ); } function comment_ID() { echo get_comment_ID(); } function get_comment_link( $comment = null, $args = array() ) { global $wp_rewrite, $in_comment_loop; $comment = get_comment( $comment ); if ( ! is_array( $args ) ) { $args = array( 'page' => $args ); } $defaults = array( 'type' => 'all', 'page' => '', 'per_page' => '', 'max_depth' => '', 'cpage' => null, ); $args = wp_parse_args( $args, $defaults ); $comment_link = get_permalink( $comment->comment_post_ID ); if ( ! is_null( $args['cpage'] ) ) { $cpage = $args['cpage']; } else { if ( '' === $args['per_page'] && get_option( 'page_comments' ) ) { $args['per_page'] = get_option( 'comments_per_page' ); } if ( empty( $args['per_page'] ) ) { $args['per_page'] = 0; $args['page'] = 0; } $cpage = $args['page']; if ( '' === $cpage ) { if ( ! empty( $in_comment_loop ) ) { $cpage = (int) get_query_var( 'cpage' ); } else { $cpage = get_page_of_comment( $comment->comment_ID, $args ); } } if ( 'oldest' === get_option( 'default_comments_page' ) && 1 === $cpage ) { $cpage = ''; } } if ( $cpage && get_option( 'page_comments' ) ) { if ( $wp_rewrite->using_permalinks() ) { $comment_link = trailingslashit( $comment_link ) . $wp_rewrite->comments_pagination_base . '-' . $cpage; } else { $comment_link = add_query_arg( 'cpage', $cpage, $comment_link ); } } if ( $wp_rewrite->using_permalinks() ) { $comment_link = user_trailingslashit( $comment_link, 'comment' ); } $comment_link = $comment_link . '#comment-' . $comment->comment_ID; return apply_filters( 'get_comment_link', $comment_link, $comment, $args, $cpage ); } function get_comments_link( $post = 0 ) { $hash = get_comments_number( $post ) ? '#comments' : '#respond'; $comments_link = get_permalink( $post ) . $hash; return apply_filters( 'get_comments_link', $comments_link, $post ); } function comments_link( $deprecated = '', $deprecated_2 = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '0.72' ); } if ( ! empty( $deprecated_2 ) ) { _deprecated_argument( __FUNCTION__, '1.3.0' ); } echo esc_url( get_comments_link() ); } function get_comments_number( $post = 0 ) { $post = get_post( $post ); $comments_number = $post ? $post->comment_count : 0; $post_id = $post ? $post->ID : 0; return apply_filters( 'get_comments_number', $comments_number, $post_id ); } function comments_number( $zero = false, $one = false, $more = false, $post = 0 ) { echo get_comments_number_text( $zero, $one, $more, $post ); } function get_comments_number_text( $zero = false, $one = false, $more = false, $post = 0 ) { $comments_number = (int) get_comments_number( $post ); if ( $comments_number > 1 ) { if ( false === $more ) { $comments_number_text = sprintf( _n( '%s Comment', '%s Comments', $comments_number ), number_format_i18n( $comments_number ) ); } else { if ( 'on' === _x( 'off', 'Comment number declension: on or off' ) ) { $text = preg_replace( '#<span class="screen-reader-text">.+?</span>#', '', $more ); $text = preg_replace( '/&.+?;/', '', $text ); $text = trim( strip_tags( $text ), '% ' ); if ( $text && ! preg_match( '/[0-9]+/', $text ) && str_contains( $more, '%' ) ) { $new_text = _n( '%s Comment', '%s Comments', $comments_number ); $new_text = trim( sprintf( $new_text, '' ) ); $more = str_replace( $text, $new_text, $more ); if ( ! str_contains( $more, '%' ) ) { $more = '% ' . $more; } } } $comments_number_text = str_replace( '%', number_format_i18n( $comments_number ), $more ); } } elseif ( 0 === $comments_number ) { $comments_number_text = ( false === $zero ) ? __( 'No Comments' ) : $zero; } else { $comments_number_text = ( false === $one ) ? __( '1 Comment' ) : $one; } return apply_filters( 'comments_number', $comments_number_text, $comments_number ); } function get_comment_text( $comment_id = 0, $args = array() ) { $comment = get_comment( $comment_id ); $comment_text = $comment->comment_content; if ( is_comment_feed() && $comment->comment_parent ) { $parent = get_comment( $comment->comment_parent ); if ( $parent ) { $parent_link = esc_url( get_comment_link( $parent ) ); $name = get_comment_author( $parent ); $comment_text = sprintf( ent2ncr( __( 'In reply to %s.' ) ), '<a href="' . $parent_link . '">' . $name . '</a>' ) . "\n\n" . $comment_text; } } return apply_filters( 'get_comment_text', $comment_text, $comment, $args ); } function comment_text( $comment_id = 0, $args = array() ) { $comment = get_comment( $comment_id ); $comment_text = get_comment_text( $comment, $args ); echo apply_filters( 'comment_text', $comment_text, $comment, $args ); } function get_comment_time( $format = '', $gmt = false, $translate = true, $comment_id = 0 ) { $comment = get_comment( $comment_id ); if ( null === $comment ) { return ''; } $comment_date = $gmt ? $comment->comment_date_gmt : $comment->comment_date; $_format = ! empty( $format ) ? $format : get_option( 'time_format' ); $comment_time = mysql2date( $_format, $comment_date, $translate ); return apply_filters( 'get_comment_time', $comment_time, $format, $gmt, $translate, $comment ); } function comment_time( $format = '', $comment_id = 0 ) { echo get_comment_time( $format, false, true, $comment_id ); } function get_comment_type( $comment_id = 0 ) { $comment = get_comment( $comment_id ); if ( '' === $comment->comment_type ) { $comment->comment_type = 'comment'; } return apply_filters( 'get_comment_type', $comment->comment_type, $comment->comment_ID, $comment ); } function comment_type( $comment_text = false, $trackback_text = false, $pingback_text = false ) { if ( false === $comment_text ) { $comment_text = _x( 'Comment', 'noun' ); } if ( false === $trackback_text ) { $trackback_text = __( 'Trackback' ); } if ( false === $pingback_text ) { $pingback_text = __( 'Pingback' ); } $type = get_comment_type(); switch ( $type ) { case 'trackback': echo $trackback_text; break; case 'pingback': echo $pingback_text; break; default: echo $comment_text; } } function get_trackback_url() { if ( get_option( 'permalink_structure' ) ) { $trackback_url = trailingslashit( get_permalink() ) . user_trailingslashit( 'trackback', 'single_trackback' ); } else { $trackback_url = get_option( 'siteurl' ) . '/wp-trackback.php?p=' . get_the_ID(); } return apply_filters( 'trackback_url', $trackback_url ); } function trackback_url( $deprecated_echo = true ) { if ( true !== $deprecated_echo ) { _deprecated_argument( __FUNCTION__, '2.5.0', sprintf( __( 'Use %s instead if you do not want the value echoed.' ), '<code>get_trackback_url()</code>' ) ); } if ( $deprecated_echo ) { echo get_trackback_url(); } else { return get_trackback_url(); } } function trackback_rdf( $deprecated = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.5.0' ); } if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && false !== stripos( $_SERVER['HTTP_USER_AGENT'], 'W3C_Validator' ) ) { return; } echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description rdf:about="'; the_permalink(); echo '"' . "\n"; echo ' dc:identifier="'; the_permalink(); echo '"' . "\n"; echo ' dc:title="' . str_replace( '--', '--', wptexturize( strip_tags( get_the_title() ) ) ) . '"' . "\n"; echo ' trackback:ping="' . get_trackback_url() . '"' . " />\n"; echo '</rdf:RDF>'; } function comments_open( $post = null ) { $_post = get_post( $post ); $post_id = $_post ? $_post->ID : 0; $comments_open = ( $_post && ( 'open' === $_post->comment_status ) ); return apply_filters( 'comments_open', $comments_open, $post_id ); } function pings_open( $post = null ) { $_post = get_post( $post ); $post_id = $_post ? $_post->ID : 0; $pings_open = ( $_post && ( 'open' === $_post->ping_status ) ); return apply_filters( 'pings_open', $pings_open, $post_id ); } function wp_comment_form_unfiltered_html_nonce() { $post = get_post(); $post_id = $post ? $post->ID : 0; if ( current_user_can( 'unfiltered_html' ) ) { wp_nonce_field( 'unfiltered-html-comment_' . $post_id, '_wp_unfiltered_html_comment_disabled', false ); wp_print_inline_script_tag( "(function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();\n//# sourceURL=" . rawurlencode( __FUNCTION__ ) ); } } function comments_template( $file = '/comments.php', $separate_comments = false ) { global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_identity, $overridden_cpage, $wp_stylesheet_path, $wp_template_path; if ( ! ( is_single() || is_page() || $withcomments ) || empty( $post ) ) { return; } if ( empty( $file ) ) { $file = '/comments.php'; } $req = get_option( 'require_name_email' ); $commenter = wp_get_current_commenter(); $comment_author = $commenter['comment_author']; $comment_author_email = $commenter['comment_author_email']; $comment_author_url = esc_url( $commenter['comment_author_url'] ); $comment_args = array( 'orderby' => 'comment_date_gmt', 'order' => 'ASC', 'status' => 'approve', 'post_id' => $post->ID, 'no_found_rows' => false, ); if ( get_option( 'thread_comments' ) ) { $comment_args['hierarchical'] = 'threaded'; } else { $comment_args['hierarchical'] = false; } if ( is_user_logged_in() ) { $comment_args['include_unapproved'] = array( get_current_user_id() ); } else { $unapproved_email = wp_get_unapproved_comment_author_email(); if ( $unapproved_email ) { $comment_args['include_unapproved'] = array( $unapproved_email ); } } $per_page = 0; if ( get_option( 'page_comments' ) ) { $per_page = (int) get_query_var( 'comments_per_page' ); if ( 0 === $per_page ) { $per_page = (int) get_option( 'comments_per_page' ); } $comment_args['number'] = $per_page; $page = (int) get_query_var( 'cpage' ); if ( $page ) { $comment_args['offset'] = ( $page - 1 ) * $per_page; } elseif ( 'oldest' === get_option( 'default_comments_page' ) ) { $comment_args['offset'] = 0; } else { $top_level_query = new WP_Comment_Query(); $top_level_args = array( 'count' => true, 'orderby' => false, 'post_id' => $post->ID, 'status' => 'approve', ); if ( $comment_args['hierarchical'] ) { $top_level_args['parent'] = 0; } if ( isset( $comment_args['include_unapproved'] ) ) { $top_level_args['include_unapproved'] = $comment_args['include_unapproved']; } $top_level_args = apply_filters( 'comments_template_top_level_query_args', $top_level_args ); $top_level_count = $top_level_query->query( $top_level_args ); $comment_args['offset'] = ( (int) ceil( $top_level_count / $per_page ) - 1 ) * $per_page; } } $comment_args = apply_filters( 'comments_template_query_args', $comment_args ); $comment_query = new WP_Comment_Query( $comment_args ); $_comments = $comment_query->comments; if ( $comment_args['hierarchical'] ) { $comments_flat = array(); foreach ( $_comments as $_comment ) { $comments_flat[] = $_comment; $comment_children = $_comment->get_children( array( 'format' => 'flat', 'status' => $comment_args['status'], 'orderby' => $comment_args['orderby'], ) ); foreach ( $comment_children as $comment_child ) { $comments_flat[] = $comment_child; } } } else { $comments_flat = $_comments; } $wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID ); $comments = &$wp_query->comments; $wp_query->comment_count = count( $wp_query->comments ); $wp_query->max_num_comment_pages = $comment_query->max_num_pages; if ( $separate_comments ) { $wp_query->comments_by_type = separate_comments( $comments ); $comments_by_type = &$wp_query->comments_by_type; } else { $wp_query->comments_by_type = array(); } $overridden_cpage = false; if ( '' === get_query_var( 'cpage' ) && $wp_query->max_num_comment_pages > 1 ) { set_query_var( 'cpage', 'newest' === get_option( 'default_comments_page' ) ? get_comment_pages_count() : 1 ); $overridden_cpage = true; } if ( ! defined( 'COMMENTS_TEMPLATE' ) ) { define( 'COMMENTS_TEMPLATE', true ); } $theme_template = trailingslashit( $wp_stylesheet_path ) . $file; $include = apply_filters( 'comments_template', $theme_template ); if ( file_exists( $include ) ) { require $include; } elseif ( file_exists( trailingslashit( $wp_template_path ) . $file ) ) { require trailingslashit( $wp_template_path ) . $file; } else { require ABSPATH . WPINC . '/theme-compat/comments.php'; } } function comments_popup_link( $zero = false, $one = false, $more = false, $css_class = '', $none = false ) { $post_id = get_the_ID(); $post_title = get_the_title(); $comments_number = (int) get_comments_number( $post_id ); if ( false === $zero ) { $zero = sprintf( __( 'No Comments<span class="screen-reader-text"> on %s</span>' ), $post_title ); } if ( false === $one ) { $one = sprintf( __( '1 Comment<span class="screen-reader-text"> on %s</span>' ), $post_title ); } if ( false === $more ) { $more = _n( '%1$s Comment<span class="screen-reader-text"> on %2$s</span>', '%1$s Comments<span class="screen-reader-text"> on %2$s</span>', $comments_number ); $more = sprintf( $more, number_format_i18n( $comments_number ), $post_title ); } if ( false === $none ) { $none = sprintf( __( 'Comments Off<span class="screen-reader-text"> on %s</span>' ), $post_title ); } if ( 0 === $comments_number && ! comments_open() && ! pings_open() ) { printf( '<span%1$s>%2$s</span>', ! empty( $css_class ) ? ' class="' . esc_attr( $css_class ) . '"' : '', $none ); return; } if ( post_password_required() ) { _e( 'Enter your password to view comments.' ); return; } if ( 0 === $comments_number ) { $respond_link = get_permalink() . '#respond'; $comments_link = apply_filters( 'respond_link', $respond_link, $post_id ); } else { $comments_link = get_comments_link(); } $link_attributes = ''; $link_attributes = apply_filters( 'comments_popup_link_attributes', $link_attributes ); printf( '<a href="%1$s"%2$s%3$s>%4$s</a>', esc_url( $comments_link ), ! empty( $css_class ) ? ' class="' . $css_class . '" ' : '', $link_attributes, get_comments_number_text( $zero, $one, $more ) ); } function get_comment_reply_link( $args = array(), $comment = null, $post = null ) { $defaults = array( 'add_below' => 'comment', 'respond_id' => 'respond', 'reply_text' => __( 'Reply' ), 'reply_to_text' => __( 'Reply to %s' ), 'login_text' => __( 'Log in to Reply' ), 'max_depth' => 0, 'depth' => 0, 'before' => '', 'after' => '', 'show_reply_to_text' => false, ); $args = wp_parse_args( $args, $defaults ); $args['max_depth'] = (int) $args['max_depth']; $args['depth'] = (int) $args['depth']; if ( 0 === $args['depth'] || $args['max_depth'] <= $args['depth'] ) { return null; } $comment = get_comment( $comment ); if ( empty( $comment ) ) { return null; } if ( empty( $post ) ) { $post = $comment->comment_post_ID; } $post = get_post( $post ); if ( ! comments_open( $post->ID ) ) { return false; } if ( get_option( 'page_comments' ) ) { $permalink = str_replace( '#comment-' . $comment->comment_ID, '', get_comment_link( $comment ) ); } else { $permalink = get_permalink( $post->ID ); } $args = apply_filters( 'comment_reply_link_args', $args, $comment, $post ); if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) { $link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>', esc_url( wp_login_url( get_permalink() ) ), $args['login_text'] ); } else { $data_attributes = array( 'commentid' => $comment->comment_ID, 'postid' => $post->ID, 'belowelement' => $args['add_below'] . '-' . $comment->comment_ID, 'respondelement' => $args['respond_id'], 'replyto' => sprintf( $args['reply_to_text'], get_comment_author( $comment ) ), ); $data_attribute_string = ''; foreach ( $data_attributes as $name => $value ) { $data_attribute_string .= " data-{$name}=\"" . esc_attr( $value ) . '"'; } $data_attribute_string = trim( $data_attribute_string ); $reply_text = $args['show_reply_to_text'] ? sprintf( $args['reply_to_text'], get_comment_author( $comment ) ) : $args['reply_text']; $aria_label = $args['show_reply_to_text'] ? '' : sprintf( $args['reply_to_text'], get_comment_author( $comment ) ); $link = sprintf( '<a rel="nofollow" class="comment-reply-link" href="%s" %s%s>%s</a>', esc_url( add_query_arg( array( 'replytocom' => $comment->comment_ID, 'unapproved' => false, 'moderation-hash' => false, ), $permalink ) ) . '#' . $args['respond_id'], $data_attribute_string, $aria_label ? ' aria-label="' . esc_attr( $aria_label ) . '"' : '', $reply_text ); } $comment_reply_link = $args['before'] . $link . $args['after']; return apply_filters( 'comment_reply_link', $comment_reply_link, $args, $comment, $post ); } function comment_reply_link( $args = array(), $comment = null, $post = null ) { echo get_comment_reply_link( $args, $comment, $post ); } function get_post_reply_link( $args = array(), $post = null ) { $defaults = array( 'add_below' => 'post', 'respond_id' => 'respond', 'reply_text' => __( 'Leave a Comment' ), 'login_text' => __( 'Log in to leave a Comment' ), 'before' => '', 'after' => '', ); $args = wp_parse_args( $args, $defaults ); $post = get_post( $post ); if ( ! comments_open( $post->ID ) ) { return false; } if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) { $link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>', wp_login_url( get_permalink() ), $args['login_text'] ); } else { $onclick = sprintf( 'return addComment.moveForm( "%1$s-%2$s", "0", "%3$s", "%2$s" )', $args['add_below'], $post->ID, $args['respond_id'] ); $link = sprintf( "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s'>%s</a>", get_permalink( $post->ID ) . '#' . $args['respond_id'], $onclick, $args['reply_text'] ); } $post_reply_link = $args['before'] . $link . $args['after']; return apply_filters( 'post_comments_link', $post_reply_link, $post ); } function post_reply_link( $args = array(), $post = null ) { echo get_post_reply_link( $args, $post ); } function get_cancel_comment_reply_link( $link_text = '', $post = null ) { if ( empty( $link_text ) ) { $link_text = __( 'Click here to cancel reply.' ); } $post = get_post( $post ); $reply_to_id = $post ? _get_comment_reply_id( $post->ID ) : 0; $link_style = 0 !== $reply_to_id ? '' : ' style="display:none;"'; $link_url = esc_url( remove_query_arg( array( 'replytocom', 'unapproved', 'moderation-hash' ) ) ) . '#respond'; $cancel_comment_reply_link = sprintf( '<a rel="nofollow" id="cancel-comment-reply-link" href="%1$s"%2$s>%3$s</a>', $link_url, $link_style, $link_text ); return apply_filters( 'cancel_comment_reply_link', $cancel_comment_reply_link, $link_url, $link_text ); } function cancel_comment_reply_link( $link_text = '' ) { echo get_cancel_comment_reply_link( $link_text ); } function get_comment_id_fields( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return ''; } $post_id = $post->ID; $reply_to_id = _get_comment_reply_id( $post_id ); $comment_id_fields = "<input type='hidden' name='comment_post_ID' value='$post_id' id='comment_post_ID' />\n"; $comment_id_fields .= "<input type='hidden' name='comment_parent' id='comment_parent' value='$reply_to_id' />\n"; return apply_filters( 'comment_id_fields', $comment_id_fields, $post_id, $reply_to_id ); } function comment_id_fields( $post = null ) { echo get_comment_id_fields( $post ); } function comment_form_title( $no_reply_text = false, $reply_text = false, $link_to_parent = true, $post = null ) { global $comment; if ( false === $no_reply_text ) { $no_reply_text = __( 'Leave a Reply' ); } if ( false === $reply_text ) { $reply_text = __( 'Leave a Reply to %s' ); } $post = get_post( $post ); if ( ! $post ) { echo $no_reply_text; return; } $reply_to_id = _get_comment_reply_id( $post->ID ); if ( 0 === $reply_to_id ) { echo $no_reply_text; return; } $comment = get_comment( $reply_to_id ); if ( $link_to_parent ) { $comment_author = sprintf( '<a href="#comment-%1$s">%2$s</a>', get_comment_ID(), get_comment_author( $reply_to_id ) ); } else { $comment_author = get_comment_author( $reply_to_id ); } printf( $reply_text, $comment_author ); } function _get_comment_reply_id( $post = null ) { $post = get_post( $post ); if ( ! $post || ! isset( $_GET['replytocom'] ) || ! is_numeric( $_GET['replytocom'] ) ) { return 0; } $reply_to_id = (int) $_GET['replytocom']; $comment = get_comment( $reply_to_id ); if ( ! $comment instanceof WP_Comment || 0 === (int) $comment->comment_approved || $post->ID !== (int) $comment->comment_post_ID ) { return 0; } return $reply_to_id; } function wp_list_comments( $args = array(), $comments = null ) { global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop; $in_comment_loop = true; $comment_alt = 0; $comment_thread_alt = 0; $comment_depth = 1; $defaults = array( 'walker' => null, 'max_depth' => '', 'style' => 'ul', 'callback' => null, 'end-callback' => null, 'type' => 'all', 'page' => '', 'per_page' => '', 'avatar_size' => 32, 'reverse_top_level' => null, 'reverse_children' => '', 'format' => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml', 'short_ping' => false, 'echo' => true, ); $parsed_args = wp_parse_args( $args, $defaults ); $parsed_args = apply_filters( 'wp_list_comments_args', $parsed_args ); if ( null !== $comments ) { $comments = (array) $comments; if ( empty( $comments ) ) { return; } if ( 'all' !== $parsed_args['type'] ) { $comments_by_type = separate_comments( $comments ); if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) { return; } $_comments = $comments_by_type[ $parsed_args['type'] ]; } else { $_comments = $comments; } } else { if ( $parsed_args['page'] || $parsed_args['per_page'] ) { $current_cpage = (int) get_query_var( 'cpage' ); if ( ! $current_cpage ) { $current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages; } $current_per_page = (int) get_query_var( 'comments_per_page' ); if ( (int) $parsed_args['page'] !== $current_cpage || (int) $parsed_args['per_page'] !== $current_per_page ) { $comment_args = array( 'post_id' => get_the_ID(), 'orderby' => 'comment_date_gmt', 'order' => 'ASC', 'status' => 'approve', ); if ( is_user_logged_in() ) { $comment_args['include_unapproved'] = array( get_current_user_id() ); } else { $unapproved_email = wp_get_unapproved_comment_author_email(); if ( $unapproved_email ) { $comment_args['include_unapproved'] = array( $unapproved_email ); } } $comments = get_comments( $comment_args ); if ( 'all' !== $parsed_args['type'] ) { $comments_by_type = separate_comments( $comments ); if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) { return; } $_comments = $comments_by_type[ $parsed_args['type'] ]; } else { $_comments = $comments; } } } else { if ( empty( $wp_query->comments ) ) { return; } if ( 'all' !== $parsed_args['type'] ) { if ( empty( $wp_query->comments_by_type ) ) { $wp_query->comments_by_type = separate_comments( $wp_query->comments ); } if ( empty( $wp_query->comments_by_type[ $parsed_args['type'] ] ) ) { return; } $_comments = $wp_query->comments_by_type[ $parsed_args['type'] ]; } else { $_comments = $wp_query->comments; } if ( $wp_query->max_num_comment_pages ) { $default_comments_page = get_option( 'default_comments_page' ); $cpage = (int) get_query_var( 'cpage' ); if ( 'newest' === $default_comments_page ) { $parsed_args['cpage'] = $cpage; } elseif ( 1 === $cpage ) { $parsed_args['cpage'] = ''; } else { $parsed_args['cpage'] = $cpage; } $parsed_args['page'] = 0; $parsed_args['per_page'] = 0; } } } if ( '' === $parsed_args['per_page'] && get_option( 'page_comments' ) ) { $parsed_args['per_page'] = get_query_var( 'comments_per_page' ); } if ( empty( $parsed_args['per_page'] ) ) { $parsed_args['per_page'] = 0; $parsed_args['page'] = 0; } if ( '' === $parsed_args['max_depth'] ) { if ( get_option( 'thread_comments' ) ) { $parsed_args['max_depth'] = get_option( 'thread_comments_depth' ); } else { $parsed_args['max_depth'] = -1; } } if ( '' === $parsed_args['page'] ) { if ( empty( $overridden_cpage ) ) { $parsed_args['page'] = get_query_var( 'cpage' ); } else { $threaded = ( -1 !== (int) $parsed_args['max_depth'] ); $parsed_args['page'] = ( 'newest' === get_option( 'default_comments_page' ) ) ? get_comment_pages_count( $_comments, $parsed_args['per_page'], $threaded ) : 1; set_query_var( 'cpage', $parsed_args['page'] ); } } $parsed_args['page'] = (int) $parsed_args['page']; $parsed_args['per_page'] = (int) $parsed_args['per_page']; if ( 0 === $parsed_args['page'] && 0 !== $parsed_args['per_page'] ) { $parsed_args['page'] = 1; } if ( null === $parsed_args['reverse_top_level'] ) { $parsed_args['reverse_top_level'] = ( 'desc' === get_option( 'comment_order' ) ); } if ( empty( $parsed_args['walker'] ) ) { $walker = new Walker_Comment(); } else { $walker = $parsed_args['walker']; } $output = $walker->paged_walk( $_comments, $parsed_args['max_depth'], $parsed_args['page'], $parsed_args['per_page'], $parsed_args ); $in_comment_loop = false; if ( $parsed_args['echo'] ) { echo $output; } else { return $output; } } function comment_form( $args = array(), $post = null ) { $post = get_post( $post ); if ( ! $post || ! comments_open( $post ) ) { do_action( 'comment_form_comments_closed' ); return; } $post_id = $post->ID; $commenter = wp_get_current_commenter(); $user = wp_get_current_user(); $user_identity = $user->exists() ? $user->display_name : ''; $args = wp_parse_args( $args ); if ( ! isset( $args['format'] ) ) { $args['format'] = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml'; } $req = get_option( 'require_name_email' ); $html5 = 'html5' === $args['format']; $required_attribute = ( $html5 ? ' required' : ' required="required"' ); $checked_attribute = ( $html5 ? ' checked' : ' checked="checked"' ); $required_indicator = ' ' . wp_required_field_indicator(); $required_text = ' ' . wp_required_field_message(); $fields = array( 'author' => sprintf( '<p class="comment-form-author">%s %s</p>', sprintf( '<label for="author">%s%s</label>', __( 'Name' ), ( $req ? $required_indicator : '' ) ), sprintf( '<input id="author" name="author" type="text" value="%s" size="30" maxlength="245" autocomplete="name"%s />', esc_attr( $commenter['comment_author'] ), ( $req ? $required_attribute : '' ) ) ), 'email' => sprintf( '<p class="comment-form-email">%s %s</p>', sprintf( '<label for="email">%s%s</label>', __( 'Email' ), ( $req ? $required_indicator : '' ) ), sprintf( '<input id="email" name="email" %s value="%s" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email"%s />', ( $html5 ? 'type="email"' : 'type="text"' ), esc_attr( $commenter['comment_author_email'] ), ( $req ? $required_attribute : '' ) ) ), 'url' => sprintf( '<p class="comment-form-url">%s %s</p>', sprintf( '<label for="url">%s</label>', __( 'Website' ) ), sprintf( '<input id="url" name="url" %s value="%s" size="30" maxlength="200" autocomplete="url" />', ( $html5 ? 'type="url"' : 'type="text"' ), esc_attr( $commenter['comment_author_url'] ) ) ), ); if ( has_action( 'set_comment_cookies', 'wp_set_comment_cookies' ) && get_option( 'show_comments_cookies_opt_in' ) ) { $consent = empty( $commenter['comment_author_email'] ) ? '' : $checked_attribute; $fields['cookies'] = sprintf( '<p class="comment-form-cookies-consent">%s %s</p>', sprintf( '<input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"%s />', $consent ), sprintf( '<label for="wp-comment-cookies-consent">%s</label>', __( 'Save my name, email, and website in this browser for the next time I comment.' ) ) ); if ( isset( $args['fields'] ) && ! isset( $args['fields']['cookies'] ) ) { $args['fields']['cookies'] = $fields['cookies']; } } $original_fields = $fields; $fields = apply_filters( 'comment_form_default_fields', $fields ); $defaults = array( 'fields' => $fields, 'comment_field' => sprintf( '<p class="comment-form-comment">%s %s</p>', sprintf( '<label for="comment">%s%s</label>', _x( 'Comment', 'noun' ), $required_indicator ), '<textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525"' . $required_attribute . '></textarea>' ), 'must_log_in' => sprintf( '<p class="must-log-in">%s</p>', sprintf( __( 'You must be <a href="%s">logged in</a> to post a comment.' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ), $post_id ) ) ) ), 'logged_in_as' => sprintf( '<p class="logged-in-as">%s%s</p>', sprintf( __( 'Logged in as %1$s. <a href="%2$s">Edit your profile</a>. <a href="%3$s">Log out?</a>' ), $user_identity, get_edit_user_link(), wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ), $post_id ) ) ), $required_text ), 'comment_notes_before' => sprintf( '<p class="comment-notes">%s%s</p>', sprintf( '<span id="email-notes">%s</span>', __( 'Your email address will not be published.' ) ), $required_text ), 'comment_notes_after' => '', 'action' => site_url( '/wp-comments-post.php' ), 'novalidate' => false, 'id_form' => 'commentform', 'id_submit' => 'submit', 'class_container' => 'comment-respond', 'class_form' => 'comment-form', 'class_submit' => 'submit', 'name_submit' => 'submit', 'title_reply' => __( 'Leave a Reply' ), 'title_reply_to' => __( 'Leave a Reply to %s' ), 'title_reply_before' => '<h3 id="reply-title" class="comment-reply-title">', 'title_reply_after' => '</h3>', 'cancel_reply_before' => ' <small>', 'cancel_reply_after' => '</small>', 'cancel_reply_link' => __( 'Cancel reply' ), 'label_submit' => __( 'Post Comment' ), 'submit_button' => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />', 'submit_field' => '<p class="form-submit">%1$s %2$s</p>', 'format' => 'xhtml', ); $args = wp_parse_args( $args, apply_filters( 'comment_form_defaults', $defaults ) ); $args = array_merge( $defaults, $args ); if ( isset( $args['fields']['email'] ) && ! str_contains( $args['comment_notes_before'], 'id="email-notes"' ) ) { $args['fields']['email'] = str_replace( ' aria-describedby="email-notes"', '', $args['fields']['email'] ); } do_action( 'comment_form_before' ); ?>
<div id="respond" class="<?php echo esc_attr( $args['class_container'] ); ?>">
<?php
echo $args['title_reply_before']; comment_form_title( $args['title_reply'], $args['title_reply_to'], true, $post_id ); if ( get_option( 'thread_comments' ) ) { echo $args['cancel_reply_before']; cancel_comment_reply_link( $args['cancel_reply_link'] ); echo $args['cancel_reply_after']; } echo $args['title_reply_after']; if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) : echo $args['must_log_in']; do_action( 'comment_form_must_log_in_after' ); else : printf( '<form action="%s" method="post" id="%s" class="%s"%s>', esc_url( $args['action'] ), esc_attr( $args['id_form'] ), esc_attr( $args['class_form'] ), ( $args['novalidate'] ? ' novalidate' : '' ) ); do_action( 'comment_form_top' ); if ( is_user_logged_in() ) : echo apply_filters( 'comment_form_logged_in', $args['logged_in_as'], $commenter, $user_identity ); do_action( 'comment_form_logged_in_after', $commenter, $user_identity ); else : echo $args['comment_notes_before']; endif; $comment_fields = array( 'comment' => $args['comment_field'] ) + (array) $args['fields']; $comment_fields = apply_filters( 'comment_form_fields', $comment_fields ); $comment_field_keys = array_diff( array_keys( $comment_fields ), array( 'comment' ) ); $first_field = reset( $comment_field_keys ); $last_field = end( $comment_field_keys ); foreach ( $comment_fields as $name => $field ) { if ( 'comment' === $name ) { echo apply_filters( 'comment_form_field_comment', $field ); echo $args['comment_notes_after']; } elseif ( ! is_user_logged_in() || ! isset( $original_fields[ $name ] ) ) { if ( $first_field === $name ) { do_action( 'comment_form_before_fields' ); } echo apply_filters( "comment_form_field_{$name}", $field ) . "\n"; if ( $last_field === $name ) { do_action( 'comment_form_after_fields' ); } } } $submit_button = sprintf( $args['submit_button'], esc_attr( $args['name_submit'] ), esc_attr( $args['id_submit'] ), esc_attr( $args['class_submit'] ), esc_attr( $args['label_submit'] ) ); $submit_button = apply_filters( 'comment_form_submit_button', $submit_button, $args ); $submit_field = sprintf( $args['submit_field'], $submit_button, get_comment_id_fields( $post_id ) ); echo apply_filters( 'comment_form_submit_field', $submit_field, $args ); do_action( 'comment_form', $post_id ); echo '</form>'; endif; ?>
</div><!-- #respond -->
<?php
do_action( 'comment_form_after' ); }
###require ABSPATH . WPINC . '/rewrite.php';
define( 'EP_NONE', 0 ); define( 'EP_PERMALINK', 1 ); define( 'EP_ATTACHMENT', 2 ); define( 'EP_DATE', 4 ); define( 'EP_YEAR', 8 ); define( 'EP_MONTH', 16 ); define( 'EP_DAY', 32 ); define( 'EP_ROOT', 64 ); define( 'EP_COMMENTS', 128 ); define( 'EP_SEARCH', 256 ); define( 'EP_CATEGORIES', 512 ); define( 'EP_TAGS', 1024 ); define( 'EP_AUTHORS', 2048 ); define( 'EP_PAGES', 4096 ); define( 'EP_ALL_ARCHIVES', EP_DATE | EP_YEAR | EP_MONTH | EP_DAY | EP_CATEGORIES | EP_TAGS | EP_AUTHORS ); define( 'EP_ALL', EP_PERMALINK | EP_ATTACHMENT | EP_ROOT | EP_COMMENTS | EP_SEARCH | EP_PAGES | EP_ALL_ARCHIVES ); function add_rewrite_rule( $regex, $query, $after = 'bottom' ) { global $wp_rewrite; $wp_rewrite->add_rule( $regex, $query, $after ); } function add_rewrite_tag( $tag, $regex, $query = '' ) { if ( strlen( $tag ) < 3 || '%' !== $tag[0] || '%' !== $tag[ strlen( $tag ) - 1 ] ) { return; } global $wp_rewrite, $wp; if ( empty( $query ) ) { $qv = trim( $tag, '%' ); $wp->add_query_var( $qv ); $query = $qv . '='; } $wp_rewrite->add_rewrite_tag( $tag, $regex, $query ); } function remove_rewrite_tag( $tag ) { global $wp_rewrite; $wp_rewrite->remove_rewrite_tag( $tag ); } function add_permastruct( $name, $struct, $args = array() ) { global $wp_rewrite; if ( ! is_array( $args ) ) { $args = array( 'with_front' => $args ); } if ( func_num_args() === 4 ) { $args['ep_mask'] = func_get_arg( 3 ); } $wp_rewrite->add_permastruct( $name, $struct, $args ); } function remove_permastruct( $name ) { global $wp_rewrite; $wp_rewrite->remove_permastruct( $name ); } function add_feed( $feedname, $callback ) { global $wp_rewrite; if ( ! in_array( $feedname, $wp_rewrite->feeds, true ) ) { $wp_rewrite->feeds[] = $feedname; } $hook = 'do_feed_' . $feedname; remove_action( $hook, $hook ); add_action( $hook, $callback, 10, 2 ); return $hook; } function flush_rewrite_rules( $hard = true ) { global $wp_rewrite; if ( is_callable( array( $wp_rewrite, 'flush_rules' ) ) ) { $wp_rewrite->flush_rules( $hard ); } } function add_rewrite_endpoint( $name, $places, $query_var = true ) { global $wp_rewrite; $wp_rewrite->add_endpoint( $name, $places, $query_var ); } function _wp_filter_taxonomy_base( $base ) { if ( ! empty( $base ) ) { $base = preg_replace( '|^/index\.php/|', '', $base ); $base = trim( $base, '/' ); } return $base; } function wp_resolve_numeric_slug_conflicts( $query_vars = array() ) { if ( ! isset( $query_vars['year'] ) && ! isset( $query_vars['monthnum'] ) && ! isset( $query_vars['day'] ) ) { return $query_vars; } $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) ); $postname_index = array_search( '%postname%', $permastructs, true ); if ( false === $postname_index ) { return $query_vars; } $compare = ''; if ( 0 === $postname_index && ( isset( $query_vars['year'] ) || isset( $query_vars['monthnum'] ) ) ) { $compare = 'year'; } elseif ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && ( isset( $query_vars['monthnum'] ) || isset( $query_vars['day'] ) ) ) { $compare = 'monthnum'; } elseif ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && isset( $query_vars['day'] ) ) { $compare = 'day'; } if ( ! $compare ) { return $query_vars; } $value = ''; if ( array_key_exists( $compare, $query_vars ) ) { $value = $query_vars[ $compare ]; } $post = get_page_by_path( $value, OBJECT, 'post' ); if ( ! ( $post instanceof WP_Post ) ) { return $query_vars; } if ( preg_match( '/^([0-9]{4})\-([0-9]{2})/', $post->post_date, $matches ) && isset( $query_vars['year'] ) && ( 'monthnum' === $compare || 'day' === $compare ) ) { if ( (int) $query_vars['year'] !== (int) $matches[1] ) { return $query_vars; } if ( 'day' === $compare && isset( $query_vars['monthnum'] ) && (int) $query_vars['monthnum'] !== (int) $matches[2] ) { return $query_vars; } } $maybe_page = ''; if ( 'year' === $compare && isset( $query_vars['monthnum'] ) ) { $maybe_page = $query_vars['monthnum']; } elseif ( 'monthnum' === $compare && isset( $query_vars['day'] ) ) { $maybe_page = $query_vars['day']; } $maybe_page = (int) trim( $maybe_page, '/' ); $post_page_count = substr_count( $post->post_content, '<!--nextpage-->' ) + 1; if ( 1 === $post_page_count && $maybe_page ) { return $query_vars; } if ( $post_page_count > 1 && $maybe_page > $post_page_count ) { return $query_vars; } $query_vars['page'] = $maybe_page; unset( $query_vars['year'] ); unset( $query_vars['monthnum'] ); unset( $query_vars['day'] ); $query_vars['name'] = $post->post_name; return $query_vars; } function url_to_postid( $url ) { global $wp_rewrite; $url = apply_filters( 'url_to_postid', $url ); $url_host = parse_url( $url, PHP_URL_HOST ); if ( is_string( $url_host ) ) { $url_host = str_replace( 'www.', '', $url_host ); } else { $url_host = ''; } $home_url_host = parse_url( home_url(), PHP_URL_HOST ); if ( is_string( $home_url_host ) ) { $home_url_host = str_replace( 'www.', '', $home_url_host ); } else { $home_url_host = ''; } if ( $url_host && $url_host !== $home_url_host ) { return 0; } if ( preg_match( '#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values ) ) { $id = absint( $values[2] ); if ( $id ) { return $id; } } $url_split = explode( '#', $url ); $url = $url_split[0]; $url_split = explode( '?', $url ); $url = $url_split[0]; $scheme = parse_url( home_url(), PHP_URL_SCHEME ); $url = set_url_scheme( $url, $scheme ); if ( str_contains( home_url(), '://www.' ) && ! str_contains( $url, '://www.' ) ) { $url = str_replace( '://', '://www.', $url ); } if ( ! str_contains( home_url(), '://www.' ) ) { $url = str_replace( '://www.', '://', $url ); } if ( trim( $url, '/' ) === home_url() && 'page' === get_option( 'show_on_front' ) ) { $page_on_front = get_option( 'page_on_front' ); if ( $page_on_front && get_post( $page_on_front ) instanceof WP_Post ) { return (int) $page_on_front; } } $rewrite = $wp_rewrite->wp_rewrite_rules(); if ( empty( $rewrite ) ) { return 0; } if ( ! $wp_rewrite->using_index_permalinks() ) { $url = str_replace( $wp_rewrite->index . '/', '', $url ); } if ( str_contains( trailingslashit( $url ), home_url( '/' ) ) ) { $url = str_replace( home_url(), '', $url ); } else { $home_path = parse_url( home_url( '/' ) ); $home_path = isset( $home_path['path'] ) ? $home_path['path'] : ''; $url = preg_replace( sprintf( '#^%s#', preg_quote( $home_path ) ), '', trailingslashit( $url ) ); } $url = trim( $url, '/' ); $request = $url; $post_type_query_vars = array(); foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) { if ( ! empty( $t->query_var ) ) { $post_type_query_vars[ $t->query_var ] = $post_type; } } $request_match = $request; foreach ( (array) $rewrite as $match => $query ) { if ( ! empty( $url ) && ( $url !== $request ) && str_starts_with( $match, $url ) ) { $request_match = $url . '/' . $request; } if ( preg_match( "#^$match#", $request_match, $matches ) ) { if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { $page = get_page_by_path( $matches[ $varmatch[1] ] ); if ( ! $page ) { continue; } $post_status_obj = get_post_status_object( $page->post_status ); if ( ! $post_status_obj->public && ! $post_status_obj->protected && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { continue; } } $query = preg_replace( '!^.+\?!', '', $query ); $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) ); global $wp; parse_str( $query, $query_vars ); $query = array(); foreach ( (array) $query_vars as $key => $value ) { if ( in_array( (string) $key, $wp->public_query_vars, true ) ) { $query[ $key ] = $value; if ( isset( $post_type_query_vars[ $key ] ) ) { $query['post_type'] = $post_type_query_vars[ $key ]; $query['name'] = $value; } } } $query = wp_resolve_numeric_slug_conflicts( $query ); $query = new WP_Query( $query ); if ( ! empty( $query->posts ) && $query->is_singular ) { return $query->post->ID; } else { return 0; } } } return 0; }
###require ABSPATH . WPINC . '/class-wp-rewrite.php';
class WP_Rewrite { public $permalink_structure; public $use_trailing_slashes; public $author_base = 'author'; public $author_structure; public $date_structure; public $page_structure; public $search_base = 'search'; public $search_structure; public $comments_base = 'comments'; public $pagination_base = 'page'; public $comments_pagination_base = 'comment-page'; public $feed_base = 'feed'; public $comment_feed_structure; public $feed_structure; public $front; public $root = ''; public $index = 'index.php'; public $matches = ''; public $rules; public $extra_rules = array(); public $extra_rules_top = array(); public $non_wp_rules = array(); public $extra_permastructs = array(); public $endpoints; public $use_verbose_rules = false; public $use_verbose_page_rules = true; public $rewritecode = array( '%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%postname%', '%post_id%', '%author%', '%pagename%', '%search%', ); public $rewritereplace = array( '([0-9]{4})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([^/]+)', '([0-9]+)', '([^/]+)', '([^/]+?)', '(.+)', ); public $queryreplace = array( 'year=', 'monthnum=', 'day=', 'hour=', 'minute=', 'second=', 'name=', 'p=', 'author_name=', 'pagename=', 's=', ); public $feeds = array( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); public function using_permalinks() { return ! empty( $this->permalink_structure ); } public function using_index_permalinks() { if ( empty( $this->permalink_structure ) ) { return false; } return preg_match( '#^/*' . $this->index . '#', $this->permalink_structure ); } public function using_mod_rewrite_permalinks() { return $this->using_permalinks() && ! $this->using_index_permalinks(); } public function preg_index( $number ) { $match_prefix = '$'; $match_suffix = ''; if ( ! empty( $this->matches ) ) { $match_prefix = '$' . $this->matches . '['; $match_suffix = ']'; } return "$match_prefix$number$match_suffix"; } public function page_uri_index() { global $wpdb; $pages = $wpdb->get_results( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'page' AND post_status != 'auto-draft'" ); $posts = get_page_hierarchy( $pages ); if ( ! $posts ) { return array( array(), array() ); } $posts = array_reverse( $posts, true ); $page_uris = array(); $page_attachment_uris = array(); foreach ( $posts as $id => $post ) { $uri = get_page_uri( $id ); $attachments = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = %d", $id ) ); if ( ! empty( $attachments ) ) { foreach ( $attachments as $attachment ) { $attach_uri = get_page_uri( $attachment->ID ); $page_attachment_uris[ $attach_uri ] = $attachment->ID; } } $page_uris[ $uri ] = $id; } return array( $page_uris, $page_attachment_uris ); } public function page_rewrite_rules() { $this->add_rewrite_tag( '%pagename%', '(.?.+?)', 'pagename=' ); return $this->generate_rewrite_rules( $this->get_page_permastruct(), EP_PAGES, true, true, false, false ); } public function get_date_permastruct() { if ( isset( $this->date_structure ) ) { return $this->date_structure; } if ( empty( $this->permalink_structure ) ) { $this->date_structure = ''; return false; } $endians = array( '%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%' ); $this->date_structure = ''; $date_endian = ''; foreach ( $endians as $endian ) { if ( str_contains( $this->permalink_structure, $endian ) ) { $date_endian = $endian; break; } } if ( empty( $date_endian ) ) { $date_endian = '%year%/%monthnum%/%day%'; } $front = $this->front; preg_match_all( '/%.+?%/', $this->permalink_structure, $tokens ); $tok_index = 1; foreach ( (array) $tokens[0] as $token ) { if ( '%post_id%' === $token && ( $tok_index <= 3 ) ) { $front = $front . 'date/'; break; } ++$tok_index; } $this->date_structure = $front . $date_endian; return $this->date_structure; } public function get_year_permastruct() { $structure = $this->get_date_permastruct(); if ( empty( $structure ) ) { return false; } $structure = str_replace( '%monthnum%', '', $structure ); $structure = str_replace( '%day%', '', $structure ); $structure = preg_replace( '#/+#', '/', $structure ); return $structure; } public function get_month_permastruct() { $structure = $this->get_date_permastruct(); if ( empty( $structure ) ) { return false; } $structure = str_replace( '%day%', '', $structure ); $structure = preg_replace( '#/+#', '/', $structure ); return $structure; } public function get_day_permastruct() { return $this->get_date_permastruct(); } public function get_category_permastruct() { return $this->get_extra_permastruct( 'category' ); } public function get_tag_permastruct() { return $this->get_extra_permastruct( 'post_tag' ); } public function get_extra_permastruct( $name ) { if ( empty( $this->permalink_structure ) ) { return false; } if ( isset( $this->extra_permastructs[ $name ] ) ) { return $this->extra_permastructs[ $name ]['struct']; } return false; } public function get_author_permastruct() { if ( isset( $this->author_structure ) ) { return $this->author_structure; } if ( empty( $this->permalink_structure ) ) { $this->author_structure = ''; return false; } $this->author_structure = $this->front . $this->author_base . '/%author%'; return $this->author_structure; } public function get_search_permastruct() { if ( isset( $this->search_structure ) ) { return $this->search_structure; } if ( empty( $this->permalink_structure ) ) { $this->search_structure = ''; return false; } $this->search_structure = $this->root . $this->search_base . '/%search%'; return $this->search_structure; } public function get_page_permastruct() { if ( isset( $this->page_structure ) ) { return $this->page_structure; } if ( empty( $this->permalink_structure ) ) { $this->page_structure = ''; return false; } $this->page_structure = $this->root . '%pagename%'; return $this->page_structure; } public function get_feed_permastruct() { if ( isset( $this->feed_structure ) ) { return $this->feed_structure; } if ( empty( $this->permalink_structure ) ) { $this->feed_structure = ''; return false; } $this->feed_structure = $this->root . $this->feed_base . '/%feed%'; return $this->feed_structure; } public function get_comment_feed_permastruct() { if ( isset( $this->comment_feed_structure ) ) { return $this->comment_feed_structure; } if ( empty( $this->permalink_structure ) ) { $this->comment_feed_structure = ''; return false; } $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%'; return $this->comment_feed_structure; } public function add_rewrite_tag( $tag, $regex, $query ) { $position = array_search( $tag, $this->rewritecode, true ); if ( false !== $position && null !== $position ) { $this->rewritereplace[ $position ] = $regex; $this->queryreplace[ $position ] = $query; } else { $this->rewritecode[] = $tag; $this->rewritereplace[] = $regex; $this->queryreplace[] = $query; } } public function remove_rewrite_tag( $tag ) { $position = array_search( $tag, $this->rewritecode, true ); if ( false !== $position && null !== $position ) { unset( $this->rewritecode[ $position ] ); unset( $this->rewritereplace[ $position ] ); unset( $this->queryreplace[ $position ] ); } } public function generate_rewrite_rules( $permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true ) { $feedregex2 = ''; foreach ( (array) $this->feeds as $feed_name ) { $feedregex2 .= $feed_name . '|'; } $feedregex2 = '(' . trim( $feedregex2, '|' ) . ')/?$'; $feedregex = $this->feed_base . '/' . $feedregex2; $trackbackregex = 'trackback/?$'; $pageregex = $this->pagination_base . '/?([0-9]{1,})/?$'; $commentregex = $this->comments_pagination_base . '-([0-9]{1,})/?$'; $embedregex = 'embed/?$'; if ( $endpoints ) { $ep_query_append = array(); foreach ( (array) $this->endpoints as $endpoint ) { $epmatch = $endpoint[1] . '(/(.*))?/?$'; $epquery = '&' . $endpoint[2] . '='; $ep_query_append[ $epmatch ] = array( $endpoint[0], $epquery ); } } $front = substr( $permalink_structure, 0, strpos( $permalink_structure, '%' ) ); preg_match_all( '/%.+?%/', $permalink_structure, $tokens ); $num_tokens = count( $tokens[0] ); $index = $this->index; $feedindex = $index; $trackbackindex = $index; $embedindex = $index; $queries = array(); for ( $i = 0; $i < $num_tokens; ++$i ) { if ( 0 < $i ) { $queries[ $i ] = $queries[ $i - 1 ] . '&'; } else { $queries[ $i ] = ''; } $query_token = str_replace( $this->rewritecode, $this->queryreplace, $tokens[0][ $i ] ) . $this->preg_index( $i + 1 ); $queries[ $i ] .= $query_token; } $structure = $permalink_structure; if ( '/' !== $front ) { $structure = str_replace( $front, '', $structure ); } $structure = trim( $structure, '/' ); $dirs = $walk_dirs ? explode( '/', $structure ) : array( $structure ); $num_dirs = count( $dirs ); $front = preg_replace( '|^/+|', '', $front ); $post_rewrite = array(); $struct = $front; for ( $j = 0; $j < $num_dirs; ++$j ) { $struct .= $dirs[ $j ] . '/'; $struct = ltrim( $struct, '/' ); $match = str_replace( $this->rewritecode, $this->rewritereplace, $struct ); $num_toks = preg_match_all( '/%.+?%/', $struct, $toks ); $query = ( ! empty( $num_toks ) && isset( $queries[ $num_toks - 1 ] ) ) ? $queries[ $num_toks - 1 ] : ''; switch ( $dirs[ $j ] ) { case '%year%': $ep_mask_specific = EP_YEAR; break; case '%monthnum%': $ep_mask_specific = EP_MONTH; break; case '%day%': $ep_mask_specific = EP_DAY; break; default: $ep_mask_specific = EP_NONE; } $pagematch = $match . $pageregex; $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index( $num_toks + 1 ); $commentmatch = $match . $commentregex; $commentquery = $index . '?' . $query . '&cpage=' . $this->preg_index( $num_toks + 1 ); if ( get_option( 'page_on_front' ) ) { $rootcommentmatch = $match . $commentregex; $rootcommentquery = $index . '?' . $query . '&page_id=' . get_option( 'page_on_front' ) . '&cpage=' . $this->preg_index( $num_toks + 1 ); } $feedmatch = $match . $feedregex; $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index( $num_toks + 1 ); $feedmatch2 = $match . $feedregex2; $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index( $num_toks + 1 ); $embedmatch = $match . $embedregex; $embedquery = $embedindex . '?' . $query . '&embed=true'; if ( $forcomments ) { $feedquery .= '&withcomments=1'; $feedquery2 .= '&withcomments=1'; } $rewrite = array(); if ( $feed ) { $rewrite = array( $feedmatch => $feedquery, $feedmatch2 => $feedquery2, $embedmatch => $embedquery, ); } if ( $paged ) { $rewrite = array_merge( $rewrite, array( $pagematch => $pagequery ) ); } if ( EP_PAGES & $ep_mask || EP_PERMALINK & $ep_mask ) { $rewrite = array_merge( $rewrite, array( $commentmatch => $commentquery ) ); } elseif ( EP_ROOT & $ep_mask && get_option( 'page_on_front' ) ) { $rewrite = array_merge( $rewrite, array( $rootcommentmatch => $rootcommentquery ) ); } if ( $endpoints ) { foreach ( (array) $ep_query_append as $regex => $ep ) { if ( $ep[0] & $ep_mask || $ep[0] & $ep_mask_specific ) { $rewrite[ $match . $regex ] = $index . '?' . $query . $ep[1] . $this->preg_index( $num_toks + 2 ); } } } if ( $num_toks ) { $post = false; $page = false; if ( str_contains( $struct, '%postname%' ) || str_contains( $struct, '%post_id%' ) || str_contains( $struct, '%pagename%' ) || ( str_contains( $struct, '%year%' ) && str_contains( $struct, '%monthnum%' ) && str_contains( $struct, '%day%' ) && str_contains( $struct, '%hour%' ) && str_contains( $struct, '%minute%' ) && str_contains( $struct, '%second%' ) ) ) { $post = true; if ( str_contains( $struct, '%pagename%' ) ) { $page = true; } } if ( ! $post ) { foreach ( get_post_types( array( '_builtin' => false ) ) as $ptype ) { if ( str_contains( $struct, "%$ptype%" ) ) { $post = true; $page = is_post_type_hierarchical( $ptype ); break; } } } if ( $post ) { $trackbackmatch = $match . $trackbackregex; $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; $embedmatch = $match . $embedregex; $embedquery = $embedindex . '?' . $query . '&embed=true'; $match = rtrim( $match, '/' ); $submatchbase = str_replace( array( '(', ')' ), '', $match ); $sub1 = $submatchbase . '/([^/]+)/'; $sub1tb = $sub1 . $trackbackregex; $sub1feed = $sub1 . $feedregex; $sub1feed2 = $sub1 . $feedregex2; $sub1comment = $sub1 . $commentregex; $sub1embed = $sub1 . $embedregex; $sub2 = $submatchbase . '/attachment/([^/]+)/'; $sub2tb = $sub2 . $trackbackregex; $sub2feed = $sub2 . $feedregex; $sub2feed2 = $sub2 . $feedregex2; $sub2comment = $sub2 . $commentregex; $sub2embed = $sub2 . $embedregex; $subquery = $index . '?attachment=' . $this->preg_index( 1 ); $subtbquery = $subquery . '&tb=1'; $subfeedquery = $subquery . '&feed=' . $this->preg_index( 2 ); $subcommentquery = $subquery . '&cpage=' . $this->preg_index( 2 ); $subembedquery = $subquery . '&embed=true'; if ( ! empty( $endpoints ) ) { foreach ( (array) $ep_query_append as $regex => $ep ) { if ( $ep[0] & EP_ATTACHMENT ) { $rewrite[ $sub1 . $regex ] = $subquery . $ep[1] . $this->preg_index( 3 ); $rewrite[ $sub2 . $regex ] = $subquery . $ep[1] . $this->preg_index( 3 ); } } } $sub1 .= '?$'; $sub2 .= '?$'; $match = $match . '(?:/([0-9]+))?/?$'; $query = $index . '?' . $query . '&page=' . $this->preg_index( $num_toks + 1 ); } else { $match .= '?$'; $query = $index . '?' . $query; } $rewrite = array_merge( $rewrite, array( $match => $query ) ); if ( $post ) { $rewrite = array_merge( array( $trackbackmatch => $trackbackquery ), $rewrite ); $rewrite = array_merge( array( $embedmatch => $embedquery ), $rewrite ); if ( ! $page ) { $rewrite = array_merge( $rewrite, array( $sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery, $sub1comment => $subcommentquery, $sub1embed => $subembedquery, ) ); } $rewrite = array_merge( array( $sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery, $sub2comment => $subcommentquery, $sub2embed => $subembedquery, ), $rewrite ); } } $post_rewrite = array_merge( $rewrite, $post_rewrite ); } return $post_rewrite; } public function generate_rewrite_rule( $permalink_structure, $walk_dirs = false ) { return $this->generate_rewrite_rules( $permalink_structure, EP_NONE, false, false, false, $walk_dirs ); } public function rewrite_rules() { $rewrite = array(); if ( empty( $this->permalink_structure ) ) { return $rewrite; } $home_path = parse_url( home_url() ); $robots_rewrite = ( empty( $home_path['path'] ) || '/' === $home_path['path'] ) ? array( 'robots\.txt$' => $this->index . '?robots=1' ) : array(); $favicon_rewrite = ( empty( $home_path['path'] ) || '/' === $home_path['path'] ) ? array( 'favicon\.ico$' => $this->index . '?favicon=1' ) : array(); $sitemap_rewrite = ( empty( $home_path['path'] ) || '/' === $home_path['path'] ) ? array( 'sitemap\.xml' => $this->index . '?sitemap=index' ) : array(); $deprecated_files = array( '.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$' => $this->index . '?feed=old', '.*wp-app\.php(/.*)?$' => $this->index . '?error=403', ); $registration_pages = array(); if ( is_multisite() && is_main_site() ) { $registration_pages['.*wp-signup.php$'] = $this->index . '?signup=true'; $registration_pages['.*wp-activate.php$'] = $this->index . '?activate=true'; } $registration_pages['.*wp-register.php$'] = $this->index . '?register=true'; $post_rewrite = $this->generate_rewrite_rules( $this->permalink_structure, EP_PERMALINK ); $post_rewrite = apply_filters( 'post_rewrite_rules', $post_rewrite ); $date_rewrite = $this->generate_rewrite_rules( $this->get_date_permastruct(), EP_DATE ); $date_rewrite = apply_filters( 'date_rewrite_rules', $date_rewrite ); $root_rewrite = $this->generate_rewrite_rules( $this->root . '/', EP_ROOT ); $root_rewrite = apply_filters( 'root_rewrite_rules', $root_rewrite ); $comments_rewrite = $this->generate_rewrite_rules( $this->root . $this->comments_base, EP_COMMENTS, false, true, true, false ); $comments_rewrite = apply_filters( 'comments_rewrite_rules', $comments_rewrite ); $search_structure = $this->get_search_permastruct(); $search_rewrite = $this->generate_rewrite_rules( $search_structure, EP_SEARCH ); $search_rewrite = apply_filters( 'search_rewrite_rules', $search_rewrite ); $author_rewrite = $this->generate_rewrite_rules( $this->get_author_permastruct(), EP_AUTHORS ); $author_rewrite = apply_filters( 'author_rewrite_rules', $author_rewrite ); $page_rewrite = $this->page_rewrite_rules(); $page_rewrite = apply_filters( 'page_rewrite_rules', $page_rewrite ); foreach ( $this->extra_permastructs as $permastructname => $struct ) { if ( is_array( $struct ) ) { if ( count( $struct ) === 2 ) { $rules = $this->generate_rewrite_rules( $struct[0], $struct[1] ); } else { $rules = $this->generate_rewrite_rules( $struct['struct'], $struct['ep_mask'], $struct['paged'], $struct['feed'], $struct['forcomments'], $struct['walk_dirs'], $struct['endpoints'] ); } } else { $rules = $this->generate_rewrite_rules( $struct ); } $rules = apply_filters( "{$permastructname}_rewrite_rules", $rules ); if ( 'post_tag' === $permastructname ) { $rules = apply_filters_deprecated( 'tag_rewrite_rules', array( $rules ), '3.1.0', 'post_tag_rewrite_rules' ); } $this->extra_rules_top = array_merge( $this->extra_rules_top, $rules ); } if ( $this->use_verbose_page_rules ) { $this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules ); } else { $this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules ); } do_action_ref_array( 'generate_rewrite_rules', array( &$this ) ); $this->rules = apply_filters( 'rewrite_rules_array', $this->rules ); return $this->rules; } public function wp_rewrite_rules() { $this->rules = get_option( 'rewrite_rules' ); if ( empty( $this->rules ) ) { $this->refresh_rewrite_rules(); } return $this->rules; } private function refresh_rewrite_rules() { $this->rules = ''; $this->matches = 'matches'; $this->rewrite_rules(); if ( ! did_action( 'wp_loaded' ) ) { add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); } else { update_option( 'rewrite_rules', $this->rules ); } } public function mod_rewrite_rules() { if ( ! $this->using_permalinks() ) { return ''; } $site_root = parse_url( site_url() ); if ( isset( $site_root['path'] ) ) { $site_root = trailingslashit( $site_root['path'] ); } $home_root = parse_url( home_url() ); if ( isset( $home_root['path'] ) ) { $home_root = trailingslashit( $home_root['path'] ); } else { $home_root = '/'; } $rules = "<IfModule mod_rewrite.c>\n"; $rules .= "RewriteEngine On\n"; $rules .= "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n"; $rules .= "RewriteBase $home_root\n"; $rules .= "RewriteRule ^index\.php$ - [L]\n"; foreach ( (array) $this->non_wp_rules as $match => $query ) { $match = str_replace( '.+?', '.+', $match ); $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; } if ( $this->use_verbose_rules ) { $this->matches = ''; $rewrite = $this->rewrite_rules(); $num_rules = count( $rewrite ); $rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" . "RewriteCond %{REQUEST_FILENAME} -d\n" . "RewriteRule ^.*$ - [S=$num_rules]\n"; foreach ( (array) $rewrite as $match => $query ) { $match = str_replace( '.+?', '.+', $match ); if ( str_contains( $query, $this->index ) ) { $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; } else { $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n"; } } } else { $rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" . "RewriteCond %{REQUEST_FILENAME} !-d\n" . "RewriteRule . {$home_root}{$this->index} [L]\n"; } $rules .= "</IfModule>\n"; $rules = apply_filters( 'mod_rewrite_rules', $rules ); return apply_filters_deprecated( 'rewrite_rules', array( $rules ), '1.5.0', 'mod_rewrite_rules' ); } public function iis7_url_rewrite_rules( $add_parent_tags = false ) { if ( ! $this->using_permalinks() ) { return ''; } $rules = ''; if ( $add_parent_tags ) { $rules .= '<configuration>
<system.webServer>
<rewrite>
<rules>'; } $rules .= '
<rule name="WordPress: ' . esc_attr( home_url() ) . '" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>'; if ( $add_parent_tags ) { $rules .= '
</rules>
</rewrite>
</system.webServer>
</configuration>'; } return apply_filters( 'iis7_url_rewrite_rules', $rules ); } public function add_rule( $regex, $query, $after = 'bottom' ) { if ( is_array( $query ) ) { $external = false; $query = add_query_arg( $query, 'index.php' ); } else { $index = ! str_contains( $query, '?' ) ? strlen( $query ) : strpos( $query, '?' ); $front = substr( $query, 0, $index ); $external = $front !== $this->index; } if ( $external ) { $this->add_external_rule( $regex, $query ); } else { if ( 'bottom' === $after ) { $this->extra_rules = array_merge( $this->extra_rules, array( $regex => $query ) ); } else { $this->extra_rules_top = array_merge( $this->extra_rules_top, array( $regex => $query ) ); } } } public function add_external_rule( $regex, $query ) { $this->non_wp_rules[ $regex ] = $query; } public function add_endpoint( $name, $places, $query_var = true ) { global $wp; if ( true === $query_var || null === $query_var ) { $query_var = $name; } $this->endpoints[] = array( $places, $name, $query_var ); if ( $query_var ) { $wp->add_query_var( $query_var ); } } public function add_permastruct( $name, $struct, $args = array() ) { if ( ! is_array( $args ) ) { $args = array( 'with_front' => $args ); } if ( func_num_args() === 4 ) { $args['ep_mask'] = func_get_arg( 3 ); } $defaults = array( 'with_front' => true, 'ep_mask' => EP_NONE, 'paged' => true, 'feed' => true, 'forcomments' => false, 'walk_dirs' => true, 'endpoints' => true, ); $args = array_intersect_key( $args, $defaults ); $args = wp_parse_args( $args, $defaults ); if ( $args['with_front'] ) { $struct = $this->front . $struct; } else { $struct = $this->root . $struct; } $args['struct'] = $struct; $this->extra_permastructs[ $name ] = $args; } public function remove_permastruct( $name ) { unset( $this->extra_permastructs[ $name ] ); } public function flush_rules( $hard = true ) { static $do_hard_later = null; if ( ! did_action( 'wp_loaded' ) ) { add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); $do_hard_later = ( isset( $do_hard_later ) ) ? $do_hard_later || $hard : $hard; return; } if ( isset( $do_hard_later ) ) { $hard = $do_hard_later; unset( $do_hard_later ); } $this->refresh_rewrite_rules(); if ( ! $hard || ! apply_filters( 'flush_rewrite_rules_hard', true ) ) { return; } if ( function_exists( 'save_mod_rewrite_rules' ) ) { save_mod_rewrite_rules(); } if ( function_exists( 'iis7_save_url_rewrite_rules' ) ) { iis7_save_url_rewrite_rules(); } } public function init() { $this->extra_rules = array(); $this->non_wp_rules = array(); $this->endpoints = array(); $this->permalink_structure = get_option( 'permalink_structure' ); $this->front = substr( $this->permalink_structure, 0, strpos( $this->permalink_structure, '%' ) ); $this->root = ''; if ( $this->using_index_permalinks() ) { $this->root = $this->index . '/'; } unset( $this->author_structure ); unset( $this->date_structure ); unset( $this->page_structure ); unset( $this->search_structure ); unset( $this->feed_structure ); unset( $this->comment_feed_structure ); $this->use_trailing_slashes = str_ends_with( $this->permalink_structure, '/' ); if ( preg_match( '/^[^%]*%(?:postname|category|tag|author)%/', $this->permalink_structure ) ) { $this->use_verbose_page_rules = true; } else { $this->use_verbose_page_rules = false; } } public function set_permalink_structure( $permalink_structure ) { if ( $this->permalink_structure !== $permalink_structure ) { $old_permalink_structure = $this->permalink_structure; update_option( 'permalink_structure', $permalink_structure ); $this->init(); do_action( 'permalink_structure_changed', $old_permalink_structure, $permalink_structure ); } } public function set_category_base( $category_base ) { if ( get_option( 'category_base' ) !== $category_base ) { update_option( 'category_base', $category_base ); $this->init(); } } public function set_tag_base( $tag_base ) { if ( get_option( 'tag_base' ) !== $tag_base ) { update_option( 'tag_base', $tag_base ); $this->init(); } } public function __construct() { $this->init(); } }
###require ABSPATH . WPINC . '/feed.php';
function get_bloginfo_rss( $show = '' ) { $info = strip_tags( get_bloginfo( $show ) ); return apply_filters( 'get_bloginfo_rss', convert_chars( $info ), $show ); } function bloginfo_rss( $show = '' ) { echo apply_filters( 'bloginfo_rss', get_bloginfo_rss( $show ), $show ); } function get_default_feed() { $default_feed = apply_filters( 'default_feed', 'rss2' ); return ( 'rss' === $default_feed ) ? 'rss2' : $default_feed; } function get_wp_title_rss( $deprecated = '–' ) { if ( '–' !== $deprecated ) { _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) ); } return apply_filters( 'get_wp_title_rss', wp_get_document_title(), $deprecated ); } function wp_title_rss( $deprecated = '–' ) { if ( '–' !== $deprecated ) { _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) ); } echo apply_filters( 'wp_title_rss', get_wp_title_rss(), $deprecated ); } function get_the_title_rss( $post = 0 ) { $title = get_the_title( $post ); return apply_filters( 'the_title_rss', $title ); } function the_title_rss() { echo get_the_title_rss(); } function get_the_content_feed( $feed_type = null ) { if ( ! $feed_type ) { $feed_type = get_default_feed(); } $content = apply_filters( 'the_content', get_the_content() ); $content = str_replace( ']]>', ']]>', $content ); return apply_filters( 'the_content_feed', $content, $feed_type ); } function the_content_feed( $feed_type = null ) { echo get_the_content_feed( $feed_type ); } function the_excerpt_rss() { $output = get_the_excerpt(); echo apply_filters( 'the_excerpt_rss', $output ); } function the_permalink_rss() { echo esc_url( apply_filters( 'the_permalink_rss', get_permalink() ) ); } function comments_link_feed() { echo esc_url( apply_filters( 'comments_link_feed', get_comments_link() ) ); } function comment_guid( $comment_id = null ) { echo esc_url( get_comment_guid( $comment_id ) ); } function get_comment_guid( $comment_id = null ) { $comment = get_comment( $comment_id ); if ( ! is_object( $comment ) ) { return false; } return get_the_guid( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID; } function comment_link( $comment = null ) { echo esc_url( apply_filters( 'comment_link', get_comment_link( $comment ) ) ); } function get_comment_author_rss() { return apply_filters( 'comment_author_rss', get_comment_author() ); } function comment_author_rss() { echo get_comment_author_rss(); } function comment_text_rss() { $comment_text = get_comment_text(); $comment_text = apply_filters( 'comment_text_rss', $comment_text ); echo $comment_text; } function get_the_category_rss( $type = null ) { if ( empty( $type ) ) { $type = get_default_feed(); } $categories = get_the_category(); $tags = get_the_tags(); $the_list = ''; $cat_names = array(); $filter = 'rss'; if ( 'atom' === $type ) { $filter = 'raw'; } if ( ! empty( $categories ) ) { foreach ( (array) $categories as $category ) { $cat_names[] = sanitize_term_field( 'name', $category->name, $category->term_id, 'category', $filter ); } } if ( ! empty( $tags ) ) { foreach ( (array) $tags as $tag ) { $cat_names[] = sanitize_term_field( 'name', $tag->name, $tag->term_id, 'post_tag', $filter ); } } $cat_names = array_unique( $cat_names ); foreach ( $cat_names as $cat_name ) { if ( 'rdf' === $type ) { $the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n"; } elseif ( 'atom' === $type ) { $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) ); } else { $the_list .= "\t\t<category><![CDATA[" . html_entity_decode( $cat_name, ENT_COMPAT, get_option( 'blog_charset' ) ) . "]]></category>\n"; } } return apply_filters( 'the_category_rss', $the_list, $type ); } function the_category_rss( $type = null ) { echo get_the_category_rss( $type ); } function html_type_rss() { $type = get_bloginfo( 'html_type' ); if ( str_contains( $type, 'xhtml' ) ) { $type = 'xhtml'; } else { $type = 'html'; } echo $type; } function rss_enclosure() { if ( post_password_required() ) { return; } foreach ( (array) get_post_custom() as $key => $val ) { if ( 'enclosure' === $key ) { foreach ( (array) $val as $enc ) { $enclosure = explode( "\n", $enc ); if ( count( $enclosure ) < 3 ) { continue; } $t = preg_split( '/[ \t]/', trim( $enclosure[2] ) ); $type = $t[0]; echo apply_filters( 'rss_enclosure', '<enclosure url="' . esc_url( trim( $enclosure[0] ) ) . '" length="' . absint( trim( $enclosure[1] ) ) . '" type="' . esc_attr( $type ) . '" />' . "\n" ); } } } } function atom_enclosure() { if ( post_password_required() ) { return; } foreach ( (array) get_post_custom() as $key => $val ) { if ( 'enclosure' === $key ) { foreach ( (array) $val as $enc ) { $enclosure = explode( "\n", $enc ); $url = ''; $type = ''; $length = 0; $mimes = get_allowed_mime_types(); if ( isset( $enclosure[0] ) && is_string( $enclosure[0] ) ) { $url = trim( $enclosure[0] ); } for ( $i = 1; $i <= 2; $i++ ) { if ( isset( $enclosure[ $i ] ) ) { if ( is_numeric( $enclosure[ $i ] ) ) { $length = trim( $enclosure[ $i ] ); } elseif ( in_array( $enclosure[ $i ], $mimes, true ) ) { $type = trim( $enclosure[ $i ] ); } } } $html_link_tag = sprintf( "<link href=\"%s\" rel=\"enclosure\" length=\"%d\" type=\"%s\" />\n", esc_url( $url ), esc_attr( $length ), esc_attr( $type ) ); echo apply_filters( 'atom_enclosure', $html_link_tag ); } } } } function prep_atom_text_construct( $data ) { if ( ! str_contains( $data, '<' ) && ! str_contains( $data, '&' ) ) { return array( 'text', $data ); } if ( ! function_exists( 'xml_parser_create' ) ) { wp_trigger_error( '', __( "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." ) ); return array( 'html', "<![CDATA[$data]]>" ); } $parser = xml_parser_create(); xml_parse( $parser, '<div>' . $data . '</div>', true ); $code = xml_get_error_code( $parser ); if ( PHP_VERSION_ID < 80000 ) { xml_parser_free( $parser ); } unset( $parser ); if ( ! $code ) { if ( ! str_contains( $data, '<' ) ) { return array( 'text', $data ); } else { $data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>"; return array( 'xhtml', $data ); } } if ( ! str_contains( $data, ']]>' ) ) { return array( 'html', "<![CDATA[$data]]>" ); } else { return array( 'html', htmlspecialchars( $data ) ); } } function atom_site_icon() { $url = get_site_icon_url( 32 ); if ( $url ) { echo '<icon>' . convert_chars( $url ) . "</icon>\n"; } } function rss2_site_icon() { $rss_title = get_wp_title_rss(); if ( empty( $rss_title ) ) { $rss_title = get_bloginfo_rss( 'name' ); } $url = get_site_icon_url( 32 ); if ( $url ) { echo '
<image>
<url>' . convert_chars( $url ) . '</url>
<title>' . $rss_title . '</title>
<link>' . get_bloginfo_rss( 'url' ) . '</link>
<width>32</width>
<height>32</height>
</image> ' . "\n"; } } function get_self_link() { $parsed = parse_url( home_url() ); $domain = $parsed['host']; if ( isset( $parsed['port'] ) ) { $domain .= ':' . $parsed['port']; } return set_url_scheme( 'http://' . $domain . wp_unslash( $_SERVER['REQUEST_URI'] ) ); } function self_link() { echo esc_url( apply_filters( 'self_link', get_self_link() ) ); } function get_feed_build_date( $format ) { global $wp_query; $datetime = false; $max_modified_time = false; $utc = new DateTimeZone( 'UTC' ); if ( ! empty( $wp_query ) && $wp_query->have_posts() ) { $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); $modified_times = array_merge( $modified_times, $comment_times ); } $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc ); } if ( false === $datetime ) { $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc ); } if ( false !== $datetime ) { $max_modified_time = $datetime->format( $format ); } return apply_filters( 'get_feed_build_date', $max_modified_time, $format ); } function feed_content_type( $type = '' ) { if ( empty( $type ) ) { $type = get_default_feed(); } $types = array( 'rss' => 'application/rss+xml', 'rss2' => 'application/rss+xml', 'rss-http' => 'text/xml', 'atom' => 'application/atom+xml', 'rdf' => 'application/rdf+xml', ); $content_type = ( ! empty( $types[ $type ] ) ) ? $types[ $type ] : 'application/octet-stream'; return apply_filters( 'feed_content_type', $content_type, $type ); } function fetch_feed( $url ) { if ( ! class_exists( 'SimplePie\SimplePie', false ) ) { require_once ABSPATH . WPINC . '/class-simplepie.php'; } require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php'; require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php'; require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php'; $feed = new SimplePie\SimplePie(); $feed->get_registry()->register( SimplePie\Sanitize::class, 'WP_SimplePie_Sanitize_KSES', true ); $feed->sanitize = new WP_SimplePie_Sanitize_KSES(); if ( method_exists( 'SimplePie_Cache', 'register' ) ) { SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' ); $feed->set_cache_location( 'wp_transient' ); } else { require_once ABSPATH . WPINC . '/class-wp-feed-cache.php'; $feed->set_cache_class( 'WP_Feed_Cache' ); } $feed->get_registry()->register( SimplePie\File::class, 'WP_SimplePie_File', true ); $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) ); do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) ); if ( empty( $url ) ) { $feed->init(); $feed->set_output_encoding( get_bloginfo( 'charset' ) ); if ( $feed->error() ) { return new WP_Error( 'simplepie-error', $feed->error() ); } return $feed; } elseif ( is_array( $url ) && count( $url ) === 1 ) { $url = array_shift( $url ); } elseif ( is_array( $url ) ) { $feeds = array(); $simplepie_errors = array(); foreach ( $url as $feed_url ) { $simplepie_instance = clone $feed; $simplepie_instance->set_feed_url( $feed_url ); $simplepie_instance->init(); $simplepie_instance->set_output_encoding( get_bloginfo( 'charset' ) ); if ( $simplepie_instance->error() ) { $simplepie_errors[] = sprintf( __( 'Error fetching feed %1$s: %2$s' ), esc_url( $feed_url ), $simplepie_instance->error() ); unset( $simplepie_instance ); continue; } $feeds[] = $simplepie_instance; unset( $simplepie_instance ); } if ( ! empty( $simplepie_errors ) ) { return new WP_Error( 'simplepie-error', $simplepie_errors ); } $feed->init(); $feed->data['items'] = SimplePie\SimplePie::merge_items( $feeds ); return $feed; } $feed->set_feed_url( $url ); $feed->init(); $feed->set_output_encoding( get_bloginfo( 'charset' ) ); if ( $feed->error() ) { return new WP_Error( 'simplepie-error', $feed->error() ); } return $feed; }
###require ABSPATH . WPINC . '/bookmark.php';
function get_bookmark( $bookmark, $output = OBJECT, $filter = 'raw' ) { global $wpdb; if ( empty( $bookmark ) ) { if ( isset( $GLOBALS['link'] ) ) { $_bookmark = & $GLOBALS['link']; } else { $_bookmark = null; } } elseif ( is_object( $bookmark ) ) { wp_cache_add( $bookmark->link_id, $bookmark, 'bookmark' ); $_bookmark = $bookmark; } else { if ( isset( $GLOBALS['link'] ) && ( $GLOBALS['link']->link_id === $bookmark ) ) { $_bookmark = & $GLOBALS['link']; } else { $_bookmark = wp_cache_get( $bookmark, 'bookmark' ); if ( ! $_bookmark ) { $_bookmark = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->links WHERE link_id = %d LIMIT 1", $bookmark ) ); if ( $_bookmark ) { $_bookmark->link_category = array_unique( wp_get_object_terms( $_bookmark->link_id, 'link_category', array( 'fields' => 'ids' ) ) ); wp_cache_add( $_bookmark->link_id, $_bookmark, 'bookmark' ); } } } } if ( ! $_bookmark ) { return $_bookmark; } $_bookmark = sanitize_bookmark( $_bookmark, $filter ); if ( OBJECT === $output ) { return $_bookmark; } elseif ( ARRAY_A === $output ) { return get_object_vars( $_bookmark ); } elseif ( ARRAY_N === $output ) { return array_values( get_object_vars( $_bookmark ) ); } else { return $_bookmark; } } function get_bookmark_field( $field, $bookmark, $context = 'display' ) { $bookmark = (int) $bookmark; $bookmark = get_bookmark( $bookmark ); if ( is_wp_error( $bookmark ) ) { return $bookmark; } if ( ! is_object( $bookmark ) ) { return ''; } if ( ! isset( $bookmark->$field ) ) { return ''; } return sanitize_bookmark_field( $field, $bookmark->$field, $bookmark->link_id, $context ); } function get_bookmarks( $args = '' ) { global $wpdb; $defaults = array( 'orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '', 'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'include' => '', 'exclude' => '', 'search' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); $key = md5( serialize( $parsed_args ) ); $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ); if ( 'rand' !== $parsed_args['orderby'] && $cache ) { if ( is_array( $cache ) && isset( $cache[ $key ] ) ) { $bookmarks = $cache[ $key ]; return apply_filters( 'get_bookmarks', $bookmarks, $parsed_args ); } } if ( ! is_array( $cache ) ) { $cache = array(); } $inclusions = ''; if ( ! empty( $parsed_args['include'] ) ) { $parsed_args['exclude'] = ''; $parsed_args['category'] = ''; $parsed_args['category_name'] = ''; $inclinks = wp_parse_id_list( $parsed_args['include'] ); if ( count( $inclinks ) ) { foreach ( $inclinks as $inclink ) { if ( empty( $inclusions ) ) { $inclusions = ' AND ( link_id = ' . $inclink . ' '; } else { $inclusions .= ' OR link_id = ' . $inclink . ' '; } } } } if ( ! empty( $inclusions ) ) { $inclusions .= ')'; } $exclusions = ''; if ( ! empty( $parsed_args['exclude'] ) ) { $exlinks = wp_parse_id_list( $parsed_args['exclude'] ); if ( count( $exlinks ) ) { foreach ( $exlinks as $exlink ) { if ( empty( $exclusions ) ) { $exclusions = ' AND ( link_id <> ' . $exlink . ' '; } else { $exclusions .= ' AND link_id <> ' . $exlink . ' '; } } } } if ( ! empty( $exclusions ) ) { $exclusions .= ')'; } if ( ! empty( $parsed_args['category_name'] ) ) { $parsed_args['category'] = get_term_by( 'name', $parsed_args['category_name'], 'link_category' ); if ( $parsed_args['category'] ) { $parsed_args['category'] = $parsed_args['category']->term_id; } else { $cache[ $key ] = array(); wp_cache_set( 'get_bookmarks', $cache, 'bookmark' ); return apply_filters( 'get_bookmarks', array(), $parsed_args ); } } $search = ''; if ( ! empty( $parsed_args['search'] ) ) { $like = '%' . $wpdb->esc_like( $parsed_args['search'] ) . '%'; $search = $wpdb->prepare( ' AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ', $like, $like, $like ); } $category_query = ''; $join = ''; if ( ! empty( $parsed_args['category'] ) ) { $incategories = wp_parse_id_list( $parsed_args['category'] ); if ( count( $incategories ) ) { foreach ( $incategories as $incat ) { if ( empty( $category_query ) ) { $category_query = ' AND ( tt.term_id = ' . $incat . ' '; } else { $category_query .= ' OR tt.term_id = ' . $incat . ' '; } } } } if ( ! empty( $category_query ) ) { $category_query .= ") AND taxonomy = 'link_category'"; $join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id"; } if ( $parsed_args['show_updated'] ) { $recently_updated_test = ', IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated '; } else { $recently_updated_test = ''; } $get_updated = ( $parsed_args['show_updated'] ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : ''; $orderby = strtolower( $parsed_args['orderby'] ); $length = ''; switch ( $orderby ) { case 'length': $length = ', CHAR_LENGTH(link_name) AS length'; break; case 'rand': $orderby = 'rand()'; break; case 'link_id': $orderby = "$wpdb->links.link_id"; break; default: $orderparams = array(); $keys = array( 'link_id', 'link_name', 'link_url', 'link_visible', 'link_rating', 'link_owner', 'link_updated', 'link_notes', 'link_description' ); foreach ( explode( ',', $orderby ) as $ordparam ) { $ordparam = trim( $ordparam ); if ( in_array( 'link_' . $ordparam, $keys, true ) ) { $orderparams[] = 'link_' . $ordparam; } elseif ( in_array( $ordparam, $keys, true ) ) { $orderparams[] = $ordparam; } } $orderby = implode( ',', $orderparams ); } if ( empty( $orderby ) ) { $orderby = 'link_name'; } $order = strtoupper( $parsed_args['order'] ); if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ), true ) ) { $order = 'ASC'; } $visible = ''; if ( $parsed_args['hide_invisible'] ) { $visible = "AND link_visible = 'Y'"; } $query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query"; $query .= " $exclusions $inclusions $search"; $query .= " ORDER BY $orderby $order"; if ( -1 !== $parsed_args['limit'] ) { $query .= ' LIMIT ' . absint( $parsed_args['limit'] ); } $results = $wpdb->get_results( $query ); if ( 'rand()' !== $orderby ) { $cache[ $key ] = $results; wp_cache_set( 'get_bookmarks', $cache, 'bookmark' ); } return apply_filters( 'get_bookmarks', $results, $parsed_args ); } function sanitize_bookmark( $bookmark, $context = 'display' ) { $fields = array( 'link_id', 'link_url', 'link_name', 'link_image', 'link_target', 'link_category', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_updated', 'link_rel', 'link_notes', 'link_rss', ); if ( is_object( $bookmark ) ) { $do_object = true; $link_id = $bookmark->link_id; } else { $do_object = false; $link_id = $bookmark['link_id']; } foreach ( $fields as $field ) { if ( $do_object ) { if ( isset( $bookmark->$field ) ) { $bookmark->$field = sanitize_bookmark_field( $field, $bookmark->$field, $link_id, $context ); } } else { if ( isset( $bookmark[ $field ] ) ) { $bookmark[ $field ] = sanitize_bookmark_field( $field, $bookmark[ $field ], $link_id, $context ); } } } return $bookmark; } function sanitize_bookmark_field( $field, $value, $bookmark_id, $context ) { $int_fields = array( 'link_id', 'link_rating' ); if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } switch ( $field ) { case 'link_category': $value = array_map( 'absint', (array) $value ); return $value; case 'link_visible': $value = preg_replace( '/[^YNyn]/', '', $value ); break; case 'link_target': $targets = array( '_top', '_blank' ); if ( ! in_array( $value, $targets, true ) ) { $value = ''; } break; } if ( 'raw' === $context ) { return $value; } if ( 'edit' === $context ) { $value = apply_filters( "edit_{$field}", $value, $bookmark_id ); if ( 'link_notes' === $field ) { $value = esc_html( $value ); } else { $value = esc_attr( $value ); } } elseif ( 'db' === $context ) { $value = apply_filters( "pre_{$field}", $value ); } else { $value = apply_filters( "{$field}", $value, $bookmark_id, $context ); if ( 'attribute' === $context ) { $value = esc_attr( $value ); } elseif ( 'js' === $context ) { $value = esc_js( $value ); } } if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } return $value; } function clean_bookmark_cache( $bookmark_id ) { wp_cache_delete( $bookmark_id, 'bookmark' ); wp_cache_delete( 'get_bookmarks', 'bookmark' ); clean_object_term_cache( $bookmark_id, 'link' ); }
###require ABSPATH . WPINC . '/bookmark-template.php';
function _walk_bookmarks( $bookmarks, $args = '' ) { $defaults = array( 'show_updated' => 0, 'show_description' => 0, 'show_images' => 1, 'show_name' => 0, 'before' => '<li>', 'after' => '</li>', 'between' => "\n", 'show_rating' => 0, 'link_before' => '', 'link_after' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); $output = ''; foreach ( (array) $bookmarks as $bookmark ) { if ( ! isset( $bookmark->recently_updated ) ) { $bookmark->recently_updated = false; } $output .= $parsed_args['before']; if ( $parsed_args['show_updated'] && $bookmark->recently_updated ) { $output .= '<em>'; } $the_link = '#'; if ( ! empty( $bookmark->link_url ) ) { $the_link = esc_url( $bookmark->link_url ); } $desc = esc_attr( sanitize_bookmark_field( 'link_description', $bookmark->link_description, $bookmark->link_id, 'display' ) ); $name = esc_attr( sanitize_bookmark_field( 'link_name', $bookmark->link_name, $bookmark->link_id, 'display' ) ); $title = $desc; if ( $parsed_args['show_updated'] ) { if ( ! str_starts_with( $bookmark->link_updated_f, '00' ) ) { $title .= ' ('; $title .= sprintf( __( 'Last updated: %s' ), gmdate( get_option( 'links_updated_date_format' ), $bookmark->link_updated_f + (int) ( (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) ); $title .= ')'; } } $alt = ' alt="' . $name . ( $parsed_args['show_description'] ? ' ' . $title : '' ) . '"'; if ( '' !== $title ) { $title = ' title="' . $title . '"'; } $rel = $bookmark->link_rel; $target = $bookmark->link_target; if ( '' !== $target ) { $target = ' target="' . $target . '"'; } if ( '' !== $rel ) { $rel = ' rel="' . esc_attr( $rel ) . '"'; } $output .= '<a href="' . $the_link . '"' . $rel . $title . $target . '>'; $output .= $parsed_args['link_before']; if ( '' !== $bookmark->link_image && $parsed_args['show_images'] ) { if ( str_starts_with( $bookmark->link_image, 'http' ) ) { $output .= '<img src="' . $bookmark->link_image . '"' . $alt . $title . ' />'; } else { $output .= '<img src="' . get_option( 'siteurl' ) . $bookmark->link_image . '"' . $alt . $title . ' />'; } if ( $parsed_args['show_name'] ) { $output .= " $name"; } } else { $output .= $name; } $output .= $parsed_args['link_after']; $output .= '</a>'; if ( $parsed_args['show_updated'] && $bookmark->recently_updated ) { $output .= '</em>'; } if ( $parsed_args['show_description'] && '' !== $desc ) { $output .= $parsed_args['between'] . $desc; } if ( $parsed_args['show_rating'] ) { $output .= $parsed_args['between'] . sanitize_bookmark_field( 'link_rating', $bookmark->link_rating, $bookmark->link_id, 'display' ); } $output .= $parsed_args['after'] . "\n"; } return $output; } function wp_list_bookmarks( $args = '' ) { $defaults = array( 'orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '', 'exclude_category' => '', 'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'echo' => 1, 'categorize' => 1, 'title_li' => __( 'Bookmarks' ), 'title_before' => '<h2>', 'title_after' => '</h2>', 'category_orderby' => 'name', 'category_order' => 'ASC', 'class' => 'linkcat', 'category_before' => '<li id="%id" class="%class">', 'category_after' => '</li>', ); $parsed_args = wp_parse_args( $args, $defaults ); $output = ''; if ( ! is_array( $parsed_args['class'] ) ) { $parsed_args['class'] = explode( ' ', $parsed_args['class'] ); } $parsed_args['class'] = array_map( 'sanitize_html_class', $parsed_args['class'] ); $parsed_args['class'] = trim( implode( ' ', $parsed_args['class'] ) ); if ( $parsed_args['categorize'] ) { $cats = get_terms( array( 'taxonomy' => 'link_category', 'name__like' => $parsed_args['category_name'], 'include' => $parsed_args['category'], 'exclude' => $parsed_args['exclude_category'], 'orderby' => $parsed_args['category_orderby'], 'order' => $parsed_args['category_order'], 'hierarchical' => 0, ) ); if ( empty( $cats ) ) { $parsed_args['categorize'] = false; } } if ( $parsed_args['categorize'] ) { foreach ( (array) $cats as $cat ) { $params = array_merge( $parsed_args, array( 'category' => $cat->term_id ) ); $bookmarks = get_bookmarks( $params ); if ( empty( $bookmarks ) ) { continue; } $output .= str_replace( array( '%id', '%class' ), array( "linkcat-$cat->term_id", $parsed_args['class'] ), $parsed_args['category_before'] ); $catname = apply_filters( 'link_category', $cat->name ); $output .= $parsed_args['title_before']; $output .= $catname; $output .= $parsed_args['title_after']; $output .= "\n\t<ul class='xoxo blogroll'>\n"; $output .= _walk_bookmarks( $bookmarks, $parsed_args ); $output .= "\n\t</ul>\n"; $output .= $parsed_args['category_after'] . "\n"; } } else { $bookmarks = get_bookmarks( $parsed_args ); if ( ! empty( $bookmarks ) ) { if ( ! empty( $parsed_args['title_li'] ) ) { $output .= str_replace( array( '%id', '%class' ), array( 'linkcat-' . $parsed_args['category'], $parsed_args['class'] ), $parsed_args['category_before'] ); $output .= $parsed_args['title_before']; $output .= $parsed_args['title_li']; $output .= $parsed_args['title_after']; $output .= "\n\t<ul class='xoxo blogroll'>\n"; $output .= _walk_bookmarks( $bookmarks, $parsed_args ); $output .= "\n\t</ul>\n"; $output .= $parsed_args['category_after'] . "\n"; } else { $output .= _walk_bookmarks( $bookmarks, $parsed_args ); } } } $html = apply_filters( 'wp_list_bookmarks', $output ); if ( $parsed_args['echo'] ) { echo $html; } else { return $html; } }
###require ABSPATH . WPINC . '/kses.php';
if ( ! defined( 'CUSTOM_TAGS' ) ) { define( 'CUSTOM_TAGS', false ); } global $allowedposttags, $allowedtags, $allowedentitynames, $allowedxmlentitynames; if ( ! CUSTOM_TAGS ) { $allowedposttags = array( 'address' => array(), 'a' => array( 'href' => true, 'rel' => true, 'rev' => true, 'name' => true, 'target' => true, 'download' => array( 'valueless' => 'y', ), ), 'abbr' => array(), 'acronym' => array(), 'area' => array( 'alt' => true, 'coords' => true, 'href' => true, 'nohref' => true, 'shape' => true, 'target' => true, ), 'article' => array( 'align' => true, ), 'aside' => array( 'align' => true, ), 'audio' => array( 'autoplay' => true, 'controls' => true, 'loop' => true, 'muted' => true, 'preload' => true, 'src' => true, ), 'b' => array(), 'bdo' => array(), 'big' => array(), 'blockquote' => array( 'cite' => true, ), 'br' => array(), 'button' => array( 'disabled' => true, 'name' => true, 'type' => true, 'value' => true, 'popovertarget' => true, 'popovertargetaction' => true, 'aria-haspopup' => true, ), 'caption' => array( 'align' => true, ), 'cite' => array(), 'code' => array(), 'col' => array( 'align' => true, 'char' => true, 'charoff' => true, 'span' => true, 'valign' => true, 'width' => true, ), 'colgroup' => array( 'align' => true, 'char' => true, 'charoff' => true, 'span' => true, 'valign' => true, 'width' => true, ), 'data' => array( 'value' => true, ), 'del' => array( 'datetime' => true, ), 'dd' => array(), 'dfn' => array(), 'details' => array( 'align' => true, 'open' => true, 'name' => true, ), 'div' => array( 'align' => true, 'popover' => true, ), 'dialog' => array( 'closedby' => true, 'open' => true, 'popover' => true, ), 'dl' => array(), 'dt' => array(), 'em' => array(), 'fieldset' => array(), 'figure' => array( 'align' => true, ), 'figcaption' => array( 'align' => true, ), 'font' => array( 'color' => true, 'face' => true, 'size' => true, ), 'footer' => array( 'align' => true, ), 'h1' => array( 'align' => true, ), 'h2' => array( 'align' => true, ), 'h3' => array( 'align' => true, ), 'h4' => array( 'align' => true, ), 'h5' => array( 'align' => true, ), 'h6' => array( 'align' => true, ), 'header' => array( 'align' => true, ), 'hgroup' => array( 'align' => true, ), 'hr' => array( 'align' => true, 'noshade' => true, 'size' => true, 'width' => true, ), 'i' => array(), 'img' => array( 'alt' => true, 'align' => true, 'border' => true, 'height' => true, 'hspace' => true, 'loading' => true, 'longdesc' => true, 'vspace' => true, 'src' => true, 'usemap' => true, 'width' => true, ), 'ins' => array( 'datetime' => true, 'cite' => true, ), 'kbd' => array(), 'label' => array( 'for' => true, ), 'legend' => array( 'align' => true, ), 'li' => array( 'align' => true, 'value' => true, ), 'main' => array( 'align' => true, ), 'map' => array( 'name' => true, ), 'mark' => array(), 'menu' => array( 'type' => true, ), 'meter' => array( 'high' => true, 'low' => true, 'max' => true, 'min' => true, 'optimum' => true, 'value' => true, ), 'nav' => array( 'align' => true, ), 'object' => array( 'data' => array( 'required' => true, 'value_callback' => '_wp_kses_allow_pdf_objects', ), 'type' => array( 'required' => true, 'values' => array( 'application/pdf' ), ), ), 'p' => array( 'align' => true, ), 'pre' => array( 'width' => true, ), 'progress' => array( 'max' => true, 'value' => true, ), 'q' => array( 'cite' => true, ), 'rb' => array(), 'rp' => array(), 'rt' => array(), 'rtc' => array(), 'ruby' => array(), 's' => array(), 'samp' => array(), 'search' => array(), 'span' => array( 'align' => true, ), 'section' => array( 'align' => true, ), 'small' => array(), 'strike' => array(), 'strong' => array(), 'sub' => array(), 'summary' => array( 'align' => true, ), 'sup' => array(), 'table' => array( 'align' => true, 'bgcolor' => true, 'border' => true, 'cellpadding' => true, 'cellspacing' => true, 'rules' => true, 'summary' => true, 'width' => true, ), 'tbody' => array( 'align' => true, 'char' => true, 'charoff' => true, 'valign' => true, ), 'td' => array( 'abbr' => true, 'align' => true, 'axis' => true, 'bgcolor' => true, 'char' => true, 'charoff' => true, 'colspan' => true, 'headers' => true, 'height' => true, 'nowrap' => true, 'rowspan' => true, 'scope' => true, 'valign' => true, 'width' => true, ), 'textarea' => array( 'cols' => true, 'rows' => true, 'disabled' => true, 'name' => true, 'readonly' => true, ), 'tfoot' => array( 'align' => true, 'char' => true, 'charoff' => true, 'valign' => true, ), 'th' => array( 'abbr' => true, 'align' => true, 'axis' => true, 'bgcolor' => true, 'char' => true, 'charoff' => true, 'colspan' => true, 'headers' => true, 'height' => true, 'nowrap' => true, 'rowspan' => true, 'scope' => true, 'valign' => true, 'width' => true, ), 'thead' => array( 'align' => true, 'char' => true, 'charoff' => true, 'valign' => true, ), 'time' => array( 'datetime' => true, ), 'title' => array(), 'tr' => array( 'align' => true, 'bgcolor' => true, 'char' => true, 'charoff' => true, 'valign' => true, ), 'track' => array( 'default' => true, 'kind' => true, 'label' => true, 'src' => true, 'srclang' => true, ), 'tt' => array(), 'u' => array(), 'ul' => array( 'type' => true, 'popover' => true, 'role' => true, ), 'ol' => array( 'start' => true, 'type' => true, 'reversed' => true, ), 'var' => array(), 'video' => array( 'autoplay' => true, 'controls' => true, 'height' => true, 'loop' => true, 'muted' => true, 'playsinline' => true, 'poster' => true, 'preload' => true, 'src' => true, 'width' => true, ), 'wbr' => array(), ); $math_global_attributes = array( 'displaystyle' => true, 'scriptlevel' => true, 'mathbackground' => true, 'mathcolor' => true, 'mathsize' => true, 'class' => true, 'data-*' => true, 'dir' => true, 'id' => true, 'style' => true, ); $math_overunder_attributes = array( 'accentunder' => true, 'accent' => true, ); $allowedposttags = array_merge( $allowedposttags, array( 'math' => array_merge( $math_global_attributes, array( 'display' => true, ) ), 'mtext' => $math_global_attributes, 'mi' => array_merge( $math_global_attributes, array( 'mathvariant' => true, ) ), 'mn' => $math_global_attributes, 'mo' => array_merge( $math_global_attributes, array( 'form' => true, 'fence' => true, 'separator' => true, 'lspace' => true, 'rspace' => true, 'stretchy' => true, 'symmetric' => true, 'maxsize' => true, 'minsize' => true, 'largeop' => true, 'movablelimits' => true, ) ), 'mspace' => array_merge( $math_global_attributes, array( 'width' => true, 'height' => true, 'depth' => true, ) ), 'ms' => $math_global_attributes, 'mrow' => $math_global_attributes, 'mfrac' => array_merge( $math_global_attributes, array( 'linethickness' => true, ) ), 'msqrt' => $math_global_attributes, 'mroot' => $math_global_attributes, 'mstyle' => $math_global_attributes, 'merror' => $math_global_attributes, 'mpadded' => array_merge( $math_global_attributes, array( 'width' => true, 'height' => true, 'depth' => true, 'lspace' => true, 'voffset' => true, ) ), 'mphantom' => $math_global_attributes, 'msub' => $math_global_attributes, 'msup' => $math_global_attributes, 'msubsup' => $math_global_attributes, 'munder' => array_merge( $math_global_attributes, $math_overunder_attributes ), 'mover' => array_merge( $math_global_attributes, $math_overunder_attributes ), 'munderover' => array_merge( $math_global_attributes, $math_overunder_attributes ), 'mmultiscripts' => $math_global_attributes, 'mprescripts' => $math_global_attributes, 'mtable' => array_merge( $math_global_attributes, array( 'columnalign' => true, 'rowspacing' => true, 'columnspacing' => true, 'align' => true, 'rowalign' => true, 'columnlines' => true, 'rowlines' => true, 'frame' => true, 'framespacing' => true, 'width' => true, ) ), 'mtr' => array_merge( $math_global_attributes, array( 'columnalign' => true, 'rowalign' => true, ) ), 'mtd' => array_merge( $math_global_attributes, array( 'columnspan' => true, 'rowspan' => true, 'columnalign' => true, 'rowalign' => true, ) ), 'semantics' => $math_global_attributes, 'annotation' => array_merge( $math_global_attributes, array( 'encoding' => true, ) ), 'menclose' => array_merge( $math_global_attributes, array( 'notation' => true, ) ), ) ); $allowedtags = array( 'a' => array( 'href' => true, 'title' => true, ), 'abbr' => array( 'title' => true, ), 'acronym' => array( 'title' => true, ), 'b' => array(), 'blockquote' => array( 'cite' => true, ), 'cite' => array(), 'code' => array(), 'del' => array( 'datetime' => true, ), 'em' => array(), 'i' => array(), 'q' => array( 'cite' => true, ), 's' => array(), 'strike' => array(), 'strong' => array(), ); $allowedentitynames = array( 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen', 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo', 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn', 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm', 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde', 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute', 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml', 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde', 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc', 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute', 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil', 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute', 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute', 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave', 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml', 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig', 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde', 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm', 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo', 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil', 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym', 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime', 'oline', 'frasl', 'weierp', 'image', 'real', 'trade', 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr', 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr', 'forall', 'part', 'exist', 'empty', 'nabla', 'isin', 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast', 'radic', 'prop', 'infin', 'ang', 'and', 'or', 'cap', 'cup', 'int', 'sim', 'cong', 'asymp', 'ne', 'equiv', 'le', 'ge', 'sub', 'sup', 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp', 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang', 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams', 'sup1', 'sup2', 'sup3', 'frac14', 'frac12', 'frac34', 'there4', ); $allowedxmlentitynames = array( 'amp', 'lt', 'gt', 'apos', 'quot', ); $allowedposttags = array_map( '_wp_add_global_attributes', $allowedposttags ); } else { $required_kses_globals = array( 'allowedposttags', 'allowedtags', 'allowedentitynames', 'allowedxmlentitynames', ); $missing_kses_globals = array(); foreach ( $required_kses_globals as $global_name ) { if ( ! isset( $GLOBALS[ $global_name ] ) || ! is_array( $GLOBALS[ $global_name ] ) ) { $missing_kses_globals[] = '<code>$' . $global_name . '</code>'; } } if ( $missing_kses_globals ) { _doing_it_wrong( 'wp_kses_allowed_html', sprintf( __( 'When using the %1$s constant, make sure to set these globals to an array: %2$s.' ), '<code>CUSTOM_TAGS</code>', implode( ', ', $missing_kses_globals ) ), '6.2.0' ); } $allowedtags = wp_kses_array_lc( $allowedtags ); $allowedposttags = wp_kses_array_lc( $allowedposttags ); } function wp_kses( $content, $allowed_html, $allowed_protocols = array() ) { if ( empty( $allowed_protocols ) ) { $allowed_protocols = wp_allowed_protocols(); } $content = wp_kses_no_null( $content, array( 'slash_zero' => 'keep' ) ); $content = wp_kses_normalize_entities( $content ); $content = wp_kses_hook( $content, $allowed_html, $allowed_protocols ); return wp_kses_split( $content, $allowed_html, $allowed_protocols ); } function wp_kses_one_attr( $attr, $element ) { $uris = wp_kses_uri_attributes(); $allowed_html = wp_kses_allowed_html( 'post' ); $allowed_protocols = wp_allowed_protocols(); $attr = wp_kses_no_null( $attr, array( 'slash_zero' => 'keep' ) ); $matches = array(); preg_match( '/^\s*/', $attr, $matches ); $lead = $matches[0]; preg_match( '/\s*$/', $attr, $matches ); $trail = $matches[0]; if ( empty( $trail ) ) { $attr = substr( $attr, strlen( $lead ) ); } else { $attr = substr( $attr, strlen( $lead ), -strlen( $trail ) ); } $split = preg_split( '/\s*=\s*/', $attr, 2 ); $name = $split[0]; if ( count( $split ) === 2 ) { $value = $split[1]; if ( '' === $value ) { $quote = ''; } else { $quote = $value[0]; } if ( '"' === $quote || "'" === $quote ) { if ( ! str_ends_with( $value, $quote ) ) { return ''; } $value = substr( $value, 1, -1 ); } else { $quote = '"'; } $value = esc_attr( $value ); if ( in_array( strtolower( $name ), $uris, true ) ) { $value = wp_kses_bad_protocol( $value, $allowed_protocols ); } $attr = "$name=$quote$value$quote"; $vless = 'n'; } else { $value = ''; $vless = 'y'; } wp_kses_attr_check( $name, $value, $attr, $vless, $element, $allowed_html ); return $lead . $attr . $trail; } function wp_kses_allowed_html( $context = '' ) { global $allowedposttags, $allowedtags, $allowedentitynames; if ( is_array( $context ) ) { $html = $context; $context = 'explicit'; return apply_filters( 'wp_kses_allowed_html', $html, $context ); } switch ( $context ) { case 'post': $tags = apply_filters( 'wp_kses_allowed_html', $allowedposttags, $context ); if ( ! CUSTOM_TAGS && ! isset( $tags['form'] ) && ( isset( $tags['input'] ) || isset( $tags['select'] ) ) ) { $tags = $allowedposttags; $tags['form'] = array( 'action' => true, 'accept' => true, 'accept-charset' => true, 'enctype' => true, 'method' => true, 'name' => true, 'target' => true, ); $tags = apply_filters( 'wp_kses_allowed_html', $tags, $context ); } return $tags; case 'user_description': case 'pre_term_description': case 'pre_user_description': $tags = $allowedtags; $tags['a']['rel'] = true; $tags['a']['target'] = true; return apply_filters( 'wp_kses_allowed_html', $tags, $context ); case 'strip': return apply_filters( 'wp_kses_allowed_html', array(), $context ); case 'entities': return apply_filters( 'wp_kses_allowed_html', $allowedentitynames, $context ); case 'data': default: return apply_filters( 'wp_kses_allowed_html', $allowedtags, $context ); } } function wp_kses_hook( $content, $allowed_html, $allowed_protocols ) { return apply_filters( 'pre_kses', $content, $allowed_html, $allowed_protocols ); } function wp_kses_version() { return '0.2.2'; } function wp_kses_split( $content, $allowed_html, $allowed_protocols ) { global $pass_allowed_html, $pass_allowed_protocols; $pass_allowed_html = $allowed_html; $pass_allowed_protocols = $allowed_protocols; $token_pattern = <<<REGEX
~
( # Detect comments of various flavors before attempting to find tags.
(<!--.*?(-->|$)) # - Normative HTML comments.
|
</[^a-zA-Z][^>]*> # - Closing tags with invalid tag names.
|
<![^>]*> # - Invalid markup declaration nodes. Not all invalid nodes
# are matched so as to avoid breaking legacy behaviors.
)
|
(<[^>]*(>|$)|>) # Tag-like spans of text.
~x
REGEX;
return preg_replace_callback( $token_pattern, '_wp_kses_split_callback', $content ); } function wp_kses_uri_attributes() { $uri_attributes = array( 'action', 'archive', 'background', 'cite', 'classid', 'codebase', 'data', 'formaction', 'href', 'icon', 'longdesc', 'manifest', 'poster', 'profile', 'src', 'usemap', 'xmlns', ); $uri_attributes = apply_filters( 'wp_kses_uri_attributes', $uri_attributes ); return $uri_attributes; } function _wp_kses_split_callback( $matches ) { global $pass_allowed_html, $pass_allowed_protocols; return wp_kses_split2( $matches[0], $pass_allowed_html, $pass_allowed_protocols ); } function wp_kses_split2( $content, $allowed_html, $allowed_protocols ) { $content = wp_kses_stripslashes( $content ); if ( ! str_starts_with( $content, '<' ) ) { return '>'; } if ( 1 === preg_match( '~^(?:</[^a-zA-Z][^>]*>|<![a-z][^>]*>)$~', $content ) ) { $opener = $content[1]; $content = substr( $content, 2, -1 ); do { $prev = $content; $content = wp_kses( $content, $allowed_html, $allowed_protocols ); } while ( $prev !== $content ); return "<{$opener}{$content}>"; } if ( str_starts_with( $content, '<!--' ) ) { $content = str_replace( array( '<!--', '-->' ), '', $content ); while ( ( $newstring = wp_kses( $content, $allowed_html, $allowed_protocols ) ) !== $content ) { $content = $newstring; } if ( '' === $content ) { return ''; } $content = preg_replace( '/--+/', '-', $content ); $content = preg_replace( '/-$/', '', $content ); return "<!--{$content}-->"; } if ( ! preg_match( '%^<\s*(/\s*)?([a-zA-Z0-9-]+)([^>]*)>?$%', $content, $matches ) ) { return ''; } $slash = trim( $matches[1] ); $elem = $matches[2]; $attrlist = $matches[3]; if ( ! is_array( $allowed_html ) ) { $allowed_html = wp_kses_allowed_html( $allowed_html ); } if ( ! isset( $allowed_html[ strtolower( $elem ) ] ) ) { return ''; } if ( '' !== $slash ) { return "</$elem>"; } return wp_kses_attr( $elem, $attrlist, $allowed_html, $allowed_protocols ); } function wp_kses_attr( $element, $attr, $allowed_html, $allowed_protocols ) { if ( ! is_array( $allowed_html ) ) { $allowed_html = wp_kses_allowed_html( $allowed_html ); } $xhtml_slash = ''; if ( preg_match( '%\s*/\s*$%', $attr ) ) { $xhtml_slash = ' /'; } $element_low = strtolower( $element ); if ( empty( $allowed_html[ $element_low ] ) || true === $allowed_html[ $element_low ] ) { return "<$element$xhtml_slash>"; } $attrarr = wp_kses_hair( $attr, $allowed_protocols ); $required_attrs = array_filter( $allowed_html[ $element_low ], static function ( $required_attr_limits ) { return isset( $required_attr_limits['required'] ) && true === $required_attr_limits['required']; } ); $stripped_tag = ''; if ( empty( $xhtml_slash ) ) { $stripped_tag = "<$element>"; } $attr2 = ''; foreach ( $attrarr as $arreach ) { $required = isset( $required_attrs[ strtolower( $arreach['name'] ) ] ); if ( wp_kses_attr_check( $arreach['name'], $arreach['value'], $arreach['whole'], $arreach['vless'], $element, $allowed_html ) ) { $attr2 .= ' ' . $arreach['whole']; if ( $required ) { unset( $required_attrs[ strtolower( $arreach['name'] ) ] ); } } elseif ( $required ) { return $stripped_tag; } } if ( ! empty( $required_attrs ) ) { return $stripped_tag; } $attr2 = preg_replace( '/[<>]/', '', $attr2 ); return "<$element$attr2$xhtml_slash>"; } function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowed_html ) { $name_low = strtolower( $name ); $element_low = strtolower( $element ); if ( ! isset( $allowed_html[ $element_low ] ) ) { $name = ''; $value = ''; $whole = ''; return false; } $allowed_attr = $allowed_html[ $element_low ]; if ( ! isset( $allowed_attr[ $name_low ] ) || '' === $allowed_attr[ $name_low ] ) { if ( str_starts_with( $name_low, 'data-' ) && ! empty( $allowed_attr['data-*'] ) && preg_match( '/^data-[a-z0-9_-]+$/', $name_low, $match ) ) { $allowed_attr[ $match[0] ] = $allowed_attr['data-*']; } else { $name = ''; $value = ''; $whole = ''; return false; } } if ( 'style' === $name_low ) { $new_value = safecss_filter_attr( $value ); if ( empty( $new_value ) ) { $name = ''; $value = ''; $whole = ''; return false; } $whole = str_replace( $value, $new_value, $whole ); $value = $new_value; } if ( is_array( $allowed_attr[ $name_low ] ) ) { foreach ( $allowed_attr[ $name_low ] as $currkey => $currval ) { if ( ! wp_kses_check_attr_val( $value, $vless, $currkey, $currval ) ) { $name = ''; $value = ''; $whole = ''; return false; } } } return true; } function wp_kses_hair( $attr, $allowed_protocols ) { $attrarr = array(); $mode = 0; $attrname = ''; $uris = wp_kses_uri_attributes(); while ( strlen( $attr ) !== 0 ) { $working = 0; switch ( $mode ) { case 0: if ( preg_match( '/^([_a-zA-Z][-_a-zA-Z0-9:.]*)/', $attr, $match ) ) { $attrname = $match[1]; $working = 1; $mode = 1; $attr = preg_replace( '/^[_a-zA-Z][-_a-zA-Z0-9:.]*/', '', $attr ); } break; case 1: if ( preg_match( '/^\s*=\s*/', $attr ) ) { $working = 1; $mode = 2; $attr = preg_replace( '/^\s*=\s*/', '', $attr ); break; } if ( preg_match( '/^\s+/', $attr ) ) { $working = 1; $mode = 0; if ( false === array_key_exists( $attrname, $attrarr ) ) { $attrarr[ $attrname ] = array( 'name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y', ); } $attr = preg_replace( '/^\s+/', '', $attr ); } break; case 2: if ( preg_match( '%^"([^"]*)"(\s+|/?$)%', $attr, $match ) ) { $thisval = $match[1]; if ( in_array( strtolower( $attrname ), $uris, true ) ) { $thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols ); } if ( false === array_key_exists( $attrname, $attrarr ) ) { $attrarr[ $attrname ] = array( 'name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n', ); } $working = 1; $mode = 0; $attr = preg_replace( '/^"[^"]*"(\s+|$)/', '', $attr ); break; } if ( preg_match( "%^'([^']*)'(\s+|/?$)%", $attr, $match ) ) { $thisval = $match[1]; if ( in_array( strtolower( $attrname ), $uris, true ) ) { $thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols ); } if ( false === array_key_exists( $attrname, $attrarr ) ) { $attrarr[ $attrname ] = array( 'name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n', ); } $working = 1; $mode = 0; $attr = preg_replace( "/^'[^']*'(\s+|$)/", '', $attr ); break; } if ( preg_match( "%^([^\s\"']+)(\s+|/?$)%", $attr, $match ) ) { $thisval = $match[1]; if ( in_array( strtolower( $attrname ), $uris, true ) ) { $thisval = wp_kses_bad_protocol( $thisval, $allowed_protocols ); } if ( false === array_key_exists( $attrname, $attrarr ) ) { $attrarr[ $attrname ] = array( 'name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n', ); } $working = 1; $mode = 0; $attr = preg_replace( "%^[^\s\"']+(\s+|$)%", '', $attr ); } break; } if ( 0 === $working ) { $attr = wp_kses_html_error( $attr ); $mode = 0; } } if ( 1 === $mode && false === array_key_exists( $attrname, $attrarr ) ) { $attrarr[ $attrname ] = array( 'name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y', ); } return $attrarr; } function wp_kses_attr_parse( $element ) { $valid = preg_match( '%^(<\s*)(/\s*)?([a-zA-Z0-9]+\s*)([^>]*)(>?)$%', $element, $matches ); if ( 1 !== $valid ) { return false; } $begin = $matches[1]; $slash = $matches[2]; $elname = $matches[3]; $attr = $matches[4]; $end = $matches[5]; if ( '' !== $slash ) { return false; } if ( 1 === preg_match( '%\s*/\s*$%', $attr, $matches ) ) { $xhtml_slash = $matches[0]; $attr = substr( $attr, 0, -strlen( $xhtml_slash ) ); } else { $xhtml_slash = ''; } $attrarr = wp_kses_hair_parse( $attr ); if ( false === $attrarr ) { return false; } array_unshift( $attrarr, $begin . $slash . $elname ); array_push( $attrarr, $xhtml_slash . $end ); return $attrarr; } function wp_kses_hair_parse( $attr ) { if ( '' === $attr ) { return array(); } $regex = '(?:
[_a-zA-Z][-_a-zA-Z0-9:.]* # Attribute name.
|
\[\[?[^\[\]]+\]\]? # Shortcode in the name position implies unfiltered_html.
)
(?: # Attribute value.
\s*=\s* # All values begin with "=".
(?:
"[^"]*" # Double-quoted.
|
\'[^\']*\' # Single-quoted.
|
[^\s"\']+ # Non-quoted.
(?:\s|$) # Must have a space.
)
|
(?:\s|$) # If attribute has no value, space is required.
)
\s* # Trailing space is optional except as mentioned above.
'; $validation = "/^($regex)+$/x"; $extraction = "/$regex/x"; if ( 1 === preg_match( $validation, $attr ) ) { preg_match_all( $extraction, $attr, $attrarr ); return $attrarr[0]; } else { return false; } } function wp_kses_check_attr_val( $value, $vless, $checkname, $checkvalue ) { $ok = true; switch ( strtolower( $checkname ) ) { case 'maxlen': if ( strlen( $value ) > $checkvalue ) { $ok = false; } break; case 'minlen': if ( strlen( $value ) < $checkvalue ) { $ok = false; } break; case 'maxval': if ( ! preg_match( '/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value ) ) { $ok = false; } if ( $value > $checkvalue ) { $ok = false; } break; case 'minval': if ( ! preg_match( '/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value ) ) { $ok = false; } if ( $value < $checkvalue ) { $ok = false; } break; case 'valueless': if ( strtolower( $checkvalue ) !== $vless ) { $ok = false; } break; case 'values': if ( false === array_search( strtolower( $value ), $checkvalue, true ) ) { $ok = false; } break; case 'value_callback': if ( ! call_user_func( $checkvalue, $value ) ) { $ok = false; } break; } return $ok; } function wp_kses_bad_protocol( $content, $allowed_protocols ) { $content = wp_kses_no_null( $content ); if ( ( str_starts_with( $content, 'https://' ) && in_array( 'https', $allowed_protocols, true ) ) || ( str_starts_with( $content, 'http://' ) && in_array( 'http', $allowed_protocols, true ) ) ) { return $content; } $iterations = 0; do { $original_content = $content; $content = wp_kses_bad_protocol_once( $content, $allowed_protocols ); } while ( $original_content !== $content && ++$iterations < 6 ); if ( $original_content !== $content ) { return ''; } return $content; } function wp_kses_no_null( $content, $options = null ) { if ( ! isset( $options['slash_zero'] ) ) { $options = array( 'slash_zero' => 'remove' ); } $content = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $content ); if ( 'remove' === $options['slash_zero'] ) { $content = preg_replace( '/\\\\+0+/', '', $content ); } return $content; } function wp_kses_stripslashes( $content ) { return preg_replace( '%\\\\"%', '"', $content ); } function wp_kses_array_lc( $inarray ) { $outarray = array(); foreach ( (array) $inarray as $inkey => $inval ) { $outkey = strtolower( $inkey ); $outarray[ $outkey ] = array(); foreach ( (array) $inval as $inkey2 => $inval2 ) { $outkey2 = strtolower( $inkey2 ); $outarray[ $outkey ][ $outkey2 ] = $inval2; } } return $outarray; } function wp_kses_html_error( $attr ) { return preg_replace( '/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $attr ); } function wp_kses_bad_protocol_once( $content, $allowed_protocols, $count = 1 ) { $content = preg_replace( '/(�*58(?![;0-9])|�*3a(?![;a-f0-9]))/i', '$1;', $content ); $content2 = preg_split( '/:|�*58;|�*3a;|:/i', $content, 2 ); if ( isset( $content2[1] ) && ! preg_match( '%/\?%', $content2[0] ) ) { $content = trim( $content2[1] ); $protocol = wp_kses_bad_protocol_once2( $content2[0], $allowed_protocols ); if ( 'feed:' === $protocol ) { if ( $count > 2 ) { return ''; } $content = wp_kses_bad_protocol_once( $content, $allowed_protocols, ++$count ); if ( empty( $content ) ) { return $content; } } $content = $protocol . $content; } return $content; } function wp_kses_bad_protocol_once2( $scheme, $allowed_protocols ) { $scheme = wp_kses_decode_entities( $scheme ); $scheme = preg_replace( '/\s/', '', $scheme ); $scheme = wp_kses_no_null( $scheme ); $scheme = strtolower( $scheme ); $allowed = false; foreach ( (array) $allowed_protocols as $one_protocol ) { if ( strtolower( $one_protocol ) === $scheme ) { $allowed = true; break; } } if ( $allowed ) { return "$scheme:"; } else { return ''; } } function wp_kses_normalize_entities( $content, $context = 'html' ) { $content = str_replace( '&', '&', $content ); $content = preg_replace_callback( '/&#(0*[1-9][0-9]{0,6});/', 'wp_kses_normalize_entities2', $content ); $content = preg_replace_callback( '/&#[Xx](0*[1-9A-Fa-f][0-9A-Fa-f]{0,5});/', 'wp_kses_normalize_entities3', $content ); if ( 'xml' === $context ) { $content = preg_replace_callback( '/&([A-Za-z]{2,8}[0-9]{0,2});/', 'wp_kses_xml_named_entities', $content ); } else { $content = preg_replace_callback( '/&([A-Za-z]{2,8}[0-9]{0,2});/', 'wp_kses_named_entities', $content ); } return $content; } function wp_kses_named_entities( $matches ) { global $allowedentitynames; if ( empty( $matches[1] ) ) { return ''; } $i = $matches[1]; return ( ! in_array( $i, $allowedentitynames, true ) ) ? "&$i;" : "&$i;"; } function wp_kses_xml_named_entities( $matches ) { global $allowedentitynames, $allowedxmlentitynames; if ( empty( $matches[1] ) ) { return ''; } $i = $matches[1]; if ( in_array( $i, $allowedxmlentitynames, true ) ) { return "&$i;"; } elseif ( in_array( $i, $allowedentitynames, true ) ) { return html_entity_decode( "&$i;", ENT_HTML5 ); } return "&$i;"; } function wp_kses_normalize_entities2( $matches ) { if ( empty( $matches[1] ) ) { return ''; } $i = $matches[1]; if ( valid_unicode( $i ) ) { $i = str_pad( ltrim( $i, '0' ), 3, '0', STR_PAD_LEFT ); $i = "&#$i;"; } else { $i = "&#$i;"; } return $i; } function wp_kses_normalize_entities3( $matches ) { if ( empty( $matches[1] ) ) { return ''; } $hexchars = $matches[1]; return ( ! valid_unicode( hexdec( $hexchars ) ) ) ? "&#x$hexchars;" : '&#x' . ltrim( $hexchars, '0' ) . ';'; } function valid_unicode( $i ) { $i = (int) $i; return ( 0x9 === $i || 0xA === $i || 0xD === $i || ( 0x20 <= $i && $i <= 0xD7FF ) || ( 0xE000 <= $i && $i <= 0xFFFD ) || ( 0x10000 <= $i && $i <= 0x10FFFF ) ); } function wp_kses_decode_entities( $content ) { $content = preg_replace_callback( '/&#([0-9]+);/', '_wp_kses_decode_entities_chr', $content ); $content = preg_replace_callback( '/&#[Xx]([0-9A-Fa-f]+);/', '_wp_kses_decode_entities_chr_hexdec', $content ); return $content; } function _wp_kses_decode_entities_chr( $matches ) { return chr( $matches[1] ); } function _wp_kses_decode_entities_chr_hexdec( $matches ) { return chr( hexdec( $matches[1] ) ); } function wp_filter_kses( $data ) { return addslashes( wp_kses( stripslashes( $data ), current_filter() ) ); } function wp_kses_data( $data ) { return wp_kses( $data, current_filter() ); } function wp_filter_post_kses( $data ) { return addslashes( wp_kses( stripslashes( $data ), 'post' ) ); } function wp_filter_global_styles_post( $data ) { $decoded_data = json_decode( wp_unslash( $data ), true ); $json_decoding_error = json_last_error(); if ( JSON_ERROR_NONE === $json_decoding_error && is_array( $decoded_data ) && isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && $decoded_data['isGlobalStylesUserThemeJSON'] ) { unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); $data_to_encode = WP_Theme_JSON::remove_insecure_properties( $decoded_data, 'custom' ); $data_to_encode['isGlobalStylesUserThemeJSON'] = true; return wp_slash( wp_json_encode( $data_to_encode ) ); } return $data; } function wp_kses_post( $data ) { return wp_kses( $data, 'post' ); } function wp_kses_post_deep( $data ) { return map_deep( $data, 'wp_kses_post' ); } function wp_filter_nohtml_kses( $data ) { return addslashes( wp_kses( stripslashes( $data ), 'strip' ) ); } function kses_init_filters() { add_filter( 'title_save_pre', 'wp_filter_kses' ); if ( current_user_can( 'unfiltered_html' ) ) { add_filter( 'pre_comment_content', 'wp_filter_post_kses' ); } else { add_filter( 'pre_comment_content', 'wp_filter_kses' ); } add_filter( 'content_save_pre', 'wp_filter_global_styles_post', 9 ); add_filter( 'content_filtered_save_pre', 'wp_filter_global_styles_post', 9 ); add_filter( 'content_save_pre', 'wp_filter_post_kses' ); add_filter( 'excerpt_save_pre', 'wp_filter_post_kses' ); add_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' ); } function kses_remove_filters() { remove_filter( 'title_save_pre', 'wp_filter_kses' ); remove_filter( 'pre_comment_content', 'wp_filter_post_kses' ); remove_filter( 'pre_comment_content', 'wp_filter_kses' ); remove_filter( 'content_save_pre', 'wp_filter_global_styles_post', 9 ); remove_filter( 'content_filtered_save_pre', 'wp_filter_global_styles_post', 9 ); remove_filter( 'content_save_pre', 'wp_filter_post_kses' ); remove_filter( 'excerpt_save_pre', 'wp_filter_post_kses' ); remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' ); } function kses_init() { kses_remove_filters(); if ( ! current_user_can( 'unfiltered_html' ) ) { kses_init_filters(); } } function safecss_filter_attr( $css, $deprecated = '' ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.8.1' ); } $css = wp_kses_no_null( $css ); $css = str_replace( array( "\n", "\r", "\t" ), '', $css ); $allowed_protocols = wp_allowed_protocols(); $css_array = explode( ';', trim( $css ) ); $allowed_attr = apply_filters( 'safe_style_css', array( 'background', 'background-color', 'background-image', 'background-position', 'background-repeat', 'background-size', 'background-attachment', 'background-blend-mode', 'border', 'border-radius', 'border-width', 'border-color', 'border-style', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-bottom', 'border-bottom-color', 'border-bottom-left-radius', 'border-bottom-right-radius', 'border-bottom-style', 'border-bottom-width', 'border-bottom-right-radius', 'border-bottom-left-radius', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-style', 'border-top-width', 'border-top-left-radius', 'border-top-right-radius', 'border-spacing', 'border-collapse', 'caption-side', 'columns', 'column-count', 'column-fill', 'column-gap', 'column-rule', 'column-span', 'column-width', 'color', 'filter', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'letter-spacing', 'line-height', 'text-align', 'text-decoration', 'text-indent', 'text-transform', 'white-space', 'height', 'min-height', 'max-height', 'width', 'min-width', 'max-width', 'margin', 'margin-right', 'margin-bottom', 'margin-left', 'margin-top', 'margin-block-start', 'margin-block-end', 'margin-inline-start', 'margin-inline-end', 'padding', 'padding-right', 'padding-bottom', 'padding-left', 'padding-top', 'padding-block-start', 'padding-block-end', 'padding-inline-start', 'padding-inline-end', 'flex', 'flex-basis', 'flex-direction', 'flex-flow', 'flex-grow', 'flex-shrink', 'flex-wrap', 'gap', 'column-gap', 'row-gap', 'grid-template-columns', 'grid-auto-columns', 'grid-column-start', 'grid-column-end', 'grid-column', 'grid-column-gap', 'grid-template-rows', 'grid-auto-rows', 'grid-row-start', 'grid-row-end', 'grid-row', 'grid-row-gap', 'grid-gap', 'justify-content', 'justify-items', 'justify-self', 'align-content', 'align-items', 'align-self', 'clear', 'cursor', 'direction', 'float', 'list-style-type', 'object-fit', 'object-position', 'opacity', 'overflow', 'vertical-align', 'writing-mode', 'position', 'top', 'right', 'bottom', 'left', 'z-index', 'box-shadow', 'aspect-ratio', 'container-type', '--*', ) ); $css_url_data_types = array( 'background', 'background-image', 'cursor', 'filter', 'list-style', 'list-style-image', ); $css_gradient_data_types = array( 'background', 'background-image', ); if ( empty( $allowed_attr ) ) { return $css; } $css = ''; foreach ( $css_array as $css_item ) { if ( '' === $css_item ) { continue; } $css_item = trim( $css_item ); $css_test_string = $css_item; $found = false; $url_attr = false; $gradient_attr = false; $is_custom_var = false; if ( ! str_contains( $css_item, ':' ) ) { $found = true; } else { $parts = explode( ':', $css_item, 2 ); $css_selector = trim( $parts[0] ); if ( in_array( '--*', $allowed_attr, true ) && preg_match( '/^--[a-zA-Z0-9-_]+$/', $css_selector ) ) { $allowed_attr[] = $css_selector; $is_custom_var = true; } if ( in_array( $css_selector, $allowed_attr, true ) ) { $found = true; $url_attr = in_array( $css_selector, $css_url_data_types, true ); $gradient_attr = in_array( $css_selector, $css_gradient_data_types, true ); } if ( $is_custom_var ) { $css_value = trim( $parts[1] ); $url_attr = str_starts_with( $css_value, 'url(' ); $gradient_attr = str_contains( $css_value, '-gradient(' ); } } if ( $found && $url_attr ) { preg_match_all( '/url\([^)]+\)/', $parts[1], $url_matches ); foreach ( $url_matches[0] as $url_match ) { preg_match( '/^url\(\s*([\'\"]?)(.*)(\g1)\s*\)$/', $url_match, $url_pieces ); if ( empty( $url_pieces[2] ) ) { $found = false; break; } $url = trim( $url_pieces[2] ); if ( empty( $url ) || wp_kses_bad_protocol( $url, $allowed_protocols ) !== $url ) { $found = false; break; } else { $css_test_string = str_replace( $url_match, '', $css_test_string ); } } } if ( $found && $gradient_attr ) { $css_value = trim( $parts[1] ); if ( preg_match( '/^(repeating-)?(linear|radial|conic)-gradient\(([^()]|rgb[a]?\([^()]*\))*\)$/', $css_value ) ) { $css_test_string = str_replace( $css_value, '', $css_test_string ); } } if ( $found ) { $css_test_string = preg_replace( '/\b(?:var|calc|min|max|minmax|clamp|repeat)(\((?:[^()]|(?1))*\))/', '', $css_test_string ); $allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ); $allow_css = apply_filters( 'safecss_filter_attr_allow_css', $allow_css, $css_test_string ); if ( $allow_css ) { if ( '' !== $css ) { $css .= ';'; } $css .= $css_item; } } } return $css; } function _wp_add_global_attributes( $value ) { $global_attributes = array( 'aria-controls' => true, 'aria-current' => true, 'aria-describedby' => true, 'aria-details' => true, 'aria-expanded' => true, 'aria-hidden' => true, 'aria-label' => true, 'aria-labelledby' => true, 'aria-live' => true, 'class' => true, 'data-*' => true, 'dir' => true, 'hidden' => true, 'id' => true, 'lang' => true, 'style' => true, 'title' => true, 'role' => true, 'xml:lang' => true, ); if ( true === $value ) { $value = array(); } if ( is_array( $value ) ) { return array_merge( $value, $global_attributes ); } return $value; } function _wp_kses_allow_pdf_objects( $url ) { if ( str_contains( $url, '?' ) || str_contains( $url, '#' ) ) { return false; } if ( ! str_ends_with( $url, '.pdf' ) ) { return false; } $upload_info = wp_upload_dir( null, false ); $parsed_url = wp_parse_url( $upload_info['url'] ); $upload_host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : ''; $upload_port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : ''; if ( str_starts_with( $url, "http://$upload_host$upload_port/" ) || str_starts_with( $url, "https://$upload_host$upload_port/" ) ) { return true; } return false; }
###require ABSPATH . WPINC . '/cron.php';
function wp_schedule_single_event( $timestamp, $hook, $args = array(), $wp_error = false ) { if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { if ( $wp_error ) { return new WP_Error( 'invalid_timestamp', __( 'Event timestamp must be a valid Unix timestamp.' ) ); } return false; } $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args, ); $pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_schedule_event_false', __( 'A plugin prevented the event from being scheduled.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } $crons = _get_cron_array(); $key = md5( serialize( $event->args ) ); $duplicate = false; if ( $event->timestamp < time() + 10 * MINUTE_IN_SECONDS ) { $min_timestamp = 0; } else { $min_timestamp = $event->timestamp - 10 * MINUTE_IN_SECONDS; } if ( $event->timestamp < time() ) { $max_timestamp = time() + 10 * MINUTE_IN_SECONDS; } else { $max_timestamp = $event->timestamp + 10 * MINUTE_IN_SECONDS; } foreach ( $crons as $event_timestamp => $cron ) { if ( $event_timestamp < $min_timestamp ) { continue; } if ( $event_timestamp > $max_timestamp ) { break; } if ( isset( $cron[ $event->hook ][ $key ] ) ) { $duplicate = true; break; } } if ( $duplicate ) { if ( $wp_error ) { return new WP_Error( 'duplicate_event', __( 'A duplicate event already exists.' ) ); } return false; } $event = apply_filters( 'schedule_event', $event ); if ( ! $event ) { if ( $wp_error ) { return new WP_Error( 'schedule_event_false', __( 'A plugin disallowed this event.' ) ); } return false; } $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( 'schedule' => $event->schedule, 'args' => $event->args, ); uksort( $crons, 'strnatcasecmp' ); return _set_cron_array( $crons, $wp_error ); } function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array(), $wp_error = false ) { if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { if ( $wp_error ) { return new WP_Error( 'invalid_timestamp', __( 'Event timestamp must be a valid Unix timestamp.' ) ); } return false; } $schedules = wp_get_schedules(); if ( ! isset( $schedules[ $recurrence ] ) ) { if ( $wp_error ) { return new WP_Error( 'invalid_schedule', __( 'Event schedule does not exist.' ) ); } return false; } $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[ $recurrence ]['interval'], ); $pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_schedule_event_false', __( 'A plugin prevented the event from being scheduled.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } $event = apply_filters( 'schedule_event', $event ); if ( ! $event ) { if ( $wp_error ) { return new WP_Error( 'schedule_event_false', __( 'A plugin disallowed this event.' ) ); } return false; } $key = md5( serialize( $event->args ) ); $crons = _get_cron_array(); $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval, ); uksort( $crons, 'strnatcasecmp' ); return _set_cron_array( $crons, $wp_error ); } function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array(), $wp_error = false ) { if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { if ( $wp_error ) { return new WP_Error( 'invalid_timestamp', __( 'Event timestamp must be a valid Unix timestamp.' ) ); } return false; } $schedules = wp_get_schedules(); $interval = 0; if ( isset( $schedules[ $recurrence ] ) ) { $interval = $schedules[ $recurrence ]['interval']; } if ( 0 === $interval ) { $scheduled_event = wp_get_scheduled_event( $hook, $args, $timestamp ); if ( $scheduled_event && isset( $scheduled_event->interval ) ) { $interval = $scheduled_event->interval; } } $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $interval, ); $pre = apply_filters( 'pre_reschedule_event', null, $event, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_reschedule_event_false', __( 'A plugin prevented the event from being rescheduled.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } if ( 0 === $interval ) { if ( $wp_error ) { return new WP_Error( 'invalid_schedule', __( 'Event schedule does not exist.' ) ); } return false; } $now = time(); if ( $timestamp >= $now ) { $timestamp = $now + $interval; } else { $timestamp = $now + ( $interval - ( ( $now - $timestamp ) % $interval ) ); } return wp_schedule_event( $timestamp, $recurrence, $hook, $args, $wp_error ); } function wp_unschedule_event( $timestamp, $hook, $args = array(), $wp_error = false ) { if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { if ( $wp_error ) { return new WP_Error( 'invalid_timestamp', __( 'Event timestamp must be a valid Unix timestamp.' ) ); } return false; } $pre = apply_filters( 'pre_unschedule_event', null, $timestamp, $hook, $args, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_unschedule_event_false', __( 'A plugin prevented the event from being unscheduled.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } $crons = _get_cron_array(); $key = md5( serialize( $args ) ); unset( $crons[ $timestamp ][ $hook ][ $key ] ); if ( empty( $crons[ $timestamp ][ $hook ] ) ) { unset( $crons[ $timestamp ][ $hook ] ); } if ( empty( $crons[ $timestamp ] ) ) { unset( $crons[ $timestamp ] ); } return _set_cron_array( $crons, $wp_error ); } function wp_clear_scheduled_hook( $hook, $args = array(), $wp_error = false ) { if ( ! is_array( $args ) ) { _deprecated_argument( __FUNCTION__, '3.0.0', __( 'This argument has changed to an array to match the behavior of the other cron functions.' ) ); $args = array_slice( func_get_args(), 1 ); $wp_error = false; } $pre = apply_filters( 'pre_clear_scheduled_hook', null, $hook, $args, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_clear_scheduled_hook_false', __( 'A plugin prevented the hook from being cleared.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } $crons = _get_cron_array(); if ( empty( $crons ) ) { return 0; } $results = array(); $key = md5( serialize( $args ) ); foreach ( $crons as $timestamp => $cron ) { if ( isset( $cron[ $hook ][ $key ] ) ) { $results[] = wp_unschedule_event( $timestamp, $hook, $args, true ); } } $errors = array_filter( $results, 'is_wp_error' ); $error = new WP_Error(); if ( $errors ) { if ( $wp_error ) { array_walk( $errors, array( $error, 'merge_from' ) ); return $error; } return false; } return count( $results ); } function wp_unschedule_hook( $hook, $wp_error = false ) { $pre = apply_filters( 'pre_unschedule_hook', null, $hook, $wp_error ); if ( null !== $pre ) { if ( $wp_error && false === $pre ) { return new WP_Error( 'pre_unschedule_hook_false', __( 'A plugin prevented the hook from being cleared.' ) ); } if ( ! $wp_error && is_wp_error( $pre ) ) { return false; } return $pre; } $crons = _get_cron_array(); if ( empty( $crons ) ) { return 0; } $results = array(); foreach ( $crons as $timestamp => $args ) { if ( ! empty( $crons[ $timestamp ][ $hook ] ) ) { $results[] = count( $crons[ $timestamp ][ $hook ] ); } unset( $crons[ $timestamp ][ $hook ] ); if ( empty( $crons[ $timestamp ] ) ) { unset( $crons[ $timestamp ] ); } } if ( empty( $results ) ) { return 0; } $set = _set_cron_array( $crons, $wp_error ); if ( true === $set ) { return array_sum( $results ); } return $set; } function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) { $pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp ); if ( null !== $pre ) { return $pre; } if ( null !== $timestamp && ! is_numeric( $timestamp ) ) { return false; } $crons = _get_cron_array(); if ( empty( $crons ) ) { return false; } $key = md5( serialize( $args ) ); if ( ! $timestamp ) { $next = false; foreach ( $crons as $timestamp => $cron ) { if ( isset( $cron[ $hook ][ $key ] ) ) { $next = $timestamp; break; } } if ( ! $next ) { return false; } $timestamp = $next; } elseif ( ! isset( $crons[ $timestamp ][ $hook ][ $key ] ) ) { return false; } $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $crons[ $timestamp ][ $hook ][ $key ]['schedule'], 'args' => $args, ); if ( isset( $crons[ $timestamp ][ $hook ][ $key ]['interval'] ) ) { $event->interval = $crons[ $timestamp ][ $hook ][ $key ]['interval']; } return $event; } function wp_next_scheduled( $hook, $args = array() ) { $next_event = wp_get_scheduled_event( $hook, $args ); if ( ! $next_event ) { return false; } return apply_filters( 'wp_next_scheduled', $next_event->timestamp, $next_event, $hook, $args ); } function spawn_cron( $gmt_time = 0 ) { if ( ! $gmt_time ) { $gmt_time = microtime( true ); } if ( defined( 'DOING_CRON' ) || isset( $_GET['doing_wp_cron'] ) ) { return false; } $lock = (float) get_transient( 'doing_cron' ); if ( $lock > $gmt_time + 10 * MINUTE_IN_SECONDS ) { $lock = 0; } if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) { return false; } $crons = wp_get_ready_cron_jobs(); if ( empty( $crons ) ) { return false; } $keys = array_keys( $crons ); if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { return false; } if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { if ( 'GET' !== $_SERVER['REQUEST_METHOD'] || defined( 'DOING_AJAX' ) || defined( 'XMLRPC_REQUEST' ) ) { return false; } $doing_wp_cron = sprintf( '%.22F', $gmt_time ); set_transient( 'doing_cron', $doing_wp_cron ); ob_start(); wp_redirect( add_query_arg( 'doing_wp_cron', $doing_wp_cron, wp_unslash( $_SERVER['REQUEST_URI'] ) ) ); echo ' '; wp_ob_end_flush_all(); flush(); require_once ABSPATH . 'wp-cron.php'; return true; } $doing_wp_cron = sprintf( '%.22F', $gmt_time ); set_transient( 'doing_cron', $doing_wp_cron ); $cron_request = apply_filters( 'cron_request', array( 'url' => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ), 'key' => $doing_wp_cron, 'args' => array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), ), ), $doing_wp_cron ); $result = wp_remote_post( $cron_request['url'], $cron_request['args'] ); return ! is_wp_error( $result ); } function wp_cron(): void { if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { if ( did_action( 'wp_loaded' ) ) { _wp_cron(); } else { add_action( 'wp_loaded', '_wp_cron', 20 ); } } elseif ( doing_action( 'shutdown' ) ) { _wp_cron(); } else { add_action( 'shutdown', '_wp_cron' ); } } function _wp_cron() { if ( str_contains( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ) { return 0; } $crons = wp_get_ready_cron_jobs(); if ( empty( $crons ) ) { return 0; } $gmt_time = microtime( true ); $keys = array_keys( $crons ); if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { return 0; } $schedules = wp_get_schedules(); $results = array(); foreach ( $crons as $timestamp => $cronhooks ) { if ( $timestamp > $gmt_time ) { break; } foreach ( (array) $cronhooks as $hook => $args ) { if ( isset( $schedules[ $hook ]['callback'] ) && ! call_user_func( $schedules[ $hook ]['callback'] ) ) { continue; } $results[] = spawn_cron( $gmt_time ); break 2; } } if ( in_array( false, $results, true ) ) { return false; } return count( $results ); } function wp_get_schedules() { $schedules = array( 'hourly' => array( 'interval' => HOUR_IN_SECONDS, 'display' => __( 'Once Hourly' ), ), 'twicedaily' => array( 'interval' => 12 * HOUR_IN_SECONDS, 'display' => __( 'Twice Daily' ), ), 'daily' => array( 'interval' => DAY_IN_SECONDS, 'display' => __( 'Once Daily' ), ), 'weekly' => array( 'interval' => WEEK_IN_SECONDS, 'display' => __( 'Once Weekly' ), ), ); return array_merge( apply_filters( 'cron_schedules', array() ), $schedules ); } function wp_get_schedule( $hook, $args = array() ) { $schedule = false; $event = wp_get_scheduled_event( $hook, $args ); if ( $event ) { $schedule = $event->schedule; } return apply_filters( 'get_schedule', $schedule, $hook, $args ); } function wp_get_ready_cron_jobs() { $pre = apply_filters( 'pre_get_ready_cron_jobs', null ); if ( null !== $pre ) { return $pre; } $crons = _get_cron_array(); $gmt_time = microtime( true ); $results = array(); foreach ( $crons as $timestamp => $cronhooks ) { if ( $timestamp > $gmt_time ) { break; } $results[ $timestamp ] = $cronhooks; } return $results; } function _get_cron_array() { $cron = get_option( 'cron' ); if ( ! is_array( $cron ) ) { return array(); } if ( ! isset( $cron['version'] ) ) { $cron = _upgrade_cron_array( $cron ); } unset( $cron['version'] ); return $cron; } function _set_cron_array( $cron, $wp_error = false ) { if ( ! is_array( $cron ) ) { $cron = array(); } $cron['version'] = 2; $result = update_option( 'cron', $cron, true ); if ( $wp_error && ! $result ) { return new WP_Error( 'could_not_set', __( 'The cron event list could not be saved.' ) ); } return $result; } function _upgrade_cron_array( $cron ) { if ( isset( $cron['version'] ) && 2 === $cron['version'] ) { return $cron; } $new_cron = array(); foreach ( (array) $cron as $timestamp => $hooks ) { foreach ( (array) $hooks as $hook => $args ) { $key = md5( serialize( $args['args'] ) ); $new_cron[ $timestamp ][ $hook ][ $key ] = $args; } } $new_cron['version'] = 2; update_option( 'cron', $new_cron, true ); return $new_cron; }
###require ABSPATH . WPINC . '/deprecated.php';
function get_postdata($postid) { _deprecated_function( __FUNCTION__, '1.5.1', 'get_post()' ); $post = get_post($postid); $postdata = array ( 'ID' => $post->ID, 'Author_ID' => $post->post_author, 'Date' => $post->post_date, 'Content' => $post->post_content, 'Excerpt' => $post->post_excerpt, 'Title' => $post->post_title, 'Category' => $post->post_category, 'post_status' => $post->post_status, 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'post_password' => $post->post_password, 'to_ping' => $post->to_ping, 'pinged' => $post->pinged, 'post_type' => $post->post_type, 'post_name' => $post->post_name ); return $postdata; } function start_wp() { global $wp_query; _deprecated_function( __FUNCTION__, '1.5.0', __('new WordPress Loop') ); $wp_query->next_post(); setup_postdata( get_post() ); } function the_category_ID($display = true) { _deprecated_function( __FUNCTION__, '0.71', 'get_the_category()' ); $categories = get_the_category(); $cat = $categories[0]->term_id; if ( $display ) echo $cat; return $cat; } function the_category_head( $before = '', $after = '' ) { global $currentcat, $previouscat; _deprecated_function( __FUNCTION__, '0.71', 'get_the_category_by_ID()' ); $categories = get_the_category(); $currentcat = $categories[0]->category_id; if ( $currentcat != $previouscat ) { echo $before; echo get_the_category_by_ID($currentcat); echo $after; $previouscat = $currentcat; } } function previous_post($format='%', $previous='previous post: ', $title='yes', $in_same_cat='no', $limitprev=1, $excluded_categories='') { _deprecated_function( __FUNCTION__, '2.0.0', 'previous_post_link()' ); if ( empty($in_same_cat) || 'no' == $in_same_cat ) $in_same_cat = false; else $in_same_cat = true; $post = get_previous_post($in_same_cat, $excluded_categories); if ( !$post ) return; $string = '<a href="'.get_permalink($post->ID).'">'.$previous; if ( 'yes' == $title ) $string .= apply_filters('the_title', $post->post_title, $post->ID); $string .= '</a>'; $format = str_replace('%', $string, $format); echo $format; } function next_post($format='%', $next='next post: ', $title='yes', $in_same_cat='no', $limitnext=1, $excluded_categories='') { _deprecated_function( __FUNCTION__, '2.0.0', 'next_post_link()' ); if ( empty($in_same_cat) || 'no' == $in_same_cat ) $in_same_cat = false; else $in_same_cat = true; $post = get_next_post($in_same_cat, $excluded_categories); if ( !$post ) return; $string = '<a href="'.get_permalink($post->ID).'">'.$next; if ( 'yes' == $title ) $string .= apply_filters('the_title', $post->post_title, $post->ID); $string .= '</a>'; $format = str_replace('%', $string, $format); echo $format; } function user_can_create_post($user_id, $blog_id = 1, $category_id = 'None') { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $author_data = get_userdata($user_id); return ($author_data->user_level > 1); } function user_can_create_draft($user_id, $blog_id = 1, $category_id = 'None') { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $author_data = get_userdata($user_id); return ($author_data->user_level >= 1); } function user_can_edit_post($user_id, $post_id, $blog_id = 1) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $author_data = get_userdata($user_id); $post = get_post($post_id); $post_author_data = get_userdata($post->post_author); if ( (($user_id == $post_author_data->ID) && !($post->post_status == 'publish' && $author_data->user_level < 2)) || ($author_data->user_level > $post_author_data->user_level) || ($author_data->user_level >= 10) ) { return true; } else { return false; } } function user_can_delete_post($user_id, $post_id, $blog_id = 1) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); return user_can_edit_post($user_id, $post_id, $blog_id); } function user_can_set_post_date($user_id, $blog_id = 1, $category_id = 'None') { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $author_data = get_userdata($user_id); return (($author_data->user_level > 4) && user_can_create_post($user_id, $blog_id, $category_id)); } function user_can_edit_post_date($user_id, $post_id, $blog_id = 1) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $author_data = get_userdata($user_id); return (($author_data->user_level > 4) && user_can_edit_post($user_id, $post_id, $blog_id)); } function user_can_edit_post_comments($user_id, $post_id, $blog_id = 1) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); return user_can_edit_post($user_id, $post_id, $blog_id); } function user_can_delete_post_comments($user_id, $post_id, $blog_id = 1) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); return user_can_edit_post_comments($user_id, $post_id, $blog_id); } function user_can_edit_user($user_id, $other_user) { _deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' ); $user = get_userdata($user_id); $other = get_userdata($other_user); if ( $user->user_level > $other->user_level || $user->user_level > 8 || $user->ID == $other->ID ) return true; else return false; } function get_linksbyname($cat_name = "noname", $before = '', $after = '<br />', $between = " ", $show_images = true, $orderby = 'id', $show_description = true, $show_rating = false, $limit = -1, $show_updated = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); $cat_id = -1; $cat = get_term_by('name', $cat_name, 'link_category'); if ( $cat ) $cat_id = $cat->term_id; get_links($cat_id, $before, $after, $between, $show_images, $orderby, $show_description, $show_rating, $limit, $show_updated); } function wp_get_linksbyname($category, $args = '') { _deprecated_function(__FUNCTION__, '2.1.0', 'wp_list_bookmarks()'); $defaults = array( 'after' => '<br />', 'before' => '', 'categorize' => 0, 'category_after' => '', 'category_before' => '', 'category_name' => $category, 'show_description' => 1, 'title_li' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); return wp_list_bookmarks($parsed_args); } function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit = -1) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); $cat_id = -1; $cat = get_term_by('name', $cat_name, 'link_category'); if ( $cat ) $cat_id = $cat->term_id; return get_linkobjects($cat_id, $orderby, $limit); } function get_linkobjects($category = 0, $orderby = 'name', $limit = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); $links = get_bookmarks( array( 'category' => $category, 'orderby' => $orderby, 'limit' => $limit ) ) ; $links_array = array(); foreach ($links as $link) $links_array[] = $link; return $links_array; } function get_linksbyname_withrating($cat_name = "noname", $before = '', $after = '<br />', $between = " ", $show_images = true, $orderby = 'id', $show_description = true, $limit = -1, $show_updated = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); get_linksbyname($cat_name, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated); } function get_links_withrating($category = -1, $before = '', $after = '<br />', $between = " ", $show_images = true, $orderby = 'id', $show_description = true, $limit = -1, $show_updated = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); get_links($category, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated); } function get_autotoggle($id = 0) { _deprecated_function( __FUNCTION__, '2.1.0' ); return 0; } function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc', $file = '', $list = true, $optiondates = 0, $optioncount = 0, $hide_empty = 1, $use_desc_for_title = 1, $children=false, $child_of=0, $categories=0, $recurse=0, $feed = '', $feed_image = '', $exclude = '', $hierarchical=false) { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_categories()' ); $query = compact('optionall', 'all', 'sort_column', 'sort_order', 'file', 'list', 'optiondates', 'optioncount', 'hide_empty', 'use_desc_for_title', 'children', 'child_of', 'categories', 'recurse', 'feed', 'feed_image', 'exclude', 'hierarchical'); return wp_list_cats($query); } function wp_list_cats($args = '') { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_categories()' ); $parsed_args = wp_parse_args( $args ); if ( isset($parsed_args['optionall']) && isset($parsed_args['all'])) $parsed_args['show_option_all'] = $parsed_args['all']; if ( isset($parsed_args['sort_column']) ) $parsed_args['orderby'] = $parsed_args['sort_column']; if ( isset($parsed_args['sort_order']) ) $parsed_args['order'] = $parsed_args['sort_order']; if ( isset($parsed_args['optiondates']) ) $parsed_args['show_last_update'] = $parsed_args['optiondates']; if ( isset($parsed_args['optioncount']) ) $parsed_args['show_count'] = $parsed_args['optioncount']; if ( isset($parsed_args['list']) ) $parsed_args['style'] = $parsed_args['list'] ? 'list' : 'break'; $parsed_args['title_li'] = ''; return wp_list_categories($parsed_args); } function dropdown_cats($optionall = 1, $all = 'All', $orderby = 'ID', $order = 'asc', $show_last_update = 0, $show_count = 0, $hide_empty = 1, $optionnone = false, $selected = 0, $exclude = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_dropdown_categories()' ); $show_option_all = ''; if ( $optionall ) $show_option_all = $all; $show_option_none = ''; if ( $optionnone ) $show_option_none = _x( 'None', 'Categories dropdown (show_option_none parameter)' ); $vars = compact('show_option_all', 'show_option_none', 'orderby', 'order', 'show_last_update', 'show_count', 'hide_empty', 'selected', 'exclude'); $query = add_query_arg($vars, ''); return wp_dropdown_categories($query); } function list_authors($optioncount = false, $exclude_admin = true, $show_fullname = false, $hide_empty = true, $feed = '', $feed_image = '') { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_authors()' ); $args = compact('optioncount', 'exclude_admin', 'show_fullname', 'hide_empty', 'feed', 'feed_image'); return wp_list_authors($args); } function wp_get_post_cats($blogid = '1', $post_id = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_get_post_categories()' ); return wp_get_post_categories($post_id); } function wp_set_post_cats($blogid = '1', $post_id = 0, $post_categories = array()) { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_set_post_categories()' ); return wp_set_post_categories($post_id, $post_categories); } function get_archives($type='', $limit='', $format='html', $before = '', $after = '', $show_post_count = false) { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_get_archives()' ); $args = compact('type', 'limit', 'format', 'before', 'after', 'show_post_count'); return wp_get_archives($args); } function get_author_link($display, $author_id, $author_nicename = '') { _deprecated_function( __FUNCTION__, '2.1.0', 'get_author_posts_url()' ); $link = get_author_posts_url($author_id, $author_nicename); if ( $display ) echo $link; return $link; } function link_pages($before='<br />', $after='<br />', $next_or_number='number', $nextpagelink='next page', $previouspagelink='previous page', $pagelink='%', $more_file='') { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_link_pages()' ); $args = compact('before', 'after', 'next_or_number', 'nextpagelink', 'previouspagelink', 'pagelink', 'more_file'); return wp_link_pages($args); } function get_settings($option) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_option()' ); return get_option($option); } function permalink_link() { _deprecated_function( __FUNCTION__, '1.2.0', 'the_permalink()' ); the_permalink(); } function permalink_single_rss($deprecated = '') { _deprecated_function( __FUNCTION__, '2.3.0', 'the_permalink_rss()' ); the_permalink_rss(); } function wp_get_links($args = '') { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_bookmarks()' ); if ( ! str_contains( $args, '=' ) ) { $cat_id = $args; $args = add_query_arg( 'category', $cat_id, $args ); } $defaults = array( 'after' => '<br />', 'before' => '', 'between' => ' ', 'categorize' => 0, 'category' => '', 'echo' => true, 'limit' => -1, 'orderby' => 'name', 'show_description' => true, 'show_images' => true, 'show_rating' => false, 'show_updated' => true, 'title_li' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); return wp_list_bookmarks($parsed_args); } function get_links($category = -1, $before = '', $after = '<br />', $between = ' ', $show_images = true, $orderby = 'name', $show_description = true, $show_rating = false, $limit = -1, $show_updated = 1, $display = true) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' ); $order = 'ASC'; if ( str_starts_with($orderby, '_') ) { $order = 'DESC'; $orderby = substr($orderby, 1); } if ( $category == -1 ) $category = ''; $results = get_bookmarks(array('category' => $category, 'orderby' => $orderby, 'order' => $order, 'show_updated' => $show_updated, 'limit' => $limit)); if ( !$results ) return; $output = ''; foreach ( (array) $results as $row ) { if ( !isset($row->recently_updated) ) $row->recently_updated = false; $output .= $before; if ( $show_updated && $row->recently_updated ) $output .= get_option('links_recently_updated_prepend'); $the_link = '#'; if ( !empty($row->link_url) ) $the_link = esc_url($row->link_url); $rel = $row->link_rel; if ( '' != $rel ) $rel = ' rel="' . $rel . '"'; $desc = esc_attr(sanitize_bookmark_field('link_description', $row->link_description, $row->link_id, 'display')); $name = esc_attr(sanitize_bookmark_field('link_name', $row->link_name, $row->link_id, 'display')); $title = $desc; if ( $show_updated ) if ( !str_starts_with($row->link_updated_f, '00') ) $title .= ' ('.__('Last updated') . ' ' . gmdate(get_option('links_updated_date_format'), $row->link_updated_f + (get_option('gmt_offset') * HOUR_IN_SECONDS)) . ')'; if ( '' != $title ) $title = ' title="' . $title . '"'; $alt = ' alt="' . $name . '"'; $target = $row->link_target; if ( '' != $target ) $target = ' target="' . $target . '"'; $output .= '<a href="' . $the_link . '"' . $rel . $title . $target. '>'; if ( '' != $row->link_image && $show_images ) { if ( str_contains( $row->link_image, 'http' ) ) $output .= '<img src="' . $row->link_image . '"' . $alt . $title . ' />'; else $output .= '<img src="' . get_option('siteurl') . $row->link_image . '"' . $alt . $title . ' />'; } else { $output .= $name; } $output .= '</a>'; if ( $show_updated && $row->recently_updated ) $output .= get_option('links_recently_updated_append'); if ( $show_description && '' != $desc ) $output .= $between . $desc; if ($show_rating) { $output .= $between . get_linkrating($row); } $output .= "$after\n"; } if ( !$display ) return $output; echo $output; } function get_links_list($order = 'name') { _deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_bookmarks()' ); $order = strtolower($order); $direction = 'ASC'; if ( str_starts_with( $order, '_' ) ) { $direction = 'DESC'; $order = substr($order,1); } if ( !isset($direction) ) $direction = ''; $cats = get_categories(array('type' => 'link', 'orderby' => $order, 'order' => $direction, 'hierarchical' => 0)); if ( $cats ) { foreach ( (array) $cats as $cat ) { echo ' <li id="linkcat-' . $cat->term_id . '" class="linkcat"><h2>' . apply_filters('link_category', $cat->name ) . "</h2>\n\t<ul>\n"; get_links($cat->term_id, '<li>', "</li>", "\n", true, 'name', false); echo "\n\t</ul>\n</li>\n"; } } } function links_popup_script($text = 'Links', $width=400, $height=400, $file='links.all.php', $count = true) { _deprecated_function( __FUNCTION__, '2.1.0' ); } function get_linkrating( $link ) { _deprecated_function( __FUNCTION__, '2.1.0', 'sanitize_bookmark_field()' ); return sanitize_bookmark_field('link_rating', $link->link_rating, $link->link_id, 'display'); } function get_linkcatname($id = 0) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_category()' ); $id = (int) $id; if ( empty($id) ) return ''; $cats = wp_get_link_cats($id); if ( empty($cats) || ! is_array($cats) ) return ''; $cat_id = (int) $cats[0]; $cat = get_category($cat_id); return $cat->name; } function comments_rss_link($link_text = 'Comments RSS') { _deprecated_function( __FUNCTION__, '2.5.0', 'post_comments_feed_link()' ); post_comments_feed_link($link_text); } function get_category_rss_link($display = false, $cat_id = 1) { _deprecated_function( __FUNCTION__, '2.5.0', 'get_category_feed_link()' ); $link = get_category_feed_link($cat_id, 'rss2'); if ( $display ) echo $link; return $link; } function get_author_rss_link($display = false, $author_id = 1) { _deprecated_function( __FUNCTION__, '2.5.0', 'get_author_feed_link()' ); $link = get_author_feed_link($author_id); if ( $display ) echo $link; return $link; } function comments_rss() { _deprecated_function( __FUNCTION__, '2.2.0', 'get_post_comments_feed_link()' ); return esc_url( get_post_comments_feed_link() ); } function create_user($username, $password, $email) { _deprecated_function( __FUNCTION__, '2.0.0', 'wp_create_user()' ); return wp_create_user($username, $password, $email); } function gzip_compression() { _deprecated_function( __FUNCTION__, '2.5.0' ); return false; } function get_commentdata( $comment_id, $no_cache = 0, $include_unapproved = false ) { _deprecated_function( __FUNCTION__, '2.7.0', 'get_comment()' ); return get_comment($comment_id, ARRAY_A); } function get_catname( $cat_id ) { _deprecated_function( __FUNCTION__, '2.8.0', 'get_cat_name()' ); return get_cat_name( $cat_id ); } function get_category_children( $id, $before = '/', $after = '', $visited = array() ) { _deprecated_function( __FUNCTION__, '2.8.0', 'get_term_children()' ); if ( 0 == $id ) return ''; $chain = ''; $cat_ids = get_all_category_ids(); foreach ( (array) $cat_ids as $cat_id ) { if ( $cat_id == $id ) continue; $category = get_category( $cat_id ); if ( is_wp_error( $category ) ) return $category; if ( $category->parent == $id && !in_array( $category->term_id, $visited ) ) { $visited[] = $category->term_id; $chain .= $before.$category->term_id.$after; $chain .= get_category_children( $category->term_id, $before, $after ); } } return $chain; } function get_all_category_ids() { _deprecated_function( __FUNCTION__, '4.0.0', 'get_terms()' ); $cat_ids = get_terms( array( 'taxonomy' => 'category', 'fields' => 'ids', 'get' => 'all', ) ); return $cat_ids; } function get_the_author_description() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'description\')' ); return get_the_author_meta('description'); } function the_author_description() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'description\')' ); the_author_meta('description'); } function get_the_author_login() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'login\')' ); return get_the_author_meta('login'); } function the_author_login() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'login\')' ); the_author_meta('login'); } function get_the_author_firstname() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'first_name\')' ); return get_the_author_meta('first_name'); } function the_author_firstname() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'first_name\')' ); the_author_meta('first_name'); } function get_the_author_lastname() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'last_name\')' ); return get_the_author_meta('last_name'); } function the_author_lastname() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'last_name\')' ); the_author_meta('last_name'); } function get_the_author_nickname() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'nickname\')' ); return get_the_author_meta('nickname'); } function the_author_nickname() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'nickname\')' ); the_author_meta('nickname'); } function get_the_author_email() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'email\')' ); return get_the_author_meta('email'); } function the_author_email() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'email\')' ); the_author_meta('email'); } function get_the_author_icq() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'icq\')' ); return get_the_author_meta('icq'); } function the_author_icq() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'icq\')' ); the_author_meta('icq'); } function get_the_author_yim() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'yim\')' ); return get_the_author_meta('yim'); } function the_author_yim() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'yim\')' ); the_author_meta('yim'); } function get_the_author_msn() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'msn\')' ); return get_the_author_meta('msn'); } function the_author_msn() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'msn\')' ); the_author_meta('msn'); } function get_the_author_aim() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'aim\')' ); return get_the_author_meta('aim'); } function the_author_aim() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'aim\')' ); the_author_meta('aim'); } function get_author_name( $auth_id = false ) { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'display_name\')' ); return get_the_author_meta('display_name', $auth_id); } function get_the_author_url() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'url\')' ); return get_the_author_meta('url'); } function the_author_url() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'url\')' ); the_author_meta('url'); } function get_the_author_ID() { _deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'ID\')' ); return get_the_author_meta('ID'); } function the_author_ID() { _deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'ID\')' ); the_author_meta('ID'); } function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file='', $cut = 0, $encode_html = 0) { _deprecated_function( __FUNCTION__, '2.9.0', 'the_content_feed()' ); $content = get_the_content($more_link_text, $stripteaser); $content = apply_filters('the_content_rss', $content); if ( $cut && !$encode_html ) $encode_html = 2; if ( 1== $encode_html ) { $content = esc_html($content); $cut = 0; } elseif ( 0 == $encode_html ) { $content = make_url_footnote($content); } elseif ( 2 == $encode_html ) { $content = strip_tags($content); } if ( $cut ) { $blah = explode(' ', $content); if ( count($blah) > $cut ) { $k = $cut; $use_dotdotdot = 1; } else { $k = count($blah); $use_dotdotdot = 0; } for ( $i=0; $i<$k; $i++ ) $excerpt .= $blah[$i].' '; $excerpt .= ($use_dotdotdot) ? '...' : ''; $content = $excerpt; } $content = str_replace(']]>', ']]>', $content); echo $content; } function make_url_footnote( $content ) { _deprecated_function( __FUNCTION__, '2.9.0', '' ); preg_match_all( '/<a(.+?)href=\"(.+?)\"(.*?)>(.+?)<\/a>/', $content, $matches ); $links_summary = "\n"; for ( $i = 0, $c = count( $matches[0] ); $i < $c; $i++ ) { $link_match = $matches[0][$i]; $link_number = '['.($i+1).']'; $link_url = $matches[2][$i]; $link_text = $matches[4][$i]; $content = str_replace( $link_match, $link_text . ' ' . $link_number, $content ); $link_url = ( ( strtolower( substr( $link_url, 0, 7 ) ) !== 'http://' ) && ( strtolower( substr( $link_url, 0, 8 ) ) !== 'https://' ) ) ? get_option( 'home' ) . $link_url : $link_url; $links_summary .= "\n" . $link_number . ' ' . $link_url; } $content = strip_tags( $content ); $content .= $links_summary; return $content; } function _c( $text, $domain = 'default' ) { _deprecated_function( __FUNCTION__, '2.9.0', '_x()' ); return before_last_bar( translate( $text, $domain ) ); } function translate_with_context( $text, $domain = 'default' ) { _deprecated_function( __FUNCTION__, '2.9.0', '_x()' ); return before_last_bar( translate( $text, $domain ) ); } function _nc( $single, $plural, $number, $domain = 'default' ) { _deprecated_function( __FUNCTION__, '2.9.0', '_nx()' ); return before_last_bar( _n( $single, $plural, $number, $domain ) ); } function __ngettext( ...$args ) { _deprecated_function( __FUNCTION__, '2.8.0', '_n()' ); return _n( ...$args ); } function __ngettext_noop( ...$args ) { _deprecated_function( __FUNCTION__, '2.8.0', '_n_noop()' ); return _n_noop( ...$args ); } function get_alloptions() { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_load_alloptions()' ); return wp_load_alloptions(); } function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false, $permalink = false) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_link()' ); $id = (int) $id; $_post = get_post($id); if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) ) return __('Missing Attachment'); if ( $permalink ) $url = get_attachment_link($_post->ID); $post_title = esc_attr($_post->post_title); $innerHTML = get_attachment_innerHTML($_post->ID, $fullsize, $max_dims); return "<a href='$url' title='$post_title'>$innerHTML</a>"; } function get_attachment_icon_src( $id = 0, $fullsize = false ) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image_src()' ); $id = (int) $id; if ( !$post = get_post($id) ) return false; $file = get_attached_file( $post->ID ); if ( !$fullsize && $src = wp_get_attachment_thumb_url( $post->ID ) ) { $src_file = wp_basename($src); } elseif ( wp_attachment_is_image( $post->ID ) ) { $src = wp_get_attachment_url( $post->ID ); $src_file = & $file; } elseif ( $src = wp_mime_type_icon( $post->ID, '.svg' ) ) { $icon_dir = apply_filters( 'icon_dir', get_template_directory() . '/images' ); $src_file = $icon_dir . '/' . wp_basename($src); } if ( !isset($src) || !$src ) return false; return array($src, $src_file); } function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image()' ); $id = (int) $id; if ( !$post = get_post($id) ) return false; if ( !$src = get_attachment_icon_src( $post->ID, $fullsize ) ) return false; list($src, $src_file) = $src; if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) { $imagesize = wp_getimagesize($src_file); if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) { $actual_aspect = $imagesize[0] / $imagesize[1]; $desired_aspect = $max_dims[0] / $max_dims[1]; if ( $actual_aspect >= $desired_aspect ) { $height = $actual_aspect * $max_dims[0]; $constraint = "width='{$max_dims[0]}' "; $post->iconsize = array($max_dims[0], $height); } else { $width = $max_dims[1] / $actual_aspect; $constraint = "height='{$max_dims[1]}' "; $post->iconsize = array($width, $max_dims[1]); } } else { $post->iconsize = array($imagesize[0], $imagesize[1]); $constraint = ''; } } else { $constraint = ''; } $post_title = esc_attr($post->post_title); $icon = "<img src='$src' title='$post_title' alt='$post_title' $constraint/>"; return apply_filters( 'attachment_icon', $icon, $post->ID ); } function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image()' ); $id = (int) $id; if ( !$post = get_post($id) ) return false; if ( $innerHTML = get_attachment_icon($post->ID, $fullsize, $max_dims)) return $innerHTML; $innerHTML = esc_attr($post->post_title); return apply_filters('attachment_innerHTML', $innerHTML, $post->ID); } function get_link( $bookmark_id, $output = OBJECT, $filter = 'raw' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmark()' ); return get_bookmark($bookmark_id, $output, $filter); } function clean_url( $url, $protocols = null, $context = 'display' ) { if ( $context == 'db' ) _deprecated_function( 'clean_url( $context = \'db\' )', '3.0.0', 'sanitize_url()' ); else _deprecated_function( __FUNCTION__, '3.0.0', 'esc_url()' ); return esc_url( $url, $protocols, $context ); } function js_escape( $text ) { _deprecated_function( __FUNCTION__, '2.8.0', 'esc_js()' ); return esc_js( $text ); } function wp_specialchars( $text, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { _deprecated_function( __FUNCTION__, '2.8.0', 'esc_html()' ); if ( func_num_args() > 1 ) { return _wp_specialchars( $text, $quote_style, $charset, $double_encode ); } else { return esc_html( $text ); } } function attribute_escape( $text ) { _deprecated_function( __FUNCTION__, '2.8.0', 'esc_attr()' ); return esc_attr( $text ); } function register_sidebar_widget($name, $output_callback, $classname = '', ...$params) { _deprecated_function( __FUNCTION__, '2.8.0', 'wp_register_sidebar_widget()' ); if ( is_array( $name ) ) { if ( count( $name ) === 3 ) { $name = sprintf( $name[0], $name[2] ); } else { $name = $name[0]; } } $id = sanitize_title( $name ); $options = array(); if ( ! empty( $classname ) && is_string( $classname ) ) { $options['classname'] = $classname; } wp_register_sidebar_widget( $id, $name, $output_callback, $options, ...$params ); } function unregister_sidebar_widget($id) { _deprecated_function( __FUNCTION__, '2.8.0', 'wp_unregister_sidebar_widget()' ); return wp_unregister_sidebar_widget($id); } function register_widget_control($name, $control_callback, $width = '', $height = '', ...$params) { _deprecated_function( __FUNCTION__, '2.8.0', 'wp_register_widget_control()' ); if ( is_array( $name ) ) { if ( count( $name ) === 3 ) { $name = sprintf( $name[0], $name[2] ); } else { $name = $name[0]; } } $id = sanitize_title( $name ); $options = array(); if ( ! empty( $width ) ) { $options['width'] = $width; } if ( ! empty( $height ) ) { $options['height'] = $height; } wp_register_widget_control( $id, $name, $control_callback, $options, ...$params ); } function unregister_widget_control($id) { _deprecated_function( __FUNCTION__, '2.8.0', 'wp_unregister_widget_control()' ); return wp_unregister_widget_control($id); } function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'delete_user_meta()' ); global $wpdb; if ( !is_numeric( $user_id ) ) return false; $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); if ( is_array($meta_value) || is_object($meta_value) ) $meta_value = serialize($meta_value); $meta_value = trim( $meta_value ); $cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); if ( $cur && $cur->umeta_id ) do_action( 'delete_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); if ( ! empty($meta_value) ) $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value) ); else $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); clean_user_cache( $user_id ); wp_cache_delete( $user_id, 'user_meta' ); if ( $cur && $cur->umeta_id ) do_action( 'deleted_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); return true; } function get_usermeta( $user_id, $meta_key = '' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'get_user_meta()' ); global $wpdb; $user_id = (int) $user_id; if ( !$user_id ) return false; if ( !empty($meta_key) ) { $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); $user = wp_cache_get($user_id, 'users'); if ( false !== $user && isset($user->$meta_key) ) $metas = array($user->$meta_key); else $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); } else { $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user_id) ); } if ( empty($metas) ) { if ( empty($meta_key) ) return array(); else return ''; } $metas = array_map('maybe_unserialize', $metas); if ( count($metas) === 1 ) return $metas[0]; else return $metas; } function update_usermeta( $user_id, $meta_key, $meta_value ) { _deprecated_function( __FUNCTION__, '3.0.0', 'update_user_meta()' ); global $wpdb; if ( !is_numeric( $user_id ) ) return false; $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); if ( is_string($meta_value) ) $meta_value = stripslashes($meta_value); $meta_value = maybe_serialize($meta_value); if (empty($meta_value)) { return delete_usermeta($user_id, $meta_key); } $cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) ); if ( $cur ) do_action( 'update_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); if ( !$cur ) $wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') ); elseif ( $cur->meta_value != $meta_value ) $wpdb->update($wpdb->usermeta, compact('meta_value'), compact('user_id', 'meta_key') ); else return false; clean_user_cache( $user_id ); wp_cache_delete( $user_id, 'user_meta' ); if ( !$cur ) do_action( 'added_usermeta', $wpdb->insert_id, $user_id, $meta_key, $meta_value ); else do_action( 'updated_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value ); return true; } function get_users_of_blog( $id = '' ) { _deprecated_function( __FUNCTION__, '3.1.0', 'get_users()' ); global $wpdb; if ( empty( $id ) ) { $id = get_current_blog_id(); } $blog_prefix = $wpdb->get_blog_prefix($id); $users = $wpdb->get_results( "SELECT user_id, user_id AS ID, user_login, display_name, user_email, meta_value FROM $wpdb->users, $wpdb->usermeta WHERE {$wpdb->users}.ID = {$wpdb->usermeta}.user_id AND meta_key = '{$blog_prefix}capabilities' ORDER BY {$wpdb->usermeta}.user_id" ); return $users; } function automatic_feed_links( $add = true ) { _deprecated_function( __FUNCTION__, '3.0.0', "add_theme_support( 'automatic-feed-links' )" ); if ( $add ) add_theme_support( 'automatic-feed-links' ); else remove_action( 'wp_head', 'feed_links_extra', 3 ); } function get_profile( $field, $user = false ) { _deprecated_function( __FUNCTION__, '3.0.0', 'get_the_author_meta()' ); if ( $user ) { $user = get_user_by( 'login', $user ); $user = $user->ID; } return get_the_author_meta( $field, $user ); } function get_usernumposts( $userid ) { _deprecated_function( __FUNCTION__, '3.0.0', 'count_user_posts()' ); return count_user_posts( $userid ); } function funky_javascript_callback($matches) { return "&#".base_convert($matches[1],16,10).";"; } function funky_javascript_fix($text) { _deprecated_function( __FUNCTION__, '3.0.0' ); global $is_macIE, $is_winIE; if ( $is_winIE || $is_macIE ) $text = preg_replace_callback("/\%u([0-9A-F]{4,4})/", "funky_javascript_callback", $text); return $text; } function is_taxonomy( $taxonomy ) { _deprecated_function( __FUNCTION__, '3.0.0', 'taxonomy_exists()' ); return taxonomy_exists( $taxonomy ); } function is_term( $term, $taxonomy = '', $parent = 0 ) { _deprecated_function( __FUNCTION__, '3.0.0', 'term_exists()' ); return term_exists( $term, $taxonomy, $parent ); } function is_plugin_page() { _deprecated_function( __FUNCTION__, '3.1.0' ); global $plugin_page; if ( isset($plugin_page) ) return true; return false; } function update_category_cache() { _deprecated_function( __FUNCTION__, '3.1.0' ); return true; } function wp_timezone_supported() { _deprecated_function( __FUNCTION__, '3.2.0' ); return true; } function the_editor($content, $id = 'content', $prev_id = 'title', $media_buttons = true, $tab_index = 2, $extended = true) { _deprecated_function( __FUNCTION__, '3.3.0', 'wp_editor()' ); wp_editor( $content, $id, array( 'media_buttons' => $media_buttons ) ); } function get_user_metavalues($ids) { _deprecated_function( __FUNCTION__, '3.3.0' ); $objects = array(); $ids = array_map('intval', $ids); foreach ( $ids as $id ) $objects[$id] = array(); $metas = update_meta_cache('user', $ids); foreach ( $metas as $id => $meta ) { foreach ( $meta as $key => $metavalues ) { foreach ( $metavalues as $value ) { $objects[$id][] = (object)array( 'user_id' => $id, 'meta_key' => $key, 'meta_value' => $value); } } } return $objects; } function sanitize_user_object($user, $context = 'display') { _deprecated_function( __FUNCTION__, '3.3.0' ); if ( is_object($user) ) { if ( !isset($user->ID) ) $user->ID = 0; if ( ! ( $user instanceof WP_User ) ) { $vars = get_object_vars($user); foreach ( array_keys($vars) as $field ) { if ( is_string($user->$field) || is_numeric($user->$field) ) $user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context); } } $user->filter = $context; } else { if ( !isset($user['ID']) ) $user['ID'] = 0; foreach ( array_keys($user) as $field ) $user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context); $user['filter'] = $context; } return $user; } function get_boundary_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $start = true) { _deprecated_function( __FUNCTION__, '3.3.0' ); $posts = get_boundary_post($in_same_cat, $excluded_categories, $start); if ( empty($posts) ) return; $post = $posts[0]; if ( empty($post->post_title) ) $post->post_title = $start ? __('First Post') : __('Last Post'); $date = mysql2date(get_option('date_format'), $post->post_date); $title = str_replace('%title', $post->post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); $link = $start ? "<link rel='start' title='" : "<link rel='end' title='"; $link .= esc_attr($title); $link .= "' href='" . get_permalink($post) . "' />\n"; $boundary = $start ? 'start' : 'end'; return apply_filters( "{$boundary}_post_rel_link", $link ); } function start_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') { _deprecated_function( __FUNCTION__, '3.3.0' ); echo get_boundary_post_rel_link($title, $in_same_cat, $excluded_categories, true); } function get_index_rel_link() { _deprecated_function( __FUNCTION__, '3.3.0' ); $link = "<link rel='index' title='" . esc_attr( get_bloginfo( 'name', 'display' ) ) . "' href='" . esc_url( user_trailingslashit( get_bloginfo( 'url', 'display' ) ) ) . "' />\n"; return apply_filters( "index_rel_link", $link ); } function index_rel_link() { _deprecated_function( __FUNCTION__, '3.3.0' ); echo get_index_rel_link(); } function get_parent_post_rel_link( $title = '%title' ) { _deprecated_function( __FUNCTION__, '3.3.0' ); if ( ! empty( $GLOBALS['post'] ) && ! empty( $GLOBALS['post']->post_parent ) ) $post = get_post($GLOBALS['post']->post_parent); if ( empty($post) ) return; $date = mysql2date(get_option('date_format'), $post->post_date); $title = str_replace('%title', $post->post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); $link = "<link rel='up' title='"; $link .= esc_attr( $title ); $link .= "' href='" . get_permalink($post) . "' />\n"; return apply_filters( "parent_post_rel_link", $link ); } function parent_post_rel_link( $title = '%title' ) { _deprecated_function( __FUNCTION__, '3.3.0' ); echo get_parent_post_rel_link($title); } function wp_admin_bar_dashboard_view_site_menu( $wp_admin_bar ) { _deprecated_function( __FUNCTION__, '3.3.0' ); $user_id = get_current_user_id(); if ( 0 != $user_id ) { if ( is_admin() ) $wp_admin_bar->add_menu( array( 'id' => 'view-site', 'title' => __( 'Visit Site' ), 'href' => home_url() ) ); elseif ( is_multisite() ) $wp_admin_bar->add_menu( array( 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => get_dashboard_url( $user_id ) ) ); else $wp_admin_bar->add_menu( array( 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => admin_url() ) ); } } function is_blog_user( $blog_id = 0 ) { _deprecated_function( __FUNCTION__, '3.3.0', 'is_user_member_of_blog()' ); return is_user_member_of_blog( get_current_user_id(), $blog_id ); } function debug_fopen( $filename, $mode ) { _deprecated_function( __FUNCTION__, '3.4.0', 'error_log()' ); return false; } function debug_fwrite( $fp, $message ) { _deprecated_function( __FUNCTION__, '3.4.0', 'error_log()' ); if ( ! empty( $GLOBALS['debug'] ) ) error_log( $message ); } function debug_fclose( $fp ) { _deprecated_function( __FUNCTION__, '3.4.0', 'error_log()' ); } function get_themes() { _deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_themes()' ); global $wp_themes; if ( isset( $wp_themes ) ) return $wp_themes; $themes = wp_get_themes(); $wp_themes = array(); foreach ( $themes as $theme ) { $name = $theme->get('Name'); if ( isset( $wp_themes[ $name ] ) ) $wp_themes[ $name . '/' . $theme->get_stylesheet() ] = $theme; else $wp_themes[ $name ] = $theme; } return $wp_themes; } function get_theme( $theme ) { _deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_theme( $stylesheet )' ); $themes = get_themes(); if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) return $themes[ $theme ]; return null; } function get_current_theme() { _deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_theme()' ); if ( $theme = get_option( 'current_theme' ) ) return $theme; return wp_get_theme()->get('Name'); } function clean_pre($matches) { _deprecated_function( __FUNCTION__, '3.4.0' ); if ( is_array($matches) ) $text = $matches[1] . $matches[2] . "</pre>"; else $text = $matches; $text = str_replace(array('<br />', '<br/>', '<br>'), array('', '', ''), $text); $text = str_replace('<p>', "\n", $text); $text = str_replace('</p>', '', $text); return $text; } function add_custom_image_header( $wp_head_callback, $admin_head_callback, $admin_preview_callback = '' ) { _deprecated_function( __FUNCTION__, '3.4.0', 'add_theme_support( \'custom-header\', $args )' ); $args = array( 'wp-head-callback' => $wp_head_callback, 'admin-head-callback' => $admin_head_callback, ); if ( $admin_preview_callback ) $args['admin-preview-callback'] = $admin_preview_callback; return add_theme_support( 'custom-header', $args ); } function remove_custom_image_header() { _deprecated_function( __FUNCTION__, '3.4.0', 'remove_theme_support( \'custom-header\' )' ); return remove_theme_support( 'custom-header' ); } function add_custom_background( $wp_head_callback = '', $admin_head_callback = '', $admin_preview_callback = '' ) { _deprecated_function( __FUNCTION__, '3.4.0', 'add_theme_support( \'custom-background\', $args )' ); $args = array(); if ( $wp_head_callback ) $args['wp-head-callback'] = $wp_head_callback; if ( $admin_head_callback ) $args['admin-head-callback'] = $admin_head_callback; if ( $admin_preview_callback ) $args['admin-preview-callback'] = $admin_preview_callback; return add_theme_support( 'custom-background', $args ); } function remove_custom_background() { _deprecated_function( __FUNCTION__, '3.4.0', 'remove_theme_support( \'custom-background\' )' ); return remove_theme_support( 'custom-background' ); } function get_theme_data( $theme_file ) { _deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_theme()' ); $theme = new WP_Theme( wp_basename( dirname( $theme_file ) ), dirname( dirname( $theme_file ) ) ); $theme_data = array( 'Name' => $theme->get('Name'), 'URI' => $theme->display('ThemeURI', true, false), 'Description' => $theme->display('Description', true, false), 'Author' => $theme->display('Author', true, false), 'AuthorURI' => $theme->display('AuthorURI', true, false), 'Version' => $theme->get('Version'), 'Template' => $theme->get('Template'), 'Status' => $theme->get('Status'), 'Tags' => $theme->get('Tags'), 'Title' => $theme->get('Name'), 'AuthorName' => $theme->get('Author'), ); foreach ( apply_filters( 'extra_theme_headers', array() ) as $extra_header ) { if ( ! isset( $theme_data[ $extra_header ] ) ) $theme_data[ $extra_header ] = $theme->get( $extra_header ); } return $theme_data; } function update_page_cache( &$pages ) { _deprecated_function( __FUNCTION__, '3.4.0', 'update_post_cache()' ); update_post_cache( $pages ); } function clean_page_cache( $id ) { _deprecated_function( __FUNCTION__, '3.4.0', 'clean_post_cache()' ); clean_post_cache( $id ); } function wp_explain_nonce( $action ) { _deprecated_function( __FUNCTION__, '3.4.1', 'wp_nonce_ays()' ); return __( 'Are you sure you want to do this?' ); } function sticky_class( $post_id = null ) { _deprecated_function( __FUNCTION__, '3.5.0', 'post_class()' ); if ( is_sticky( $post_id ) ) echo ' sticky'; } function _get_post_ancestors( &$post ) { _deprecated_function( __FUNCTION__, '3.5.0' ); } function wp_load_image( $file ) { _deprecated_function( __FUNCTION__, '3.5.0', 'wp_get_image_editor()' ); if ( is_numeric( $file ) ) $file = get_attached_file( $file ); if ( ! is_file( $file ) ) { return sprintf( __( 'File “%s” does not exist?' ), $file ); } if ( ! function_exists('imagecreatefromstring') ) return __('The GD image library is not installed.'); wp_raise_memory_limit( 'image' ); $image = imagecreatefromstring( file_get_contents( $file ) ); if ( ! is_gd_image( $image ) ) { return sprintf( __( 'File “%s” is not an image.' ), $file ); } return $image; } function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { _deprecated_function( __FUNCTION__, '3.5.0', 'wp_get_image_editor()' ); $editor = wp_get_image_editor( $file ); if ( is_wp_error( $editor ) ) return $editor; $editor->set_quality( $jpeg_quality ); $resized = $editor->resize( $max_w, $max_h, $crop ); if ( is_wp_error( $resized ) ) return $resized; $dest_file = $editor->generate_filename( $suffix, $dest_path ); $saved = $editor->save( $dest_file ); if ( is_wp_error( $saved ) ) return $saved; return $dest_file; } function wp_get_single_post( $postid = 0, $mode = OBJECT ) { _deprecated_function( __FUNCTION__, '3.5.0', 'get_post()' ); return get_post( $postid, $mode ); } function user_pass_ok($user_login, $user_pass) { _deprecated_function( __FUNCTION__, '3.5.0', 'wp_authenticate()' ); $user = wp_authenticate( $user_login, $user_pass ); if ( is_wp_error( $user ) ) return false; return true; } function _save_post_hook() {} function gd_edit_image_support($mime_type) { _deprecated_function( __FUNCTION__, '3.5.0', 'wp_image_editor_supports()' ); if ( function_exists('imagetypes') ) { switch( $mime_type ) { case 'image/jpeg': return (imagetypes() & IMG_JPG) != 0; case 'image/png': return (imagetypes() & IMG_PNG) != 0; case 'image/gif': return (imagetypes() & IMG_GIF) != 0; case 'image/webp': return (imagetypes() & IMG_WEBP) != 0; case 'image/avif': return (imagetypes() & IMG_AVIF) != 0; } } else { switch( $mime_type ) { case 'image/jpeg': return function_exists('imagecreatefromjpeg'); case 'image/png': return function_exists('imagecreatefrompng'); case 'image/gif': return function_exists('imagecreatefromgif'); case 'image/webp': return function_exists('imagecreatefromwebp'); case 'image/avif': return function_exists('imagecreatefromavif'); } } return false; } function wp_convert_bytes_to_hr( $bytes ) { _deprecated_function( __FUNCTION__, '3.6.0', 'size_format()' ); $units = array( 0 => 'B', 1 => 'KB', 2 => 'MB', 3 => 'GB', 4 => 'TB' ); $log = log( $bytes, KB_IN_BYTES ); $power = ! is_nan( $log ) && ! is_infinite( $log ) ? (int) $log : 0; $size = KB_IN_BYTES ** ( $log - $power ); if ( ! is_nan( $size ) && array_key_exists( $power, $units ) ) { $unit = $units[ $power ]; } else { $size = $bytes; $unit = $units[0]; } return $size . $unit; } function _search_terms_tidy( $t ) { _deprecated_function( __FUNCTION__, '3.7.0' ); return trim( $t, "\"'\n\r " ); } function rich_edit_exists() { global $wp_rich_edit_exists; _deprecated_function( __FUNCTION__, '3.9.0' ); if ( ! isset( $wp_rich_edit_exists ) ) $wp_rich_edit_exists = file_exists( ABSPATH . WPINC . '/js/tinymce/tinymce.js' ); return $wp_rich_edit_exists; } function default_topic_count_text( $count ) { return $count; } function format_to_post( $content ) { _deprecated_function( __FUNCTION__, '3.9.0' ); return $content; } function like_escape($text) { _deprecated_function( __FUNCTION__, '4.0.0', 'wpdb::esc_like()' ); return str_replace( array( "%", "_" ), array( "\\%", "\\_" ), $text ); } function url_is_accessable_via_ssl( $url ) { _deprecated_function( __FUNCTION__, '4.0.0' ); $response = wp_remote_get( set_url_scheme( $url, 'https' ) ); if ( !is_wp_error( $response ) ) { $status = wp_remote_retrieve_response_code( $response ); if ( 200 == $status || 401 == $status ) { return true; } } return false; } function preview_theme() { _deprecated_function( __FUNCTION__, '4.3.0' ); } function _preview_theme_template_filter() { _deprecated_function( __FUNCTION__, '4.3.0' ); return ''; } function _preview_theme_stylesheet_filter() { _deprecated_function( __FUNCTION__, '4.3.0' ); return ''; } function preview_theme_ob_filter( $content ) { _deprecated_function( __FUNCTION__, '4.3.0' ); return $content; } function preview_theme_ob_filter_callback( $matches ) { _deprecated_function( __FUNCTION__, '4.3.0' ); return ''; } function wp_richedit_pre($text) { _deprecated_function( __FUNCTION__, '4.3.0', 'format_for_editor()' ); if ( empty( $text ) ) { return apply_filters( 'richedit_pre', '' ); } $output = convert_chars($text); $output = wpautop($output); $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); return apply_filters( 'richedit_pre', $output ); } function wp_htmledit_pre($output) { _deprecated_function( __FUNCTION__, '4.3.0', 'format_for_editor()' ); if ( !empty($output) ) $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); return apply_filters( 'htmledit_pre', $output ); } function post_permalink( $post = 0 ) { _deprecated_function( __FUNCTION__, '4.4.0', 'get_permalink()' ); return get_permalink( $post ); } function wp_get_http( $url, $file_path = false, $red = 1 ) { _deprecated_function( __FUNCTION__, '4.4.0', 'WP_Http' ); if ( function_exists( 'set_time_limit' ) ) { @set_time_limit( 60 ); } if ( $red > 5 ) return false; $options = array(); $options['redirection'] = 5; if ( false == $file_path ) $options['method'] = 'HEAD'; else $options['method'] = 'GET'; $response = wp_safe_remote_request( $url, $options ); if ( is_wp_error( $response ) ) return false; $headers = wp_remote_retrieve_headers( $response ); $headers['response'] = wp_remote_retrieve_response_code( $response ); if ( 'HEAD' == $options['method'] && in_array($headers['response'], array(301, 302)) && isset( $headers['location'] ) ) { return wp_get_http( $headers['location'], $file_path, ++$red ); } if ( false == $file_path ) return $headers; $out_fp = fopen($file_path, 'w'); if ( !$out_fp ) return $headers; fwrite( $out_fp, wp_remote_retrieve_body( $response ) ); fclose($out_fp); clearstatcache(); return $headers; } function force_ssl_login( $force = null ) { _deprecated_function( __FUNCTION__, '4.4.0', 'force_ssl_admin()' ); return force_ssl_admin( $force ); } function get_comments_popup_template() { _deprecated_function( __FUNCTION__, '4.5.0' ); return ''; } function is_comments_popup() { _deprecated_function( __FUNCTION__, '4.5.0' ); return false; } function comments_popup_script() { _deprecated_function( __FUNCTION__, '4.5.0' ); } function popuplinks( $text ) { _deprecated_function( __FUNCTION__, '4.5.0' ); $text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text); return $text; } function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) { _deprecated_function( __FUNCTION__, '4.6.0' ); return ''; } function get_paged_template() { _deprecated_function( __FUNCTION__, '4.7.0' ); return get_query_template( 'paged' ); } function wp_kses_js_entities( $content ) { _deprecated_function( __FUNCTION__, '4.7.0' ); return preg_replace( '%&\s*\{[^}]*(\}\s*;?|$)%', '', $content ); } function _usort_terms_by_ID( $a, $b ) { _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort()' ); if ( $a->term_id > $b->term_id ) return 1; elseif ( $a->term_id < $b->term_id ) return -1; else return 0; } function _usort_terms_by_name( $a, $b ) { _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort()' ); return strcmp( $a->name, $b->name ); } function _sort_nav_menu_items( $a, $b ) { global $_menu_item_sort_prop; _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort()' ); if ( empty( $_menu_item_sort_prop ) ) return 0; if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) ) return 0; $_a = (int) $a->$_menu_item_sort_prop; $_b = (int) $b->$_menu_item_sort_prop; if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop ) return 0; elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop ) return $_a < $_b ? -1 : 1; else return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop ); } function get_shortcut_link() { _deprecated_function( __FUNCTION__, '4.9.0' ); $link = ''; return apply_filters( 'shortcut_link', $link ); } function wp_ajax_press_this_save_post() { _deprecated_function( __FUNCTION__, '4.9.0' ); if ( is_plugin_active( 'press-this/press-this-plugin.php' ) ) { include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php'; $wp_press_this = new WP_Press_This_Plugin(); $wp_press_this->save_post(); } else { wp_send_json_error( array( 'errorMessage' => __( 'The Press This plugin is required.' ) ) ); } } function wp_ajax_press_this_add_category() { _deprecated_function( __FUNCTION__, '4.9.0' ); if ( is_plugin_active( 'press-this/press-this-plugin.php' ) ) { include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php'; $wp_press_this = new WP_Press_This_Plugin(); $wp_press_this->add_category(); } else { wp_send_json_error( array( 'errorMessage' => __( 'The Press This plugin is required.' ) ) ); } } function wp_get_user_request_data( $request_id ) { _deprecated_function( __FUNCTION__, '5.4.0', 'wp_get_user_request()' ); return wp_get_user_request( $request_id ); } function wp_make_content_images_responsive( $content ) { _deprecated_function( __FUNCTION__, '5.5.0', 'wp_filter_content_tags()' ); return wp_filter_content_tags( $content ); } function wp_unregister_GLOBALS() { _deprecated_function( __FUNCTION__, '5.5.0' ); } function wp_blacklist_check( $author, $email, $url, $comment, $user_ip, $user_agent ) { _deprecated_function( __FUNCTION__, '5.5.0', 'wp_check_comment_disallowed_list()' ); return wp_check_comment_disallowed_list( $author, $email, $url, $comment, $user_ip, $user_agent ); } function _wp_register_meta_args_whitelist( $args, $default_args ) { _deprecated_function( __FUNCTION__, '5.5.0', '_wp_register_meta_args_allowed_list()' ); return _wp_register_meta_args_allowed_list( $args, $default_args ); } function add_option_whitelist( $new_options, $options = '' ) { _deprecated_function( __FUNCTION__, '5.5.0', 'add_allowed_options()' ); return add_allowed_options( $new_options, $options ); } function remove_option_whitelist( $del_options, $options = '' ) { _deprecated_function( __FUNCTION__, '5.5.0', 'remove_allowed_options()' ); return remove_allowed_options( $del_options, $options ); } function wp_slash_strings_only( $value ) { return map_deep( $value, 'addslashes_strings_only' ); } function addslashes_strings_only( $value ) { return is_string( $value ) ? addslashes( $value ) : $value; } function noindex() { _deprecated_function( __FUNCTION__, '5.7.0', 'wp_robots_noindex()' ); if ( '0' == get_option( 'blog_public' ) ) { wp_no_robots(); } } function wp_no_robots() { _deprecated_function( __FUNCTION__, '5.7.0', 'wp_robots_no_robots()' ); if ( get_option( 'blog_public' ) ) { echo "<meta name='robots' content='noindex,follow' />\n"; return; } echo "<meta name='robots' content='noindex,nofollow' />\n"; } function wp_sensitive_page_meta() { _deprecated_function( __FUNCTION__, '5.7.0', 'wp_robots_sensitive_page()' ); ?>
<meta name='robots' content='noindex,noarchive' />
<?php
wp_strict_cross_origin_referrer(); } function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) { _deprecated_function( __FUNCTION__, '5.8.0', '_excerpt_render_inner_blocks()' ); return _excerpt_render_inner_blocks( $columns, $allowed_blocks ); } function wp_render_duotone_filter_preset( $preset ) { _deprecated_function( __FUNCTION__, '5.9.1', 'wp_get_duotone_filter_property()' ); return wp_get_duotone_filter_property( $preset ); } function wp_skip_border_serialization( $block_type ) { _deprecated_function( __FUNCTION__, '6.0.0', 'wp_should_skip_block_supports_serialization()' ); $border_support = isset( $block_type->supports['__experimentalBorder'] ) ? $block_type->supports['__experimentalBorder'] : false; return is_array( $border_support ) && array_key_exists( '__experimentalSkipSerialization', $border_support ) && $border_support['__experimentalSkipSerialization']; } function wp_skip_dimensions_serialization( $block_type ) { _deprecated_function( __FUNCTION__, '6.0.0', 'wp_should_skip_block_supports_serialization()' ); $dimensions_support = isset( $block_type->supports['__experimentalDimensions'] ) ? $block_type->supports['__experimentalDimensions'] : false; return is_array( $dimensions_support ) && array_key_exists( '__experimentalSkipSerialization', $dimensions_support ) && $dimensions_support['__experimentalSkipSerialization']; } function wp_skip_spacing_serialization( $block_type ) { _deprecated_function( __FUNCTION__, '6.0.0', 'wp_should_skip_block_supports_serialization()' ); $spacing_support = isset( $block_type->supports['spacing'] ) ? $block_type->supports['spacing'] : false; return is_array( $spacing_support ) && array_key_exists( '__experimentalSkipSerialization', $spacing_support ) && $spacing_support['__experimentalSkipSerialization']; } function wp_add_iframed_editor_assets_html() { _deprecated_function( __FUNCTION__, '6.0.0' ); } function wp_get_attachment_thumb_file( $post_id = 0 ) { _deprecated_function( __FUNCTION__, '6.1.0' ); $post_id = (int) $post_id; $post = get_post( $post_id ); if ( ! $post ) { return false; } $imagedata = wp_get_attachment_metadata( $post->ID ); if ( ! is_array( $imagedata ) ) { return false; } $file = get_attached_file( $post->ID ); if ( ! empty( $imagedata['thumb'] ) ) { $thumbfile = str_replace( wp_basename( $file ), $imagedata['thumb'], $file ); if ( file_exists( $thumbfile ) ) { return apply_filters( 'wp_get_attachment_thumb_file', $thumbfile, $post->ID ); } } return false; } function _get_path_to_translation( $domain, $reset = false ) { _deprecated_function( __FUNCTION__, '6.1.0', 'WP_Textdomain_Registry' ); static $available_translations = array(); if ( true === $reset ) { $available_translations = array(); } if ( ! isset( $available_translations[ $domain ] ) ) { $available_translations[ $domain ] = _get_path_to_translation_from_lang_dir( $domain ); } return $available_translations[ $domain ]; } function _get_path_to_translation_from_lang_dir( $domain ) { _deprecated_function( __FUNCTION__, '6.1.0', 'WP_Textdomain_Registry' ); static $cached_mofiles = null; if ( null === $cached_mofiles ) { $cached_mofiles = array(); $locations = array( WP_LANG_DIR . '/plugins', WP_LANG_DIR . '/themes', ); foreach ( $locations as $location ) { $mofiles = glob( $location . '/*.mo' ); if ( $mofiles ) { $cached_mofiles = array_merge( $cached_mofiles, $mofiles ); } } } $locale = determine_locale(); $mofile = "{$domain}-{$locale}.mo"; $path = WP_LANG_DIR . '/plugins/' . $mofile; if ( in_array( $path, $cached_mofiles, true ) ) { return $path; } $path = WP_LANG_DIR . '/themes/' . $mofile; if ( in_array( $path, $cached_mofiles, true ) ) { return $path; } return false; } function _wp_multiple_block_styles( $metadata ) { _deprecated_function( __FUNCTION__, '6.1.0' ); return $metadata; } function wp_typography_get_css_variable_inline_style( $attributes, $feature, $css_property ) { _deprecated_function( __FUNCTION__, '6.1.0', 'wp_style_engine_get_styles()' ); $style_value = _wp_array_get( $attributes, array( 'style', 'typography', $feature ), false ); if ( ! $style_value ) { return; } if ( ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) { return sprintf( '%s:%s;', $css_property, $style_value ); } $index_to_splice = strrpos( $style_value, '|' ) + 1; $slug = substr( $style_value, $index_to_splice ); return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug ); } function global_terms_enabled() { _deprecated_function( __FUNCTION__, '6.1.0' ); return false; } function _filter_query_attachment_filenames( $clauses ) { _deprecated_function( __FUNCTION__, '6.0.3', 'add_filter( "wp_allow_query_attachment_by_filename", "__return_true" )' ); remove_filter( 'posts_clauses', __FUNCTION__ ); return $clauses; } function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) { _deprecated_function( __FUNCTION__, '6.2.0', 'WP_Query' ); global $wpdb; if ( is_array( $post_type ) ) { $post_type = esc_sql( $post_type ); $post_type_in_string = "'" . implode( "','", $post_type ) . "'"; $sql = $wpdb->prepare( "SELECT ID
FROM $wpdb->posts
WHERE post_title = %s
AND post_type IN ($post_type_in_string)", $page_title ); } else { $sql = $wpdb->prepare( "SELECT ID
FROM $wpdb->posts
WHERE post_title = %s
AND post_type = %s", $page_title, $post_type ); } $page = $wpdb->get_var( $sql ); if ( $page ) { return get_post( $page, $output ); } return null; } function _resolve_home_block_template() { _deprecated_function( __FUNCTION__, '6.2.0' ); $show_on_front = get_option( 'show_on_front' ); $front_page_id = get_option( 'page_on_front' ); if ( 'page' === $show_on_front && $front_page_id ) { return array( 'postType' => 'page', 'postId' => $front_page_id, ); } $hierarchy = array( 'front-page', 'home', 'index' ); $template = resolve_block_template( 'home', $hierarchy, '' ); if ( ! $template ) { return null; } return array( 'postType' => 'wp_template', 'postId' => $template->id, ); } function wlwmanifest_link() { _deprecated_function( __FUNCTION__, '6.3.0' ); } function wp_queue_comments_for_comment_meta_lazyload( $comments ) { _deprecated_function( __FUNCTION__, '6.3.0', 'wp_lazyload_comment_meta()' ); $comment_ids = array(); if ( is_array( $comments ) ) { foreach ( $comments as $comment ) { if ( $comment instanceof WP_Comment ) { $comment_ids[] = $comment->comment_ID; } } } wp_lazyload_comment_meta( $comment_ids ); } function wp_get_loading_attr_default( $context ) { _deprecated_function( __FUNCTION__, '6.3.0', 'wp_get_loading_optimization_attributes()' ); global $wp_query; if ( 'template' === $context ) { return false; } $header_area = WP_TEMPLATE_PART_AREA_HEADER; if ( "template_part_{$header_area}" === $context ) { return false; } if ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context ) { if ( doing_filter( 'the_content' ) ) { return false; } if ( $wp_query->before_loop && $wp_query->is_main_query() && did_action( 'get_header' ) && ! did_action( 'get_footer' ) ) { return false; } } if ( 'the_content' === $context || 'the_post_thumbnail' === $context ) { if ( is_admin() || ! in_the_loop() || ! is_main_query() ) { return 'lazy'; } $content_media_count = wp_increase_content_media_count(); if ( $content_media_count <= wp_omit_loading_attr_threshold() ) { return false; } return 'lazy'; } return 'lazy'; } function wp_img_tag_add_loading_attr( $image, $context ) { _deprecated_function( __FUNCTION__, '6.3.0', 'wp_img_tag_add_loading_optimization_attrs()' ); $value = wp_get_loading_attr_default( $context ); if ( ! str_contains( $image, ' src="' ) || ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) { return $image; } $value = apply_filters( 'wp_img_tag_add_loading_attr', $value, $image, $context ); if ( $value ) { if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) { $value = 'lazy'; } return str_replace( '<img', '<img loading="' . esc_attr( $value ) . '"', $image ); } return $image; } function wp_tinycolor_bound01( $n, $max ) { _deprecated_function( __FUNCTION__, '6.3.0' ); if ( 'string' === gettype( $n ) && str_contains( $n, '.' ) && 1 === (float) $n ) { $n = '100%'; } $n = min( $max, max( 0, (float) $n ) ); if ( 'string' === gettype( $n ) && str_contains( $n, '%' ) ) { $n = (int) ( $n * $max ) / 100; } if ( ( abs( $n - $max ) < 0.000001 ) ) { return 1.0; } return ( $n % $max ) / (float) $max; } function _wp_tinycolor_bound_alpha( $n ) { _deprecated_function( __FUNCTION__, '6.3.0' ); if ( is_numeric( $n ) ) { $n = (float) $n; if ( $n >= 0 && $n <= 1 ) { return $n; } } return 1; } function wp_tinycolor_rgb_to_rgb( $rgb_color ) { _deprecated_function( __FUNCTION__, '6.3.0' ); return array( 'r' => wp_tinycolor_bound01( $rgb_color['r'], 255 ) * 255, 'g' => wp_tinycolor_bound01( $rgb_color['g'], 255 ) * 255, 'b' => wp_tinycolor_bound01( $rgb_color['b'], 255 ) * 255, ); } function wp_tinycolor_hue_to_rgb( $p, $q, $t ) { _deprecated_function( __FUNCTION__, '6.3.0' ); if ( $t < 0 ) { ++$t; } if ( $t > 1 ) { --$t; } if ( $t < 1 / 6 ) { return $p + ( $q - $p ) * 6 * $t; } if ( $t < 1 / 2 ) { return $q; } if ( $t < 2 / 3 ) { return $p + ( $q - $p ) * ( 2 / 3 - $t ) * 6; } return $p; } function wp_tinycolor_hsl_to_rgb( $hsl_color ) { _deprecated_function( __FUNCTION__, '6.3.0' ); $h = wp_tinycolor_bound01( $hsl_color['h'], 360 ); $s = wp_tinycolor_bound01( $hsl_color['s'], 100 ); $l = wp_tinycolor_bound01( $hsl_color['l'], 100 ); if ( 0 === $s ) { $r = $l; $g = $l; $b = $l; } else { $q = $l < 0.5 ? $l * ( 1 + $s ) : $l + $s - $l * $s; $p = 2 * $l - $q; $r = wp_tinycolor_hue_to_rgb( $p, $q, $h + 1 / 3 ); $g = wp_tinycolor_hue_to_rgb( $p, $q, $h ); $b = wp_tinycolor_hue_to_rgb( $p, $q, $h - 1 / 3 ); } return array( 'r' => $r * 255, 'g' => $g * 255, 'b' => $b * 255, ); } function wp_tinycolor_string_to_rgb( $color_str ) { _deprecated_function( __FUNCTION__, '6.3.0' ); $color_str = strtolower( trim( $color_str ) ); $css_integer = '[-\\+]?\\d+%?'; $css_number = '[-\\+]?\\d*\\.\\d+%?'; $css_unit = '(?:' . $css_number . ')|(?:' . $css_integer . ')'; $permissive_match3 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?'; $permissive_match4 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?'; $rgb_regexp = '/^rgb' . $permissive_match3 . '$/'; if ( preg_match( $rgb_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => $match[1], 'g' => $match[2], 'b' => $match[3], ) ); $rgb['a'] = 1; return $rgb; } $rgba_regexp = '/^rgba' . $permissive_match4 . '$/'; if ( preg_match( $rgba_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => $match[1], 'g' => $match[2], 'b' => $match[3], ) ); $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] ); return $rgb; } $hsl_regexp = '/^hsl' . $permissive_match3 . '$/'; if ( preg_match( $hsl_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_hsl_to_rgb( array( 'h' => $match[1], 's' => $match[2], 'l' => $match[3], ) ); $rgb['a'] = 1; return $rgb; } $hsla_regexp = '/^hsla' . $permissive_match4 . '$/'; if ( preg_match( $hsla_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_hsl_to_rgb( array( 'h' => $match[1], 's' => $match[2], 'l' => $match[3], ) ); $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] ); return $rgb; } $hex8_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/'; if ( preg_match( $hex8_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => base_convert( $match[1], 16, 10 ), 'g' => base_convert( $match[2], 16, 10 ), 'b' => base_convert( $match[3], 16, 10 ), ) ); $rgb['a'] = _wp_tinycolor_bound_alpha( base_convert( $match[4], 16, 10 ) / 255 ); return $rgb; } $hex6_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/'; if ( preg_match( $hex6_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => base_convert( $match[1], 16, 10 ), 'g' => base_convert( $match[2], 16, 10 ), 'b' => base_convert( $match[3], 16, 10 ), ) ); $rgb['a'] = 1; return $rgb; } $hex4_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/'; if ( preg_match( $hex4_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => base_convert( $match[1] . $match[1], 16, 10 ), 'g' => base_convert( $match[2] . $match[2], 16, 10 ), 'b' => base_convert( $match[3] . $match[3], 16, 10 ), ) ); $rgb['a'] = _wp_tinycolor_bound_alpha( base_convert( $match[4] . $match[4], 16, 10 ) / 255 ); return $rgb; } $hex3_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/'; if ( preg_match( $hex3_regexp, $color_str, $match ) ) { $rgb = wp_tinycolor_rgb_to_rgb( array( 'r' => base_convert( $match[1] . $match[1], 16, 10 ), 'g' => base_convert( $match[2] . $match[2], 16, 10 ), 'b' => base_convert( $match[3] . $match[3], 16, 10 ), ) ); $rgb['a'] = 1; return $rgb; } if ( 'transparent' === $color_str ) { return array( 'r' => 0, 'g' => 0, 'b' => 0, 'a' => 0, ); } } function wp_get_duotone_filter_id( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0' ); return WP_Duotone::get_filter_id_from_preset( $preset ); } function wp_get_duotone_filter_property( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0' ); return WP_Duotone::get_filter_css_property_value_from_preset( $preset ); } function wp_get_duotone_filter_svg( $preset ) { _deprecated_function( __FUNCTION__, '6.3.0', 'WP_Duotone::get_filter_svg_from_preset()' ); return WP_Duotone::get_filter_svg_from_preset( $preset ); } function wp_register_duotone_support( $block_type ) { _deprecated_function( __FUNCTION__, '6.3.0', 'WP_Duotone::register_duotone_support()' ); return WP_Duotone::register_duotone_support( $block_type ); } function wp_render_duotone_support( $block_content, $block ) { _deprecated_function( __FUNCTION__, '6.3.0', 'WP_Duotone::render_duotone_support()' ); $wp_block = new WP_Block( $block ); return WP_Duotone::render_duotone_support( $block_content, $block, $wp_block ); } function wp_get_global_styles_svg_filters() { _deprecated_function( __FUNCTION__, '6.3.0' ); $can_use_cached = ! wp_is_development_mode( 'theme' ); $cache_group = 'theme_json'; $cache_key = 'wp_get_global_styles_svg_filters'; if ( $can_use_cached ) { $cached = wp_cache_get( $cache_key, $cache_group ); if ( $cached ) { return $cached; } } $supports_theme_json = wp_theme_has_theme_json(); $origins = array( 'default', 'theme', 'custom' ); if ( ! $supports_theme_json ) { $origins = array( 'default' ); } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $svgs = $tree->get_svg_filters( $origins ); if ( $can_use_cached ) { wp_cache_set( $cache_key, $svgs, $cache_group ); } return $svgs; } function wp_global_styles_render_svg_filters() { _deprecated_function( __FUNCTION__, '6.3.0' ); if ( is_admin() && ! get_current_screen()->is_block_editor() ) { return; } $filters = wp_get_global_styles_svg_filters(); if ( ! empty( $filters ) ) { echo $filters; } } function block_core_navigation_submenu_build_css_colors( $context, $attributes, $is_sub_menu = false ) { _deprecated_function( __FUNCTION__, '6.3.0' ); $colors = array( 'css_classes' => array(), 'inline_styles' => '', ); $named_text_color = null; $custom_text_color = null; if ( $is_sub_menu && array_key_exists( 'customOverlayTextColor', $context ) ) { $custom_text_color = $context['customOverlayTextColor']; } elseif ( $is_sub_menu && array_key_exists( 'overlayTextColor', $context ) ) { $named_text_color = $context['overlayTextColor']; } elseif ( array_key_exists( 'customTextColor', $context ) ) { $custom_text_color = $context['customTextColor']; } elseif ( array_key_exists( 'textColor', $context ) ) { $named_text_color = $context['textColor']; } elseif ( isset( $context['style']['color']['text'] ) ) { $custom_text_color = $context['style']['color']['text']; } if ( ! is_null( $named_text_color ) ) { array_push( $colors['css_classes'], 'has-text-color', sprintf( 'has-%s-color', $named_text_color ) ); } elseif ( ! is_null( $custom_text_color ) ) { $colors['css_classes'][] = 'has-text-color'; $colors['inline_styles'] .= sprintf( 'color: %s;', $custom_text_color ); } $named_background_color = null; $custom_background_color = null; if ( $is_sub_menu && array_key_exists( 'customOverlayBackgroundColor', $context ) ) { $custom_background_color = $context['customOverlayBackgroundColor']; } elseif ( $is_sub_menu && array_key_exists( 'overlayBackgroundColor', $context ) ) { $named_background_color = $context['overlayBackgroundColor']; } elseif ( array_key_exists( 'customBackgroundColor', $context ) ) { $custom_background_color = $context['customBackgroundColor']; } elseif ( array_key_exists( 'backgroundColor', $context ) ) { $named_background_color = $context['backgroundColor']; } elseif ( isset( $context['style']['color']['background'] ) ) { $custom_background_color = $context['style']['color']['background']; } if ( ! is_null( $named_background_color ) ) { array_push( $colors['css_classes'], 'has-background', sprintf( 'has-%s-background-color', $named_background_color ) ); } elseif ( ! is_null( $custom_background_color ) ) { $colors['css_classes'][] = 'has-background'; $colors['inline_styles'] .= sprintf( 'background-color: %s;', $custom_background_color ); } return $colors; } function _wp_theme_json_webfonts_handler() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_print_font_faces' ); if ( wp_installing() ) { return; } if ( ! wp_theme_has_theme_json() ) { return; } $registered_webfonts = array(); $fn_get_webfonts_from_theme_json = static function() { $settings = WP_Theme_JSON_Resolver::get_merged_data()->get_settings(); if ( is_admin() || wp_is_rest_endpoint() ) { $variations = WP_Theme_JSON_Resolver::get_style_variations(); foreach ( $variations as $variation ) { if ( empty( $variation['settings']['typography']['fontFamilies'] ) ) { continue; } if ( empty( $settings['typography'] ) ) { $settings['typography'] = array(); } if ( empty( $settings['typography']['fontFamilies'] ) ) { $settings['typography']['fontFamilies'] = array(); } if ( empty( $settings['typography']['fontFamilies']['theme'] ) ) { $settings['typography']['fontFamilies']['theme'] = array(); } $settings['typography']['fontFamilies']['theme'] = array_merge( $settings['typography']['fontFamilies']['theme'], $variation['settings']['typography']['fontFamilies']['theme'] ); $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'] ); } } if ( empty( $settings['typography']['fontFamilies'] ) ) { return array(); } $webfonts = array(); foreach ( $settings['typography']['fontFamilies'] as $font_families ) { foreach ( $font_families as $font_family ) { if ( empty( $font_family['fontFace'] ) ) { continue; } if ( ! is_array( $font_family['fontFace'] ) ) { continue; } $webfonts = array_merge( $webfonts, $font_family['fontFace'] ); } } return $webfonts; }; $fn_transform_src_into_uri = static function( array $src ) { foreach ( $src as $key => $url ) { if ( ! str_starts_with( $url, 'file:./' ) ) { continue; } $src[ $key ] = get_theme_file_uri( str_replace( 'file:./', '', $url ) ); } return $src; }; $fn_convert_keys_to_kebab_case = static function( array $font_face ) { foreach ( $font_face as $property => $value ) { $kebab_case = _wp_to_kebab_case( $property ); $font_face[ $kebab_case ] = $value; if ( $kebab_case !== $property ) { unset( $font_face[ $property ] ); } } return $font_face; }; $fn_validate_webfont = static function( $webfont ) { $webfont = wp_parse_args( $webfont, array( 'font-family' => '', 'font-style' => 'normal', 'font-weight' => '400', 'font-display' => 'fallback', 'src' => array(), ) ); if ( empty( $webfont['font-family'] ) || ! is_string( $webfont['font-family'] ) ) { trigger_error( __( 'Webfont font family must be a non-empty string.' ) ); return false; } if ( empty( $webfont['src'] ) || ( ! is_string( $webfont['src'] ) && ! is_array( $webfont['src'] ) ) ) { trigger_error( __( 'Webfont src must be a non-empty string or an array of strings.' ) ); return false; } foreach ( (array) $webfont['src'] as $src ) { if ( ! is_string( $src ) || '' === trim( $src ) ) { trigger_error( __( 'Each webfont src must be a non-empty string.' ) ); return false; } } if ( ! is_string( $webfont['font-weight'] ) && ! is_int( $webfont['font-weight'] ) ) { trigger_error( __( 'Webfont font weight must be a properly formatted string or integer.' ) ); return false; } if ( ! in_array( $webfont['font-display'], array( 'auto', 'block', 'fallback', 'optional', 'swap' ), true ) ) { $webfont['font-display'] = 'fallback'; } $valid_props = array( 'ascend-override', 'descend-override', 'font-display', 'font-family', 'font-stretch', 'font-style', 'font-weight', 'font-variant', 'font-feature-settings', 'font-variation-settings', 'line-gap-override', 'size-adjust', 'src', 'unicode-range', ); foreach ( $webfont as $prop => $value ) { if ( ! in_array( $prop, $valid_props, true ) ) { unset( $webfont[ $prop ] ); } } return $webfont; }; $fn_register_webfonts = static function() use ( &$registered_webfonts, $fn_get_webfonts_from_theme_json, $fn_convert_keys_to_kebab_case, $fn_validate_webfont, $fn_transform_src_into_uri ) { $registered_webfonts = array(); foreach ( $fn_get_webfonts_from_theme_json() as $webfont ) { if ( ! is_array( $webfont ) ) { continue; } $webfont = $fn_convert_keys_to_kebab_case( $webfont ); $webfont = $fn_validate_webfont( $webfont ); $webfont['src'] = $fn_transform_src_into_uri( (array) $webfont['src'] ); if ( empty( $webfont ) ) { continue; } $registered_webfonts[] = $webfont; } }; $fn_order_src = static function( array $webfont ) { $src = array(); $src_ordered = array(); foreach ( $webfont['src'] as $url ) { if ( str_starts_with( trim( $url ), 'data:' ) ) { $src_ordered[] = array( 'url' => $url, 'format' => 'data', ); continue; } $format = pathinfo( $url, PATHINFO_EXTENSION ); $src[ $format ] = $url; } if ( ! empty( $src['woff2'] ) ) { $src_ordered[] = array( 'url' => sanitize_url( $src['woff2'] ), 'format' => 'woff2', ); } if ( ! empty( $src['woff'] ) ) { $src_ordered[] = array( 'url' => sanitize_url( $src['woff'] ), 'format' => 'woff', ); } if ( ! empty( $src['ttf'] ) ) { $src_ordered[] = array( 'url' => sanitize_url( $src['ttf'] ), 'format' => 'truetype', ); } if ( ! empty( $src['eot'] ) ) { $src_ordered[] = array( 'url' => sanitize_url( $src['eot'] ), 'format' => 'embedded-opentype', ); } if ( ! empty( $src['otf'] ) ) { $src_ordered[] = array( 'url' => sanitize_url( $src['otf'] ), 'format' => 'opentype', ); } $webfont['src'] = $src_ordered; return $webfont; }; $fn_compile_src = static function( $font_family, array $value ) { $src = ''; foreach ( $value as $item ) { $src .= ( 'data' === $item['format'] ) ? ", url({$item['url']})" : ", url('{$item['url']}') format('{$item['format']}')"; } $src = ltrim( $src, ', ' ); return $src; }; $fn_compile_variations = static function( array $font_variation_settings ) { $variations = ''; foreach ( $font_variation_settings as $key => $value ) { $variations .= "$key $value"; } return $variations; }; $fn_build_font_face_css = static function( array $webfont ) use ( $fn_compile_src, $fn_compile_variations ) { $css = ''; if ( str_contains( $webfont['font-family'], ' ' ) && ! str_contains( $webfont['font-family'], '"' ) && ! str_contains( $webfont['font-family'], "'" ) ) { $webfont['font-family'] = '"' . $webfont['font-family'] . '"'; } foreach ( $webfont as $key => $value ) { if ( 'provider' === $key ) { continue; } if ( 'src' === $key ) { $value = $fn_compile_src( $webfont['font-family'], $value ); } if ( 'font-variation-settings' === $key && is_array( $value ) ) { $value = $fn_compile_variations( $value ); } if ( ! empty( $value ) ) { $css .= "$key:$value;"; } } return $css; }; $fn_get_css = static function() use ( &$registered_webfonts, $fn_order_src, $fn_build_font_face_css ) { $css = ''; foreach ( $registered_webfonts as $webfont ) { $webfont = $fn_order_src( $webfont ); $css .= '@font-face{' . $fn_build_font_face_css( $webfont ) . '}'; } return $css; }; $fn_generate_and_enqueue_styles = static function() use ( $fn_get_css ) { $styles = $fn_get_css(); if ( '' === $styles ) { return; } wp_register_style( 'wp-webfonts', '' ); wp_enqueue_style( 'wp-webfonts' ); wp_add_inline_style( 'wp-webfonts', $styles ); }; $fn_generate_and_enqueue_editor_styles = static function() use ( $fn_get_css ) { $styles = $fn_get_css(); if ( '' === $styles ) { return; } wp_add_inline_style( 'wp-block-library', $styles ); }; add_action( 'wp_loaded', $fn_register_webfonts ); add_action( 'wp_enqueue_scripts', $fn_generate_and_enqueue_styles ); add_action( 'admin_init', $fn_generate_and_enqueue_editor_styles ); } function print_embed_styles() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_enqueue_embed_styles' ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; $suffix = SCRIPT_DEBUG ? '' : '.min'; ?>
<style<?php echo $type_attr; ?>>
<?php echo file_get_contents( ABSPATH . WPINC . "/css/wp-embed-template$suffix.css" ); ?>
</style>
<?php
} function print_emoji_styles() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_enqueue_emoji_styles' ); static $printed = false; if ( $printed ) { return; } $printed = true; $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?>
<style<?php echo $type_attr; ?>>
img.wp-smiley,
img.emoji {
display: inline !important;
border: none !important;
box-shadow: none !important;
height: 1em !important;
width: 1em !important;
margin: 0 0.07em !important;
vertical-align: -0.1em !important;
background: none !important;
padding: 0 !important;
}
</style>
<?php
} function wp_admin_bar_header() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_enqueue_admin_bar_header_styles' ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?>
<style<?php echo $type_attr; ?> media="print">#wpadminbar { display:none; }</style>
<?php
} function _admin_bar_bump_cb() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_enqueue_admin_bar_bump_styles' ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?>
<style<?php echo $type_attr; ?> media="screen">
html { margin-top: 32px !important; }
@media screen and ( max-width: 782px ) {
html { margin-top: 46px !important; }
}
</style>
<?php
} function wp_update_https_detection_errors() { _deprecated_function( __FUNCTION__, '6.4.0' ); $support_errors = apply_filters( 'pre_wp_update_https_detection_errors', null ); if ( is_wp_error( $support_errors ) ) { update_option( 'https_detection_errors', $support_errors->errors, false ); return; } $support_errors = wp_get_https_detection_errors(); update_option( 'https_detection_errors', $support_errors ); } function wp_img_tag_add_decoding_attr( $image, $context ) { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_img_tag_add_loading_optimization_attrs()' ); if ( ! str_contains( $image, ' src="' ) ) { return $image; } $value = apply_filters( 'wp_img_tag_add_decoding_attr', 'async', $image, $context ); if ( in_array( $value, array( 'async', 'sync', 'auto' ), true ) ) { $image = str_replace( '<img ', '<img decoding="' . esc_attr( $value ) . '" ', $image ); } return $image; } function _inject_theme_attribute_in_block_template_content( $template_content ) { _deprecated_function( __FUNCTION__, '6.4.0', 'traverse_and_serialize_blocks( parse_blocks( $template_content ), "_inject_theme_attribute_in_template_part_block" )' ); $has_updated_content = false; $new_content = ''; $template_blocks = parse_blocks( $template_content ); $blocks = _flatten_blocks( $template_blocks ); foreach ( $blocks as &$block ) { if ( 'core/template-part' === $block['blockName'] && ! isset( $block['attrs']['theme'] ) ) { $block['attrs']['theme'] = get_stylesheet(); $has_updated_content = true; } } if ( $has_updated_content ) { foreach ( $template_blocks as &$block ) { $new_content .= serialize_block( $block ); } return $new_content; } return $template_content; } function _remove_theme_attribute_in_block_template_content( $template_content ) { _deprecated_function( __FUNCTION__, '6.4.0', 'traverse_and_serialize_blocks( parse_blocks( $template_content ), "_remove_theme_attribute_from_template_part_block" )' ); $has_updated_content = false; $new_content = ''; $template_blocks = parse_blocks( $template_content ); $blocks = _flatten_blocks( $template_blocks ); foreach ( $blocks as $key => $block ) { if ( 'core/template-part' === $block['blockName'] && isset( $block['attrs']['theme'] ) ) { unset( $blocks[ $key ]['attrs']['theme'] ); $has_updated_content = true; } } if ( ! $has_updated_content ) { return $template_content; } foreach ( $template_blocks as $block ) { $new_content .= serialize_block( $block ); } return $new_content; } function the_block_template_skip_link() { _deprecated_function( __FUNCTION__, '6.4.0', 'wp_enqueue_block_template_skip_link()' ); global $_wp_current_template_content; if ( ! current_theme_supports( 'block-templates' ) ) { return; } if ( ! $_wp_current_template_content ) { return; } ?>
<?php
?>
<style id="skip-link-styles">
.skip-link.screen-reader-text {
border: 0;
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute !important;
width: 1px;
word-wrap: normal !important;
}
.skip-link.screen-reader-text:focus {
background-color: #eee;
clip-path: none;
color: #444;
display: block;
font-size: 1em;
height: auto;
left: 5px;
line-height: normal;
padding: 15px 23px 14px;
text-decoration: none;
top: 5px;
width: auto;
z-index: 100000;
}
</style>
<?php
?>
<script>
( function() {
var skipLinkTarget = document.querySelector( 'main' ),
sibling,
skipLinkTargetID,
skipLink;
// Early exit if a skip-link target can't be located.
if ( ! skipLinkTarget ) {
return;
}
/*
* Get the site wrapper.
* The skip-link will be injected in the beginning of it.
*/
sibling = document.querySelector( '.wp-site-blocks' );
// Early exit if the root element was not found.
if ( ! sibling ) {
return;
}
// Get the skip-link target's ID, and generate one if it doesn't exist.
skipLinkTargetID = skipLinkTarget.id;
if ( ! skipLinkTargetID ) {
skipLinkTargetID = 'wp--skip-link--target';
skipLinkTarget.id = skipLinkTargetID;
}
// Create the skip link.
skipLink = document.createElement( 'a' );
skipLink.classList.add( 'skip-link', 'screen-reader-text' );
skipLink.href = '#' + skipLinkTargetID;
skipLink.innerHTML = '<?php esc_html_e( 'Skip to content' ); ?>';
// Inject the skip link.
sibling.parentElement.insertBefore( skipLink, sibling );
}() );
</script>
<?php
} function block_core_query_ensure_interactivity_dependency() { _deprecated_function( __FUNCTION__, '6.5.0', 'wp_register_script_module' ); } function block_core_file_ensure_interactivity_dependency() { _deprecated_function( __FUNCTION__, '6.5.0', 'wp_register_script_module' ); } function block_core_image_ensure_interactivity_dependency() { _deprecated_function( __FUNCTION__, '6.5.0', 'wp_register_script_module' ); } function wp_render_elements_support( $block_content, $block ) { _deprecated_function( __FUNCTION__, '6.6.0', 'wp_render_elements_class_name' ); return $block_content; } function wp_interactivity_process_directives_of_interactive_blocks( array $parsed_block ): array { _deprecated_function( __FUNCTION__, '6.6.0' ); return $parsed_block; } function wp_get_global_styles_custom_css() { _deprecated_function( __FUNCTION__, '6.7.0', 'wp_get_global_stylesheet' ); if ( ! wp_theme_has_theme_json() ) { return ''; } $can_use_cached = ! wp_is_development_mode( 'theme' ); $cache_key = 'wp_get_global_styles_custom_css'; $cache_group = 'theme_json'; if ( $can_use_cached ) { $cached = wp_cache_get( $cache_key, $cache_group ); if ( $cached ) { return $cached; } } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $stylesheet = $tree->get_custom_css(); if ( $can_use_cached ) { wp_cache_set( $cache_key, $stylesheet, $cache_group ); } return $stylesheet; } function wp_enqueue_global_styles_custom_css() { _deprecated_function( __FUNCTION__, '6.7.0', 'wp_enqueue_global_styles' ); if ( ! wp_is_block_theme() ) { return; } remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); $custom_css = wp_get_custom_css(); $custom_css .= wp_get_global_styles_custom_css(); if ( ! empty( $custom_css ) ) { wp_add_inline_style( 'global-styles', $custom_css ); } } function wp_create_block_style_variation_instance_name( $block, $variation ) { _deprecated_function( __FUNCTION__, '6.7.0', 'wp_unique_id' ); return $variation . '--' . md5( serialize( $block ) ); } function current_user_can_for_blog( $blog_id, $capability, ...$args ) { return current_user_can_for_site( $blog_id, $capability, ...$args ); } function wp_add_editor_classic_theme_styles( $editor_settings ) { _deprecated_function( __FUNCTION__, '6.8.0', 'wp_enqueue_classic_theme_styles' ); if ( wp_theme_has_theme_json() ) { return $editor_settings; } $suffix = wp_scripts_get_suffix(); $classic_theme_styles = ABSPATH . WPINC . "/css/classic-themes$suffix.css"; $classic_theme_styles_settings = array( 'css' => file_get_contents( $classic_theme_styles ), '__unstableType' => 'core', 'isGlobalStyles' => false, ); array_unshift( $editor_settings['styles'], $classic_theme_styles_settings ); return $editor_settings; } function wp_print_auto_sizes_contain_css_fix() { _deprecated_function( __FUNCTION__, '6.9.0', 'wp_enqueue_img_auto_sizes_contain_css_fix' ); $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); if ( ! $add_auto_sizes ) { return; } ?>
<style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style>
<?php
}
###require ABSPATH . WPINC . '/script-loader.php';
require ABSPATH . WPINC . '/class-wp-dependency.php'; require ABSPATH . WPINC . '/class-wp-dependencies.php'; require ABSPATH . WPINC . '/class-wp-scripts.php'; require ABSPATH . WPINC . '/functions.wp-scripts.php'; require ABSPATH . WPINC . '/class-wp-styles.php'; require ABSPATH . WPINC . '/functions.wp-styles.php'; function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) { global $tinymce_version, $concatenate_scripts, $compress_scripts; $suffix = wp_scripts_get_suffix(); $dev_suffix = wp_scripts_get_suffix( 'dev' ); script_concat_settings(); $compressed = $compress_scripts && $concatenate_scripts && ! $force_uncompressed; if ( $compressed ) { $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . 'wp-tinymce.js', array(), $tinymce_version ); } else { $scripts->add( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce$dev_suffix.js", array(), $tinymce_version ); $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin$dev_suffix.js", array( 'wp-tinymce-root' ), $tinymce_version ); } $scripts->add( 'wp-tinymce-lists', includes_url( "js/tinymce/plugins/lists/plugin$suffix.js" ), array( 'wp-tinymce' ), $tinymce_version ); } function wp_default_packages_vendor( $scripts ) { global $wp_locale; $suffix = wp_scripts_get_suffix(); $vendor_scripts = array( 'react', 'react-dom' => array( 'react' ), 'react-jsx-runtime' => array( 'react' ), 'regenerator-runtime', 'moment', 'lodash', 'wp-polyfill-fetch', 'wp-polyfill-formdata', 'wp-polyfill-node-contains', 'wp-polyfill-url', 'wp-polyfill-dom-rect', 'wp-polyfill-element-closest', 'wp-polyfill-object-fit', 'wp-polyfill-inert', 'wp-polyfill', ); $vendor_scripts_versions = array( 'react' => '18.3.1.1', 'react-dom' => '18.3.1.1', 'react-jsx-runtime' => '18.3.1', 'regenerator-runtime' => '0.14.1', 'moment' => '2.30.1', 'lodash' => '4.17.21', 'wp-polyfill-fetch' => '3.6.20', 'wp-polyfill-formdata' => '4.0.10', 'wp-polyfill-node-contains' => '4.8.0', 'wp-polyfill-url' => '3.6.4', 'wp-polyfill-dom-rect' => '4.8.0', 'wp-polyfill-element-closest' => '3.0.2', 'wp-polyfill-object-fit' => '2.3.5', 'wp-polyfill-inert' => '3.1.3', 'wp-polyfill' => '3.15.0', ); foreach ( $vendor_scripts as $handle => $dependencies ) { if ( is_string( $dependencies ) ) { $handle = $dependencies; $dependencies = array(); } $path = "/wp-includes/js/dist/vendor/$handle$suffix.js"; $version = $vendor_scripts_versions[ $handle ]; $scripts->add( $handle, $path, $dependencies, $version, 1 ); } did_action( 'init' ) && $scripts->add_inline_script( 'lodash', 'window.lodash = _.noConflict();' ); did_action( 'init' ) && $scripts->add_inline_script( 'moment', sprintf( "moment.updateLocale( '%s', %s );", esc_js( get_user_locale() ), wp_json_encode( array( 'months' => array_values( $wp_locale->month ), 'monthsShort' => array_values( $wp_locale->month_abbrev ), 'weekdays' => array_values( $wp_locale->weekday ), 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 'week' => array( 'dow' => (int) get_option( 'start_of_week', 0 ), ), 'longDateFormat' => array( 'LT' => get_option( 'time_format', __( 'g:i a' ) ), 'LTS' => null, 'L' => null, 'LL' => get_option( 'date_format', __( 'F j, Y' ) ), 'LLL' => __( 'F j, Y g:i a' ), 'LLLL' => null, ), ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); } function wp_get_script_polyfill( $scripts, $tests ) { $polyfill = ''; foreach ( $tests as $test => $handle ) { if ( ! array_key_exists( $handle, $scripts->registered ) ) { continue; } $src = $scripts->registered[ $handle ]->src; $ver = $scripts->registered[ $handle ]->ver; if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $scripts->content_url && str_starts_with( $src, $scripts->content_url ) ) ) { $src = $scripts->base_url . $src; } if ( ! empty( $ver ) ) { $src = add_query_arg( 'ver', $ver, $src ); } $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) ); if ( ! $src ) { continue; } $polyfill .= ( '( ' . $test . ' ) || ' . 'document.write( \'<script src="' . $src . '"></scr\' + \'ipt>\' );' ); } return $polyfill; } function wp_register_development_scripts( $scripts ) { if ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG || empty( $scripts->registered['react'] ) || defined( 'WP_RUN_CORE_TESTS' ) ) { return; } $development_scripts = array( 'react-refresh-entry', 'react-refresh-runtime', ); foreach ( $development_scripts as $script_name ) { $assets = include ABSPATH . WPINC . '/assets/script-loader-' . $script_name . '.php'; if ( ! is_array( $assets ) ) { return; } $scripts->add( 'wp-' . $script_name, '/wp-includes/js/dist/development/' . $script_name . '.js', $assets['dependencies'], $assets['version'] ); } $scripts->registered['react']->deps[] = 'wp-react-refresh-entry'; } function wp_default_packages_scripts( $scripts ) { $suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); $assets = include ABSPATH . WPINC . "/assets/script-loader-packages{$suffix}.php"; foreach ( $assets as $file_name => $package_data ) { $basename = str_replace( $suffix . '.js', '', basename( $file_name ) ); $handle = 'wp-' . $basename; $path = "/wp-includes/js/dist/{$basename}{$suffix}.js"; if ( ! empty( $package_data['dependencies'] ) ) { $dependencies = $package_data['dependencies']; } else { $dependencies = array(); } switch ( $handle ) { case 'wp-block-library': array_push( $dependencies, 'editor' ); break; case 'wp-edit-post': array_push( $dependencies, 'media-models', 'media-views', 'postbox', 'wp-dom-ready' ); break; case 'wp-preferences': array_push( $dependencies, 'wp-preferences-persistence' ); break; } $scripts->add( $handle, $path, $dependencies, $package_data['version'], 1 ); if ( in_array( 'wp-i18n', $dependencies, true ) ) { $scripts->set_translations( $handle ); } if ( 'wp-i18n' === $handle ) { $ltr = _x( 'ltr', 'text direction' ); $script = sprintf( "wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ '%s' ] } );", $ltr ); $scripts->add_inline_script( $handle, $script, 'after' ); } } } function wp_default_packages_inline_scripts( $scripts ) { global $wp_locale, $wpdb; if ( isset( $scripts->registered['wp-api-fetch'] ) ) { $scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; } $scripts->add_inline_script( 'wp-api-fetch', sprintf( 'wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "%s" ) );', sanitize_url( get_rest_url() ) ), 'after' ); $scripts->add_inline_script( 'wp-api-fetch', implode( "\n", array( sprintf( 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );', wp_installing() ? '' : wp_create_nonce( 'wp_rest' ) ), 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );', 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', sprintf( 'wp.apiFetch.nonceEndpoint = "%s";', admin_url( 'admin-ajax.php?action=rest-nonce' ) ), ) ), 'after' ); $meta_key = $wpdb->get_blog_prefix() . 'persisted_preferences'; $user_id = get_current_user_id(); $preload_data = get_user_meta( $user_id, $meta_key, true ); $scripts->add_inline_script( 'wp-preferences', sprintf( '( function() {
var serverData = %s;
var userId = "%d";
var persistenceLayer = wp.preferencesPersistence.__unstableCreatePersistenceLayer( serverData, userId );
var preferencesStore = wp.preferences.store;
wp.data.dispatch( preferencesStore ).setPersistenceLayer( persistenceLayer );
} ) ();', wp_json_encode( $preload_data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ), $user_id ) ); $scripts->add_inline_script( 'wp-data', implode( "\n", array( '( function() {', ' var userId = ' . get_current_user_id() . ';', ' var storageKey = "WP_DATA_USER_" + userId;', ' wp.data', ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', '} )();', ) ) ); $timezone_string = get_option( 'timezone_string', 'UTC' ); $timezone_abbr = ''; if ( ! empty( $timezone_string ) ) { $timezone_date = new DateTime( 'now', new DateTimeZone( $timezone_string ) ); $timezone_abbr = $timezone_date->format( 'T' ); } $gmt_offset = get_option( 'gmt_offset', 0 ); $scripts->add_inline_script( 'wp-date', sprintf( 'wp.date.setSettings( %s );', wp_json_encode( array( 'l10n' => array( 'locale' => get_user_locale(), 'months' => array_values( $wp_locale->month ), 'monthsShort' => array_values( $wp_locale->month_abbrev ), 'weekdays' => array_values( $wp_locale->weekday ), 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 'meridiem' => (object) $wp_locale->meridiem, 'relative' => array( 'future' => __( '%s from now' ), 'past' => __( '%s ago' ), 's' => __( 'a second' ), 'ss' => __( '%d seconds' ), 'm' => __( 'a minute' ), 'mm' => __( '%d minutes' ), 'h' => __( 'an hour' ), 'hh' => __( '%d hours' ), 'd' => __( 'a day' ), 'dd' => __( '%d days' ), 'M' => __( 'a month' ), 'MM' => __( '%d months' ), 'y' => __( 'a year' ), 'yy' => __( '%d years' ), ), 'startOfWeek' => (int) get_option( 'start_of_week', 0 ), ), 'formats' => array( 'time' => get_option( 'time_format', __( 'g:i a' ) ), 'date' => get_option( 'date_format', __( 'F j, Y' ) ), 'datetime' => __( 'F j, Y g:i a' ), 'datetimeAbbreviated' => __( 'M j, Y g:i a' ), ), 'timezone' => array( 'offset' => (float) $gmt_offset, 'offsetFormatted' => str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), (string) $gmt_offset ), 'string' => $timezone_string, 'abbr' => $timezone_abbr, ), ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); $scripts->add_inline_script( 'editor', 'window.wp.oldEditor = window.wp.editor;', 'after' ); $scripts->add_inline_script( 'wp-editor', 'Object.assign( window.wp.editor, window.wp.oldEditor );', 'after' ); } function wp_tinymce_inline_scripts() { global $wp_scripts; $editor_settings = apply_filters( 'wp_editor_settings', array( 'tinymce' => true ), 'classic-block' ); $tinymce_plugins = array( 'charmap', 'colorpicker', 'hr', 'lists', 'media', 'paste', 'tabfocus', 'textcolor', 'fullscreen', 'wordpress', 'wpautoresize', 'wpeditimage', 'wpemoji', 'wpgallery', 'wplink', 'wpdialogs', 'wptextpattern', 'wpview', ); $tinymce_plugins = apply_filters( 'tiny_mce_plugins', $tinymce_plugins, 'classic-block' ); $tinymce_plugins = array_unique( $tinymce_plugins ); $disable_captions = false; if ( apply_filters( 'disable_captions', '' ) ) { $disable_captions = true; } $toolbar1 = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'wp_add_media', 'wp_adv', ); $toolbar1 = apply_filters( 'mce_buttons', $toolbar1, 'classic-block' ); $toolbar2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help', ); $toolbar2 = apply_filters( 'mce_buttons_2', $toolbar2, 'classic-block' ); $toolbar3 = apply_filters( 'mce_buttons_3', array(), 'classic-block' ); $toolbar4 = apply_filters( 'mce_buttons_4', array(), 'classic-block' ); $external_plugins = apply_filters( 'mce_external_plugins', array(), 'classic-block' ); $tinymce_settings = array( 'plugins' => implode( ',', $tinymce_plugins ), 'toolbar1' => implode( ',', $toolbar1 ), 'toolbar2' => implode( ',', $toolbar2 ), 'toolbar3' => implode( ',', $toolbar3 ), 'toolbar4' => implode( ',', $toolbar4 ), 'external_plugins' => wp_json_encode( $external_plugins ), 'classic_block_editor' => true, ); if ( $disable_captions ) { $tinymce_settings['wpeditimage_disable_captions'] = true; } if ( ! empty( $editor_settings['tinymce'] ) && is_array( $editor_settings['tinymce'] ) ) { $tinymce_settings = array_merge( $tinymce_settings, $editor_settings['tinymce'] ); } $tinymce_settings = apply_filters( 'tiny_mce_before_init', $tinymce_settings, 'classic-block' ); $init_obj = ''; foreach ( $tinymce_settings as $key => $value ) { if ( is_bool( $value ) ) { $val = $value ? 'true' : 'false'; $init_obj .= $key . ':' . $val . ','; continue; } elseif ( ! empty( $value ) && is_string( $value ) && ( ( '{' === $value[0] && '}' === $value[ strlen( $value ) - 1 ] ) || ( '[' === $value[0] && ']' === $value[ strlen( $value ) - 1 ] ) || preg_match( '/^\(?function ?\(/', $value ) ) ) { $init_obj .= $key . ':' . $value . ','; continue; } $init_obj .= $key . ':"' . $value . '",'; } $init_obj = '{' . trim( $init_obj, ' ,' ) . '}'; $script = 'window.wpEditorL10n = {
tinymce: {
baseURL: ' . wp_json_encode( includes_url( 'js/tinymce' ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) . ',
suffix: ' . ( SCRIPT_DEBUG ? '""' : '".min"' ) . ',
settings: ' . $init_obj . ',
}
}'; $wp_scripts->add_inline_script( 'wp-block-library', $script, 'before' ); } function wp_default_packages( $scripts ) { wp_default_packages_vendor( $scripts ); wp_register_development_scripts( $scripts ); wp_register_tinymce_scripts( $scripts ); wp_default_packages_scripts( $scripts ); if ( did_action( 'init' ) ) { wp_default_packages_inline_scripts( $scripts ); } } function wp_scripts_get_suffix( $type = '' ) { static $suffixes; if ( null === $suffixes ) { require ABSPATH . WPINC . '/version.php'; $develop_src = false !== strpos( $wp_version, '-src' ); if ( ! defined( 'SCRIPT_DEBUG' ) ) { define( 'SCRIPT_DEBUG', $develop_src ); } $suffix = SCRIPT_DEBUG ? '' : '.min'; $dev_suffix = $develop_src ? '' : '.min'; $suffixes = array( 'suffix' => $suffix, 'dev_suffix' => $dev_suffix, ); } if ( 'dev' === $type ) { return $suffixes['dev_suffix']; } return $suffixes['suffix']; } function wp_default_scripts( $scripts ) { $suffix = wp_scripts_get_suffix(); $dev_suffix = wp_scripts_get_suffix( 'dev' ); $guessurl = site_url(); if ( ! $guessurl ) { $guessed_url = true; $guessurl = wp_guess_url(); } $scripts->base_url = $guessurl; $scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; $scripts->default_version = get_bloginfo( 'version' ); $scripts->default_dirs = array( '/wp-admin/js/', '/wp-includes/js/' ); $scripts->add( 'utils', "/wp-includes/js/utils$suffix.js" ); did_action( 'init' ) && $scripts->localize( 'utils', 'userSettings', array( 'url' => (string) SITECOOKIEPATH, 'uid' => (string) get_current_user_id(), 'time' => (string) time(), 'secure' => (string) ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ), ) ); $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array( 'jquery', 'hoverIntent', 'utils', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'common' ); $bulk_action_observer_ids = array( 'bulk_action' => 'action', 'changeit' => 'new_role', ); did_action( 'init' ) && $scripts->localize( 'common', 'bulkActionObserverIds', apply_filters( 'bulk_action_observer_ids', $bulk_action_observer_ids ) ); $scripts->add( 'wp-sanitize', "/wp-includes/js/wp-sanitize$suffix.js", array(), false, 1 ); $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", array(), '1.6.1', 1 ); $scripts->add( 'quicktags', "/wp-includes/js/quicktags$suffix.js", array(), false, 1 ); did_action( 'init' ) && $scripts->localize( 'quicktags', 'quicktagsL10n', array( 'closeAllOpenTags' => __( 'Close all open tags' ), 'closeTags' => __( 'close tags' ), 'enterURL' => __( 'Enter the URL' ), 'enterImageURL' => __( 'Enter the URL of the image' ), 'enterImageDescription' => __( 'Enter a description of the image' ), 'textdirection' => __( 'text direction' ), 'toggleTextdirection' => __( 'Toggle Editor Text Direction' ), 'dfw' => __( 'Distraction-free writing mode' ), 'strong' => __( 'Bold' ), 'strongClose' => __( 'Close bold tag' ), 'em' => __( 'Italic' ), 'emClose' => __( 'Close italic tag' ), 'link' => __( 'Insert link' ), 'blockquote' => __( 'Blockquote' ), 'blockquoteClose' => __( 'Close blockquote tag' ), 'del' => __( 'Deleted text (strikethrough)' ), 'delClose' => __( 'Close deleted text tag' ), 'ins' => __( 'Inserted text' ), 'insClose' => __( 'Close inserted text tag' ), 'image' => __( 'Insert image' ), 'ul' => __( 'Bulleted list' ), 'ulClose' => __( 'Close bulleted list tag' ), 'ol' => __( 'Numbered list' ), 'olClose' => __( 'Close numbered list tag' ), 'li' => __( 'List item' ), 'liClose' => __( 'Close list item tag' ), 'code' => __( 'Code' ), 'codeClose' => __( 'Close code tag' ), 'more' => __( 'Insert Read More tag' ), ) ); $scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array( 'prototype' ), '3517m' ); $scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array( 'utils', 'jquery' ), false, 1 ); $scripts->add( 'clipboard', "/wp-includes/js/clipboard$suffix.js", array(), '2.0.11', 1 ); $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-ajax-response', 'wpAjax', array( 'noPerm' => __( 'Sorry, you are not allowed to do that.' ), 'broken' => __( 'An error occurred while processing your request. Please try again later.' ), ) ); $scripts->add( 'wp-api-request', "/wp-includes/js/api-request$suffix.js", array( 'jquery' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-api-request', 'wpApiSettings', array( 'root' => sanitize_url( get_rest_url() ), 'nonce' => wp_installing() ? '' : wp_create_nonce( 'wp_rest' ), 'versionString' => 'wp/v2/', ) ); $scripts->add( 'wp-pointer', "/wp-includes/js/wp-pointer$suffix.js", array( 'jquery-ui-core' ), false, 1 ); $scripts->set_translations( 'wp-pointer' ); $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array( 'heartbeat' ), false, 1 ); $scripts->add( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array( 'jquery', 'wp-hooks' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'heartbeat', 'heartbeatSettings', apply_filters( 'heartbeat_settings', array() ) ); $scripts->add( 'wp-auth-check', "/wp-includes/js/wp-auth-check$suffix.js", array( 'heartbeat' ), false, 1 ); $scripts->set_translations( 'wp-auth-check' ); $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 ); $scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery' ), false, 1 ); $scripts->set_translations( 'site-icon' ); $scripts->add( 'prototype', 'https://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1' ); $scripts->add( 'scriptaculous-root', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array( 'prototype' ), '1.9.0' ); $scripts->add( 'scriptaculous-builder', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/builder.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-dragdrop', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/dragdrop.js', array( 'scriptaculous-builder', 'scriptaculous-effects' ), '1.9.0' ); $scripts->add( 'scriptaculous-effects', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/effects.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-slider', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/slider.js', array( 'scriptaculous-effects' ), '1.9.0' ); $scripts->add( 'scriptaculous-sound', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/sound.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-controls', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/controls.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous', false, array( 'scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls' ) ); $scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array( 'scriptaculous-dragdrop' ) ); $scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ), '3.7.1' ); $scripts->add( 'jquery-core', "/wp-includes/js/jquery/jquery$suffix.js", array(), '3.7.1' ); $scripts->add( 'jquery-migrate', "/wp-includes/js/jquery/jquery-migrate$suffix.js", array(), '3.4.1' ); $scripts->add( 'jquery-ui-core', "/wp-includes/js/jquery/ui/core$suffix.js", array( 'jquery' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-core', "/wp-includes/js/jquery/ui/effect$suffix.js", array( 'jquery' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-blind', "/wp-includes/js/jquery/ui/effect-blind$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-bounce', "/wp-includes/js/jquery/ui/effect-bounce$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-clip', "/wp-includes/js/jquery/ui/effect-clip$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-drop', "/wp-includes/js/jquery/ui/effect-drop$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-explode', "/wp-includes/js/jquery/ui/effect-explode$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-fade', "/wp-includes/js/jquery/ui/effect-fade$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-fold', "/wp-includes/js/jquery/ui/effect-fold$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-highlight', "/wp-includes/js/jquery/ui/effect-highlight$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-puff', "/wp-includes/js/jquery/ui/effect-puff$suffix.js", array( 'jquery-effects-core', 'jquery-effects-scale' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-pulsate', "/wp-includes/js/jquery/ui/effect-pulsate$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-scale', "/wp-includes/js/jquery/ui/effect-scale$suffix.js", array( 'jquery-effects-core', 'jquery-effects-size' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-shake', "/wp-includes/js/jquery/ui/effect-shake$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-size', "/wp-includes/js/jquery/ui/effect-size$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-slide', "/wp-includes/js/jquery/ui/effect-slide$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-button', "/wp-includes/js/jquery/ui/button$suffix.js", array( 'jquery-ui-core', 'jquery-ui-controlgroup', 'jquery-ui-checkboxradio' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-dialog', "/wp-includes/js/jquery/ui/dialog$suffix.js", array( 'jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-menu', "/wp-includes/js/jquery/ui/menu$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-mouse', "/wp-includes/js/jquery/ui/mouse$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-progressbar', "/wp-includes/js/jquery/ui/progressbar$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-selectmenu', "/wp-includes/js/jquery/ui/selectmenu$suffix.js", array( 'jquery-ui-menu' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-slider', "/wp-includes/js/jquery/ui/slider$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-spinner', "/wp-includes/js/jquery/ui/spinner$suffix.js", array( 'jquery-ui-button' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-tabs', "/wp-includes/js/jquery/ui/tabs$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-tooltip', "/wp-includes/js/jquery/ui/tooltip$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-checkboxradio', "/wp-includes/js/jquery/ui/checkboxradio$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-controlgroup', "/wp-includes/js/jquery/ui/controlgroup$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-draggable', "/wp-includes/js/jquery/ui/draggable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-droppable', "/wp-includes/js/jquery/ui/droppable$suffix.js", array( 'jquery-ui-draggable' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-resizable', "/wp-includes/js/jquery/ui/resizable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-selectable', "/wp-includes/js/jquery/ui/selectable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-sortable', "/wp-includes/js/jquery/ui/sortable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-position', false, array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-widget', false, array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array( 'jquery' ), '4.3.0', 1 ); $scripts->add( 'jquery-color', '/wp-includes/js/jquery/jquery.color.min.js', array( 'jquery' ), '3.0.0', 1 ); $scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array( 'jquery' ), '20m', 1 ); $scripts->add( 'jquery-query', '/wp-includes/js/jquery/jquery.query.js', array( 'jquery' ), '2.2.3', 1 ); $scripts->add( 'jquery-serialize-object', '/wp-includes/js/jquery/jquery.serialize-object.js', array( 'jquery' ), '0.2-wp', 1 ); $scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array( 'jquery' ), '0.0.2m', 1 ); $scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array( 'jquery', 'jquery-hotkeys' ), false, 1 ); $scripts->add( 'jquery-touch-punch', '/wp-includes/js/jquery/jquery.ui.touch-punch.js', array( 'jquery-ui-core', 'jquery-ui-mouse' ), '0.2.2', 1 ); $scripts->add( 'suggest', "/wp-includes/js/jquery/suggest$suffix.js", array( 'jquery' ), '1.1-20110113', 1 ); $scripts->add( 'imagesloaded', '/wp-includes/js/imagesloaded.min.js', array(), '5.0.0', 1 ); $scripts->add( 'masonry', '/wp-includes/js/masonry.min.js', array( 'imagesloaded' ), '4.2.2', 1 ); $scripts->add( 'jquery-masonry', '/wp-includes/js/jquery/jquery.masonry.min.js', array( 'jquery', 'masonry' ), '3.1.2b', 1 ); $scripts->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array( 'jquery' ), '3.1-20121105', 1 ); did_action( 'init' ) && $scripts->localize( 'thickbox', 'thickboxL10n', array( 'next' => __( 'Next >' ), 'prev' => __( '< Prev' ), 'image' => __( 'Image' ), 'of' => __( 'of' ), 'close' => __( 'Close' ), 'noiframes' => __( 'This feature requires inline frames. You have iframes disabled or your browser does not support them.' ), 'loadingAnimation' => includes_url( 'js/thickbox/loadingAnimation.gif' ), ) ); $scripts->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.js', array( 'jquery' ), '0.9.15' ); $uploader_l10n = array( 'queue_limit_exceeded' => __( 'You have attempted to queue too many files.' ), 'file_exceeds_size_limit' => __( '%s exceeds the maximum upload size for this site.' ), 'zero_byte_file' => __( 'This file is empty. Please try another.' ), 'invalid_filetype' => __( 'This file cannot be processed by the web server.' ), 'not_an_image' => __( 'This file is not an image. Please try another.' ), 'image_memory_exceeded' => __( 'Memory exceeded. Please try another smaller file.' ), 'image_dimensions_exceeded' => __( 'This is larger than the maximum size. Please try another.' ), 'default_error' => __( 'An error occurred in the upload. Please try again later.' ), 'missing_upload_url' => __( 'There was a configuration error. Please contact the server administrator.' ), 'upload_limit_exceeded' => __( 'You may only upload 1 file.' ), 'http_error' => __( 'Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.' ), 'http_error_image' => __( 'The server cannot process the image. This can happen if the server is busy or does not have enough resources to complete the task. Uploading a smaller image may help. Suggested maximum size is 2560 pixels.' ), 'upload_failed' => __( 'Upload failed.' ), 'big_upload_failed' => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.' ), 'big_upload_queued' => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.' ), 'io_error' => __( 'IO error.' ), 'security_error' => __( 'Security error.' ), 'file_cancelled' => __( 'File canceled.' ), 'upload_stopped' => __( 'Upload stopped.' ), 'dismiss' => __( 'Dismiss' ), 'crunching' => __( 'Crunching…' ), 'deleted' => __( 'moved to the Trash.' ), 'error_uploading' => __( '“%s” has failed to upload.' ), 'unsupported_image' => __( 'This image cannot be displayed in a web browser. For best results convert it to JPEG before uploading.' ), 'noneditable_image' => __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), 'file_url_copied' => __( 'The file URL has been copied to your clipboard' ), ); $scripts->add( 'moxiejs', "/wp-includes/js/plupload/moxie$suffix.js", array(), '1.3.5.1' ); $scripts->add( 'plupload', "/wp-includes/js/plupload/plupload$suffix.js", array( 'moxiejs' ), '2.1.9' ); foreach ( array( 'all', 'html5', 'flash', 'silverlight', 'html4' ) as $handle ) { $scripts->add( "plupload-$handle", false, array( 'plupload' ), '2.1.1' ); } $scripts->add( 'plupload-handlers', "/wp-includes/js/plupload/handlers$suffix.js", array( 'clipboard', 'jquery', 'plupload', 'underscore', 'wp-a11y', 'wp-i18n' ) ); did_action( 'init' ) && $scripts->localize( 'plupload-handlers', 'pluploadL10n', $uploader_l10n ); $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array( 'plupload', 'jquery', 'media-models' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-plupload', 'pluploadL10n', $uploader_l10n ); $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 ); if ( did_action( 'init' ) ) { $scripts->add_data( 'comment-reply', 'strategy', 'async' ); $scripts->add_data( 'comment-reply', 'fetchpriority', 'low' ); } $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' ); did_action( 'init' ) && $scripts->add_data( 'json2', 'conditional', '_required-conditional-dependency_' ); $scripts->add( 'underscore', "/wp-includes/js/underscore$dev_suffix.js", array(), '1.13.7', 1 ); $scripts->add( 'backbone', "/wp-includes/js/backbone$dev_suffix.js", array( 'underscore', 'jquery' ), '1.6.0', 1 ); $scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array( 'underscore', 'jquery' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-util', '_wpUtilSettings', array( 'ajax' => array( 'url' => admin_url( 'admin-ajax.php', 'relative' ), ), ) ); $scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array( 'backbone', 'wp-util' ), false, 1 ); $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'wp-backbone', 'jquery-ui-slider', 'hoverIntent' ), false, 1 ); $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'mediaelement', false, array( 'jquery', 'mediaelement-core', 'mediaelement-migrate' ), '4.2.17', 1 ); $scripts->add( 'mediaelement-core', "/wp-includes/js/mediaelement/mediaelement-and-player$suffix.js", array(), '4.2.17', 1 ); $scripts->add( 'mediaelement-migrate', "/wp-includes/js/mediaelement/mediaelement-migrate$suffix.js", array(), false, 1 ); did_action( 'init' ) && $scripts->add_inline_script( 'mediaelement-core', sprintf( 'var mejsL10n = %s;', wp_json_encode( array( 'language' => strtolower( strtok( determine_locale(), '_-' ) ), 'strings' => array( 'mejs.download-file' => __( 'Download File' ), 'mejs.install-flash' => __( 'You are using a browser that does not have Flash player enabled or installed. Please turn on your Flash player plugin or download the latest version from https://get.adobe.com/flashplayer/' ), 'mejs.fullscreen' => __( 'Fullscreen' ), 'mejs.play' => __( 'Play' ), 'mejs.pause' => __( 'Pause' ), 'mejs.time-slider' => __( 'Time Slider' ), 'mejs.time-help-text' => __( 'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.' ), 'mejs.live-broadcast' => __( 'Live Broadcast' ), 'mejs.volume-help-text' => __( 'Use Up/Down Arrow keys to increase or decrease volume.' ), 'mejs.unmute' => __( 'Unmute' ), 'mejs.mute' => __( 'Mute' ), 'mejs.volume-slider' => __( 'Volume Slider' ), 'mejs.video-player' => __( 'Video Player' ), 'mejs.audio-player' => __( 'Audio Player' ), 'mejs.captions-subtitles' => __( 'Captions/Subtitles' ), 'mejs.captions-chapters' => __( 'Chapters' ), 'mejs.none' => __( 'None' ), 'mejs.afrikaans' => __( 'Afrikaans' ), 'mejs.albanian' => __( 'Albanian' ), 'mejs.arabic' => __( 'Arabic' ), 'mejs.belarusian' => __( 'Belarusian' ), 'mejs.bulgarian' => __( 'Bulgarian' ), 'mejs.catalan' => __( 'Catalan' ), 'mejs.chinese' => __( 'Chinese' ), 'mejs.chinese-simplified' => __( 'Chinese (Simplified)' ), 'mejs.chinese-traditional' => __( 'Chinese (Traditional)' ), 'mejs.croatian' => __( 'Croatian' ), 'mejs.czech' => __( 'Czech' ), 'mejs.danish' => __( 'Danish' ), 'mejs.dutch' => __( 'Dutch' ), 'mejs.english' => __( 'English' ), 'mejs.estonian' => __( 'Estonian' ), 'mejs.filipino' => __( 'Filipino' ), 'mejs.finnish' => __( 'Finnish' ), 'mejs.french' => __( 'French' ), 'mejs.galician' => __( 'Galician' ), 'mejs.german' => __( 'German' ), 'mejs.greek' => __( 'Greek' ), 'mejs.haitian-creole' => __( 'Haitian Creole' ), 'mejs.hebrew' => __( 'Hebrew' ), 'mejs.hindi' => __( 'Hindi' ), 'mejs.hungarian' => __( 'Hungarian' ), 'mejs.icelandic' => __( 'Icelandic' ), 'mejs.indonesian' => __( 'Indonesian' ), 'mejs.irish' => __( 'Irish' ), 'mejs.italian' => __( 'Italian' ), 'mejs.japanese' => __( 'Japanese' ), 'mejs.korean' => __( 'Korean' ), 'mejs.latvian' => __( 'Latvian' ), 'mejs.lithuanian' => __( 'Lithuanian' ), 'mejs.macedonian' => __( 'Macedonian' ), 'mejs.malay' => __( 'Malay' ), 'mejs.maltese' => __( 'Maltese' ), 'mejs.norwegian' => __( 'Norwegian' ), 'mejs.persian' => __( 'Persian' ), 'mejs.polish' => __( 'Polish' ), 'mejs.portuguese' => __( 'Portuguese' ), 'mejs.romanian' => __( 'Romanian' ), 'mejs.russian' => __( 'Russian' ), 'mejs.serbian' => __( 'Serbian' ), 'mejs.slovak' => __( 'Slovak' ), 'mejs.slovenian' => __( 'Slovenian' ), 'mejs.spanish' => __( 'Spanish' ), 'mejs.swahili' => __( 'Swahili' ), 'mejs.swedish' => __( 'Swedish' ), 'mejs.tagalog' => __( 'Tagalog' ), 'mejs.thai' => __( 'Thai' ), 'mejs.turkish' => __( 'Turkish' ), 'mejs.ukrainian' => __( 'Ukrainian' ), 'mejs.vietnamese' => __( 'Vietnamese' ), 'mejs.welsh' => __( 'Welsh' ), 'mejs.yiddish' => __( 'Yiddish' ), ), ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'before' ); $scripts->add( 'mediaelement-vimeo', '/wp-includes/js/mediaelement/renderers/vimeo.min.js', array( 'mediaelement' ), '4.2.17', 1 ); $scripts->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.js", array( 'mediaelement' ), false, 1 ); $mejs_settings = array( 'pluginPath' => includes_url( 'js/mediaelement/', 'relative' ), 'classPrefix' => 'mejs-', 'stretching' => 'responsive', 'audioShortcodeLibrary' => apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ), 'videoShortcodeLibrary' => apply_filters( 'wp_video_shortcode_library', 'mediaelement' ), ); did_action( 'init' ) && $scripts->localize( 'mediaelement', '_wpmejsSettings', apply_filters( 'mejs_settings', $mejs_settings ) ); $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' ); $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' ); $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.0' ); $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.2' ); $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' ); $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) ); $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror', 'underscore' ) ); $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'common', 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ), false, 1 ); $scripts->set_translations( 'wp-theme-plugin-editor' ); $scripts->add( 'wp-playlist', "/wp-includes/js/mediaelement/wp-playlist$suffix.js", array( 'wp-util', 'backbone', 'mediaelement' ), false, 1 ); $scripts->add( 'zxcvbn-async', "/wp-includes/js/zxcvbn-async$suffix.js", array(), '1.0' ); did_action( 'init' ) && $scripts->localize( 'zxcvbn-async', '_zxcvbnSettings', array( 'src' => empty( $guessed_url ) ? includes_url( '/js/zxcvbn.min.js' ) : $scripts->base_url . '/wp-includes/js/zxcvbn.min.js', ) ); $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array( 'jquery', 'zxcvbn-async' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'password-strength-meter', 'pwsL10n', array( 'unknown' => _x( 'Password strength unknown', 'password strength' ), 'short' => _x( 'Very weak', 'password strength' ), 'bad' => _x( 'Weak', 'password strength' ), 'good' => _x( 'Medium', 'password strength' ), 'strong' => _x( 'Strong', 'password strength' ), 'mismatch' => _x( 'Mismatch', 'password mismatch' ), ) ); $scripts->set_translations( 'password-strength-meter' ); $scripts->add( 'password-toggle', "/wp-admin/js/password-toggle$suffix.js", array(), false, 1 ); $scripts->set_translations( 'password-toggle' ); $scripts->add( 'application-passwords', "/wp-admin/js/application-passwords$suffix.js", array( 'jquery', 'wp-util', 'wp-api-request', 'wp-date', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'application-passwords' ); $scripts->add( 'auth-app', "/wp-admin/js/auth-app$suffix.js", array( 'jquery', 'wp-api-request', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'auth-app' ); $scripts->add( 'user-profile', "/wp-admin/js/user-profile$suffix.js", array( 'clipboard', 'jquery', 'password-strength-meter', 'wp-util', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'user-profile' ); $user_id = isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : 0; did_action( 'init' ) && $scripts->localize( 'user-profile', 'userProfileL10n', array( 'user_id' => $user_id, 'nonce' => wp_installing() ? '' : wp_create_nonce( 'reset-password-for-' . $user_id ), ) ); $scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'user-suggest', "/wp-admin/js/user-suggest$suffix.js", array( 'jquery-ui-autocomplete' ), false, 1 ); $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array( 'hoverintent-js' ), false, 1 ); $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'common', 'jquery', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'wplink' ); did_action( 'init' ) && $scripts->localize( 'wplink', 'wpLinkL10n', array( 'title' => __( 'Insert/edit link' ), 'update' => __( 'Update' ), 'save' => __( 'Add Link' ), 'noTitle' => __( '(no title)' ), 'noMatchesFound' => __( 'No results found.' ), 'linkSelected' => __( 'Link selected.' ), 'linkInserted' => __( 'Link inserted.' ), 'minInputLength' => (int) _x( '3', 'minimum input length for searching post links' ), ) ); $scripts->add( 'wpdialogs', "/wp-includes/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), false, 1 ); $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 ); $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 ); $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.10.2', 1 ); $scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 ); $scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'underscore' ), false, 1 ); $scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 ); $scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'wp-a11y', 'customize-base' ), false, 1 ); $scripts->add( 'customize-models', '/wp-includes/js/customize-models.js', array( 'underscore', 'backbone' ), false, 1 ); $scripts->add( 'customize-views', '/wp-includes/js/customize-views.js', array( 'jquery', 'underscore', 'imgareaselect', 'customize-models', 'media-editor', 'media-views' ), false, 1 ); $scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base', 'wp-a11y', 'wp-util', 'jquery-ui-core' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'customize-controls', '_wpCustomizeControlsL10n', array( 'activate' => __( 'Activate & Publish' ), 'save' => __( 'Save & Publish' ), 'publish' => __( 'Publish' ), 'published' => __( 'Published' ), 'saveDraft' => __( 'Save Draft' ), 'draftSaved' => __( 'Draft Saved' ), 'updating' => __( 'Updating' ), 'schedule' => _x( 'Schedule', 'customizer changeset action/button label' ), 'scheduled' => _x( 'Scheduled', 'customizer changeset status' ), 'invalid' => __( 'Invalid' ), 'saveBeforeShare' => __( 'Please save your changes in order to share the preview.' ), 'futureDateError' => __( 'You must supply a future date to schedule.' ), 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ), 'saved' => __( 'Saved' ), 'cancel' => __( 'Cancel' ), 'close' => __( 'Close' ), 'action' => __( 'Action' ), 'discardChanges' => __( 'Discard changes' ), 'cheatin' => __( 'An error occurred. Please try again later.' ), 'notAllowedHeading' => __( 'You need a higher level of permission.' ), 'notAllowed' => __( 'Sorry, you are not allowed to customize this site.' ), 'previewIframeTitle' => __( 'Site Preview' ), 'loginIframeTitle' => __( 'Session expired' ), 'collapseSidebar' => _x( 'Hide Controls', 'label for hide controls button without length constraints' ), 'expandSidebar' => _x( 'Show Controls', 'label for hide controls button without length constraints' ), 'untitledBlogName' => __( '(Untitled)' ), 'unknownRequestFail' => __( 'Looks like something’s gone wrong. Wait a couple seconds, and then try again.' ), 'themeDownloading' => __( 'Downloading your new theme…' ), 'themePreviewWait' => __( 'Setting up your live preview. This may take a bit.' ), 'revertingChanges' => __( 'Reverting unpublished changes…' ), 'trashConfirm' => __( 'Are you sure you want to discard your unpublished changes?' ), 'takenOverMessage' => __( '%s has taken over and is currently customizing.' ), 'autosaveNotice' => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ), 'videoHeaderNotice' => __( 'This theme does not support video headers on this page. Navigate to the front page or another page that supports video headers.' ), 'allowedFiles' => __( 'Allowed Files' ), 'customCssError' => array( 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), ), 'pageOnFrontError' => __( 'Homepage and posts page must be different.' ), 'saveBlockedError' => array( 'singular' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 1 ), 'plural' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 2 ), ), 'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ), 'themePreviewUnavailable' => __( 'Sorry, you cannot preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.' ), 'themeInstallUnavailable' => sprintf( __( 'You will not be able to install new themes from here yet since your install requires SFTP credentials. For now, please <a href="%s">add themes in the admin</a>.' ), esc_url( admin_url( 'theme-install.php' ) ) ), 'publishSettings' => __( 'Publish Settings' ), 'invalidDate' => __( 'Invalid date.' ), 'invalidValue' => __( 'Invalid value.' ), 'blockThemeNotification' => sprintf( __( 'Hurray! Your theme supports site editing with blocks. <a href="%1$s">Tell me more</a>. %2$s' ), __( 'https://wordpress.org/documentation/article/site-editor/' ), sprintf( '<button type="button" data-action="%1$s" class="button switch-to-editor">%2$s</button>', esc_url( admin_url( 'site-editor.php' ) ), __( 'Use Site Editor' ) ) ), ) ); $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); $scripts->add( 'customize-widgets', "/wp-admin/js/customize-widgets$suffix.js", array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-droppable', 'wp-backbone', 'customize-controls' ), false, 1 ); $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); $scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu', 'wp-sanitize' ), false, 1 ); $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); $scripts->add( 'wp-custom-header', "/wp-includes/js/wp-custom-header$suffix.js", array( 'wp-a11y' ), false, 1 ); $scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 ); $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'wp-backbone' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'media-models', '_wpMediaModelsL10n', array( 'settings' => array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'post' => array( 'id' => 0 ), ), ) ); $scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js" ); did_action( 'init' ) && $scripts->add_data( 'wp-embed', 'strategy', 'defer' ); $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'clipboard' ), false, 1 ); $scripts->set_translations( 'media-views' ); $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); $scripts->set_translations( 'media-editor' ); $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 ); $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'jquery', 'media-views', 'media-audiovideo' ), false, 1 ); $scripts->add( 'wp-api', "/wp-includes/js/wp-api$suffix.js", array( 'jquery', 'backbone', 'underscore', 'wp-api-request' ), false, 1 ); if ( is_admin() ) { $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 ); $scripts->set_translations( 'admin-tags' ); $scripts->add( 'admin-comments', "/wp-admin/js/edit-comments$suffix.js", array( 'wp-lists', 'quicktags', 'jquery-query', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'admin-comments' ); did_action( 'init' ) && $scripts->localize( 'admin-comments', 'adminCommentsSettings', array( 'hotkeys_highlight_first' => isset( $_GET['hotkeys_highlight_first'] ), 'hotkeys_highlight_last' => isset( $_GET['hotkeys_highlight_last'] ), ) ); $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'postbox' ); $scripts->add( 'tags-box', "/wp-admin/js/tags-box$suffix.js", array( 'jquery', 'tags-suggest' ), false, 1 ); $scripts->set_translations( 'tags-box' ); $scripts->add( 'tags-suggest', "/wp-admin/js/tags-suggest$suffix.js", array( 'common', 'jquery-ui-autocomplete', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'tags-suggest' ); $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y', 'wp-sanitize', 'clipboard' ), false, 1 ); $scripts->set_translations( 'post' ); $scripts->add( 'editor-expand', "/wp-admin/js/editor-expand$suffix.js", array( 'jquery', 'underscore' ), false, 1 ); $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array( 'wp-lists', 'postbox' ), false, 1 ); $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array( 'jquery', 'postbox' ), false, 1 ); $scripts->set_translations( 'comment' ); $scripts->add( 'admin-gallery', "/wp-admin/js/gallery$suffix.js", array( 'jquery-ui-sortable' ) ); $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'admin-widgets' ); $scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views', 'wp-api-request' ) ); $scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' ); $scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) ); $scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) ); $scripts->add( 'media-gallery-widget', "/wp-admin/js/widgets/media-gallery-widget$suffix.js", array( 'media-widgets' ) ); $scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo', 'wp-api-request' ) ); $scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util', 'wp-a11y' ) ); $scripts->add( 'custom-html-widgets', "/wp-admin/js/widgets/custom-html-widgets$suffix.js", array( 'jquery', 'backbone', 'wp-util', 'jquery-ui-core', 'wp-a11y' ) ); $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y', 'customize-base' ), false, 1 ); $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'tags-suggest', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'inline-edit-post' ); $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'inline-edit-tax' ); $scripts->add( 'plugin-install', "/wp-admin/js/plugin-install$suffix.js", array( 'jquery', 'jquery-ui-core', 'thickbox' ), false, 1 ); $scripts->set_translations( 'plugin-install' ); $scripts->add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-api-request', 'wp-url', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'site-health' ); $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'privacy-tools' ); $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'updates' ); did_action( 'init' ) && $scripts->localize( 'updates', '_wpUpdatesSettings', array( 'ajax_nonce' => wp_installing() ? '' : wp_create_nonce( 'updates' ), ) ); $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array( 'jquery' ), '1.2' ); $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.1.1', 1 ); $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); $scripts->set_translations( 'wp-color-picker' ); $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'common', 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 ); $scripts->set_translations( 'dashboard' ); $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); $scripts->add( 'media-grid', "/wp-includes/js/media-grid$suffix.js", array( 'media-editor' ), false, 1 ); $scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery', 'clipboard', 'wp-i18n', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'media' ); $scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'imgareaselect', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'image-edit' ); $scripts->add( 'set-post-thumbnail', "/wp-admin/js/set-post-thumbnail$suffix.js", array( 'jquery' ), false, 1 ); $scripts->set_translations( 'set-post-thumbnail' ); $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-lists', 'postbox', 'underscore' ) ); $scripts->set_translations( 'nav-menu' ); $scripts->add( 'custom-header', '/wp-admin/js/custom-header.js', array( 'jquery-masonry' ), false, 1 ); $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 ); $scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'svg-painter', '/wp-admin/js/svg-painter.js', array( 'jquery' ), false, 1 ); } } function wp_default_styles( $styles ) { global $editor_styles; require ABSPATH . WPINC . '/version.php'; if ( ! defined( 'SCRIPT_DEBUG' ) ) { define( 'SCRIPT_DEBUG', false !== strpos( $wp_version, '-src' ) ); } $guessurl = site_url(); if ( ! $guessurl ) { $guessurl = wp_guess_url(); } $styles->base_url = $guessurl; $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; $styles->default_version = get_bloginfo( 'version' ); $styles->text_direction = function_exists( 'is_rtl' ) && is_rtl() ? 'rtl' : 'ltr'; $styles->default_dirs = array( '/wp-admin/', '/wp-includes/css/' ); $open_sans_font_url = ''; if ( 'off' !== _x( 'on', 'Open Sans font: on or off' ) ) { $subsets = 'latin,latin-ext'; $subset = _x( 'no-subset', 'Open Sans font: add new subset (greek, cyrillic, vietnamese)' ); if ( 'cyrillic' === $subset ) { $subsets .= ',cyrillic,cyrillic-ext'; } elseif ( 'greek' === $subset ) { $subsets .= ',greek,greek-ext'; } elseif ( 'vietnamese' === $subset ) { $subsets .= ',vietnamese'; } $open_sans_font_url = "https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets&display=fallback"; } $styles->add( 'colors', true, array( 'wp-admin', 'buttons' ) ); $suffix = SCRIPT_DEBUG ? '' : '.min'; $styles->add( 'common', "/wp-admin/css/common$suffix.css" ); $styles->add( 'forms', "/wp-admin/css/forms$suffix.css" ); $styles->add( 'admin-menu', "/wp-admin/css/admin-menu$suffix.css" ); $styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css" ); $styles->add( 'list-tables', "/wp-admin/css/list-tables$suffix.css" ); $styles->add( 'edit', "/wp-admin/css/edit$suffix.css" ); $styles->add( 'revisions', "/wp-admin/css/revisions$suffix.css" ); $styles->add( 'media', "/wp-admin/css/media$suffix.css" ); $styles->add( 'themes', "/wp-admin/css/themes$suffix.css" ); $styles->add( 'about', "/wp-admin/css/about$suffix.css" ); $styles->add( 'nav-menus', "/wp-admin/css/nav-menus$suffix.css" ); $styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array( 'wp-pointer' ) ); $styles->add( 'site-icon', "/wp-admin/css/site-icon$suffix.css" ); $styles->add( 'l10n', "/wp-admin/css/l10n$suffix.css" ); $styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) ); $styles->add( 'site-health', "/wp-admin/css/site-health$suffix.css" ); $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n' ) ); $styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); $styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); $styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" ); $styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'imgareaselect' ) ); $styles->add( 'customize-widgets', "/wp-admin/css/customize-widgets$suffix.css", array( 'wp-admin', 'colors' ) ); $styles->add( 'customize-nav-menus', "/wp-admin/css/customize-nav-menus$suffix.css", array( 'wp-admin', 'colors' ) ); $styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" ); $styles->add( 'dashicons', "/wp-includes/css/dashicons$suffix.css" ); $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css", array( 'dashicons' ) ); $styles->add( 'wp-auth-check', "/wp-includes/css/wp-auth-check$suffix.css", array( 'dashicons' ) ); $styles->add( 'editor-buttons', "/wp-includes/css/editor$suffix.css", array( 'dashicons' ) ); $styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons', 'dashicons', 'wp-mediaelement' ) ); $styles->add( 'wp-pointer', "/wp-includes/css/wp-pointer$suffix.css", array( 'dashicons' ) ); $styles->add( 'customize-preview', "/wp-includes/css/customize-preview$suffix.css", array( 'dashicons' ) ); $styles->add( 'wp-empty-template-alert', "/wp-includes/css/wp-empty-template-alert$suffix.css" ); $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.8' ); $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css", array( 'dashicons' ) ); $styles->add( 'mediaelement', '/wp-includes/js/mediaelement/mediaelementplayer-legacy.min.css', array(), '4.2.17' ); $styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.css", array( 'mediaelement' ) ); $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array( 'dashicons' ) ); $styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' ); $styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" ); $styles->add( 'farbtastic', "/wp-admin/css/farbtastic$suffix.css", array(), '1.3u1' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.css', array(), '0.9.15' ); $styles->add( 'colors-fresh', false, array( 'wp-admin', 'buttons' ) ); $styles->add( 'open-sans', $open_sans_font_url ); $styles->add( 'wp-embed-template-ie', false ); $styles->add_data( 'wp-embed-template-ie', 'conditional', '_required-conditional-dependency_' ); $fonts_url = ''; $font_family = _x( 'Noto Serif:400,400i,700,700i', 'Google Font Name and Variants' ); if ( 'off' !== $font_family ) { $fonts_url = 'https://fonts.googleapis.com/css?family=' . urlencode( $font_family ); } $styles->add( 'wp-editor-font', $fonts_url ); $block_library_theme_path = WPINC . "/css/dist/block-library/theme$suffix.css"; $styles->add( 'wp-block-library-theme', "/$block_library_theme_path" ); $styles->add_data( 'wp-block-library-theme', 'path', ABSPATH . $block_library_theme_path ); $classic_theme_styles_path = WPINC . "/css/classic-themes$suffix.css"; $styles->add( 'classic-theme-styles', "/$classic_theme_styles_path" ); $styles->add_data( 'classic-theme-styles', 'path', ABSPATH . $classic_theme_styles_path ); $styles->add( 'wp-reset-editor-styles', "/wp-includes/css/dist/block-library/reset$suffix.css", array( 'common', 'forms' ) ); $styles->add( 'wp-editor-classic-layout-styles', "/wp-includes/css/dist/edit-post/classic$suffix.css", array() ); $styles->add( 'wp-block-editor-content', "/wp-includes/css/dist/block-editor/content$suffix.css", array( 'wp-components' ) ); $wp_edit_blocks_dependencies = array( 'wp-components', 'wp-reset-editor-styles', 'wp-block-library', 'wp-block-editor-content', ); if ( ! wp_theme_has_theme_json() ) { $wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles'; } if ( current_theme_supports( 'wp-block-styles' ) && ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) ) { $wp_edit_blocks_dependencies[] = 'wp-block-library-theme'; } $styles->add( 'wp-edit-blocks', "/wp-includes/css/dist/block-library/editor$suffix.css", $wp_edit_blocks_dependencies ); $package_styles = array( 'block-editor' => array( 'wp-components', 'wp-preferences' ), 'block-library' => array(), 'block-directory' => array(), 'components' => array(), 'commands' => array( 'wp-components' ), 'edit-post' => array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-commands', 'wp-preferences', ), 'editor' => array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks', 'wp-patterns', 'wp-preferences', ), 'format-library' => array(), 'list-reusable-blocks' => array( 'wp-components' ), 'reusable-blocks' => array( 'wp-components' ), 'patterns' => array( 'wp-components' ), 'preferences' => array( 'wp-components' ), 'nux' => array( 'wp-components' ), 'widgets' => array( 'wp-components', ), 'edit-widgets' => array( 'wp-widgets', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-patterns', 'wp-preferences', ), 'customize-widgets' => array( 'wp-widgets', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-patterns', 'wp-preferences', ), 'edit-site' => array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-commands', 'wp-preferences', ), ); foreach ( $package_styles as $package => $dependencies ) { $handle = 'wp-' . $package; $path = "/wp-includes/css/dist/$package/style$suffix.css"; if ( 'block-library' === $package && wp_should_load_separate_core_block_assets() ) { $path = "/wp-includes/css/dist/$package/common$suffix.css"; } $styles->add( $handle, $path, $dependencies ); $styles->add_data( $handle, 'path', ABSPATH . $path ); } $rtl_styles = array( 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'install', 'wp-color-picker', 'customize-controls', 'customize-widgets', 'customize-nav-menus', 'customize-preview', 'login', 'site-health', 'wp-empty-template-alert', 'buttons', 'admin-bar', 'wp-auth-check', 'editor-buttons', 'media-views', 'wp-pointer', 'wp-jquery-ui-dialog', 'wp-reset-editor-styles', 'wp-editor-classic-layout-styles', 'wp-block-library-theme', 'wp-edit-blocks', 'wp-block-editor', 'wp-block-library', 'wp-block-directory', 'wp-commands', 'wp-components', 'wp-customize-widgets', 'wp-edit-post', 'wp-edit-site', 'wp-edit-widgets', 'wp-editor', 'wp-format-library', 'wp-list-reusable-blocks', 'wp-reusable-blocks', 'wp-patterns', 'wp-nux', 'wp-widgets', 'deprecated-media', 'farbtastic', ); foreach ( $rtl_styles as $rtl_style ) { $styles->add_data( $rtl_style, 'rtl', 'replace' ); if ( $suffix ) { $styles->add_data( $rtl_style, 'suffix', $suffix ); } } } function wp_prototype_before_jquery( $js_array ) { $prototype = array_search( 'prototype', $js_array, true ); if ( false === $prototype ) { return $js_array; } $jquery = array_search( 'jquery', $js_array, true ); if ( false === $jquery ) { return $js_array; } if ( $prototype < $jquery ) { return $js_array; } unset( $js_array[ $prototype ] ); array_splice( $js_array, $jquery, 0, 'prototype' ); return $js_array; } function wp_just_in_time_script_localization() { wp_localize_script( 'autosave', 'autosaveL10n', array( 'autosaveInterval' => AUTOSAVE_INTERVAL, 'blog_id' => get_current_blog_id(), ) ); wp_localize_script( 'mce-view', 'mceViewL10n', array( 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), ) ); wp_localize_script( 'word-count', 'wordCountL10n', array( 'type' => wp_get_word_count_type(), 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), ) ); } function wp_localize_jquery_ui_datepicker() { global $wp_locale; if ( ! wp_script_is( 'jquery-ui-datepicker', 'enqueued' ) ) { return; } $datepicker_date_format = str_replace( array( 'd', 'j', 'l', 'z', 'F', 'M', 'n', 'm', 'Y', 'y', ), array( 'dd', 'd', 'DD', 'o', 'MM', 'M', 'm', 'mm', 'yy', 'y', ), get_option( 'date_format' ) ); $datepicker_defaults = wp_json_encode( array( 'closeText' => __( 'Close' ), 'currentText' => __( 'Today' ), 'monthNames' => array_values( $wp_locale->month ), 'monthNamesShort' => array_values( $wp_locale->month_abbrev ), 'nextText' => __( 'Next' ), 'prevText' => __( 'Previous' ), 'dayNames' => array_values( $wp_locale->weekday ), 'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ), 'dayNamesMin' => array_values( $wp_locale->weekday_initial ), 'dateFormat' => $datepicker_date_format, 'firstDay' => absint( get_option( 'start_of_week' ) ), 'isRTL' => $wp_locale->is_rtl(), ), JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ); wp_add_inline_script( 'jquery-ui-datepicker', "jQuery(function(jQuery){jQuery.datepicker.setDefaults({$datepicker_defaults});});" ); } function wp_localize_community_events() { if ( ! wp_script_is( 'dashboard' ) ) { return; } require_once ABSPATH . 'wp-admin/includes/class-wp-community-events.php'; $user_id = get_current_user_id(); $saved_location = get_user_option( 'community-events-location', $user_id ); $saved_ip_address = isset( $saved_location['ip'] ) ? $saved_location['ip'] : false; $current_ip_address = WP_Community_Events::get_unsafe_client_ip(); if ( $saved_ip_address && $current_ip_address && $current_ip_address !== $saved_ip_address ) { $saved_location['ip'] = $current_ip_address; update_user_meta( $user_id, 'community-events-location', $saved_location ); } $events_client = new WP_Community_Events( $user_id, $saved_location ); wp_localize_script( 'dashboard', 'communityEventsData', array( 'nonce' => wp_create_nonce( 'community_events' ), 'cache' => $events_client->get_cached_events(), 'time_format' => get_option( 'time_format' ), ) ); } function wp_style_loader_src( $src, $handle ) { global $_wp_admin_css_colors; if ( wp_installing() ) { return preg_replace( '#^wp-admin/#', './', $src ); } if ( 'colors' === $handle ) { $color = get_user_option( 'admin_color' ); if ( empty( $color ) || ! isset( $_wp_admin_css_colors[ $color ] ) ) { $color = 'fresh'; } $color = $_wp_admin_css_colors[ $color ]; $url = $color->url; if ( ! $url ) { return false; } $parsed = parse_url( $src ); if ( isset( $parsed['query'] ) && $parsed['query'] ) { wp_parse_str( $parsed['query'], $qv ); $url = add_query_arg( $qv, $url ); } return $url; } return $src; } function print_head_scripts() { global $concatenate_scripts; if ( ! did_action( 'wp_print_scripts' ) ) { do_action( 'wp_print_scripts' ); } $wp_scripts = wp_scripts(); script_concat_settings(); $wp_scripts->do_concat = $concatenate_scripts; $wp_scripts->do_head_items(); if ( apply_filters( 'print_head_scripts', true ) ) { _print_scripts(); } $wp_scripts->reset(); return $wp_scripts->done; } function print_footer_scripts() { global $wp_scripts, $concatenate_scripts; if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { return array(); } script_concat_settings(); $wp_scripts->do_concat = $concatenate_scripts; $wp_scripts->do_footer_items(); if ( apply_filters( 'print_footer_scripts', true ) ) { _print_scripts(); } $wp_scripts->reset(); return $wp_scripts->done; } function _print_scripts() { global $wp_scripts, $compress_scripts; $zip = $compress_scripts ? 1 : 0; if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { $zip = 'gzip'; } $concat = trim( $wp_scripts->concat, ', ' ); $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : " type='text/javascript'"; if ( $concat ) { if ( ! empty( $wp_scripts->print_code ) ) { echo "\n<script{$type_attr}>\n"; echo "/* <![CDATA[ */\n"; echo $wp_scripts->print_code; echo sprintf( "\n//# sourceURL=%s\n", rawurlencode( 'js-inline-concat-' . $concat ) ); echo "/* ]]> */\n"; echo "</script>\n"; } $concat = str_split( $concat, 128 ); $concatenated = ''; foreach ( $concat as $key => $chunk ) { $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; } $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}" . $concatenated . '&ver=' . $wp_scripts->default_version; echo "<script{$type_attr} src='" . esc_attr( $src ) . "'></script>\n"; } if ( ! empty( $wp_scripts->print_html ) ) { echo $wp_scripts->print_html; } } function wp_print_head_scripts() { global $wp_scripts; if ( ! did_action( 'wp_print_scripts' ) ) { do_action( 'wp_print_scripts' ); } if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { return array(); } return print_head_scripts(); } function _wp_footer_scripts() { print_late_styles(); print_footer_scripts(); } function wp_print_footer_scripts() { do_action( 'wp_print_footer_scripts' ); } function wp_enqueue_scripts() { do_action( 'wp_enqueue_scripts' ); } function print_admin_styles() { global $concatenate_scripts; $wp_styles = wp_styles(); script_concat_settings(); $wp_styles->do_concat = $concatenate_scripts; $wp_styles->do_items( false ); if ( apply_filters( 'print_admin_styles', true ) ) { _print_styles(); } $wp_styles->reset(); return $wp_styles->done; } function print_late_styles() { global $wp_styles, $concatenate_scripts; if ( ! ( $wp_styles instanceof WP_Styles ) ) { return; } script_concat_settings(); $wp_styles->do_concat = $concatenate_scripts; $wp_styles->do_footer_items(); if ( apply_filters( 'print_late_styles', true ) ) { _print_styles(); } $wp_styles->reset(); return $wp_styles->done; } function _print_styles() { global $compress_css; $wp_styles = wp_styles(); $zip = $compress_css ? 1 : 0; if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { $zip = 'gzip'; } $concat = trim( $wp_styles->concat, ', ' ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; if ( $concat ) { $dir = $wp_styles->text_direction; $ver = $wp_styles->default_version; $concat_source_url = 'css-inline-concat-' . $concat; $concat = str_split( $concat, 128 ); $concatenated = ''; foreach ( $concat as $key => $chunk ) { $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; } $href = $wp_styles->base_url . "/wp-admin/load-styles.php?c={$zip}&dir={$dir}" . $concatenated . '&ver=' . $ver; echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "'{$type_attr} media='all' />\n"; if ( ! empty( $wp_styles->print_code ) ) { echo "<style{$type_attr}>\n"; echo $wp_styles->print_code; echo sprintf( "\n/*# sourceURL=%s */", rawurlencode( $concat_source_url ) ); echo "\n</style>\n"; } } if ( ! empty( $wp_styles->print_html ) ) { echo $wp_styles->print_html; } } function script_concat_settings() { global $concatenate_scripts, $compress_scripts, $compress_css; $compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ); $can_compress_scripts = ! wp_installing() && get_site_option( 'can_compress_scripts' ); if ( ! isset( $concatenate_scripts ) ) { $concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true; if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) { $concatenate_scripts = false; } } if ( ! isset( $compress_scripts ) ) { $compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true; if ( $compress_scripts && ( ! $can_compress_scripts || $compressed_output ) ) { $compress_scripts = false; } } if ( ! isset( $compress_css ) ) { $compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true; if ( $compress_css && ( ! $can_compress_scripts || $compressed_output ) ) { $compress_css = false; } } } function wp_common_block_scripts_and_styles() { if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) { return; } wp_enqueue_style( 'wp-block-library' ); if ( current_theme_supports( 'wp-block-styles' ) && ! wp_should_load_separate_core_block_assets() ) { wp_enqueue_style( 'wp-block-library-theme' ); } do_action( 'enqueue_block_assets' ); } function wp_filter_out_block_nodes( $nodes ) { return array_filter( $nodes, static function ( $node ) { return ! in_array( 'blocks', $node['path'], true ); }, ARRAY_FILTER_USE_BOTH ); } function wp_enqueue_global_styles() { $assets_on_demand = wp_should_load_block_assets_on_demand(); $is_block_theme = wp_is_block_theme(); $is_classic_theme = ! $is_block_theme; if ( ( $is_block_theme && doing_action( 'wp_footer' ) ) || ( $is_classic_theme && doing_action( 'wp_footer' ) && ! $assets_on_demand ) || ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $assets_on_demand ) ) { return; } add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); $stylesheet = wp_get_global_stylesheet(); if ( $is_block_theme ) { remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); $custom_css = trim( wp_get_custom_css() ); if ( $custom_css || is_customize_preview() ) { if ( is_customize_preview() ) { $before_milestone = '/*BEGIN_CUSTOMIZER_CUSTOM_CSS*/'; $after_milestone = '/*END_CUSTOMIZER_CUSTOM_CSS*/'; $custom_css = str_replace( array( $before_milestone, $after_milestone ), '', $custom_css ); $custom_css = $before_milestone . "\n" . $custom_css . "\n" . $after_milestone; } $custom_css = "\n" . $custom_css; } $stylesheet .= $custom_css; $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); } if ( empty( $stylesheet ) ) { return; } wp_register_style( 'global-styles', false ); wp_add_inline_style( 'global-styles', $stylesheet ); wp_enqueue_style( 'global-styles' ); wp_add_global_styles_for_blocks(); } function wp_should_load_block_editor_scripts_and_styles() { global $current_screen; $is_block_editor_screen = ( $current_screen instanceof WP_Screen ) && $current_screen->is_block_editor(); return apply_filters( 'should_load_block_editor_scripts_and_styles', $is_block_editor_screen ); } function wp_should_load_separate_core_block_assets() { if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) { return false; } return apply_filters( 'should_load_separate_core_block_assets', false ); } function wp_should_load_block_assets_on_demand() { if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) { return false; } $load_assets_on_demand = wp_should_load_separate_core_block_assets(); return apply_filters( 'should_load_block_assets_on_demand', $load_assets_on_demand ); } function wp_enqueue_registered_block_scripts_and_styles() { if ( wp_should_load_block_assets_on_demand() ) { return; } $load_editor_scripts_and_styles = is_admin() && wp_should_load_block_editor_scripts_and_styles(); $block_registry = WP_Block_Type_Registry::get_instance(); foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) { foreach ( $block_type->style_handles as $style_handle ) { wp_enqueue_style( $style_handle ); } foreach ( $block_type->script_handles as $script_handle ) { wp_enqueue_script( $script_handle ); } if ( $load_editor_scripts_and_styles ) { foreach ( $block_type->editor_style_handles as $editor_style_handle ) { wp_enqueue_style( $editor_style_handle ); } foreach ( $block_type->editor_script_handles as $editor_script_handle ) { wp_enqueue_script( $editor_script_handle ); } } } } function enqueue_block_styles_assets() { global $wp_styles; $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); foreach ( $block_styles as $block_name => $styles ) { foreach ( $styles as $style_properties ) { if ( isset( $style_properties['style_handle'] ) ) { if ( wp_should_load_block_assets_on_demand() ) { add_filter( 'render_block', static function ( $html, $block ) use ( $block_name, $style_properties ) { if ( $block['blockName'] === $block_name ) { wp_enqueue_style( $style_properties['style_handle'] ); } return $html; }, 10, 2 ); } else { wp_enqueue_style( $style_properties['style_handle'] ); } } if ( isset( $style_properties['inline_style'] ) ) { $handle = 'wp-block-library'; if ( wp_should_load_block_assets_on_demand() ) { $block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' ); if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) { $handle = $block_stylesheet_handle; } } wp_add_inline_style( $handle, $style_properties['inline_style'] ); } } } } function enqueue_editor_block_styles_assets() { $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); $register_script_lines = array( '( function() {' ); foreach ( $block_styles as $block_name => $styles ) { foreach ( $styles as $style_properties ) { $block_style = array( 'name' => $style_properties['name'], 'label' => $style_properties['label'], ); if ( isset( $style_properties['is_default'] ) ) { $block_style['isDefault'] = $style_properties['is_default']; } $register_script_lines[] = sprintf( ' wp.blocks.registerBlockStyle( \'%s\', %s );', $block_name, wp_json_encode( $block_style, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ); } } $register_script_lines[] = '} )();'; $inline_script = implode( "\n", $register_script_lines ); wp_register_script( 'wp-block-styles', false, array( 'wp-blocks' ), true, array( 'in_footer' => true ) ); wp_add_inline_script( 'wp-block-styles', $inline_script ); wp_enqueue_script( 'wp-block-styles' ); } function wp_enqueue_editor_block_directory_assets() { wp_enqueue_script( 'wp-block-directory' ); wp_enqueue_style( 'wp-block-directory' ); } function wp_enqueue_editor_format_library_assets() { wp_enqueue_script( 'wp-format-library' ); wp_enqueue_style( 'wp-format-library' ); } function wp_sanitize_script_attributes( $attributes ) { $html5_script_support = is_admin() || current_theme_supports( 'html5', 'script' ); $attributes_string = ''; foreach ( $attributes as $attribute_name => $attribute_value ) { if ( is_bool( $attribute_value ) ) { if ( $attribute_value ) { $attributes_string .= $html5_script_support ? ' ' . esc_attr( $attribute_name ) : sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_name ) ); } } else { $attributes_string .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } return $attributes_string; } function wp_get_script_tag( $attributes ) { if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { $attributes = array_merge( array( 'type' => 'text/javascript' ), $attributes ); } $attributes = apply_filters( 'wp_script_attributes', $attributes ); return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); } function wp_print_script_tag( $attributes ) { echo wp_get_script_tag( $attributes ); } function wp_get_inline_script_tag( $data, $attributes = array() ) { $is_html5 = current_theme_supports( 'html5', 'script' ) || is_admin(); if ( ! isset( $attributes['type'] ) && ! $is_html5 ) { $attributes = array_merge( array( 'type' => 'text/javascript' ), $attributes ); } if ( ! $is_html5 && ( ! isset( $attributes['type'] ) || 'module' === $attributes['type'] || str_contains( $attributes['type'], 'javascript' ) || str_contains( $attributes['type'], 'ecmascript' ) || str_contains( $attributes['type'], 'jscript' ) || str_contains( $attributes['type'], 'livescript' ) ) ) { $data = str_replace( ']]>', ']]]]><![CDATA[>', $data ); $data = sprintf( "/* <![CDATA[ */\n%s\n/* ]]> */", $data ); } $data = "\n" . trim( $data, "\n\r " ) . "\n"; $attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $data ); return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $data ); } function wp_print_inline_script_tag( $data, $attributes = array() ) { echo wp_get_inline_script_tag( $data, $attributes ); } function wp_maybe_inline_styles() { global $wp_styles; $total_inline_limit = 40000; $total_inline_limit = apply_filters( 'styles_inline_size_limit', $total_inline_limit ); $styles = array(); foreach ( $wp_styles->queue as $handle ) { if ( ! isset( $wp_styles->registered[ $handle ] ) ) { continue; } $src = $wp_styles->registered[ $handle ]->src; $path = $wp_styles->get_data( $handle, 'path' ); if ( $path && $src ) { $size = wp_filesize( $path ); if ( ! $size ) { continue; } $styles[] = array( 'handle' => $handle, 'src' => $src, 'path' => $path, 'size' => $size, ); } } if ( ! empty( $styles ) ) { usort( $styles, static function ( $a, $b ) { return ( $a['size'] <= $b['size'] ) ? -1 : 1; } ); $total_inline_size = 0; foreach ( $styles as $style ) { if ( $total_inline_size + $style['size'] > $total_inline_limit ) { break; } $style['css'] = file_get_contents( $style['path'] ); $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] ); $wp_styles->add_data( $style['handle'], 'inlined_src', $style['src'] ); $wp_styles->registered[ $style['handle'] ]->src = false; if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) { $wp_styles->registered[ $style['handle'] ]->extra['after'] = array(); } array_unshift( $wp_styles->registered[ $style['handle'] ]->extra['after'], $style['css'] ); $total_inline_size += (int) $style['size']; } } } function _wp_normalize_relative_css_links( $css, $stylesheet_url ) { return preg_replace_callback( '#(url\s*\(\s*[\'"]?\s*)([^\'"\)]+)#', static function ( $matches ) use ( $stylesheet_url ) { list( , $prefix, $url ) = $matches; if ( str_starts_with( $url, 'http:' ) || str_starts_with( $url, 'https:' ) || str_starts_with( $url, '/' ) || str_starts_with( $url, '#' ) || str_starts_with( $url, 'data:' ) ) { return $matches[0]; } $absolute_url = dirname( $stylesheet_url ) . '/' . $url; $absolute_url = str_replace( '/./', '/', $absolute_url ); $url = wp_make_link_relative( $absolute_url ); return $prefix . $url; }, $css ); } function wp_enqueue_global_styles_css_custom_properties() { wp_register_style( 'global-styles-css-custom-properties', false ); wp_add_inline_style( 'global-styles-css-custom-properties', wp_get_global_stylesheet( array( 'variables' ) ) ); wp_enqueue_style( 'global-styles-css-custom-properties' ); } function wp_enqueue_block_support_styles( $style, $priority = 10 ) { $action_hook_name = 'wp_footer'; if ( wp_is_block_theme() ) { $action_hook_name = 'wp_head'; } add_action( $action_hook_name, static function () use ( $style ) { echo "<style>$style</style>\n"; }, $priority ); } function wp_enqueue_stored_styles( $options = array() ) { $is_block_theme = wp_is_block_theme(); $is_classic_theme = ! $is_block_theme; if ( ( $is_block_theme && doing_action( 'wp_footer' ) ) || ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) ) ) { return; } $core_styles_keys = array( 'block-supports' ); $compiled_core_stylesheet = ''; $style_tag_id = 'core'; $should_prettify = isset( $options['prettify'] ) ? true === $options['prettify'] : defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG; foreach ( $core_styles_keys as $style_key ) { if ( $should_prettify ) { $compiled_core_stylesheet .= "/**\n * Core styles: $style_key\n */\n"; } $style_tag_id .= '-' . $style_key; $compiled_core_stylesheet .= wp_style_engine_get_stylesheet_from_context( $style_key, $options ); } if ( ! empty( $compiled_core_stylesheet ) ) { wp_register_style( $style_tag_id, false ); wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet ); wp_enqueue_style( $style_tag_id ); } $additional_stores = WP_Style_Engine_CSS_Rules_Store::get_stores(); foreach ( array_keys( $additional_stores ) as $store_name ) { if ( in_array( $store_name, $core_styles_keys, true ) ) { continue; } $styles = wp_style_engine_get_stylesheet_from_context( $store_name, $options ); if ( ! empty( $styles ) ) { $key = "wp-style-engine-$store_name"; wp_register_style( $key, false ); wp_add_inline_style( $key, $styles ); wp_enqueue_style( $key ); } } } function wp_enqueue_block_style( $block_name, $args ) { $args = wp_parse_args( $args, array( 'handle' => '', 'src' => '', 'deps' => array(), 'ver' => false, 'media' => 'all', ) ); $callback = static function ( $content ) use ( $args ) { if ( ! empty( $args['src'] ) ) { wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] ); } if ( isset( $args['path'] ) ) { wp_style_add_data( $args['handle'], 'path', $args['path'] ); $rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] ); if ( file_exists( $rtl_file_path ) ) { wp_style_add_data( $args['handle'], 'rtl', 'replace' ); if ( is_rtl() ) { wp_style_add_data( $args['handle'], 'path', $rtl_file_path ); } } } wp_enqueue_style( $args['handle'] ); return $content; }; $hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts'; if ( wp_should_load_block_assets_on_demand() ) { $callback_separate = static function ( $content, $block ) use ( $block_name, $callback ) { if ( ! empty( $block['blockName'] ) && $block_name === $block['blockName'] ) { return $callback( $content ); } return $content; }; add_filter( 'render_block', $callback_separate, 10, 2 ); return; } add_filter( $hook, $callback ); add_action( 'enqueue_block_assets', $callback ); } function wp_enqueue_classic_theme_styles() { if ( ! wp_theme_has_theme_json() ) { wp_enqueue_style( 'classic-theme-styles' ); } } function wp_enqueue_command_palette_assets() { global $menu, $submenu; $command_palette_settings = array( 'is_network_admin' => is_network_admin(), ); if ( $menu ) { $menu_commands = array(); foreach ( $menu as $menu_item ) { if ( empty( $menu_item[0] ) || ! empty( $menu_item[1] ) && ! current_user_can( $menu_item[1] ) ) { continue; } $menu_label = $menu_item[0]; while ( preg_match( '/<[^>]*>/', $menu_label ) ) { $menu_label = preg_replace( '/<[^>]*>.*?<\/[^>]*>|<[^>]*\/>|<[^>]*>/s', '', $menu_label ); } $menu_label = trim( $menu_label ); $menu_url = ''; $menu_slug = $menu_item[2]; if ( preg_match( '/\.php($|\?)/', $menu_slug ) || wp_http_validate_url( $menu_slug ) ) { $menu_url = $menu_slug; } elseif ( ! empty( menu_page_url( $menu_slug, false ) ) ) { $menu_url = html_entity_decode( menu_page_url( $menu_slug, false ), ENT_QUOTES, get_bloginfo( 'charset' ) ); } if ( $menu_url ) { $menu_commands[] = array( 'label' => $menu_label, 'url' => $menu_url, 'name' => $menu_slug, ); } if ( array_key_exists( $menu_slug, $submenu ) ) { foreach ( $submenu[ $menu_slug ] as $submenu_item ) { if ( empty( $submenu_item[0] ) || ! empty( $submenu_item[1] ) && ! current_user_can( $submenu_item[1] ) ) { continue; } $submenu_label = $submenu_item[0]; while ( preg_match( '/<[^>]*>/', $submenu_label ) ) { $submenu_label = preg_replace( '/<[^>]*>.*?<\/[^>]*>|<[^>]*\/>|<[^>]*>/s', '', $submenu_label ); } $submenu_label = trim( $submenu_label ); $submenu_url = ''; $submenu_slug = $submenu_item[2]; if ( preg_match( '/\.php($|\?)/', $submenu_slug ) || wp_http_validate_url( $submenu_slug ) ) { $submenu_url = $submenu_slug; } elseif ( ! empty( menu_page_url( $submenu_slug, false ) ) ) { $submenu_url = html_entity_decode( menu_page_url( $submenu_slug, false ), ENT_QUOTES, get_bloginfo( 'charset' ) ); } if ( $submenu_url ) { $menu_commands[] = array( 'label' => sprintf( __( '%1$s > %2$s' ), $menu_label, $submenu_label ), 'url' => $submenu_url, 'name' => $menu_slug . '-' . $submenu_item[2], ); } } } } $command_palette_settings['menu_commands'] = $menu_commands; } wp_enqueue_script( 'wp-commands' ); wp_enqueue_style( 'wp-commands' ); wp_enqueue_script( 'wp-core-commands' ); wp_add_inline_script( 'wp-core-commands', sprintf( 'wp.coreCommands.initializeCommandPalette( %s );', wp_json_encode( $command_palette_settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ) ); } function wp_remove_surrounding_empty_script_tags( $contents ) { $contents = trim( $contents ); $opener = '<SCRIPT>'; $closer = '</SCRIPT>'; if ( strlen( $contents ) > strlen( $opener ) + strlen( $closer ) && strtoupper( substr( $contents, 0, strlen( $opener ) ) ) === $opener && strtoupper( substr( $contents, -strlen( $closer ) ) ) === $closer ) { return substr( $contents, strlen( $opener ), -strlen( $closer ) ); } else { $error_message = __( 'Expected string to start with script tag (without attributes) and end with script tag, with optional whitespace.' ); _doing_it_wrong( __FUNCTION__, $error_message, '6.4' ); return sprintf( 'console.error(%s)', wp_json_encode( sprintf( __( 'Function %s used incorrectly in PHP.' ), 'wp_remove_surrounding_empty_script_tags()' ) . ' ' . $error_message ) ); } } function wp_load_classic_theme_block_styles_on_demand() { if ( wp_is_block_theme() ) { return; } add_filter( 'wp_should_output_buffer_template_for_enhancement', '__return_true', 0 ); if ( ! wp_should_output_buffer_template_for_enhancement() ) { return; } add_filter( 'should_load_separate_core_block_assets', '__return_true', 0 ); if ( ! wp_should_load_separate_core_block_assets() ) { return; } add_filter( 'should_load_block_assets_on_demand', '__return_true', 0 ); if ( ! wp_should_load_block_assets_on_demand() ) { return; } add_action( 'wp_template_enhancement_output_buffer_started', 'wp_hoist_late_printed_styles' ); } function wp_hoist_late_printed_styles() { if ( is_embed() ) { return; } $style_handles_at_enqueue_block_assets = array(); add_action( 'enqueue_block_assets', static function () use ( &$style_handles_at_enqueue_block_assets ) { $style_handles_at_enqueue_block_assets = wp_styles()->queue; }, PHP_INT_MIN ); add_action( 'enqueue_block_assets', static function () use ( &$style_handles_at_enqueue_block_assets ) { $style_handles_at_enqueue_block_assets = array_values( array_diff( wp_styles()->queue, $style_handles_at_enqueue_block_assets ) ); }, PHP_INT_MAX ); $placeholder = sprintf( '/*%s*/', uniqid( 'wp_block_styles_on_demand_placeholder:' ) ); add_action( 'wp_print_styles', static function () use ( $placeholder ) { wp_add_inline_style( 'wp-block-library', $placeholder ); } ); $printed_core_block_styles = ''; $printed_other_block_styles = ''; $printed_global_styles = ''; $printed_late_styles = ''; $capture_late_styles = static function () use ( &$printed_core_block_styles, &$printed_other_block_styles, &$printed_global_styles, &$printed_late_styles ) { $all_core_block_style_handles = array(); $all_other_block_style_handles = array(); foreach ( WP_Block_Type_Registry::get_instance()->get_all_registered() as $block_type ) { if ( str_starts_with( $block_type->name, 'core/' ) ) { foreach ( $block_type->style_handles as $style_handle ) { $all_core_block_style_handles[] = $style_handle; } } else { foreach ( $block_type->style_handles as $style_handle ) { $all_other_block_style_handles[] = $style_handle; } } } $enqueued_core_block_styles = array_values( array_intersect( $all_core_block_style_handles, wp_styles()->queue ) ); if ( count( $enqueued_core_block_styles ) > 0 ) { ob_start(); wp_styles()->do_items( $enqueued_core_block_styles ); $printed_core_block_styles = ob_get_clean(); } $enqueued_other_block_styles = array_values( array_intersect( $all_other_block_style_handles, wp_styles()->queue ) ); if ( count( $enqueued_other_block_styles ) > 0 ) { ob_start(); wp_styles()->do_items( $enqueued_other_block_styles ); $printed_other_block_styles = ob_get_clean(); } if ( wp_style_is( 'global-styles' ) ) { ob_start(); wp_styles()->do_items( array( 'global-styles' ) ); $printed_global_styles = ob_get_clean(); } ob_start(); wp_styles()->do_footer_items(); $printed_late_styles = ob_get_clean(); }; $wp_print_footer_scripts_priority = has_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); if ( false === $wp_print_footer_scripts_priority || false === has_action( 'wp_footer', 'wp_print_footer_scripts' ) ) { add_action( 'wp_footer', $capture_late_styles, 20 ); } else { remove_action( 'wp_print_footer_scripts', '_wp_footer_scripts', $wp_print_footer_scripts_priority ); add_action( 'wp_print_footer_scripts', static function () use ( $capture_late_styles ) { $capture_late_styles(); print_footer_scripts(); }, $wp_print_footer_scripts_priority ); } add_filter( 'wp_template_enhancement_output_buffer', static function ( $buffer ) use ( $placeholder, &$style_handles_at_enqueue_block_assets, &$printed_core_block_styles, &$printed_other_block_styles, &$printed_global_styles, &$printed_late_styles ) { $processor = new class( $buffer ) extends WP_HTML_Tag_Processor { private function get_span(): WP_HTML_Span { $this->set_bookmark( 'here' ); return $this->bookmarks['here']; } public function insert_before( string $text ) { $this->lexical_updates[] = new WP_HTML_Text_Replacement( $this->get_span()->start, 0, $text ); } public function insert_after( string $text ) { $span = $this->get_span(); $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $text ); } public function remove() { $span = $this->get_span(); $this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start, $span->length, '' ); } }; while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) { if ( 'STYLE' === $processor->get_tag() && 'wp-block-library-inline-css' === $processor->get_attribute( 'id' ) ) { $processor->set_bookmark( 'wp_block_library' ); } elseif ( 'HEAD' === $processor->get_tag() && $processor->is_tag_closer() ) { $processor->set_bookmark( 'head_end' ); break; } elseif ( ( 'STYLE' === $processor->get_tag() || 'LINK' === $processor->get_tag() ) && $processor->get_attribute( 'id' ) ) { $id = $processor->get_attribute( 'id' ); $handle = null; if ( 'STYLE' === $processor->get_tag() ) { if ( preg_match( '/^(.+)-inline-css$/', $id, $matches ) ) { $handle = $matches[1]; } } elseif ( preg_match( '/^(.+)-css$/', $id, $matches ) ) { $handle = $matches[1]; } if ( 'classic-theme-styles' === $handle ) { $processor->set_bookmark( 'classic_theme_styles' ); } if ( $handle && in_array( $handle, $style_handles_at_enqueue_block_assets, true ) ) { if ( ! $processor->has_bookmark( 'first_style_at_enqueue_block_assets' ) ) { $processor->set_bookmark( 'first_style_at_enqueue_block_assets' ); } $processor->set_bookmark( 'last_style_at_enqueue_block_assets' ); } } } if ( $processor->has_bookmark( 'wp_block_library' ) ) { $processor->seek( 'wp_block_library' ); $css_text = $processor->get_modifiable_text(); $css_text = str_replace( $placeholder, '', $css_text ); if ( preg_match( ':^/\*# sourceURL=\S+? \*/$:', trim( $css_text ) ) ) { $processor->remove(); } else { $processor->set_modifiable_text( $css_text ); } $inserted_after = $printed_core_block_styles; $printed_core_block_styles = ''; if ( ! $processor->has_bookmark( 'classic_theme_styles' ) ) { if ( '' !== $printed_other_block_styles ) { $inserted_after .= $printed_other_block_styles; } $printed_other_block_styles = ''; if ( ! $processor->has_bookmark( 'last_style_at_enqueue_block_assets' ) ) { if ( '' !== $printed_global_styles ) { $inserted_after .= $printed_global_styles; } $printed_global_styles = ''; } } if ( '' !== $inserted_after ) { $processor->insert_after( "\n" . $inserted_after ); } } if ( '' !== $printed_global_styles && $processor->has_bookmark( 'last_style_at_enqueue_block_assets' ) ) { $processor->seek( 'last_style_at_enqueue_block_assets' ); $processor->insert_after( "\n" . $printed_global_styles ); $printed_global_styles = ''; if ( ! $processor->has_bookmark( 'classic_theme_styles' ) && '' !== $printed_other_block_styles ) { $processor->insert_after( "\n" . $printed_other_block_styles ); $printed_other_block_styles = ''; } } if ( '' !== $printed_other_block_styles && $processor->has_bookmark( 'classic_theme_styles' ) ) { $processor->seek( 'classic_theme_styles' ); $processor->insert_after( "\n" . $printed_other_block_styles ); $printed_other_block_styles = ''; } $remaining_styles = $printed_core_block_styles . $printed_other_block_styles . $printed_global_styles . $printed_late_styles; if ( $remaining_styles && $processor->has_bookmark( 'head_end' ) ) { $processor->seek( 'head_end' ); $processor->insert_before( $remaining_styles . "\n" ); } return $processor->get_updated_html(); } ); } function wp_js_dataset_name( string $html_attribute_name ): ?string { if ( 0 !== substr_compare( $html_attribute_name, 'data-', 0, 5, true ) ) { return null; } $end = strlen( $html_attribute_name ); if ( ( $end - 5 ) !== strcspn( $html_attribute_name, "=/> \t\f\r\n", 5 ) ) { return null; } $custom_name = ''; $at = 5; $was_at = $at; while ( $at < $end ) { $next_dash_at = strpos( $html_attribute_name, '-', $at ); if ( false === $next_dash_at || $next_dash_at === $end - 1 ) { break; } $c = $html_attribute_name[ $next_dash_at + 1 ]; if ( ( $c >= 'A' && $c <= 'Z' ) || ( $c >= 'a' && $c <= 'z' ) ) { $prefix = substr( $html_attribute_name, $was_at, $next_dash_at - $was_at ); $custom_name .= strtolower( $prefix ); $custom_name .= strtoupper( $c ); $at = $next_dash_at + 2; $was_at = $at; continue; } $at = $next_dash_at + 1; } return '' === $custom_name ? strtolower( substr( $html_attribute_name, 5 ) ) : ( $custom_name . strtolower( substr( $html_attribute_name, $was_at ) ) ); } function wp_html_custom_data_attribute_name( string $js_dataset_name ): ?string { $end = strlen( $js_dataset_name ); if ( 0 === $end ) { return 'data-'; } if ( strcspn( $js_dataset_name, "=/> \t\f\r\n" ) !== $end ) { return null; } $html_name = 'data-'; $at = 0; $was_at = $at; while ( $at < $end ) { $next_upper_after = strcspn( $js_dataset_name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', $at ); $next_upper_at = $at + $next_upper_after; if ( $next_upper_at >= $end ) { break; } $prefix = substr( $js_dataset_name, $was_at, $next_upper_at - $was_at ); $html_name .= strtolower( $prefix ); $html_name .= '-' . strtolower( $js_dataset_name[ $next_upper_at ] ); $at = $next_upper_at + 1; $was_at = $at; } if ( $was_at < $end ) { $html_name .= strtolower( substr( $js_dataset_name, $was_at ) ); } return $html_name; }
###require ABSPATH . WPINC . '/taxonomy.php';
function create_initial_taxonomies() { global $wp_rewrite; WP_Taxonomy::reset_default_labels(); if ( ! did_action( 'init' ) ) { $rewrite = array( 'category' => false, 'post_tag' => false, 'post_format' => false, ); } else { $post_format_base = apply_filters( 'post_format_rewrite_base', 'type' ); $rewrite = array( 'category' => array( 'hierarchical' => true, 'slug' => get_option( 'category_base' ) ? get_option( 'category_base' ) : 'category', 'with_front' => ! get_option( 'category_base' ) || $wp_rewrite->using_index_permalinks(), 'ep_mask' => EP_CATEGORIES, ), 'post_tag' => array( 'hierarchical' => false, 'slug' => get_option( 'tag_base' ) ? get_option( 'tag_base' ) : 'tag', 'with_front' => ! get_option( 'tag_base' ) || $wp_rewrite->using_index_permalinks(), 'ep_mask' => EP_TAGS, ), 'post_format' => $post_format_base ? array( 'slug' => $post_format_base ) : false, ); } register_taxonomy( 'category', 'post', array( 'hierarchical' => true, 'query_var' => 'category_name', 'rewrite' => $rewrite['category'], 'public' => true, 'show_ui' => true, 'show_admin_column' => true, '_builtin' => true, 'capabilities' => array( 'manage_terms' => 'manage_categories', 'edit_terms' => 'edit_categories', 'delete_terms' => 'delete_categories', 'assign_terms' => 'assign_categories', ), 'show_in_rest' => true, 'rest_base' => 'categories', 'rest_controller_class' => 'WP_REST_Terms_Controller', ) ); register_taxonomy( 'post_tag', 'post', array( 'hierarchical' => false, 'query_var' => 'tag', 'rewrite' => $rewrite['post_tag'], 'public' => true, 'show_ui' => true, 'show_admin_column' => true, '_builtin' => true, 'capabilities' => array( 'manage_terms' => 'manage_post_tags', 'edit_terms' => 'edit_post_tags', 'delete_terms' => 'delete_post_tags', 'assign_terms' => 'assign_post_tags', ), 'show_in_rest' => true, 'rest_base' => 'tags', 'rest_controller_class' => 'WP_REST_Terms_Controller', ) ); register_taxonomy( 'nav_menu', 'nav_menu_item', array( 'public' => false, 'hierarchical' => false, 'labels' => array( 'name' => __( 'Navigation Menus' ), 'singular_name' => __( 'Navigation Menu' ), ), 'query_var' => false, 'rewrite' => false, 'show_ui' => false, '_builtin' => true, 'show_in_nav_menus' => false, 'capabilities' => array( 'manage_terms' => 'edit_theme_options', 'edit_terms' => 'edit_theme_options', 'delete_terms' => 'edit_theme_options', 'assign_terms' => 'edit_theme_options', ), 'show_in_rest' => true, 'rest_base' => 'menus', 'rest_controller_class' => 'WP_REST_Menus_Controller', ) ); register_taxonomy( 'link_category', 'link', array( 'hierarchical' => false, 'labels' => array( 'name' => __( 'Link Categories' ), 'singular_name' => __( 'Link Category' ), 'search_items' => __( 'Search Link Categories' ), 'popular_items' => null, 'all_items' => __( 'All Link Categories' ), 'edit_item' => __( 'Edit Link Category' ), 'update_item' => __( 'Update Link Category' ), 'add_new_item' => __( 'Add Link Category' ), 'new_item_name' => __( 'New Link Category Name' ), 'separate_items_with_commas' => null, 'add_or_remove_items' => null, 'choose_from_most_used' => null, 'back_to_items' => __( '← Go to Link Categories' ), ), 'capabilities' => array( 'manage_terms' => 'manage_links', 'edit_terms' => 'manage_links', 'delete_terms' => 'manage_links', 'assign_terms' => 'manage_links', ), 'query_var' => false, 'rewrite' => false, 'public' => false, 'show_ui' => true, '_builtin' => true, ) ); register_taxonomy( 'post_format', 'post', array( 'public' => true, 'hierarchical' => false, 'labels' => array( 'name' => _x( 'Formats', 'post format' ), 'singular_name' => _x( 'Format', 'post format' ), ), 'query_var' => true, 'rewrite' => $rewrite['post_format'], 'show_ui' => false, '_builtin' => true, 'show_in_nav_menus' => current_theme_supports( 'post-formats' ), ) ); register_taxonomy( 'wp_theme', array( 'wp_template', 'wp_template_part', 'wp_global_styles' ), array( 'public' => false, 'hierarchical' => false, 'labels' => array( 'name' => __( 'Themes' ), 'singular_name' => __( 'Theme' ), ), 'query_var' => false, 'rewrite' => false, 'show_ui' => false, '_builtin' => true, 'show_in_nav_menus' => false, 'show_in_rest' => false, ) ); register_taxonomy( 'wp_template_part_area', array( 'wp_template_part' ), array( 'public' => false, 'hierarchical' => false, 'labels' => array( 'name' => __( 'Template Part Areas' ), 'singular_name' => __( 'Template Part Area' ), ), 'query_var' => false, 'rewrite' => false, 'show_ui' => false, '_builtin' => true, 'show_in_nav_menus' => false, 'show_in_rest' => false, ) ); register_taxonomy( 'wp_pattern_category', array( 'wp_block' ), array( 'public' => false, 'publicly_queryable' => false, 'hierarchical' => false, 'labels' => array( 'name' => _x( 'Pattern Categories', 'taxonomy general name' ), 'singular_name' => _x( 'Pattern Category', 'taxonomy singular name' ), 'add_new_item' => __( 'Add Category' ), 'add_or_remove_items' => __( 'Add or remove pattern categories' ), 'back_to_items' => __( '← Go to Pattern Categories' ), 'choose_from_most_used' => __( 'Choose from the most used pattern categories' ), 'edit_item' => __( 'Edit Pattern Category' ), 'item_link' => __( 'Pattern Category Link' ), 'item_link_description' => __( 'A link to a pattern category.' ), 'items_list' => __( 'Pattern Categories list' ), 'items_list_navigation' => __( 'Pattern Categories list navigation' ), 'new_item_name' => __( 'New Pattern Category Name' ), 'no_terms' => __( 'No pattern categories' ), 'not_found' => __( 'No pattern categories found.' ), 'popular_items' => __( 'Popular Pattern Categories' ), 'search_items' => __( 'Search Pattern Categories' ), 'separate_items_with_commas' => __( 'Separate pattern categories with commas' ), 'update_item' => __( 'Update Pattern Category' ), 'view_item' => __( 'View Pattern Category' ), ), 'query_var' => false, 'rewrite' => false, 'show_ui' => true, '_builtin' => true, 'show_in_nav_menus' => false, 'show_in_rest' => true, 'show_admin_column' => true, 'show_tagcloud' => false, ) ); } function get_taxonomies( $args = array(), $output = 'names', $operator = 'and' ) { global $wp_taxonomies; $field = ( 'names' === $output ) ? 'name' : false; return wp_filter_object_list( $wp_taxonomies, $args, $operator, $field ); } function get_object_taxonomies( $object_type, $output = 'names' ) { global $wp_taxonomies; if ( is_object( $object_type ) ) { if ( 'attachment' === $object_type->post_type ) { return get_attachment_taxonomies( $object_type, $output ); } $object_type = $object_type->post_type; } $object_type = (array) $object_type; $taxonomies = array(); foreach ( (array) $wp_taxonomies as $tax_name => $tax_obj ) { if ( array_intersect( $object_type, (array) $tax_obj->object_type ) ) { if ( 'names' === $output ) { $taxonomies[] = $tax_name; } else { $taxonomies[ $tax_name ] = $tax_obj; } } } return $taxonomies; } function get_taxonomy( $taxonomy ) { global $wp_taxonomies; if ( ! taxonomy_exists( $taxonomy ) ) { return false; } return $wp_taxonomies[ $taxonomy ]; } function taxonomy_exists( $taxonomy ) { global $wp_taxonomies; return is_string( $taxonomy ) && isset( $wp_taxonomies[ $taxonomy ] ); } function is_taxonomy_hierarchical( $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return false; } $taxonomy = get_taxonomy( $taxonomy ); return $taxonomy->hierarchical; } function register_taxonomy( $taxonomy, $object_type, $args = array() ) { global $wp_taxonomies; if ( ! is_array( $wp_taxonomies ) ) { $wp_taxonomies = array(); } $args = wp_parse_args( $args ); if ( empty( $taxonomy ) || strlen( $taxonomy ) > 32 ) { _doing_it_wrong( __FUNCTION__, __( 'Taxonomy names must be between 1 and 32 characters in length.' ), '4.2.0' ); return new WP_Error( 'taxonomy_length_invalid', __( 'Taxonomy names must be between 1 and 32 characters in length.' ) ); } $taxonomy_object = new WP_Taxonomy( $taxonomy, $object_type, $args ); $taxonomy_object->add_rewrite_rules(); $wp_taxonomies[ $taxonomy ] = $taxonomy_object; $taxonomy_object->add_hooks(); if ( ! empty( $taxonomy_object->default_term ) ) { $term = term_exists( $taxonomy_object->default_term['name'], $taxonomy ); if ( $term ) { update_option( 'default_term_' . $taxonomy_object->name, $term['term_id'] ); } else { $term = wp_insert_term( $taxonomy_object->default_term['name'], $taxonomy, array( 'slug' => sanitize_title( $taxonomy_object->default_term['slug'] ), 'description' => $taxonomy_object->default_term['description'], ) ); if ( ! is_wp_error( $term ) ) { update_option( 'default_term_' . $taxonomy_object->name, $term['term_id'] ); } } } do_action( 'registered_taxonomy', $taxonomy, $object_type, (array) $taxonomy_object ); do_action( "registered_taxonomy_{$taxonomy}", $taxonomy, $object_type, (array) $taxonomy_object ); return $taxonomy_object; } function unregister_taxonomy( $taxonomy ) { global $wp_taxonomies; if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } $taxonomy_object = get_taxonomy( $taxonomy ); if ( $taxonomy_object->_builtin ) { return new WP_Error( 'invalid_taxonomy', __( 'Unregistering a built-in taxonomy is not allowed.' ) ); } $taxonomy_object->remove_rewrite_rules(); $taxonomy_object->remove_hooks(); unset( $wp_taxonomies[ $taxonomy ] ); do_action( 'unregistered_taxonomy', $taxonomy ); return true; } function get_taxonomy_labels( $tax ) { $tax->labels = (array) $tax->labels; if ( isset( $tax->helps ) && empty( $tax->labels['separate_items_with_commas'] ) ) { $tax->labels['separate_items_with_commas'] = $tax->helps; } if ( isset( $tax->no_tagcloud ) && empty( $tax->labels['not_found'] ) ) { $tax->labels['not_found'] = $tax->no_tagcloud; } $nohier_vs_hier_defaults = WP_Taxonomy::get_default_labels(); $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name']; $labels = _get_custom_object_labels( $tax, $nohier_vs_hier_defaults ); if ( ! isset( $tax->labels->template_name ) && isset( $labels->singular_name ) ) { $labels->template_name = sprintf( _x( '%s Archives', 'taxonomy template name' ), $labels->singular_name ); } $taxonomy = $tax->name; $default_labels = clone $labels; $labels = apply_filters( "taxonomy_labels_{$taxonomy}", $labels ); $labels = (object) array_merge( (array) $default_labels, (array) $labels ); return $labels; } function register_taxonomy_for_object_type( $taxonomy, $object_type ) { global $wp_taxonomies; if ( ! isset( $wp_taxonomies[ $taxonomy ] ) ) { return false; } if ( ! get_post_type_object( $object_type ) ) { return false; } if ( ! in_array( $object_type, $wp_taxonomies[ $taxonomy ]->object_type, true ) ) { $wp_taxonomies[ $taxonomy ]->object_type[] = $object_type; } $wp_taxonomies[ $taxonomy ]->object_type = array_filter( $wp_taxonomies[ $taxonomy ]->object_type ); do_action( 'registered_taxonomy_for_object_type', $taxonomy, $object_type ); return true; } function unregister_taxonomy_for_object_type( $taxonomy, $object_type ) { global $wp_taxonomies; if ( ! isset( $wp_taxonomies[ $taxonomy ] ) ) { return false; } if ( ! get_post_type_object( $object_type ) ) { return false; } $key = array_search( $object_type, $wp_taxonomies[ $taxonomy ]->object_type, true ); if ( false === $key ) { return false; } unset( $wp_taxonomies[ $taxonomy ]->object_type[ $key ] ); do_action( 'unregistered_taxonomy_for_object_type', $taxonomy, $object_type ); return true; } function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) { global $wpdb; if ( ! is_array( $term_ids ) ) { $term_ids = array( $term_ids ); } if ( ! is_array( $taxonomies ) ) { $taxonomies = array( $taxonomies ); } foreach ( (array) $taxonomies as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } } $defaults = array( 'order' => 'ASC' ); $args = wp_parse_args( $args, $defaults ); $order = ( 'desc' === strtolower( $args['order'] ) ) ? 'DESC' : 'ASC'; $term_ids = array_map( 'intval', $term_ids ); $taxonomies = "'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "'"; $term_ids = "'" . implode( "', '", $term_ids ) . "'"; $sql = "SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($term_ids) ORDER BY tr.object_id $order"; $last_changed = wp_cache_get_last_changed( 'terms' ); $cache_key = 'get_objects_in_term:' . md5( $sql ); $cache = wp_cache_get_salted( $cache_key, 'term-queries', $last_changed ); if ( false === $cache ) { $object_ids = $wpdb->get_col( $sql ); wp_cache_set_salted( $cache_key, $object_ids, 'term-queries', $last_changed ); } else { $object_ids = (array) $cache; } if ( ! $object_ids ) { return array(); } return $object_ids; } function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) { $tax_query_obj = new WP_Tax_Query( $tax_query ); return $tax_query_obj->get_sql( $primary_table, $primary_id_column ); } function get_term( $term, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) { if ( empty( $term ) ) { return new WP_Error( 'invalid_term', __( 'Empty Term.' ) ); } if ( $taxonomy && ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } if ( $term instanceof WP_Term ) { $_term = $term; } elseif ( is_object( $term ) ) { if ( empty( $term->filter ) || 'raw' === $term->filter ) { $_term = sanitize_term( $term, $taxonomy, 'raw' ); $_term = new WP_Term( $_term ); } else { $_term = WP_Term::get_instance( $term->term_id ); } } else { $_term = WP_Term::get_instance( $term, $taxonomy ); } if ( is_wp_error( $_term ) ) { return $_term; } elseif ( ! $_term ) { return null; } $taxonomy = $_term->taxonomy; $old_term = $_term; $_term = apply_filters( 'get_term', $_term, $taxonomy ); $_term = apply_filters( "get_{$taxonomy}", $_term, $taxonomy ); if ( ! ( $_term instanceof WP_Term ) ) { return $_term; } if ( $_term !== $old_term || $_term->filter !== $filter ) { $_term->filter( $filter ); } if ( ARRAY_A === $output ) { return $_term->to_array(); } elseif ( ARRAY_N === $output ) { return array_values( $_term->to_array() ); } return $_term; } function get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) { if ( 'term_taxonomy_id' !== $field && ! taxonomy_exists( $taxonomy ) ) { return false; } if ( 'slug' === $field || 'name' === $field ) { $value = (string) $value; if ( 0 === strlen( $value ) ) { return false; } } if ( 'id' === $field || 'ID' === $field || 'term_id' === $field ) { $term = get_term( (int) $value, $taxonomy, $output, $filter ); if ( is_wp_error( $term ) || null === $term ) { $term = false; } return $term; } $args = array( 'get' => 'all', 'number' => 1, 'taxonomy' => $taxonomy, 'update_term_meta_cache' => false, 'orderby' => 'none', 'suppress_filter' => true, ); switch ( $field ) { case 'slug': $args['slug'] = $value; break; case 'name': $args['name'] = $value; break; case 'term_taxonomy_id': $args['term_taxonomy_id'] = $value; unset( $args['taxonomy'] ); break; default: return false; } $terms = get_terms( $args ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return false; } $term = array_shift( $terms ); if ( 'term_taxonomy_id' === $field ) { $taxonomy = $term->taxonomy; } return get_term( $term, $taxonomy, $output, $filter ); } function get_term_children( $term_id, $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } $term_id = (int) $term_id; $terms = _get_term_hierarchy( $taxonomy ); if ( ! isset( $terms[ $term_id ] ) ) { return array(); } $children = $terms[ $term_id ]; foreach ( (array) $terms[ $term_id ] as $child ) { if ( $term_id === $child ) { continue; } if ( isset( $terms[ $child ] ) ) { $children = array_merge( $children, get_term_children( $child, $taxonomy ) ); } } return $children; } function get_term_field( $field, $term, $taxonomy = '', $context = 'display' ) { $term = get_term( $term, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } if ( ! is_object( $term ) ) { return ''; } if ( ! isset( $term->$field ) ) { return ''; } return sanitize_term_field( $field, $term->$field, $term->term_id, $term->taxonomy, $context ); } function get_term_to_edit( $id, $taxonomy ) { $term = get_term( $id, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } if ( ! is_object( $term ) ) { return ''; } return sanitize_term( $term, $taxonomy, 'edit' ); } function get_terms( $args = array(), $deprecated = '' ) { $term_query = new WP_Term_Query(); $defaults = array( 'suppress_filter' => false, ); $_args = wp_parse_args( $args ); $key_intersect = array_intersect_key( $term_query->query_var_defaults, (array) $_args ); $do_legacy_args = $deprecated || empty( $key_intersect ); if ( $do_legacy_args ) { $taxonomies = (array) $args; $args = wp_parse_args( $deprecated, $defaults ); $args['taxonomy'] = $taxonomies; } else { $args = wp_parse_args( $args, $defaults ); if ( isset( $args['taxonomy'] ) ) { $args['taxonomy'] = (array) $args['taxonomy']; } } if ( ! empty( $args['taxonomy'] ) ) { foreach ( $args['taxonomy'] as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } } } $suppress_filter = $args['suppress_filter']; unset( $args['suppress_filter'] ); $terms = $term_query->query( $args ); if ( ! is_array( $terms ) ) { return $terms; } if ( $suppress_filter ) { return $terms; } return apply_filters( 'get_terms', $terms, $term_query->query_vars['taxonomy'], $term_query->query_vars, $term_query ); } function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) { if ( wp_term_is_shared( $term_id ) ) { return new WP_Error( 'ambiguous_term_id', __( 'Term meta cannot be added to terms that are shared between taxonomies.' ), $term_id ); } return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique ); } function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) { return delete_metadata( 'term', $term_id, $meta_key, $meta_value ); } function get_term_meta( $term_id, $key = '', $single = false ) { return get_metadata( 'term', $term_id, $key, $single ); } function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) { if ( wp_term_is_shared( $term_id ) ) { return new WP_Error( 'ambiguous_term_id', __( 'Term meta cannot be added to terms that are shared between taxonomies.' ), $term_id ); } return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value ); } function update_termmeta_cache( $term_ids ) { return update_meta_cache( 'term', $term_ids ); } function wp_lazyload_term_meta( array $term_ids ) { if ( empty( $term_ids ) ) { return; } $lazyloader = wp_metadata_lazyloader(); $lazyloader->queue_objects( 'term', $term_ids ); } function has_term_meta( $term_id ) { $check = wp_check_term_meta_support_prefilter( null ); if ( null !== $check ) { return $check; } global $wpdb; return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, term_id FROM $wpdb->termmeta WHERE term_id = %d ORDER BY meta_key,meta_id", $term_id ), ARRAY_A ); } function register_term_meta( $taxonomy, $meta_key, array $args ) { $args['object_subtype'] = $taxonomy; return register_meta( 'term', $meta_key, $args ); } function unregister_term_meta( $taxonomy, $meta_key ) { return unregister_meta_key( 'term', $meta_key, $taxonomy ); } function term_exists( $term, $taxonomy = '', $parent_term = null ) { global $_wp_suspend_cache_invalidation; if ( null === $term ) { return null; } $defaults = array( 'get' => 'all', 'fields' => 'ids', 'number' => 1, 'update_term_meta_cache' => false, 'order' => 'ASC', 'orderby' => 'term_id', 'suppress_filter' => true, ); if ( ! empty( $_wp_suspend_cache_invalidation ) ) { $defaults['cache_results'] = false; } if ( ! empty( $taxonomy ) ) { $defaults['taxonomy'] = $taxonomy; $defaults['fields'] = 'all'; } $defaults = apply_filters( 'term_exists_default_query_args', $defaults, $term, $taxonomy, $parent_term ); if ( ! empty( $taxonomy ) && is_numeric( $parent_term ) ) { $defaults['parent'] = (int) $parent_term; } if ( is_int( $term ) ) { if ( 0 === $term ) { return 0; } $args = wp_parse_args( array( 'include' => array( $term ) ), $defaults ); $terms = get_terms( $args ); } else { $term = trim( wp_unslash( $term ) ); if ( '' === $term ) { return null; } $args = wp_parse_args( array( 'slug' => sanitize_title( $term ) ), $defaults ); $terms = get_terms( $args ); if ( empty( $terms ) || is_wp_error( $terms ) ) { $args = wp_parse_args( array( 'name' => $term ), $defaults ); $terms = get_terms( $args ); } } if ( empty( $terms ) || is_wp_error( $terms ) ) { return null; } $_term = array_shift( $terms ); if ( ! empty( $taxonomy ) ) { return array( 'term_id' => (string) $_term->term_id, 'term_taxonomy_id' => (string) $_term->term_taxonomy_id, ); } return (string) $_term; } function term_is_ancestor_of( $term1, $term2, $taxonomy ) { if ( ! isset( $term1->term_id ) ) { $term1 = get_term( $term1, $taxonomy ); } if ( ! isset( $term2->parent ) ) { $term2 = get_term( $term2, $taxonomy ); } if ( empty( $term1->term_id ) || empty( $term2->parent ) ) { return false; } if ( $term2->parent === $term1->term_id ) { return true; } return term_is_ancestor_of( $term1, get_term( $term2->parent, $taxonomy ), $taxonomy ); } function sanitize_term( $term, $taxonomy, $context = 'display' ) { $fields = array( 'term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group', 'term_taxonomy_id', 'object_id' ); $do_object = is_object( $term ); $term_id = $do_object ? $term->term_id : ( isset( $term['term_id'] ) ? $term['term_id'] : 0 ); foreach ( (array) $fields as $field ) { if ( $do_object ) { if ( isset( $term->$field ) ) { $term->$field = sanitize_term_field( $field, $term->$field, $term_id, $taxonomy, $context ); } } else { if ( isset( $term[ $field ] ) ) { $term[ $field ] = sanitize_term_field( $field, $term[ $field ], $term_id, $taxonomy, $context ); } } } if ( $do_object ) { $term->filter = $context; } else { $term['filter'] = $context; } return $term; } function sanitize_term_field( $field, $value, $term_id, $taxonomy, $context ) { $int_fields = array( 'parent', 'term_id', 'count', 'term_group', 'term_taxonomy_id', 'object_id' ); if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; if ( $value < 0 ) { $value = 0; } } $context = strtolower( $context ); if ( 'raw' === $context ) { return $value; } if ( 'edit' === $context ) { $value = apply_filters( "edit_term_{$field}", $value, $term_id, $taxonomy ); $value = apply_filters( "edit_{$taxonomy}_{$field}", $value, $term_id ); if ( 'description' === $field ) { $value = esc_html( $value ); } else { $value = esc_attr( $value ); } } elseif ( 'db' === $context ) { $value = apply_filters( "pre_term_{$field}", $value, $taxonomy ); $value = apply_filters( "pre_{$taxonomy}_{$field}", $value ); if ( 'slug' === $field ) { $value = apply_filters( 'pre_category_nicename', $value ); } } elseif ( 'rss' === $context ) { $value = apply_filters( "term_{$field}_rss", $value, $taxonomy ); $value = apply_filters( "{$taxonomy}_{$field}_rss", $value ); } else { $value = apply_filters( "term_{$field}", $value, $term_id, $taxonomy, $context ); $value = apply_filters( "{$taxonomy}_{$field}", $value, $term_id, $context ); } if ( 'attribute' === $context ) { $value = esc_attr( $value ); } elseif ( 'js' === $context ) { $value = esc_js( $value ); } if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } return $value; } function wp_count_terms( $args = array(), $deprecated = '' ) { $use_legacy_args = false; if ( $args && ( is_string( $args ) && taxonomy_exists( $args ) || is_array( $args ) && wp_is_numeric_array( $args ) ) ) { $use_legacy_args = true; } $defaults = array( 'hide_empty' => false ); if ( $use_legacy_args ) { $defaults['taxonomy'] = $args; $args = $deprecated; } $args = wp_parse_args( $args, $defaults ); if ( isset( $args['ignore_empty'] ) ) { $args['hide_empty'] = $args['ignore_empty']; unset( $args['ignore_empty'] ); } $args['fields'] = 'count'; return get_terms( $args ); } function wp_delete_object_term_relationships( $object_id, $taxonomies ) { $object_id = (int) $object_id; if ( ! is_array( $taxonomies ) ) { $taxonomies = array( $taxonomies ); } foreach ( (array) $taxonomies as $taxonomy ) { $term_ids = wp_get_object_terms( $object_id, $taxonomy, array( 'fields' => 'ids' ) ); $term_ids = array_map( 'intval', $term_ids ); wp_remove_object_terms( $object_id, $term_ids, $taxonomy ); } } function wp_delete_term( $term, $taxonomy, $args = array() ) { global $wpdb; $term = (int) $term; $ids = term_exists( $term, $taxonomy ); if ( ! $ids ) { return false; } if ( is_wp_error( $ids ) ) { return $ids; } $tt_id = $ids['term_taxonomy_id']; $defaults = array(); if ( 'category' === $taxonomy ) { $defaults['default'] = (int) get_option( 'default_category' ); if ( $defaults['default'] === $term ) { return 0; } } $taxonomy_object = get_taxonomy( $taxonomy ); if ( ! empty( $taxonomy_object->default_term ) ) { $defaults['default'] = (int) get_option( 'default_term_' . $taxonomy ); if ( $defaults['default'] === $term ) { return 0; } } $args = wp_parse_args( $args, $defaults ); if ( isset( $args['default'] ) ) { $default = (int) $args['default']; if ( ! term_exists( $default, $taxonomy ) ) { unset( $default ); } } if ( isset( $args['force_default'] ) ) { $force_default = $args['force_default']; } do_action( 'pre_delete_term', $term, $taxonomy ); if ( is_taxonomy_hierarchical( $taxonomy ) ) { $term_obj = get_term( $term, $taxonomy ); if ( is_wp_error( $term_obj ) ) { return $term_obj; } $parent = $term_obj->parent; $edit_ids = $wpdb->get_results( "SELECT term_id, term_taxonomy_id FROM $wpdb->term_taxonomy WHERE `parent` = " . (int) $term_obj->term_id ); $edit_tt_ids = wp_list_pluck( $edit_ids, 'term_taxonomy_id' ); do_action( 'edit_term_taxonomies', $edit_tt_ids ); $wpdb->update( $wpdb->term_taxonomy, compact( 'parent' ), array( 'parent' => $term_obj->term_id ) + compact( 'taxonomy' ) ); $edit_term_ids = wp_list_pluck( $edit_ids, 'term_id' ); clean_term_cache( $edit_term_ids, $taxonomy ); do_action( 'edited_term_taxonomies', $edit_tt_ids ); } $deleted_term = get_term( $term, $taxonomy ); $object_ids = (array) $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) ); foreach ( $object_ids as $object_id ) { if ( ! isset( $default ) ) { wp_remove_object_terms( $object_id, $term, $taxonomy ); continue; } $terms = wp_get_object_terms( $object_id, $taxonomy, array( 'fields' => 'ids', 'orderby' => 'none', ) ); if ( 1 === count( $terms ) ) { $terms = array( $default ); } else { $terms = array_diff( $terms, array( $term ) ); if ( isset( $force_default ) && $force_default ) { $terms = array_merge( $terms, array( $default ) ); } } $terms = array_map( 'intval', $terms ); wp_set_object_terms( $object_id, $terms, $taxonomy ); } $tax_object = get_taxonomy( $taxonomy ); foreach ( $tax_object->object_type as $object_type ) { clean_object_term_cache( $object_ids, $object_type ); } $term_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->termmeta WHERE term_id = %d ", $term ) ); foreach ( $term_meta_ids as $mid ) { delete_metadata_by_mid( 'term', $mid ); } do_action( 'delete_term_taxonomy', $tt_id ); $wpdb->delete( $wpdb->term_taxonomy, array( 'term_taxonomy_id' => $tt_id ) ); do_action( 'deleted_term_taxonomy', $tt_id ); if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = %d", $term ) ) ) { $wpdb->delete( $wpdb->terms, array( 'term_id' => $term ) ); } clean_term_cache( $term, $taxonomy ); do_action( 'delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids ); do_action( "delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids ); return true; } function wp_delete_category( $cat_id ) { return wp_delete_term( $cat_id, 'category' ); } function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { if ( empty( $object_ids ) || empty( $taxonomies ) ) { return array(); } if ( ! is_array( $taxonomies ) ) { $taxonomies = array( $taxonomies ); } foreach ( $taxonomies as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } } if ( ! is_array( $object_ids ) ) { $object_ids = array( $object_ids ); } $object_ids = array_map( 'intval', $object_ids ); $defaults = array( 'update_term_meta_cache' => false, ); $args = wp_parse_args( $args, $defaults ); $args = apply_filters( 'wp_get_object_terms_args', $args, $object_ids, $taxonomies ); $terms = array(); if ( count( $taxonomies ) > 1 ) { foreach ( $taxonomies as $index => $taxonomy ) { $t = get_taxonomy( $taxonomy ); if ( isset( $t->args ) && is_array( $t->args ) && array_merge( $args, $t->args ) != $args ) { unset( $taxonomies[ $index ] ); $terms = array_merge( $terms, wp_get_object_terms( $object_ids, $taxonomy, array_merge( $args, $t->args ) ) ); } } } else { $t = get_taxonomy( $taxonomies[0] ); if ( isset( $t->args ) && is_array( $t->args ) ) { $args = array_merge( $args, $t->args ); } } $args['taxonomy'] = $taxonomies; $args['object_ids'] = $object_ids; if ( ! empty( $taxonomies ) ) { $terms_from_remaining_taxonomies = get_terms( $args ); if ( ! empty( $args['fields'] ) && str_starts_with( $args['fields'], 'id=>' ) ) { $terms = $terms + $terms_from_remaining_taxonomies; } else { $terms = array_merge( $terms, $terms_from_remaining_taxonomies ); } } $terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args ); $object_ids = implode( ',', $object_ids ); $taxonomies = "'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "'"; return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args ); } function wp_insert_term( $term, $taxonomy, $args = array() ) { global $wpdb; if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } $term = apply_filters( 'pre_insert_term', $term, $taxonomy, $args ); if ( is_wp_error( $term ) ) { return $term; } if ( is_int( $term ) && 0 === $term ) { return new WP_Error( 'invalid_term_id', __( 'Invalid term ID.' ) ); } if ( '' === trim( $term ) ) { return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) ); } $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '', ); $args = wp_parse_args( $args, $defaults ); if ( (int) $args['parent'] > 0 && ! term_exists( (int) $args['parent'] ) ) { return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) ); } $args['name'] = $term; $args['taxonomy'] = $taxonomy; $args['description'] = (string) $args['description']; $args = sanitize_term( $args, $taxonomy, 'db' ); $name = wp_unslash( $args['name'] ); $description = wp_unslash( $args['description'] ); $parent = (int) $args['parent']; if ( '' === $name ) { return new WP_Error( 'invalid_term_name', __( 'Invalid term name.' ) ); } $slug_provided = ! empty( $args['slug'] ); if ( ! $slug_provided ) { $slug = sanitize_title( $name ); } else { $slug = $args['slug']; } $term_group = 0; if ( $args['alias_of'] ) { $alias = get_term_by( 'slug', $args['alias_of'], $taxonomy ); if ( ! empty( $alias->term_group ) ) { $term_group = $alias->term_group; } elseif ( ! empty( $alias->term_id ) ) { $term_group = $wpdb->get_var( "SELECT MAX(term_group) FROM $wpdb->terms" ) + 1; wp_update_term( $alias->term_id, $taxonomy, array( 'term_group' => $term_group, ) ); } } $name_matches = get_terms( array( 'taxonomy' => $taxonomy, 'name' => $name, 'hide_empty' => false, 'parent' => $args['parent'], 'update_term_meta_cache' => false, ) ); $name_match = null; if ( $name_matches ) { foreach ( $name_matches as $_match ) { if ( strtolower( $name ) === strtolower( $_match->name ) ) { $name_match = $_match; break; } } } if ( $name_match ) { $slug_match = get_term_by( 'slug', $slug, $taxonomy ); if ( ! $slug_provided || $name_match->slug === $slug || $slug_match ) { if ( is_taxonomy_hierarchical( $taxonomy ) ) { $siblings = get_terms( array( 'taxonomy' => $taxonomy, 'get' => 'all', 'parent' => $parent, 'update_term_meta_cache' => false, ) ); $existing_term = null; $sibling_names = wp_list_pluck( $siblings, 'name' ); $sibling_slugs = wp_list_pluck( $siblings, 'slug' ); if ( ( ! $slug_provided || $name_match->slug === $slug ) && in_array( $name, $sibling_names, true ) ) { $existing_term = $name_match; } elseif ( $slug_match && in_array( $slug, $sibling_slugs, true ) ) { $existing_term = $slug_match; } if ( $existing_term ) { return new WP_Error( 'term_exists', __( 'A term with the name provided already exists with this parent.' ), $existing_term->term_id ); } } else { return new WP_Error( 'term_exists', __( 'A term with the name provided already exists in this taxonomy.' ), $name_match->term_id ); } } } $slug = wp_unique_term_slug( $slug, (object) $args ); $data = compact( 'name', 'slug', 'term_group' ); $data = apply_filters( 'wp_insert_term_data', $data, $taxonomy, $args ); if ( false === $wpdb->insert( $wpdb->terms, $data ) ) { return new WP_Error( 'db_insert_error', __( 'Could not insert term into the database.' ), $wpdb->last_error ); } $term_id = (int) $wpdb->insert_id; if ( empty( $slug ) ) { $slug = sanitize_title( $slug, $term_id ); do_action( 'edit_terms', $term_id, $taxonomy ); $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); do_action( 'edited_terms', $term_id, $taxonomy ); } $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); if ( ! empty( $tt_id ) ) { return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id, ); } if ( false === $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ) + array( 'count' => 0 ) ) ) { return new WP_Error( 'db_insert_error', __( 'Could not insert term taxonomy into the database.' ), $wpdb->last_error ); } $tt_id = (int) $wpdb->insert_id; $duplicate_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.term_id, t.slug, tt.term_taxonomy_id, tt.taxonomy FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON ( tt.term_id = t.term_id ) WHERE t.slug = %s AND tt.parent = %d AND tt.taxonomy = %s AND t.term_id < %d AND tt.term_taxonomy_id != %d", $slug, $parent, $taxonomy, $term_id, $tt_id ) ); $duplicate_term = apply_filters( 'wp_insert_term_duplicate_term_check', $duplicate_term, $term, $taxonomy, $args, $tt_id ); if ( $duplicate_term ) { $wpdb->delete( $wpdb->terms, array( 'term_id' => $term_id ) ); $wpdb->delete( $wpdb->term_taxonomy, array( 'term_taxonomy_id' => $tt_id ) ); $term_id = (int) $duplicate_term->term_id; $tt_id = (int) $duplicate_term->term_taxonomy_id; clean_term_cache( $term_id, $taxonomy ); return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id, ); } do_action( 'create_term', $term_id, $tt_id, $taxonomy, $args ); do_action( "create_{$taxonomy}", $term_id, $tt_id, $args ); $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id, $args ); clean_term_cache( $term_id, $taxonomy ); do_action( 'created_term', $term_id, $tt_id, $taxonomy, $args ); do_action( "created_{$taxonomy}", $term_id, $tt_id, $args ); do_action( 'saved_term', $term_id, $tt_id, $taxonomy, false, $args ); do_action( "saved_{$taxonomy}", $term_id, $tt_id, false, $args ); return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id, ); } function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) { global $wpdb; $object_id = (int) $object_id; if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } if ( empty( $terms ) ) { $terms = array(); } elseif ( ! is_array( $terms ) ) { $terms = array( $terms ); } if ( ! $append ) { $old_tt_ids = wp_get_object_terms( $object_id, $taxonomy, array( 'fields' => 'tt_ids', 'orderby' => 'none', 'update_term_meta_cache' => false, ) ); } else { $old_tt_ids = array(); } $tt_ids = array(); $new_tt_ids = array(); foreach ( (array) $terms as $term ) { if ( '' === trim( $term ) ) { continue; } $term_info = term_exists( $term, $taxonomy ); if ( ! $term_info ) { if ( is_int( $term ) ) { continue; } $term_info = wp_insert_term( $term, $taxonomy ); } if ( is_wp_error( $term_info ) ) { return $term_info; } $tt_id = $term_info['term_taxonomy_id']; $tt_ids[] = $tt_id; if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id ) ) ) { continue; } do_action( 'add_term_relationship', $object_id, $tt_id, $taxonomy ); $wpdb->insert( $wpdb->term_relationships, array( 'object_id' => $object_id, 'term_taxonomy_id' => $tt_id, ) ); do_action( 'added_term_relationship', $object_id, $tt_id, $taxonomy ); $new_tt_ids[] = $tt_id; } if ( $new_tt_ids ) { wp_update_term_count( $new_tt_ids, $taxonomy ); } if ( ! $append ) { $delete_tt_ids = array_diff( $old_tt_ids, $tt_ids ); if ( $delete_tt_ids ) { $in_delete_tt_ids = "'" . implode( "', '", $delete_tt_ids ) . "'"; $delete_term_ids = $wpdb->get_col( $wpdb->prepare( "SELECT tt.term_id FROM $wpdb->term_taxonomy AS tt WHERE tt.taxonomy = %s AND tt.term_taxonomy_id IN ($in_delete_tt_ids)", $taxonomy ) ); $delete_term_ids = array_map( 'intval', $delete_term_ids ); $remove = wp_remove_object_terms( $object_id, $delete_term_ids, $taxonomy ); if ( is_wp_error( $remove ) ) { return $remove; } } } $t = get_taxonomy( $taxonomy ); if ( ! $append && isset( $t->sort ) && $t->sort ) { $values = array(); $term_order = 0; $final_tt_ids = wp_get_object_terms( $object_id, $taxonomy, array( 'fields' => 'tt_ids', 'update_term_meta_cache' => false, ) ); foreach ( $tt_ids as $tt_id ) { if ( in_array( (int) $tt_id, $final_tt_ids, true ) ) { $values[] = $wpdb->prepare( '(%d, %d, %d)', $object_id, $tt_id, ++$term_order ); } } if ( $values ) { if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' ) ) { return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database.' ), $wpdb->last_error ); } } } wp_cache_delete( $object_id, $taxonomy . '_relationships' ); wp_cache_set_terms_last_changed(); do_action( 'set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ); return $tt_ids; } function wp_add_object_terms( $object_id, $terms, $taxonomy ) { return wp_set_object_terms( $object_id, $terms, $taxonomy, true ); } function wp_remove_object_terms( $object_id, $terms, $taxonomy ) { global $wpdb; $object_id = (int) $object_id; if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } if ( ! is_array( $terms ) ) { $terms = array( $terms ); } $tt_ids = array(); foreach ( (array) $terms as $term ) { if ( '' === trim( $term ) ) { continue; } $term_info = term_exists( $term, $taxonomy ); if ( ! $term_info ) { if ( is_int( $term ) ) { continue; } } if ( is_wp_error( $term_info ) ) { return $term_info; } $tt_ids[] = $term_info['term_taxonomy_id']; } if ( $tt_ids ) { $in_tt_ids = "'" . implode( "', '", $tt_ids ) . "'"; do_action( 'delete_term_relationships', $object_id, $tt_ids, $taxonomy ); $deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) ); wp_cache_delete( $object_id, $taxonomy . '_relationships' ); wp_cache_set_terms_last_changed(); do_action( 'deleted_term_relationships', $object_id, $tt_ids, $taxonomy ); wp_update_term_count( $tt_ids, $taxonomy ); return (bool) $deleted; } return false; } function wp_unique_term_slug( $slug, $term ) { global $wpdb; $needs_suffix = true; $original_slug = $slug; if ( ! term_exists( $slug ) || get_option( 'db_version' ) >= 30133 && ! get_term_by( 'slug', $slug, $term->taxonomy ) ) { $needs_suffix = false; } $parent_suffix = ''; if ( $needs_suffix && is_taxonomy_hierarchical( $term->taxonomy ) && ! empty( $term->parent ) ) { $the_parent = $term->parent; while ( ! empty( $the_parent ) ) { $parent_term = get_term( $the_parent, $term->taxonomy ); if ( is_wp_error( $parent_term ) || empty( $parent_term ) ) { break; } $parent_suffix .= '-' . $parent_term->slug; if ( ! term_exists( $slug . $parent_suffix ) ) { break; } if ( empty( $parent_term->parent ) ) { break; } $the_parent = $parent_term->parent; } } if ( apply_filters( 'wp_unique_term_slug_is_bad_slug', $needs_suffix, $slug, $term ) ) { if ( $parent_suffix ) { $slug .= $parent_suffix; } if ( ! empty( $term->term_id ) ) { $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $term->term_id ); } else { $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); } if ( $wpdb->get_var( $query ) ) { $num = 2; do { $alt_slug = $slug . "-$num"; ++$num; $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); } while ( $slug_check ); $slug = $alt_slug; } } return apply_filters( 'wp_unique_term_slug', $slug, $term, $original_slug ); } function wp_update_term( $term_id, $taxonomy, $args = array() ) { global $wpdb; if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } $term_id = (int) $term_id; $term = get_term( $term_id, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } if ( ! $term ) { return new WP_Error( 'invalid_term', __( 'Empty Term.' ) ); } $term = (array) $term->data; $term = wp_slash( $term ); $args = array_merge( $term, $args ); $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '', ); $args = wp_parse_args( $args, $defaults ); $args = sanitize_term( $args, $taxonomy, 'db' ); $parsed_args = $args; $name = wp_unslash( $args['name'] ); $description = wp_unslash( $args['description'] ); $parsed_args['name'] = $name; $parsed_args['description'] = $description; if ( '' === trim( $name ) ) { return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) ); } if ( (int) $parsed_args['parent'] > 0 && ! term_exists( (int) $parsed_args['parent'] ) ) { return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) ); } $empty_slug = false; if ( empty( $args['slug'] ) ) { $empty_slug = true; $slug = sanitize_title( $name ); } else { $slug = $args['slug']; } $parsed_args['slug'] = $slug; $term_group = isset( $parsed_args['term_group'] ) ? $parsed_args['term_group'] : 0; if ( $args['alias_of'] ) { $alias = get_term_by( 'slug', $args['alias_of'], $taxonomy ); if ( ! empty( $alias->term_group ) ) { $term_group = $alias->term_group; } elseif ( ! empty( $alias->term_id ) ) { $term_group = $wpdb->get_var( "SELECT MAX(term_group) FROM $wpdb->terms" ) + 1; wp_update_term( $alias->term_id, $taxonomy, array( 'term_group' => $term_group, ) ); } $parsed_args['term_group'] = $term_group; } $parent = (int) apply_filters( 'wp_update_term_parent', $args['parent'], $term_id, $taxonomy, $parsed_args, $args ); $duplicate = get_term_by( 'slug', $slug, $taxonomy ); if ( $duplicate && $duplicate->term_id !== $term_id ) { if ( $empty_slug || ( $parent !== (int) $term['parent'] ) ) { $slug = wp_unique_term_slug( $slug, (object) $args ); } else { return new WP_Error( 'duplicate_term_slug', sprintf( __( 'The slug “%s” is already in use by another term.' ), $slug ) ); } } $tt_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); $_term_id = _split_shared_term( $term_id, $tt_id ); if ( ! is_wp_error( $_term_id ) ) { $term_id = $_term_id; } do_action( 'edit_terms', $term_id, $taxonomy, $args ); $data = compact( 'name', 'slug', 'term_group' ); $data = apply_filters( 'wp_update_term_data', $data, $term_id, $taxonomy, $args ); $wpdb->update( $wpdb->terms, $data, compact( 'term_id' ) ); if ( empty( $slug ) ) { $slug = sanitize_title( $name, $term_id ); $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); } do_action( 'edited_terms', $term_id, $taxonomy, $args ); do_action( 'edit_term_taxonomy', $tt_id, $taxonomy, $args ); $wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) ); do_action( 'edited_term_taxonomy', $tt_id, $taxonomy, $args ); do_action( 'edit_term', $term_id, $tt_id, $taxonomy, $args ); do_action( "edit_{$taxonomy}", $term_id, $tt_id, $args ); $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id ); clean_term_cache( $term_id, $taxonomy ); do_action( 'edited_term', $term_id, $tt_id, $taxonomy, $args ); do_action( "edited_{$taxonomy}", $term_id, $tt_id, $args ); do_action( 'saved_term', $term_id, $tt_id, $taxonomy, true, $args ); do_action( "saved_{$taxonomy}", $term_id, $tt_id, true, $args ); return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id, ); } function wp_defer_term_counting( $defer = null ) { static $_defer = false; if ( is_bool( $defer ) ) { $_defer = $defer; if ( ! $defer ) { wp_update_term_count( null, null, true ); } } return $_defer; } function wp_update_term_count( $terms, $taxonomy, $do_deferred = false ) { static $_deferred = array(); if ( $do_deferred ) { foreach ( (array) array_keys( $_deferred ) as $tax ) { wp_update_term_count_now( $_deferred[ $tax ], $tax ); unset( $_deferred[ $tax ] ); } } if ( empty( $terms ) ) { return false; } if ( ! is_array( $terms ) ) { $terms = array( $terms ); } if ( wp_defer_term_counting() ) { if ( ! isset( $_deferred[ $taxonomy ] ) ) { $_deferred[ $taxonomy ] = array(); } $_deferred[ $taxonomy ] = array_unique( array_merge( $_deferred[ $taxonomy ], $terms ) ); return true; } return wp_update_term_count_now( $terms, $taxonomy ); } function wp_update_term_count_now( $terms, $taxonomy ) { $terms = array_map( 'intval', $terms ); $taxonomy = get_taxonomy( $taxonomy ); if ( ! empty( $taxonomy->update_count_callback ) ) { call_user_func( $taxonomy->update_count_callback, $terms, $taxonomy ); } else { $object_types = (array) $taxonomy->object_type; foreach ( $object_types as &$object_type ) { if ( str_starts_with( $object_type, 'attachment:' ) ) { list( $object_type ) = explode( ':', $object_type ); } } if ( array_filter( $object_types, 'post_type_exists' ) == $object_types ) { _update_post_term_count( $terms, $taxonomy ); } else { _update_generic_term_count( $terms, $taxonomy ); } } clean_term_cache( $terms, '', false ); return true; } function clean_object_term_cache( $object_ids, $object_type ) { global $_wp_suspend_cache_invalidation; if ( ! empty( $_wp_suspend_cache_invalidation ) ) { return; } if ( ! is_array( $object_ids ) ) { $object_ids = array( $object_ids ); } $taxonomies = get_object_taxonomies( $object_type ); foreach ( $taxonomies as $taxonomy ) { wp_cache_delete_multiple( $object_ids, "{$taxonomy}_relationships" ); } wp_cache_set_terms_last_changed(); do_action( 'clean_object_term_cache', $object_ids, $object_type ); } function clean_term_cache( $ids, $taxonomy = '', $clean_taxonomy = true ) { global $wpdb, $_wp_suspend_cache_invalidation; if ( ! empty( $_wp_suspend_cache_invalidation ) ) { return; } if ( ! is_array( $ids ) ) { $ids = array( $ids ); } $taxonomies = array(); if ( empty( $taxonomy ) ) { $tt_ids = array_map( 'intval', $ids ); $tt_ids = implode( ', ', $tt_ids ); $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)" ); $ids = array(); foreach ( (array) $terms as $term ) { $taxonomies[] = $term->taxonomy; $ids[] = $term->term_id; } wp_cache_delete_multiple( $ids, 'terms' ); $taxonomies = array_unique( $taxonomies ); } else { wp_cache_delete_multiple( $ids, 'terms' ); $taxonomies = array( $taxonomy ); } foreach ( $taxonomies as $taxonomy ) { if ( $clean_taxonomy ) { clean_taxonomy_cache( $taxonomy ); } do_action( 'clean_term_cache', $ids, $taxonomy, $clean_taxonomy ); } wp_cache_set_terms_last_changed(); } function clean_taxonomy_cache( $taxonomy ) { wp_cache_delete( 'all_ids', $taxonomy ); wp_cache_delete( 'get', $taxonomy ); wp_cache_set_terms_last_changed(); if ( is_taxonomy_hierarchical( $taxonomy ) ) { delete_option( "{$taxonomy}_children" ); _get_term_hierarchy( $taxonomy ); } do_action( 'clean_taxonomy_cache', $taxonomy ); } function get_object_term_cache( $id, $taxonomy ) { $_term_ids = wp_cache_get( $id, "{$taxonomy}_relationships" ); if ( false === $_term_ids ) { return false; } $term_ids = array(); foreach ( $_term_ids as $term_id ) { if ( is_numeric( $term_id ) ) { $term_ids[] = (int) $term_id; } elseif ( isset( $term_id->term_id ) ) { $term_ids[] = (int) $term_id->term_id; } } _prime_term_caches( $term_ids ); $terms = array(); foreach ( $term_ids as $term_id ) { $term = get_term( $term_id, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } $terms[] = $term; } return $terms; } function update_object_term_cache( $object_ids, $object_type ) { if ( empty( $object_ids ) ) { return; } if ( ! is_array( $object_ids ) ) { $object_ids = explode( ',', $object_ids ); } $object_ids = array_map( 'intval', $object_ids ); $non_cached_ids = array(); $taxonomies = get_object_taxonomies( $object_type ); foreach ( $taxonomies as $taxonomy ) { $cache_values = wp_cache_get_multiple( (array) $object_ids, "{$taxonomy}_relationships" ); foreach ( $cache_values as $id => $value ) { if ( false === $value ) { $non_cached_ids[] = $id; } } } if ( empty( $non_cached_ids ) ) { return false; } $non_cached_ids = array_unique( $non_cached_ids ); $terms = wp_get_object_terms( $non_cached_ids, $taxonomies, array( 'fields' => 'all_with_object_id', 'orderby' => 'name', 'update_term_meta_cache' => false, ) ); $object_terms = array(); foreach ( (array) $terms as $term ) { $object_terms[ $term->object_id ][ $term->taxonomy ][] = $term->term_id; } foreach ( $non_cached_ids as $id ) { foreach ( $taxonomies as $taxonomy ) { if ( ! isset( $object_terms[ $id ][ $taxonomy ] ) ) { if ( ! isset( $object_terms[ $id ] ) ) { $object_terms[ $id ] = array(); } $object_terms[ $id ][ $taxonomy ] = array(); } } } $cache_values = array(); foreach ( $object_terms as $id => $value ) { foreach ( $value as $taxonomy => $terms ) { $cache_values[ $taxonomy ][ $id ] = $terms; } } foreach ( $cache_values as $taxonomy => $data ) { wp_cache_add_multiple( $data, "{$taxonomy}_relationships" ); } } function update_term_cache( $terms, $taxonomy = '' ) { $data = array(); foreach ( (array) $terms as $term ) { $_term = clone $term; unset( $_term->object_id ); $data[ $term->term_id ] = $_term; } wp_cache_add_multiple( $data, 'terms' ); } function _get_term_hierarchy( $taxonomy ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { return array(); } $children = get_option( "{$taxonomy}_children" ); if ( is_array( $children ) ) { return $children; } $children = array(); $terms = get_terms( array( 'taxonomy' => $taxonomy, 'get' => 'all', 'orderby' => 'id', 'fields' => 'id=>parent', 'update_term_meta_cache' => false, ) ); foreach ( $terms as $term_id => $parent ) { if ( $parent > 0 ) { $children[ $parent ][] = $term_id; } } update_option( "{$taxonomy}_children", $children ); return $children; } function _get_term_children( $term_id, $terms, $taxonomy, &$ancestors = array() ) { $empty_array = array(); if ( empty( $terms ) ) { return $empty_array; } $term_id = (int) $term_id; $term_list = array(); $has_children = _get_term_hierarchy( $taxonomy ); if ( $term_id && ! isset( $has_children[ $term_id ] ) ) { return $empty_array; } if ( empty( $ancestors ) ) { $ancestors[ $term_id ] = 1; } foreach ( (array) $terms as $term ) { $use_id = false; if ( ! is_object( $term ) ) { $term = get_term( $term, $taxonomy ); if ( is_wp_error( $term ) ) { return $term; } $use_id = true; } if ( isset( $ancestors[ $term->term_id ] ) ) { continue; } if ( (int) $term->parent === $term_id ) { if ( $use_id ) { $term_list[] = $term->term_id; } else { $term_list[] = $term; } if ( ! isset( $has_children[ $term->term_id ] ) ) { continue; } $ancestors[ $term->term_id ] = 1; $children = _get_term_children( $term->term_id, $terms, $taxonomy, $ancestors ); if ( $children ) { $term_list = array_merge( $term_list, $children ); } } } return $term_list; } function _pad_term_counts( &$terms, $taxonomy ) { global $wpdb; if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { return; } $term_hier = _get_term_hierarchy( $taxonomy ); if ( empty( $term_hier ) ) { return; } $term_items = array(); $terms_by_id = array(); $term_ids = array(); foreach ( (array) $terms as $key => $term ) { $terms_by_id[ $term->term_id ] = & $terms[ $key ]; $term_ids[ $term->term_taxonomy_id ] = $term->term_id; } $tax_obj = get_taxonomy( $taxonomy ); $object_types = esc_sql( $tax_obj->object_type ); $results = $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode( ',', array_keys( $term_ids ) ) . ") AND post_type IN ('" . implode( "', '", $object_types ) . "') AND post_status = 'publish'" ); foreach ( $results as $row ) { $id = $term_ids[ $row->term_taxonomy_id ]; $term_items[ $id ][ $row->object_id ] = isset( $term_items[ $id ][ $row->object_id ] ) ? ++$term_items[ $id ][ $row->object_id ] : 1; } foreach ( $term_ids as $term_id ) { $child = $term_id; $ancestors = array(); while ( ! empty( $terms_by_id[ $child ] ) && $parent = $terms_by_id[ $child ]->parent ) { $ancestors[] = $child; if ( ! empty( $term_items[ $term_id ] ) ) { foreach ( $term_items[ $term_id ] as $item_id => $touches ) { $term_items[ $parent ][ $item_id ] = isset( $term_items[ $parent ][ $item_id ] ) ? ++$term_items[ $parent ][ $item_id ] : 1; } } $child = $parent; if ( in_array( $parent, $ancestors, true ) ) { break; } } } foreach ( (array) $term_items as $id => $items ) { if ( isset( $terms_by_id[ $id ] ) ) { $terms_by_id[ $id ]->count = count( $items ); } } } function _prime_term_caches( $term_ids, $update_meta_cache = true ) { global $wpdb; $non_cached_ids = _get_non_cached_ids( $term_ids, 'terms' ); if ( ! empty( $non_cached_ids ) ) { $fresh_terms = $wpdb->get_results( sprintf( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); update_term_cache( $fresh_terms ); } if ( $update_meta_cache ) { wp_lazyload_term_meta( $term_ids ); } } function _update_post_term_count( $terms, $taxonomy ) { global $wpdb; $object_types = (array) $taxonomy->object_type; foreach ( $object_types as &$object_type ) { list( $object_type ) = explode( ':', $object_type ); } $object_types = array_unique( $object_types ); $check_attachments = array_search( 'attachment', $object_types, true ); if ( false !== $check_attachments ) { unset( $object_types[ $check_attachments ] ); $check_attachments = true; } if ( $object_types ) { $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) ); } $post_statuses = array( 'publish' ); $post_statuses = esc_sql( apply_filters( 'update_post_term_count_statuses', $post_statuses, $taxonomy ) ); foreach ( (array) $terms as $tt_id ) { $count = 0; if ( $check_attachments ) { $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status IN ('" . implode( "', '", $post_statuses ) . "') OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) IN ('" . implode( "', '", $post_statuses ) . "') ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $tt_id ) ); } if ( $object_types ) { $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status IN ('" . implode( "', '", $post_statuses ) . "') AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $tt_id ) ); } do_action( 'update_term_count', $tt_id, $taxonomy->name, $count ); do_action( 'edit_term_taxonomy', $tt_id, $taxonomy->name ); $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $tt_id ) ); do_action( 'edited_term_taxonomy', $tt_id, $taxonomy->name ); } } function _update_generic_term_count( $terms, $taxonomy ) { global $wpdb; foreach ( (array) $terms as $term ) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term ) ); do_action( 'update_term_count', $term, $taxonomy->name, $count ); do_action( 'edit_term_taxonomy', $term, $taxonomy->name ); $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); do_action( 'edited_term_taxonomy', $term, $taxonomy->name ); } } function _split_shared_term( $term_id, $term_taxonomy_id, $record = true ) { global $wpdb; if ( is_object( $term_id ) ) { $shared_term = $term_id; $term_id = (int) $shared_term->term_id; } if ( is_object( $term_taxonomy_id ) ) { $term_taxonomy = $term_taxonomy_id; $term_taxonomy_id = (int) $term_taxonomy->term_taxonomy_id; } $shared_tt_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy tt WHERE tt.term_id = %d AND tt.term_taxonomy_id != %d", $term_id, $term_taxonomy_id ) ); if ( ! $shared_tt_count ) { return $term_id; } $check_term_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) ); if ( $check_term_id !== $term_id ) { return $check_term_id; } if ( empty( $shared_term ) ) { $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) ); } $new_term_data = array( 'name' => $shared_term->name, 'slug' => $shared_term->slug, 'term_group' => $shared_term->term_group, ); if ( false === $wpdb->insert( $wpdb->terms, $new_term_data ) ) { return new WP_Error( 'db_insert_error', __( 'Could not split shared term.' ), $wpdb->last_error ); } $new_term_id = (int) $wpdb->insert_id; $wpdb->update( $wpdb->term_taxonomy, array( 'term_id' => $new_term_id ), array( 'term_taxonomy_id' => $term_taxonomy_id ) ); if ( empty( $term_taxonomy ) ) { $term_taxonomy = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) ); } $children_tt_ids = $wpdb->get_col( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy ) ); if ( ! empty( $children_tt_ids ) ) { foreach ( $children_tt_ids as $child_tt_id ) { $wpdb->update( $wpdb->term_taxonomy, array( 'parent' => $new_term_id ), array( 'term_taxonomy_id' => $child_tt_id ) ); clean_term_cache( (int) $child_tt_id, '', false ); } } else { clean_term_cache( $new_term_id, $term_taxonomy->taxonomy, false ); } clean_term_cache( $term_id, $term_taxonomy->taxonomy, false ); $taxonomies_to_clean = array( $term_taxonomy->taxonomy ); $shared_term_taxonomies = $wpdb->get_col( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) ); $taxonomies_to_clean = array_merge( $taxonomies_to_clean, $shared_term_taxonomies ); foreach ( $taxonomies_to_clean as $taxonomy_to_clean ) { clean_taxonomy_cache( $taxonomy_to_clean ); } if ( $record ) { $split_term_data = get_option( '_split_terms', array() ); if ( ! isset( $split_term_data[ $term_id ] ) ) { $split_term_data[ $term_id ] = array(); } $split_term_data[ $term_id ][ $term_taxonomy->taxonomy ] = $new_term_id; update_option( '_split_terms', $split_term_data ); } $shared_terms_exist = $wpdb->get_results( "SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt
LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id
GROUP BY t.term_id
HAVING term_tt_count > 1
LIMIT 1" ); if ( ! $shared_terms_exist ) { update_option( 'finished_splitting_shared_terms', true ); } do_action( 'split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy ); return $new_term_id; } function _wp_batch_split_terms() { global $wpdb; $lock_name = 'term_split.lock'; $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'off') /* LOCK */", $lock_name, time() ) ); if ( ! $lock_result ) { $lock_result = get_option( $lock_name ); if ( ! $lock_result || ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) ) { wp_schedule_single_event( time() + ( 5 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' ); return; } } update_option( $lock_name, time() ); $shared_terms = $wpdb->get_results( "SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt
LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id
GROUP BY t.term_id
HAVING term_tt_count > 1
LIMIT 10" ); if ( ! $shared_terms ) { update_option( 'finished_splitting_shared_terms', true ); delete_option( $lock_name ); return; } wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' ); $_shared_terms = array(); foreach ( $shared_terms as $shared_term ) { $term_id = (int) $shared_term->term_id; $_shared_terms[ $term_id ] = $shared_term; } $shared_terms = $_shared_terms; $shared_term_ids = implode( ',', array_keys( $shared_terms ) ); $shared_tts = $wpdb->get_results( "SELECT * FROM {$wpdb->term_taxonomy} WHERE `term_id` IN ({$shared_term_ids})" ); $split_term_data = get_option( '_split_terms', array() ); $skipped_first_term = array(); $taxonomies = array(); foreach ( $shared_tts as $shared_tt ) { $term_id = (int) $shared_tt->term_id; if ( ! isset( $skipped_first_term[ $term_id ] ) ) { $skipped_first_term[ $term_id ] = 1; continue; } if ( ! isset( $split_term_data[ $term_id ] ) ) { $split_term_data[ $term_id ] = array(); } if ( ! isset( $taxonomies[ $shared_tt->taxonomy ] ) ) { $taxonomies[ $shared_tt->taxonomy ] = 1; } $split_term_data[ $term_id ][ $shared_tt->taxonomy ] = _split_shared_term( $shared_terms[ $term_id ], $shared_tt, false ); } foreach ( array_keys( $taxonomies ) as $tax ) { delete_option( "{$tax}_children" ); _get_term_hierarchy( $tax ); } update_option( '_split_terms', $split_term_data ); delete_option( $lock_name ); } function _wp_check_for_scheduled_split_terms() { if ( ! get_option( 'finished_splitting_shared_terms' ) && ! wp_next_scheduled( 'wp_split_shared_term_batch' ) ) { wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'wp_split_shared_term_batch' ); } } function _wp_check_split_default_terms( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { if ( 'category' !== $taxonomy ) { return; } foreach ( array( 'default_category', 'default_link_category', 'default_email_category' ) as $option ) { if ( (int) get_option( $option, -1 ) === $term_id ) { update_option( $option, $new_term_id ); } } } function _wp_check_split_terms_in_menus( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { global $wpdb; $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT m1.post_id
FROM {$wpdb->postmeta} AS m1
INNER JOIN {$wpdb->postmeta} AS m2 ON ( m2.post_id = m1.post_id )
INNER JOIN {$wpdb->postmeta} AS m3 ON ( m3.post_id = m1.post_id )
WHERE ( m1.meta_key = '_menu_item_type' AND m1.meta_value = 'taxonomy' )
AND ( m2.meta_key = '_menu_item_object' AND m2.meta_value = %s )
AND ( m3.meta_key = '_menu_item_object_id' AND m3.meta_value = %d )", $taxonomy, $term_id ) ); if ( $post_ids ) { foreach ( $post_ids as $post_id ) { update_post_meta( $post_id, '_menu_item_object_id', $new_term_id, $term_id ); } } } function _wp_check_split_nav_menu_terms( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { if ( 'nav_menu' !== $taxonomy ) { return; } $locations = get_nav_menu_locations(); foreach ( $locations as $location => $menu_id ) { if ( $term_id === $menu_id ) { $locations[ $location ] = $new_term_id; } } set_theme_mod( 'nav_menu_locations', $locations ); } function wp_get_split_terms( $old_term_id ) { $split_terms = get_option( '_split_terms', array() ); $terms = array(); if ( isset( $split_terms[ $old_term_id ] ) ) { $terms = $split_terms[ $old_term_id ]; } return $terms; } function wp_get_split_term( $old_term_id, $taxonomy ) { $split_terms = wp_get_split_terms( $old_term_id ); $term_id = false; if ( isset( $split_terms[ $taxonomy ] ) ) { $term_id = (int) $split_terms[ $taxonomy ]; } return $term_id; } function wp_term_is_shared( $term_id ) { global $wpdb; if ( get_option( 'finished_splitting_shared_terms' ) ) { return false; } $tt_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) ); return $tt_count > 1; } function get_term_link( $term, $taxonomy = '' ) { global $wp_rewrite; if ( ! is_object( $term ) ) { if ( is_int( $term ) ) { $term = get_term( $term, $taxonomy ); } else { $term = get_term_by( 'slug', $term, $taxonomy ); } } if ( ! is_object( $term ) ) { $term = new WP_Error( 'invalid_term', __( 'Empty Term.' ) ); } if ( is_wp_error( $term ) ) { return $term; } $taxonomy = $term->taxonomy; $termlink = $wp_rewrite->get_extra_permastruct( $taxonomy ); $termlink = apply_filters( 'pre_term_link', $termlink, $term ); $slug = $term->slug; $t = get_taxonomy( $taxonomy ); if ( empty( $termlink ) ) { if ( 'category' === $taxonomy ) { $termlink = '?cat=' . $term->term_id; } elseif ( $t->query_var ) { $termlink = "?$t->query_var=$slug"; } else { $termlink = "?taxonomy=$taxonomy&term=$slug"; } $termlink = home_url( $termlink ); } else { if ( ! empty( $t->rewrite['hierarchical'] ) ) { $hierarchical_slugs = array(); $ancestors = get_ancestors( $term->term_id, $taxonomy, 'taxonomy' ); foreach ( (array) $ancestors as $ancestor ) { $ancestor_term = get_term( $ancestor, $taxonomy ); $hierarchical_slugs[] = $ancestor_term->slug; } $hierarchical_slugs = array_reverse( $hierarchical_slugs ); $hierarchical_slugs[] = $slug; $termlink = str_replace( "%$taxonomy%", implode( '/', $hierarchical_slugs ), $termlink ); } else { $termlink = str_replace( "%$taxonomy%", $slug, $termlink ); } $termlink = home_url( user_trailingslashit( $termlink, 'category' ) ); } if ( 'post_tag' === $taxonomy ) { $termlink = apply_filters( 'tag_link', $termlink, $term->term_id ); } elseif ( 'category' === $taxonomy ) { $termlink = apply_filters( 'category_link', $termlink, $term->term_id ); } return apply_filters( 'term_link', $termlink, $term, $taxonomy ); } function the_taxonomies( $args = array() ) { $defaults = array( 'post' => 0, 'before' => '', 'sep' => ' ', 'after' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); echo $parsed_args['before'] . implode( $parsed_args['sep'], get_the_taxonomies( $parsed_args['post'], $parsed_args ) ) . $parsed_args['after']; } function get_the_taxonomies( $post = 0, $args = array() ) { $post = get_post( $post ); $args = wp_parse_args( $args, array( 'template' => __( '%s: %l.' ), 'term_template' => '<a href="%1$s">%2$s</a>', ) ); $taxonomies = array(); if ( ! $post ) { return $taxonomies; } foreach ( get_object_taxonomies( $post ) as $taxonomy ) { $t = (array) get_taxonomy( $taxonomy ); if ( empty( $t['label'] ) ) { $t['label'] = $taxonomy; } if ( empty( $t['args'] ) ) { $t['args'] = array(); } if ( empty( $t['template'] ) ) { $t['template'] = $args['template']; } if ( empty( $t['term_template'] ) ) { $t['term_template'] = $args['term_template']; } $terms = get_object_term_cache( $post->ID, $taxonomy ); if ( false === $terms ) { $terms = wp_get_object_terms( $post->ID, $taxonomy, $t['args'] ); } $links = array(); foreach ( $terms as $term ) { $links[] = wp_sprintf( $t['term_template'], esc_attr( get_term_link( $term ) ), $term->name ); } if ( $links ) { $taxonomies[ $taxonomy ] = wp_sprintf( $t['template'], $t['label'], $links, $terms ); } } return $taxonomies; } function get_post_taxonomies( $post = 0 ) { $post = get_post( $post ); return get_object_taxonomies( $post ); } function is_object_in_term( $object_id, $taxonomy, $terms = null ) { $object_id = (int) $object_id; if ( ! $object_id ) { return new WP_Error( 'invalid_object', __( 'Invalid object ID.' ) ); } $object_terms = get_object_term_cache( $object_id, $taxonomy ); if ( false === $object_terms ) { $object_terms = wp_get_object_terms( $object_id, $taxonomy, array( 'update_term_meta_cache' => false ) ); if ( is_wp_error( $object_terms ) ) { return $object_terms; } wp_cache_set( $object_id, wp_list_pluck( $object_terms, 'term_id' ), "{$taxonomy}_relationships" ); } if ( is_wp_error( $object_terms ) ) { return $object_terms; } if ( empty( $object_terms ) ) { return false; } if ( empty( $terms ) ) { return true; } $terms = (array) $terms; $ints = array_filter( $terms, 'is_int' ); if ( $ints ) { $strs = array_diff( $terms, $ints ); } else { $strs =& $terms; } foreach ( $object_terms as $object_term ) { if ( $ints && in_array( $object_term->term_id, $ints, true ) ) { return true; } if ( $strs ) { $numeric_strs = array_map( 'intval', array_filter( $strs, 'is_numeric' ) ); if ( in_array( $object_term->term_id, $numeric_strs, true ) ) { return true; } if ( in_array( $object_term->name, $strs, true ) ) { return true; } if ( in_array( $object_term->slug, $strs, true ) ) { return true; } } } return false; } function is_object_in_taxonomy( $object_type, $taxonomy ) { $taxonomies = get_object_taxonomies( $object_type ); if ( empty( $taxonomies ) ) { return false; } return in_array( $taxonomy, $taxonomies, true ); } function get_ancestors( $object_id = 0, $object_type = '', $resource_type = '' ) { $object_id = (int) $object_id; $ancestors = array(); if ( empty( $object_id ) ) { return apply_filters( 'get_ancestors', $ancestors, $object_id, $object_type, $resource_type ); } if ( ! $resource_type ) { if ( is_taxonomy_hierarchical( $object_type ) ) { $resource_type = 'taxonomy'; } elseif ( post_type_exists( $object_type ) ) { $resource_type = 'post_type'; } } if ( 'taxonomy' === $resource_type ) { $term = get_term( $object_id, $object_type ); while ( ! is_wp_error( $term ) && ! empty( $term->parent ) && ! in_array( $term->parent, $ancestors, true ) ) { $ancestors[] = (int) $term->parent; $term = get_term( $term->parent, $object_type ); } } elseif ( 'post_type' === $resource_type ) { $ancestors = get_post_ancestors( $object_id ); } return apply_filters( 'get_ancestors', $ancestors, $object_id, $object_type, $resource_type ); } function wp_get_term_taxonomy_parent_id( $term_id, $taxonomy ) { $term = get_term( $term_id, $taxonomy ); if ( ! $term || is_wp_error( $term ) ) { return false; } return (int) $term->parent; } function wp_check_term_hierarchy_for_loops( $parent_term, $term_id, $taxonomy ) { if ( ! $parent_term ) { return 0; } if ( $parent_term === $term_id ) { return 0; } $loop = wp_find_hierarchy_loop( 'wp_get_term_taxonomy_parent_id', $term_id, $parent_term, array( $taxonomy ) ); if ( ! $loop ) { return $parent_term; } if ( isset( $loop[ $term_id ] ) ) { return 0; } foreach ( array_keys( $loop ) as $loop_member ) { wp_update_term( $loop_member, $taxonomy, array( 'parent' => 0 ) ); } return $parent_term; } function is_taxonomy_viewable( $taxonomy ) { if ( is_scalar( $taxonomy ) ) { $taxonomy = get_taxonomy( $taxonomy ); if ( ! $taxonomy ) { return false; } } return $taxonomy->publicly_queryable; } function is_term_publicly_viewable( $term ) { $term = get_term( $term ); if ( ! $term ) { return false; } return is_taxonomy_viewable( $term->taxonomy ); } function wp_cache_set_terms_last_changed() { wp_cache_set_last_changed( 'terms' ); } function wp_check_term_meta_support_prefilter( $check ) { if ( get_option( 'db_version' ) < 34370 ) { return false; } return $check; }
###require ABSPATH . WPINC . '/class-wp-taxonomy.php';
final class WP_Taxonomy { public $name; public $label; public $labels; protected static $default_labels = array(); public $description = ''; public $public = true; public $publicly_queryable = true; public $hierarchical = false; public $show_ui = true; public $show_in_menu = true; public $show_in_nav_menus = true; public $show_tagcloud = true; public $show_in_quick_edit = true; public $show_admin_column = false; public $meta_box_cb = null; public $meta_box_sanitize_cb = null; public $object_type = null; public $cap; public $rewrite; public $query_var; public $update_count_callback; public $show_in_rest; public $rest_base; public $rest_namespace; public $rest_controller_class; public $rest_controller; public $default_term; public $sort = null; public $args = null; public $_builtin; public function __construct( $taxonomy, $object_type, $args = array() ) { $this->name = $taxonomy; $this->set_props( $object_type, $args ); } public function set_props( $object_type, $args ) { $args = wp_parse_args( $args ); $args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type ); $taxonomy = $this->name; $args = apply_filters( "register_{$taxonomy}_taxonomy_args", $args, $this->name, (array) $object_type ); $defaults = array( 'labels' => array(), 'description' => '', 'public' => true, 'publicly_queryable' => null, 'hierarchical' => false, 'show_ui' => null, 'show_in_menu' => null, 'show_in_nav_menus' => null, 'show_tagcloud' => null, 'show_in_quick_edit' => null, 'show_admin_column' => false, 'meta_box_cb' => null, 'meta_box_sanitize_cb' => null, 'capabilities' => array(), 'rewrite' => true, 'query_var' => $this->name, 'update_count_callback' => '', 'show_in_rest' => false, 'rest_base' => false, 'rest_namespace' => false, 'rest_controller_class' => false, 'default_term' => null, 'sort' => null, 'args' => null, '_builtin' => false, ); $args = array_merge( $defaults, $args ); if ( null === $args['publicly_queryable'] ) { $args['publicly_queryable'] = $args['public']; } if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) { if ( true === $args['query_var'] ) { $args['query_var'] = $this->name; } else { $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] ); } } else { $args['query_var'] = false; } if ( false !== $args['rewrite'] && ( is_admin() || get_option( 'permalink_structure' ) ) ) { $args['rewrite'] = wp_parse_args( $args['rewrite'], array( 'with_front' => true, 'hierarchical' => false, 'ep_mask' => EP_NONE, ) ); if ( empty( $args['rewrite']['slug'] ) ) { $args['rewrite']['slug'] = sanitize_title_with_dashes( $this->name ); } } if ( null === $args['show_ui'] ) { $args['show_ui'] = $args['public']; } if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { $args['show_in_menu'] = $args['show_ui']; } if ( null === $args['show_in_nav_menus'] ) { $args['show_in_nav_menus'] = $args['public']; } if ( null === $args['show_tagcloud'] ) { $args['show_tagcloud'] = $args['show_ui']; } if ( null === $args['show_in_quick_edit'] ) { $args['show_in_quick_edit'] = $args['show_ui']; } if ( false === $args['rest_namespace'] && ! empty( $args['show_in_rest'] ) ) { $args['rest_namespace'] = 'wp/v2'; } $default_caps = array( 'manage_terms' => 'manage_categories', 'edit_terms' => 'manage_categories', 'delete_terms' => 'manage_categories', 'assign_terms' => 'edit_posts', ); $args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] ); unset( $args['capabilities'] ); $args['object_type'] = array_unique( (array) $object_type ); if ( null === $args['meta_box_cb'] ) { if ( $args['hierarchical'] ) { $args['meta_box_cb'] = 'post_categories_meta_box'; } else { $args['meta_box_cb'] = 'post_tags_meta_box'; } } $args['name'] = $this->name; if ( null === $args['meta_box_sanitize_cb'] ) { switch ( $args['meta_box_cb'] ) { case 'post_categories_meta_box': $args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_checkboxes'; break; case 'post_tags_meta_box': default: $args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_input'; break; } } if ( ! empty( $args['default_term'] ) ) { if ( ! is_array( $args['default_term'] ) ) { $args['default_term'] = array( 'name' => $args['default_term'] ); } $args['default_term'] = wp_parse_args( $args['default_term'], array( 'name' => '', 'slug' => '', 'description' => '', ) ); } foreach ( $args as $property_name => $property_value ) { $this->$property_name = $property_value; } $this->labels = get_taxonomy_labels( $this ); $this->label = $this->labels->name; } public function add_rewrite_rules() { global $wp; if ( false !== $this->query_var && $wp ) { $wp->add_query_var( $this->query_var ); } if ( false !== $this->rewrite && ( is_admin() || get_option( 'permalink_structure' ) ) ) { if ( $this->hierarchical && $this->rewrite['hierarchical'] ) { $tag = '(.+?)'; } else { $tag = '([^/]+)'; } add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" ); add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $this->rewrite ); } } public function remove_rewrite_rules() { global $wp; if ( false !== $this->query_var ) { $wp->remove_query_var( $this->query_var ); } if ( false !== $this->rewrite ) { remove_rewrite_tag( "%$this->name%" ); remove_permastruct( $this->name ); } } public function add_hooks() { add_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' ); } public function remove_hooks() { remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' ); } public function get_rest_controller() { if ( ! $this->show_in_rest ) { return null; } $class = $this->rest_controller_class ? $this->rest_controller_class : WP_REST_Terms_Controller::class; if ( ! class_exists( $class ) ) { return null; } if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) { return null; } if ( ! $this->rest_controller ) { $this->rest_controller = new $class( $this->name ); } if ( ! ( $this->rest_controller instanceof $class ) ) { return null; } return $this->rest_controller; } public static function get_default_labels() { if ( ! empty( self::$default_labels ) ) { return self::$default_labels; } $name_field_description = __( 'The name is how it appears on your site.' ); $slug_field_description = __( 'The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.' ); $parent_field_description = __( 'Assign a parent term to create a hierarchy. The term Jazz, for example, would be the parent of Bebop and Big Band.' ); $desc_field_description = __( 'The description is not prominent by default; however, some themes may show it.' ); self::$default_labels = array( 'name' => array( _x( 'Tags', 'taxonomy general name' ), _x( 'Categories', 'taxonomy general name' ) ), 'singular_name' => array( _x( 'Tag', 'taxonomy singular name' ), _x( 'Category', 'taxonomy singular name' ) ), 'search_items' => array( __( 'Search Tags' ), __( 'Search Categories' ) ), 'popular_items' => array( __( 'Popular Tags' ), null ), 'all_items' => array( __( 'All Tags' ), __( 'All Categories' ) ), 'parent_item' => array( null, __( 'Parent Category' ) ), 'parent_item_colon' => array( null, __( 'Parent Category:' ) ), 'name_field_description' => array( $name_field_description, $name_field_description ), 'slug_field_description' => array( $slug_field_description, $slug_field_description ), 'parent_field_description' => array( null, $parent_field_description ), 'desc_field_description' => array( $desc_field_description, $desc_field_description ), 'edit_item' => array( __( 'Edit Tag' ), __( 'Edit Category' ) ), 'view_item' => array( __( 'View Tag' ), __( 'View Category' ) ), 'update_item' => array( __( 'Update Tag' ), __( 'Update Category' ) ), 'add_new_item' => array( __( 'Add Tag' ), __( 'Add Category' ) ), 'new_item_name' => array( __( 'New Tag Name' ), __( 'New Category Name' ) ), 'separate_items_with_commas' => array( __( 'Separate tags with commas' ), null ), 'add_or_remove_items' => array( __( 'Add or remove tags' ), null ), 'choose_from_most_used' => array( __( 'Choose from the most used tags' ), null ), 'not_found' => array( __( 'No tags found.' ), __( 'No categories found.' ) ), 'no_terms' => array( __( 'No tags' ), __( 'No categories' ) ), 'filter_by_item' => array( null, __( 'Filter by category' ) ), 'items_list_navigation' => array( __( 'Tags list navigation' ), __( 'Categories list navigation' ) ), 'items_list' => array( __( 'Tags list' ), __( 'Categories list' ) ), 'most_used' => array( _x( 'Most Used', 'tags' ), _x( 'Most Used', 'categories' ) ), 'back_to_items' => array( __( '← Go to Tags' ), __( '← Go to Categories' ) ), 'item_link' => array( _x( 'Tag Link', 'navigation link block title' ), _x( 'Category Link', 'navigation link block title' ), ), 'item_link_description' => array( _x( 'A link to a tag.', 'navigation link block description' ), _x( 'A link to a category.', 'navigation link block description' ), ), ); return self::$default_labels; } public static function reset_default_labels() { self::$default_labels = array(); } }
###require ABSPATH . WPINC . '/class-wp-term.php';
final class WP_Term { public $term_id; public $name = ''; public $slug = ''; public $term_group = ''; public $term_taxonomy_id = 0; public $taxonomy = ''; public $description = ''; public $parent = 0; public $count = 0; public $filter = 'raw'; public static function get_instance( $term_id, $taxonomy = null ) { global $wpdb; $term_id = (int) $term_id; if ( ! $term_id ) { return false; } $_term = wp_cache_get( $term_id, 'terms' ); if ( ! $_term || ( $taxonomy && $taxonomy !== $_term->taxonomy ) ) { $_term = false; $terms = $wpdb->get_results( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id = %d", $term_id ) ); if ( ! $terms ) { return false; } if ( $taxonomy ) { foreach ( $terms as $match ) { if ( $taxonomy === $match->taxonomy ) { $_term = $match; break; } } } elseif ( 1 === count( $terms ) ) { $_term = reset( $terms ); } else { foreach ( $terms as $t ) { if ( ! taxonomy_exists( $t->taxonomy ) ) { continue; } if ( $_term ) { return new WP_Error( 'ambiguous_term_id', __( 'Term ID is shared between multiple taxonomies' ), $term_id ); } $_term = $t; } } if ( ! $_term ) { return false; } if ( ! taxonomy_exists( $_term->taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } $_term = sanitize_term( $_term, $_term->taxonomy, 'raw' ); if ( 1 === count( $terms ) ) { wp_cache_add( $term_id, $_term, 'terms' ); } } $term_obj = new WP_Term( $_term ); $term_obj->filter( $term_obj->filter ); return $term_obj; } public function __construct( $term ) { foreach ( get_object_vars( $term ) as $key => $value ) { $this->$key = $value; } } public function filter( $filter ) { sanitize_term( $this, $this->taxonomy, $filter ); } public function to_array() { return get_object_vars( $this ); } public function __get( $key ) { switch ( $key ) { case 'data': $data = new stdClass(); $columns = array( 'term_id', 'name', 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description', 'parent', 'count' ); foreach ( $columns as $column ) { $data->{$column} = isset( $this->{$column} ) ? $this->{$column} : null; } return sanitize_term( $data, $data->taxonomy, 'raw' ); } } }
###require ABSPATH . WPINC . '/class-wp-term-query.php';
class WP_Term_Query { public $request; public $meta_query = false; protected $meta_query_clauses; protected $sql_clauses = array( 'select' => '', 'from' => '', 'where' => array(), 'orderby' => '', 'limits' => '', ); public $query_vars; public $query_var_defaults; public $terms; public function __construct( $query = '' ) { $this->query_var_defaults = array( 'taxonomy' => null, 'object_ids' => null, 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'include' => array(), 'exclude' => array(), 'exclude_tree' => array(), 'number' => '', 'offset' => '', 'fields' => 'all', 'name' => '', 'slug' => '', 'term_taxonomy_id' => '', 'hierarchical' => true, 'search' => '', 'name__like' => '', 'description__like' => '', 'pad_counts' => false, 'get' => '', 'child_of' => 0, 'parent' => '', 'childless' => false, 'cache_domain' => 'core', 'cache_results' => true, 'update_term_meta_cache' => true, 'meta_query' => '', 'meta_key' => '', 'meta_value' => '', 'meta_type' => '', 'meta_compare' => '', ); if ( ! empty( $query ) ) { $this->query( $query ); } } public function parse_query( $query = '' ) { if ( empty( $query ) ) { $query = $this->query_vars; } $taxonomies = isset( $query['taxonomy'] ) ? (array) $query['taxonomy'] : null; $this->query_var_defaults = apply_filters( 'get_terms_defaults', $this->query_var_defaults, $taxonomies ); $query = wp_parse_args( $query, $this->query_var_defaults ); $query['number'] = absint( $query['number'] ); $query['offset'] = absint( $query['offset'] ); if ( 0 < (int) $query['parent'] ) { $query['child_of'] = false; } if ( 'all' === $query['get'] ) { $query['childless'] = false; $query['child_of'] = 0; $query['hide_empty'] = 0; $query['hierarchical'] = false; $query['pad_counts'] = false; } $query['taxonomy'] = $taxonomies; $this->query_vars = $query; do_action( 'parse_term_query', $this ); } public function query( $query ) { $this->query_vars = wp_parse_args( $query ); return $this->get_terms(); } public function get_terms() { global $wpdb; $this->parse_query( $this->query_vars ); $args = &$this->query_vars; $this->meta_query = new WP_Meta_Query(); $this->meta_query->parse_query_vars( $args ); do_action_ref_array( 'pre_get_terms', array( &$this ) ); $taxonomies = (array) $args['taxonomy']; $has_hierarchical_tax = false; if ( $taxonomies ) { foreach ( $taxonomies as $_tax ) { if ( is_taxonomy_hierarchical( $_tax ) ) { $has_hierarchical_tax = true; } } } else { $has_hierarchical_tax = true; } if ( ! $has_hierarchical_tax ) { $args['hierarchical'] = false; $args['pad_counts'] = false; } if ( 0 < (int) $args['parent'] ) { $args['child_of'] = false; } if ( 'all' === $args['get'] ) { $args['childless'] = false; $args['child_of'] = 0; $args['hide_empty'] = 0; $args['hierarchical'] = false; $args['pad_counts'] = false; } $args = apply_filters( 'get_terms_args', $args, $taxonomies ); $child_of = $args['child_of']; $parent = $args['parent']; if ( $child_of ) { $_parent = $child_of; } elseif ( $parent ) { $_parent = $parent; } else { $_parent = false; } if ( $_parent ) { $in_hierarchy = false; foreach ( $taxonomies as $_tax ) { $hierarchy = _get_term_hierarchy( $_tax ); if ( isset( $hierarchy[ $_parent ] ) ) { $in_hierarchy = true; } } if ( ! $in_hierarchy ) { if ( 'count' === $args['fields'] ) { return 0; } else { $this->terms = array(); return $this->terms; } } } $_orderby = $this->query_vars['orderby']; if ( 'term_order' === $_orderby && empty( $this->query_vars['object_ids'] ) ) { $_orderby = 'term_id'; } $orderby = $this->parse_orderby( $_orderby ); if ( $orderby ) { $orderby = "ORDER BY $orderby"; } $order = $this->parse_order( $this->query_vars['order'] ); if ( $taxonomies ) { $this->sql_clauses['where']['taxonomy'] = "tt.taxonomy IN ('" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "')"; } if ( empty( $args['exclude'] ) ) { $args['exclude'] = array(); } if ( empty( $args['include'] ) ) { $args['include'] = array(); } $exclude = $args['exclude']; $exclude_tree = $args['exclude_tree']; $include = $args['include']; if ( ! empty( $include ) ) { $exclude = ''; $exclude_tree = ''; $inclusions = implode( ',', wp_parse_id_list( $include ) ); $this->sql_clauses['where']['inclusions'] = 't.term_id IN ( ' . $inclusions . ' )'; } $exclusions = array(); if ( ! empty( $exclude_tree ) ) { $exclude_tree = wp_parse_id_list( $exclude_tree ); $excluded_children = $exclude_tree; foreach ( $exclude_tree as $extrunk ) { $excluded_children = array_merge( $excluded_children, (array) get_terms( array( 'taxonomy' => reset( $taxonomies ), 'child_of' => (int) $extrunk, 'fields' => 'ids', 'hide_empty' => 0, ) ) ); } $exclusions = array_merge( $excluded_children, $exclusions ); } if ( ! empty( $exclude ) ) { $exclusions = array_merge( wp_parse_id_list( $exclude ), $exclusions ); } $childless = (bool) $args['childless']; if ( $childless ) { foreach ( $taxonomies as $_tax ) { $term_hierarchy = _get_term_hierarchy( $_tax ); $exclusions = array_merge( array_keys( $term_hierarchy ), $exclusions ); } } if ( ! empty( $exclusions ) ) { $exclusions = 't.term_id NOT IN (' . implode( ',', array_map( 'intval', $exclusions ) ) . ')'; } else { $exclusions = ''; } $exclusions = apply_filters( 'list_terms_exclusions', $exclusions, $args, $taxonomies ); if ( ! empty( $exclusions ) ) { $this->sql_clauses['where']['exclusions'] = preg_replace( '/^\s*AND\s*/', '', $exclusions ); } if ( '' === $args['name'] ) { $args['name'] = array(); } else { $args['name'] = (array) $args['name']; } if ( ! empty( $args['name'] ) ) { $names = $args['name']; foreach ( $names as &$_name ) { $_name = stripslashes( sanitize_term_field( 'name', $_name, 0, reset( $taxonomies ), 'db' ) ); } $this->sql_clauses['where']['name'] = "t.name IN ('" . implode( "', '", array_map( 'esc_sql', $names ) ) . "')"; } if ( '' === $args['slug'] ) { $args['slug'] = array(); } else { $args['slug'] = array_map( 'sanitize_title', (array) $args['slug'] ); } if ( ! empty( $args['slug'] ) ) { $slug = implode( "', '", $args['slug'] ); $this->sql_clauses['where']['slug'] = "t.slug IN ('" . $slug . "')"; } if ( '' === $args['term_taxonomy_id'] ) { $args['term_taxonomy_id'] = array(); } else { $args['term_taxonomy_id'] = array_map( 'intval', (array) $args['term_taxonomy_id'] ); } if ( ! empty( $args['term_taxonomy_id'] ) ) { $tt_ids = implode( ',', $args['term_taxonomy_id'] ); $this->sql_clauses['where']['term_taxonomy_id'] = "tt.term_taxonomy_id IN ({$tt_ids})"; } if ( ! empty( $args['name__like'] ) ) { $this->sql_clauses['where']['name__like'] = $wpdb->prepare( 't.name LIKE %s', '%' . $wpdb->esc_like( $args['name__like'] ) . '%' ); } if ( ! empty( $args['description__like'] ) ) { $this->sql_clauses['where']['description__like'] = $wpdb->prepare( 'tt.description LIKE %s', '%' . $wpdb->esc_like( $args['description__like'] ) . '%' ); } if ( '' === $args['object_ids'] ) { $args['object_ids'] = array(); } else { $args['object_ids'] = array_map( 'intval', (array) $args['object_ids'] ); } if ( ! empty( $args['object_ids'] ) ) { $object_ids = implode( ', ', $args['object_ids'] ); $this->sql_clauses['where']['object_ids'] = "tr.object_id IN ($object_ids)"; } if ( ! empty( $args['object_ids'] ) ) { $args['hide_empty'] = false; } if ( '' !== $parent ) { $parent = (int) $parent; $this->sql_clauses['where']['parent'] = "tt.parent = '$parent'"; } $hierarchical = $args['hierarchical']; if ( 'count' === $args['fields'] ) { $hierarchical = false; } if ( $args['hide_empty'] && ! $hierarchical ) { $this->sql_clauses['where']['count'] = 'tt.count > 0'; } $number = $args['number']; $offset = $args['offset']; if ( $number && ! $hierarchical && ! $child_of && '' === $parent ) { if ( $offset ) { $limits = 'LIMIT ' . $offset . ',' . $number; } else { $limits = 'LIMIT ' . $number; } } else { $limits = ''; } if ( ! empty( $args['search'] ) ) { $this->sql_clauses['where']['search'] = $this->get_search_sql( $args['search'] ); } $join = ''; $distinct = ''; $this->meta_query->parse_query_vars( $this->query_vars ); $mq_sql = $this->meta_query->get_sql( 'term', 't', 'term_id' ); $meta_clauses = $this->meta_query->get_clauses(); if ( ! empty( $meta_clauses ) ) { $join .= $mq_sql['join']; $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $mq_sql['where'] ); $distinct .= 'DISTINCT'; } $selects = array(); switch ( $args['fields'] ) { case 'count': $orderby = ''; $order = ''; $selects = array( 'COUNT(*)' ); break; default: $selects = array( 't.term_id' ); if ( 'all_with_object_id' === $args['fields'] && ! empty( $args['object_ids'] ) ) { $selects[] = 'tr.object_id'; } break; } $_fields = $args['fields']; $fields = implode( ', ', apply_filters( 'get_terms_fields', $selects, $args, $taxonomies ) ); $join .= " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id"; if ( ! empty( $this->query_vars['object_ids'] ) ) { $join .= " INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id"; $distinct = 'DISTINCT'; } $where = implode( ' AND ', $this->sql_clauses['where'] ); $pieces = array( 'fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits' ); $clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args ); $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $order = isset( $clauses['order'] ) ? $clauses['order'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; $fields_is_filtered = implode( ', ', $selects ) !== $fields; if ( $where ) { $where = "WHERE $where"; } $this->sql_clauses['select'] = "SELECT $distinct $fields"; $this->sql_clauses['from'] = "FROM $wpdb->terms AS t $join"; $this->sql_clauses['orderby'] = $orderby ? "$orderby $order" : ''; $this->sql_clauses['limits'] = $limits; $this->request = "{$this->sql_clauses['select']}
{$this->sql_clauses['from']}
{$where}
{$this->sql_clauses['orderby']}
{$this->sql_clauses['limits']}"; $this->terms = null; $this->terms = apply_filters_ref_array( 'terms_pre_query', array( $this->terms, &$this ) ); if ( null !== $this->terms ) { return $this->terms; } if ( $args['cache_results'] ) { $cache_key = $this->generate_cache_key( $args, $this->request ); $last_changed = wp_cache_get_last_changed( 'terms' ); $cache = wp_cache_get_salted( $cache_key, 'term-queries', $last_changed ); if ( false !== $cache ) { if ( 'ids' === $_fields ) { $cache = array_map( 'intval', $cache ); } elseif ( 'count' !== $_fields ) { if ( ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) || ( 'all' === $_fields && $args['pad_counts'] || $fields_is_filtered ) ) { $term_ids = wp_list_pluck( $cache, 'term_id' ); } else { $term_ids = array_map( 'intval', $cache ); } _prime_term_caches( $term_ids, $args['update_term_meta_cache'] ); $term_objects = $this->populate_terms( $cache ); $cache = $this->format_terms( $term_objects, $_fields ); } $this->terms = $cache; return $this->terms; } } if ( 'count' === $_fields ) { $count = $wpdb->get_var( $this->request ); if ( $args['cache_results'] ) { wp_cache_set_salted( $cache_key, $count, 'term-queries', $last_changed ); } return $count; } $terms = $wpdb->get_results( $this->request ); if ( empty( $terms ) ) { $this->terms = array(); if ( $args['cache_results'] ) { wp_cache_set_salted( $cache_key, $this->terms, 'term-queries', $last_changed ); } return $this->terms; } $term_ids = wp_list_pluck( $terms, 'term_id' ); _prime_term_caches( $term_ids, false ); $term_objects = $this->populate_terms( $terms ); if ( $child_of ) { foreach ( $taxonomies as $_tax ) { $children = _get_term_hierarchy( $_tax ); if ( ! empty( $children ) ) { $term_objects = _get_term_children( $child_of, $term_objects, $_tax ); } } } if ( $args['pad_counts'] && 'all' === $_fields ) { foreach ( $taxonomies as $_tax ) { _pad_term_counts( $term_objects, $_tax ); } } if ( $hierarchical && $args['hide_empty'] && is_array( $term_objects ) ) { foreach ( $term_objects as $k => $term ) { if ( ! $term->count ) { $children = get_term_children( $term->term_id, $term->taxonomy ); if ( is_array( $children ) ) { foreach ( $children as $child_id ) { $child = get_term( $child_id, $term->taxonomy ); if ( $child instanceof WP_Term && $child->count ) { continue 2; } } } unset( $term_objects[ $k ] ); } } } if ( $hierarchical && $number && is_array( $term_objects ) ) { if ( $offset >= count( $term_objects ) ) { $term_objects = array(); } else { $term_objects = array_slice( $term_objects, $offset, $number, true ); } } if ( $args['update_term_meta_cache'] ) { $term_ids = wp_list_pluck( $term_objects, 'term_id' ); wp_lazyload_term_meta( $term_ids ); } if ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) { $term_cache = array(); foreach ( $term_objects as $term ) { $object = new stdClass(); $object->term_id = $term->term_id; $object->object_id = $term->object_id; $term_cache[] = $object; } } elseif ( 'all' === $_fields && $args['pad_counts'] ) { $term_cache = array(); foreach ( $term_objects as $term ) { $object = new stdClass(); $object->term_id = $term->term_id; $object->count = $term->count; $term_cache[] = $object; } } elseif ( $fields_is_filtered ) { $term_cache = $term_objects; } else { $term_cache = wp_list_pluck( $term_objects, 'term_id' ); } if ( $args['cache_results'] ) { wp_cache_set_salted( $cache_key, $term_cache, 'term-queries', $last_changed ); } $this->terms = $this->format_terms( $term_objects, $_fields ); return $this->terms; } protected function parse_orderby( $orderby_raw ) { $_orderby = strtolower( $orderby_raw ); $maybe_orderby_meta = false; if ( in_array( $_orderby, array( 'term_id', 'name', 'slug', 'term_group' ), true ) ) { $orderby = "t.$_orderby"; } elseif ( in_array( $_orderby, array( 'count', 'parent', 'taxonomy', 'term_taxonomy_id', 'description' ), true ) ) { $orderby = "tt.$_orderby"; } elseif ( 'term_order' === $_orderby ) { $orderby = 'tr.term_order'; } elseif ( 'include' === $_orderby && ! empty( $this->query_vars['include'] ) ) { $include = implode( ',', wp_parse_id_list( $this->query_vars['include'] ) ); $orderby = "FIELD( t.term_id, $include )"; } elseif ( 'slug__in' === $_orderby && ! empty( $this->query_vars['slug'] ) && is_array( $this->query_vars['slug'] ) ) { $slugs = implode( "', '", array_map( 'sanitize_title_for_query', $this->query_vars['slug'] ) ); $orderby = "FIELD( t.slug, '" . $slugs . "')"; } elseif ( 'none' === $_orderby ) { $orderby = ''; } elseif ( empty( $_orderby ) || 'id' === $_orderby || 'term_id' === $_orderby ) { $orderby = 't.term_id'; } else { $orderby = 't.name'; $maybe_orderby_meta = true; } $orderby = apply_filters( 'get_terms_orderby', $orderby, $this->query_vars, $this->query_vars['taxonomy'] ); if ( $maybe_orderby_meta ) { $maybe_orderby_meta = $this->parse_orderby_meta( $_orderby ); if ( $maybe_orderby_meta ) { $orderby = $maybe_orderby_meta; } } return $orderby; } protected function format_terms( $term_objects, $_fields ) { $_terms = array(); if ( 'id=>parent' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[ $term->term_id ] = $term->parent; } } elseif ( 'ids' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[] = (int) $term->term_id; } } elseif ( 'tt_ids' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[] = (int) $term->term_taxonomy_id; } } elseif ( 'names' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[] = $term->name; } } elseif ( 'slugs' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[] = $term->slug; } } elseif ( 'id=>name' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[ $term->term_id ] = $term->name; } } elseif ( 'id=>slug' === $_fields ) { foreach ( $term_objects as $term ) { $_terms[ $term->term_id ] = $term->slug; } } elseif ( 'all' === $_fields || 'all_with_object_id' === $_fields ) { $_terms = $term_objects; } return $_terms; } protected function parse_orderby_meta( $orderby_raw ) { $orderby = ''; $this->meta_query->get_sql( 'term', 't', 'term_id' ); $meta_clauses = $this->meta_query->get_clauses(); if ( ! $meta_clauses || ! $orderby_raw ) { return $orderby; } $allowed_keys = array(); $primary_meta_key = null; $primary_meta_query = reset( $meta_clauses ); if ( ! empty( $primary_meta_query['key'] ) ) { $primary_meta_key = $primary_meta_query['key']; $allowed_keys[] = $primary_meta_key; } $allowed_keys[] = 'meta_value'; $allowed_keys[] = 'meta_value_num'; $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_clauses ) ); if ( ! in_array( $orderby_raw, $allowed_keys, true ) ) { return $orderby; } switch ( $orderby_raw ) { case $primary_meta_key: case 'meta_value': if ( ! empty( $primary_meta_query['type'] ) ) { $orderby = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})"; } else { $orderby = "{$primary_meta_query['alias']}.meta_value"; } break; case 'meta_value_num': $orderby = "{$primary_meta_query['alias']}.meta_value+0"; break; default: if ( array_key_exists( $orderby_raw, $meta_clauses ) ) { $meta_clause = $meta_clauses[ $orderby_raw ]; $orderby = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})"; } break; } return $orderby; } protected function parse_order( $order ) { if ( ! is_string( $order ) || empty( $order ) ) { return 'DESC'; } if ( 'ASC' === strtoupper( $order ) ) { return 'ASC'; } else { return 'DESC'; } } protected function get_search_sql( $search ) { global $wpdb; $like = '%' . $wpdb->esc_like( $search ) . '%'; return $wpdb->prepare( '((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like ); } protected function populate_terms( $terms ) { $term_objects = array(); if ( ! is_array( $terms ) ) { return $term_objects; } foreach ( $terms as $key => $term_data ) { if ( is_object( $term_data ) && property_exists( $term_data, 'term_id' ) ) { $term = get_term( $term_data->term_id ); if ( property_exists( $term_data, 'object_id' ) ) { $term->object_id = (int) $term_data->object_id; } if ( property_exists( $term_data, 'count' ) ) { $term->count = (int) $term_data->count; } } else { $term = get_term( $term_data ); } if ( $term instanceof WP_Term ) { $term_objects[ $key ] = $term; } } return $term_objects; } protected function generate_cache_key( array $args, $sql ) { global $wpdb; $cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) ); unset( $cache_args['cache_results'], $cache_args['update_term_meta_cache'] ); if ( 'count' !== $args['fields'] && 'all_with_object_id' !== $args['fields'] ) { $cache_args['fields'] = 'all'; } $sql = $wpdb->remove_placeholder_escape( $sql ); $key = md5( serialize( $cache_args ) . $sql ); return "get_terms:$key"; } }
###require ABSPATH . WPINC . '/class-wp-tax-query.php';
class WP_Tax_Query { public $queries = array(); public $relation; private static $no_results = array( 'join' => array( '' ), 'where' => array( '0 = 1' ), ); protected $table_aliases = array(); public $queried_terms = array(); public $primary_table; public $primary_id_column; public function __construct( $tax_query ) { if ( isset( $tax_query['relation'] ) ) { $this->relation = $this->sanitize_relation( $tax_query['relation'] ); } else { $this->relation = 'AND'; } $this->queries = $this->sanitize_query( $tax_query ); } public function sanitize_query( $queries ) { $cleaned_query = array(); $defaults = array( 'taxonomy' => '', 'terms' => array(), 'field' => 'term_id', 'operator' => 'IN', 'include_children' => true, ); foreach ( $queries as $key => $query ) { if ( 'relation' === $key ) { $cleaned_query['relation'] = $this->sanitize_relation( $query ); } elseif ( self::is_first_order_clause( $query ) ) { $cleaned_clause = array_merge( $defaults, $query ); $cleaned_clause['terms'] = (array) $cleaned_clause['terms']; $cleaned_query[] = $cleaned_clause; if ( ! empty( $cleaned_clause['taxonomy'] ) && 'NOT IN' !== $cleaned_clause['operator'] ) { $taxonomy = $cleaned_clause['taxonomy']; if ( ! isset( $this->queried_terms[ $taxonomy ] ) ) { $this->queried_terms[ $taxonomy ] = array(); } if ( ! empty( $cleaned_clause['terms'] ) && ! isset( $this->queried_terms[ $taxonomy ]['terms'] ) ) { $this->queried_terms[ $taxonomy ]['terms'] = $cleaned_clause['terms']; } if ( ! empty( $cleaned_clause['field'] ) && ! isset( $this->queried_terms[ $taxonomy ]['field'] ) ) { $this->queried_terms[ $taxonomy ]['field'] = $cleaned_clause['field']; } } } elseif ( is_array( $query ) ) { $cleaned_subquery = $this->sanitize_query( $query ); if ( ! empty( $cleaned_subquery ) ) { if ( ! isset( $cleaned_subquery['relation'] ) ) { $cleaned_subquery['relation'] = 'AND'; } $cleaned_query[] = $cleaned_subquery; } } } return $cleaned_query; } public function sanitize_relation( $relation ) { if ( 'OR' === strtoupper( $relation ) ) { return 'OR'; } else { return 'AND'; } } protected static function is_first_order_clause( $query ) { return is_array( $query ) && ( empty( $query ) || array_key_exists( 'terms', $query ) || array_key_exists( 'taxonomy', $query ) || array_key_exists( 'include_children', $query ) || array_key_exists( 'field', $query ) || array_key_exists( 'operator', $query ) ); } public function get_sql( $primary_table, $primary_id_column ) { $this->primary_table = $primary_table; $this->primary_id_column = $primary_id_column; return $this->get_sql_clauses(); } protected function get_sql_clauses() { $queries = $this->queries; $sql = $this->get_sql_for_query( $queries ); if ( ! empty( $sql['where'] ) ) { $sql['where'] = ' AND ' . $sql['where']; } return $sql; } protected function get_sql_for_query( &$query, $depth = 0 ) { $sql_chunks = array( 'join' => array(), 'where' => array(), ); $sql = array( 'join' => '', 'where' => '', ); $indent = ''; for ( $i = 0; $i < $depth; $i++ ) { $indent .= ' '; } foreach ( $query as $key => &$clause ) { if ( 'relation' === $key ) { $relation = $query['relation']; } elseif ( is_array( $clause ) ) { if ( $this->is_first_order_clause( $clause ) ) { $clause_sql = $this->get_sql_for_clause( $clause, $query ); $where_count = count( $clause_sql['where'] ); if ( ! $where_count ) { $sql_chunks['where'][] = ''; } elseif ( 1 === $where_count ) { $sql_chunks['where'][] = $clause_sql['where'][0]; } else { $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; } $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); } else { $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); $sql_chunks['where'][] = $clause_sql['where']; $sql_chunks['join'][] = $clause_sql['join']; } } } $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); if ( empty( $relation ) ) { $relation = 'AND'; } if ( ! empty( $sql_chunks['join'] ) ) { $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); } if ( ! empty( $sql_chunks['where'] ) ) { $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; } return $sql; } public function get_sql_for_clause( &$clause, $parent_query ) { global $wpdb; $sql = array( 'where' => array(), 'join' => array(), ); $join = ''; $where = ''; $this->clean_query( $clause ); if ( is_wp_error( $clause ) ) { return self::$no_results; } $terms = $clause['terms']; $operator = strtoupper( $clause['operator'] ); if ( 'IN' === $operator ) { if ( empty( $terms ) ) { return self::$no_results; } $terms = implode( ',', $terms ); $alias = $this->find_compatible_table_alias( $clause, $parent_query ); if ( false === $alias ) { $i = count( $this->table_aliases ); $alias = $i ? 'tt' . $i : $wpdb->term_relationships; $this->table_aliases[] = $alias; $clause['alias'] = $alias; $join .= " LEFT JOIN $wpdb->term_relationships"; $join .= $i ? " AS $alias" : ''; $join .= " ON ($this->primary_table.$this->primary_id_column = $alias.object_id)"; } $where = "$alias.term_taxonomy_id $operator ($terms)"; } elseif ( 'NOT IN' === $operator ) { if ( empty( $terms ) ) { return $sql; } $terms = implode( ',', $terms ); $where = "$this->primary_table.$this->primary_id_column NOT IN (
SELECT object_id
FROM $wpdb->term_relationships
WHERE term_taxonomy_id IN ($terms)
)"; } elseif ( 'AND' === $operator ) { if ( empty( $terms ) ) { return $sql; } $num_terms = count( $terms ); $terms = implode( ',', $terms ); $where = "(
SELECT COUNT(1)
FROM $wpdb->term_relationships
WHERE term_taxonomy_id IN ($terms)
AND object_id = $this->primary_table.$this->primary_id_column
) = $num_terms"; } elseif ( 'NOT EXISTS' === $operator || 'EXISTS' === $operator ) { $where = $wpdb->prepare( "$operator (
SELECT 1
FROM $wpdb->term_relationships
INNER JOIN $wpdb->term_taxonomy
ON $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
WHERE $wpdb->term_taxonomy.taxonomy = %s
AND $wpdb->term_relationships.object_id = $this->primary_table.$this->primary_id_column
)", $clause['taxonomy'] ); } $sql['join'][] = $join; $sql['where'][] = $where; return $sql; } protected function find_compatible_table_alias( $clause, $parent_query ) { $alias = false; if ( ! isset( $clause['operator'] ) || 'IN' !== $clause['operator'] ) { return $alias; } if ( ! isset( $parent_query['relation'] ) || 'OR' !== $parent_query['relation'] ) { return $alias; } $compatible_operators = array( 'IN' ); foreach ( $parent_query as $sibling ) { if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) { continue; } if ( empty( $sibling['alias'] ) || empty( $sibling['operator'] ) ) { continue; } if ( in_array( strtoupper( $sibling['operator'] ), $compatible_operators, true ) ) { $alias = preg_replace( '/\W/', '_', $sibling['alias'] ); break; } } return $alias; } private function clean_query( &$query ) { if ( empty( $query['taxonomy'] ) ) { if ( 'term_taxonomy_id' !== $query['field'] ) { $query = new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); return; } $query['include_children'] = false; } elseif ( ! taxonomy_exists( $query['taxonomy'] ) ) { $query = new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); return; } if ( 'slug' === $query['field'] || 'name' === $query['field'] ) { $query['terms'] = array_unique( (array) $query['terms'] ); } else { $query['terms'] = wp_parse_id_list( $query['terms'] ); } if ( is_taxonomy_hierarchical( $query['taxonomy'] ) && $query['include_children'] ) { $this->transform_query( $query, 'term_id' ); if ( is_wp_error( $query ) ) { return; } $children = array(); foreach ( $query['terms'] as $term ) { $children = array_merge( $children, get_term_children( $term, $query['taxonomy'] ) ); $children[] = $term; } $query['terms'] = $children; } $this->transform_query( $query, 'term_taxonomy_id' ); } public function transform_query( &$query, $resulting_field ) { if ( empty( $query['terms'] ) ) { return; } if ( $query['field'] === $resulting_field ) { return; } $resulting_field = sanitize_key( $resulting_field ); $terms = array_filter( $query['terms'] ); if ( empty( $terms ) ) { $query['terms'] = array(); $query['field'] = $resulting_field; return; } $args = array( 'get' => 'all', 'number' => 0, 'taxonomy' => $query['taxonomy'], 'update_term_meta_cache' => false, 'orderby' => 'none', ); switch ( $query['field'] ) { case 'slug': $args['slug'] = $terms; break; case 'name': $args['name'] = $terms; break; case 'term_taxonomy_id': $args['term_taxonomy_id'] = $terms; break; default: $args['include'] = wp_parse_id_list( $terms ); break; } if ( ! is_taxonomy_hierarchical( $query['taxonomy'] ) ) { $args['number'] = count( $terms ); } $term_query = new WP_Term_Query(); $term_list = $term_query->query( $args ); if ( is_wp_error( $term_list ) ) { $query = $term_list; return; } if ( 'AND' === $query['operator'] && count( $term_list ) < count( $query['terms'] ) ) { $query = new WP_Error( 'inexistent_terms', __( 'Inexistent terms.' ) ); return; } $query['terms'] = wp_list_pluck( $term_list, $resulting_field ); $query['field'] = $resulting_field; } }
require ABSPATH . WPINC . '/update.php';
###require ABSPATH . WPINC . '/canonical.php';
function redirect_canonical( $requested_url = null, $do_redirect = true ) { global $wp_rewrite, $is_IIS, $wp_query, $wpdb, $wp; if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ), true ) ) { return; } if ( is_preview() && get_query_var( 'p' ) && 'publish' === get_post_status( get_query_var( 'p' ) ) ) { if ( ! isset( $_GET['preview_id'] ) || ! isset( $_GET['preview_nonce'] ) || ! wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . (int) $_GET['preview_id'] ) ) { $wp_query->is_preview = false; } } if ( is_admin() || is_search() || is_preview() || is_trackback() || is_favicon() || ( $is_IIS && ! iis7_supports_permalinks() ) ) { return; } if ( ! $requested_url && isset( $_SERVER['HTTP_HOST'] ) ) { $requested_url = is_ssl() ? 'https://' : 'http://'; $requested_url .= $_SERVER['HTTP_HOST']; $requested_url .= $_SERVER['REQUEST_URI']; } $original = parse_url( $requested_url ); if ( false === $original ) { return; } $original += array( 'host' => '', 'path' => '', 'query' => '', 'scheme' => '', ); $redirect = $original; $redirect_url = false; $redirect_obj = false; $redirect['path'] = preg_replace( '|(%C2%A0)+$|i', '', $redirect['path'] ); if ( get_query_var( 'preview' ) ) { $redirect['query'] = remove_query_arg( 'preview', $redirect['query'] ); } $post_id = get_query_var( 'p' ); if ( is_feed() && $post_id ) { $redirect_url = get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) ); $redirect_obj = get_post( $post_id ); if ( $redirect_url ) { $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type', 'feed' ), $redirect_url ); $redirect['path'] = parse_url( $redirect_url, PHP_URL_PATH ); } } if ( is_singular() && $wp_query->post_count < 1 && $post_id ) { $vars = $wpdb->get_results( $wpdb->prepare( "SELECT post_type, post_parent FROM $wpdb->posts WHERE ID = %d", $post_id ) ); if ( ! empty( $vars[0] ) ) { $vars = $vars[0]; if ( 'revision' === $vars->post_type && $vars->post_parent > 0 ) { $post_id = $vars->post_parent; } $redirect_url = get_permalink( $post_id ); $redirect_obj = get_post( $post_id ); if ( $redirect_url ) { $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url ); } } } if ( is_404() ) { $post_id = max( get_query_var( 'p' ), get_query_var( 'page_id' ), get_query_var( 'attachment_id' ) ); $redirect_post = $post_id ? get_post( $post_id ) : false; if ( $redirect_post ) { $post_type_obj = get_post_type_object( $redirect_post->post_type ); if ( $post_type_obj && $post_type_obj->public && 'auto-draft' !== $redirect_post->post_status ) { $redirect_url = get_permalink( $redirect_post ); $redirect_obj = get_post( $redirect_post ); $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url ); } } $year = get_query_var( 'year' ); $month = get_query_var( 'monthnum' ); $day = get_query_var( 'day' ); if ( $year && $month && $day ) { $date = sprintf( '%04d-%02d-%02d', $year, $month, $day ); if ( ! wp_checkdate( $month, $day, $year, $date ) ) { $redirect_url = get_month_link( $year, $month ); $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum', 'day' ), $redirect_url ); } } elseif ( $year && $month && $month > 12 ) { $redirect_url = get_year_link( $year ); $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum' ), $redirect_url ); } if ( get_query_var( 'page' ) ) { $post_id = 0; if ( $wp_query->queried_object instanceof WP_Post ) { $post_id = $wp_query->queried_object->ID; } elseif ( $wp_query->post ) { $post_id = $wp_query->post->ID; } if ( $post_id ) { $redirect_url = get_permalink( $post_id ); $redirect_obj = get_post( $post_id ); $redirect['path'] = rtrim( $redirect['path'], (int) get_query_var( 'page' ) . '/' ); $redirect['query'] = remove_query_arg( 'page', $redirect['query'] ); } } if ( ! $redirect_url ) { $redirect_url = redirect_guess_404_permalink(); if ( $redirect_url ) { $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'page', 'feed', 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url ); } } } elseif ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) { if ( is_attachment() && ! array_diff( array_keys( $wp->query_vars ), array( 'attachment', 'attachment_id' ) ) && ! $redirect_url ) { if ( ! empty( $_GET['attachment_id'] ) ) { $redirect_url = get_attachment_link( get_query_var( 'attachment_id' ) ); $redirect_obj = get_post( get_query_var( 'attachment_id' ) ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'attachment_id', $redirect['query'] ); } } else { $redirect_url = get_attachment_link(); $redirect_obj = get_post(); } } elseif ( is_single() && ! empty( $_GET['p'] ) && ! $redirect_url ) { $redirect_url = get_permalink( get_query_var( 'p' ) ); $redirect_obj = get_post( get_query_var( 'p' ) ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( array( 'p', 'post_type' ), $redirect['query'] ); } } elseif ( is_single() && ! empty( $_GET['name'] ) && ! $redirect_url ) { $redirect_url = get_permalink( $wp_query->get_queried_object_id() ); $redirect_obj = get_post( $wp_query->get_queried_object_id() ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'name', $redirect['query'] ); } } elseif ( is_page() && ! empty( $_GET['page_id'] ) && ! $redirect_url ) { $redirect_url = get_permalink( get_query_var( 'page_id' ) ); $redirect_obj = get_post( get_query_var( 'page_id' ) ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] ); } } elseif ( is_page() && ! is_feed() && ! $redirect_url && 'page' === get_option( 'show_on_front' ) && get_queried_object_id() === (int) get_option( 'page_on_front' ) ) { $redirect_url = home_url( '/' ); } elseif ( is_home() && ! empty( $_GET['page_id'] ) && ! $redirect_url && 'page' === get_option( 'show_on_front' ) && get_query_var( 'page_id' ) === (int) get_option( 'page_for_posts' ) ) { $redirect_url = get_permalink( get_option( 'page_for_posts' ) ); $redirect_obj = get_post( get_option( 'page_for_posts' ) ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] ); } } elseif ( ! empty( $_GET['m'] ) && ( is_year() || is_month() || is_day() ) ) { $m = get_query_var( 'm' ); switch ( strlen( $m ) ) { case 4: $redirect_url = get_year_link( $m ); break; case 6: $redirect_url = get_month_link( substr( $m, 0, 4 ), substr( $m, 4, 2 ) ); break; case 8: $redirect_url = get_day_link( substr( $m, 0, 4 ), substr( $m, 4, 2 ), substr( $m, 6, 2 ) ); break; } if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'm', $redirect['query'] ); } } elseif ( is_date() ) { $year = get_query_var( 'year' ); $month = get_query_var( 'monthnum' ); $day = get_query_var( 'day' ); if ( is_day() && $year && $month && ! empty( $_GET['day'] ) ) { $redirect_url = get_day_link( $year, $month, $day ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( array( 'year', 'monthnum', 'day' ), $redirect['query'] ); } } elseif ( is_month() && $year && ! empty( $_GET['monthnum'] ) ) { $redirect_url = get_month_link( $year, $month ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( array( 'year', 'monthnum' ), $redirect['query'] ); } } elseif ( is_year() && ! empty( $_GET['year'] ) ) { $redirect_url = get_year_link( $year ); if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'year', $redirect['query'] ); } } } elseif ( is_author() && ! empty( $_GET['author'] ) && is_string( $_GET['author'] ) && preg_match( '|^[0-9]+$|', $_GET['author'] ) ) { $author = get_userdata( get_query_var( 'author' ) ); if ( false !== $author && $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_author = %d AND $wpdb->posts.post_status = 'publish' LIMIT 1", $author->ID ) ) ) { $redirect_url = get_author_posts_url( $author->ID, $author->user_nicename ); $redirect_obj = $author; if ( $redirect_url ) { $redirect['query'] = remove_query_arg( 'author', $redirect['query'] ); } } } elseif ( is_category() || is_tag() || is_tax() ) { $term_count = 0; foreach ( $wp_query->tax_query->queried_terms as $tax_query ) { if ( isset( $tax_query['terms'] ) && is_countable( $tax_query['terms'] ) ) { $term_count += count( $tax_query['terms'] ); } } $obj = $wp_query->get_queried_object(); if ( $term_count <= 1 && ! empty( $obj->term_id ) ) { $tax_url = get_term_link( (int) $obj->term_id, $obj->taxonomy ); if ( $tax_url && ! is_wp_error( $tax_url ) ) { if ( ! empty( $redirect['query'] ) ) { $qv_remove = array( 'term', 'taxonomy' ); if ( is_category() ) { $qv_remove[] = 'category_name'; $qv_remove[] = 'cat'; } elseif ( is_tag() ) { $qv_remove[] = 'tag'; $qv_remove[] = 'tag_id'; } else { $tax_obj = get_taxonomy( $obj->taxonomy ); if ( false !== $tax_obj->query_var ) { $qv_remove[] = $tax_obj->query_var; } } $rewrite_vars = array_diff( array_keys( $wp_query->query ), array_keys( $_GET ) ); if ( ! array_diff( $rewrite_vars, array_keys( $_GET ) ) ) { $redirect['query'] = remove_query_arg( $qv_remove, $redirect['query'] ); $tax_url = parse_url( $tax_url ); if ( ! empty( $tax_url['query'] ) ) { parse_str( $tax_url['query'], $query_vars ); $redirect['query'] = add_query_arg( $query_vars, $redirect['query'] ); } else { $redirect['path'] = $tax_url['path']; } } else { foreach ( $qv_remove as $_qv ) { if ( isset( $rewrite_vars[ $_qv ] ) ) { $redirect['query'] = remove_query_arg( $_qv, $redirect['query'] ); } } } } } } } elseif ( is_single() && str_contains( $wp_rewrite->permalink_structure, '%category%' ) ) { $category_name = get_query_var( 'category_name' ); if ( $category_name ) { $category = get_category_by_path( $category_name ); if ( ! $category || is_wp_error( $category ) || ! has_term( $category->term_id, 'category', $wp_query->get_queried_object_id() ) ) { $redirect_url = get_permalink( $wp_query->get_queried_object_id() ); $redirect_obj = get_post( $wp_query->get_queried_object_id() ); } } } if ( is_singular() && get_query_var( 'page' ) ) { $page = get_query_var( 'page' ); if ( ! $redirect_url ) { $redirect_url = get_permalink( get_queried_object_id() ); $redirect_obj = get_post( get_queried_object_id() ); } if ( $page > 1 ) { $redirect_url = trailingslashit( $redirect_url ); if ( is_front_page() ) { $redirect_url .= user_trailingslashit( "$wp_rewrite->pagination_base/$page", 'paged' ); } else { $redirect_url .= user_trailingslashit( $page, 'single_paged' ); } } $redirect['query'] = remove_query_arg( 'page', $redirect['query'] ); } if ( get_query_var( 'sitemap' ) ) { $redirect_url = get_sitemap_url( get_query_var( 'sitemap' ), get_query_var( 'sitemap-subtype' ), get_query_var( 'paged' ) ); $redirect['query'] = remove_query_arg( array( 'sitemap', 'sitemap-subtype', 'paged' ), $redirect['query'] ); } elseif ( get_query_var( 'paged' ) || is_feed() || get_query_var( 'cpage' ) ) { $paged = get_query_var( 'paged' ); $feed = get_query_var( 'feed' ); $cpage = get_query_var( 'cpage' ); while ( preg_match( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", $redirect['path'] ) || preg_match( '#/(comments/?)?(feed|rss2?|rdf|atom)(/+)?$#', $redirect['path'] ) || preg_match( "#/{$wp_rewrite->comments_pagination_base}-[0-9]+(/+)?$#", $redirect['path'] ) ) { $redirect['path'] = preg_replace( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", '/', $redirect['path'] ); $redirect['path'] = preg_replace( '#/(comments/?)?(feed|rss2?|rdf|atom)(/+|$)#', '/', $redirect['path'] ); $redirect['path'] = preg_replace( "#/{$wp_rewrite->comments_pagination_base}-[0-9]+?(/+)?$#", '/', $redirect['path'] ); } $addl_path = ''; $default_feed = get_default_feed(); if ( is_feed() && in_array( $feed, $wp_rewrite->feeds, true ) ) { $addl_path = ! empty( $addl_path ) ? trailingslashit( $addl_path ) : ''; if ( ! is_singular() && get_query_var( 'withcomments' ) ) { $addl_path .= 'comments/'; } if ( ( 'rss' === $default_feed && 'feed' === $feed ) || 'rss' === $feed ) { $format = ( 'rss2' === $default_feed ) ? '' : 'rss2'; } else { $format = ( $default_feed === $feed || 'feed' === $feed ) ? '' : $feed; } $addl_path .= user_trailingslashit( 'feed/' . $format, 'feed' ); $redirect['query'] = remove_query_arg( 'feed', $redirect['query'] ); } elseif ( is_feed() && 'old' === $feed ) { $old_feed_files = array( 'wp-atom.php' => 'atom', 'wp-commentsrss2.php' => 'comments_rss2', 'wp-feed.php' => $default_feed, 'wp-rdf.php' => 'rdf', 'wp-rss.php' => 'rss2', 'wp-rss2.php' => 'rss2', ); if ( isset( $old_feed_files[ basename( $redirect['path'] ) ] ) ) { $redirect_url = get_feed_link( $old_feed_files[ basename( $redirect['path'] ) ] ); wp_redirect( $redirect_url, 301 ); die(); } } if ( $paged > 0 ) { $redirect['query'] = remove_query_arg( 'paged', $redirect['query'] ); if ( ! is_feed() ) { if ( ! is_single() ) { $addl_path = ! empty( $addl_path ) ? trailingslashit( $addl_path ) : ''; if ( $paged > 1 ) { $addl_path .= user_trailingslashit( "$wp_rewrite->pagination_base/$paged", 'paged' ); } } } elseif ( $paged > 1 ) { $redirect['query'] = add_query_arg( 'paged', $paged, $redirect['query'] ); } } $default_comments_page = get_option( 'default_comments_page' ); if ( get_option( 'page_comments' ) && ( 'newest' === $default_comments_page && $cpage > 0 || 'newest' !== $default_comments_page && $cpage > 1 ) ) { $addl_path = ( ! empty( $addl_path ) ? trailingslashit( $addl_path ) : '' ); $addl_path .= user_trailingslashit( $wp_rewrite->comments_pagination_base . '-' . $cpage, 'commentpaged' ); $redirect['query'] = remove_query_arg( 'cpage', $redirect['query'] ); } $redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/?$|', '/', $redirect['path'] ); $redirect['path'] = user_trailingslashit( $redirect['path'] ); if ( ! empty( $addl_path ) && $wp_rewrite->using_index_permalinks() && ! str_contains( $redirect['path'], '/' . $wp_rewrite->index . '/' ) ) { $redirect['path'] = trailingslashit( $redirect['path'] ) . $wp_rewrite->index . '/'; } if ( ! empty( $addl_path ) ) { $redirect['path'] = trailingslashit( $redirect['path'] ) . $addl_path; } $redirect_url = $redirect['scheme'] . '://' . $redirect['host'] . $redirect['path']; } if ( 'wp-register.php' === basename( $redirect['path'] ) ) { if ( is_multisite() ) { $redirect_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ); } else { $redirect_url = wp_registration_url(); } wp_redirect( $redirect_url, 301 ); die(); } } $is_attachment_redirect = false; if ( is_attachment() && ! get_option( 'wp_attachment_pages_enabled' ) ) { $attachment_id = get_query_var( 'attachment_id' ); $attachment_post = get_post( $attachment_id ); $attachment_parent_id = $attachment_post ? $attachment_post->post_parent : 0; $attachment_url = wp_get_attachment_url( $attachment_id ); if ( $attachment_url !== $redirect_url ) { if ( $attachment_parent_id ) { $redirect_obj = get_post( $attachment_parent_id ); } $redirect_url = $attachment_url; } $is_attachment_redirect = true; } $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] ); if ( $redirect_url && ! empty( $redirect['query'] ) ) { parse_str( $redirect['query'], $_parsed_query ); $redirect = parse_url( $redirect_url ); if ( ! empty( $_parsed_query['name'] ) && ! empty( $redirect['query'] ) ) { parse_str( $redirect['query'], $_parsed_redirect_query ); if ( empty( $_parsed_redirect_query['name'] ) ) { unset( $_parsed_query['name'] ); } } $_parsed_query = array_combine( rawurlencode_deep( array_keys( $_parsed_query ) ), rawurlencode_deep( array_values( $_parsed_query ) ) ); $redirect_url = add_query_arg( $_parsed_query, $redirect_url ); } if ( $redirect_url ) { $redirect = parse_url( $redirect_url ); } $user_home = parse_url( home_url() ); if ( ! empty( $user_home['host'] ) ) { $redirect['host'] = $user_home['host']; } if ( empty( $user_home['path'] ) ) { $user_home['path'] = '/'; } if ( ! empty( $user_home['port'] ) ) { $redirect['port'] = $user_home['port']; } else { unset( $redirect['port'] ); } $redirect += array( 'host' => '', 'path' => '', 'query' => '', 'scheme' => '', ); $redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/*?$|', '/', $redirect['path'] ); $punctuation_pattern = implode( '|', array_map( 'preg_quote', array( ' ', '%20', '!', '%21', '"', '%22', "'", '%27', '(', '%28', ')', '%29', ',', '%2C', '.', '%2E', ';', '%3B', '{', '%7B', '}', '%7D', '%E2%80%9C', '%E2%80%9D', ) ) ); $redirect['path'] = preg_replace( "#($punctuation_pattern)+$#", '', $redirect['path'] ); if ( ! empty( $redirect['query'] ) ) { $redirect['query'] = preg_replace( "#((^|&)(p|page_id|cat|tag)=[^&]*?)($punctuation_pattern)+$#", '$1', $redirect['query'] ); $redirect['query'] = trim( preg_replace( '#(^|&)(p|page_id|cat|tag)=?(&|$)#', '&', $redirect['query'] ), '&' ); $redirect['query'] = preg_replace( '#(^|&)feed=rss(&|$)#', '$1feed=rss2$2', $redirect['query'] ); $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] ); } if ( ! $wp_rewrite->using_index_permalinks() ) { $redirect['path'] = str_replace( '/' . $wp_rewrite->index . '/', '/', $redirect['path'] ); } if ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() && ! $is_attachment_redirect && ! is_404() && ( ! is_front_page() || is_front_page() && get_query_var( 'paged' ) > 1 ) ) { $user_ts_type = ''; if ( get_query_var( 'paged' ) > 0 ) { $user_ts_type = 'paged'; } else { foreach ( array( 'single', 'category', 'page', 'day', 'month', 'year', 'home' ) as $type ) { $func = 'is_' . $type; if ( call_user_func( $func ) ) { $user_ts_type = $type; break; } } } $redirect['path'] = user_trailingslashit( $redirect['path'], $user_ts_type ); } elseif ( is_front_page() ) { $redirect['path'] = trailingslashit( $redirect['path'] ); } if ( is_robots() || ! empty( get_query_var( 'sitemap' ) ) || ! empty( get_query_var( 'sitemap-stylesheet' ) ) ) { $redirect['path'] = untrailingslashit( $redirect['path'] ); } if ( str_contains( $redirect['path'], '//' ) ) { $redirect['path'] = preg_replace( '|/+|', '/', $redirect['path'] ); } if ( trailingslashit( $redirect['path'] ) === trailingslashit( $user_home['path'] ) ) { $redirect['path'] = trailingslashit( $redirect['path'] ); } $original_host_low = strtolower( $original['host'] ); $redirect_host_low = strtolower( $redirect['host'] ); if ( $original_host_low === $redirect_host_low || ( 'www.' . $original_host_low !== $redirect_host_low && 'www.' . $redirect_host_low !== $original_host_low ) ) { $redirect['host'] = $original['host']; } $compare_original = array( $original['host'], $original['path'] ); if ( ! empty( $original['port'] ) ) { $compare_original[] = $original['port']; } if ( ! empty( $original['query'] ) ) { $compare_original[] = $original['query']; } $compare_redirect = array( $redirect['host'], $redirect['path'] ); if ( ! empty( $redirect['port'] ) ) { $compare_redirect[] = $redirect['port']; } if ( ! empty( $redirect['query'] ) ) { $compare_redirect[] = $redirect['query']; } if ( $compare_original !== $compare_redirect ) { $redirect_url = $redirect['scheme'] . '://' . $redirect['host']; if ( ! empty( $redirect['port'] ) ) { $redirect_url .= ':' . $redirect['port']; } $redirect_url .= $redirect['path']; if ( ! empty( $redirect['query'] ) ) { $redirect_url .= '?' . $redirect['query']; } } if ( ! $redirect_url || $redirect_url === $requested_url ) { return; } if ( str_contains( $requested_url, '%' ) ) { if ( ! function_exists( 'lowercase_octets' ) ) { function lowercase_octets( $matches ) { return strtolower( $matches[0] ); } } $requested_url = preg_replace_callback( '|%[a-fA-F0-9][a-fA-F0-9]|', 'lowercase_octets', $requested_url ); } if ( $redirect_obj instanceof WP_Post ) { $post_status_obj = get_post_status_object( get_post_status( $redirect_obj ) ); if ( ! ( $post_status_obj->private && current_user_can( 'read_post', $redirect_obj->ID ) ) && ! is_post_publicly_viewable( $redirect_obj ) ) { $redirect_obj = false; $redirect_url = false; } } $redirect_url = apply_filters( 'redirect_canonical', $redirect_url, $requested_url ); if ( ! $redirect_url || strip_fragment_from_url( $redirect_url ) === strip_fragment_from_url( $requested_url ) ) { return; } if ( $do_redirect ) { if ( ! redirect_canonical( $redirect_url, false ) ) { wp_redirect( $redirect_url, 301 ); exit; } else { return; } } else { return $redirect_url; } } function _remove_qs_args_if_not_in_url( $query_string, array $args_to_check, $url ) { $parsed_url = parse_url( $url ); if ( ! empty( $parsed_url['query'] ) ) { parse_str( $parsed_url['query'], $parsed_query ); foreach ( $args_to_check as $qv ) { if ( ! isset( $parsed_query[ $qv ] ) ) { $query_string = remove_query_arg( $qv, $query_string ); } } } else { $query_string = remove_query_arg( $args_to_check, $query_string ); } return $query_string; } function strip_fragment_from_url( $url ) { $parsed_url = wp_parse_url( $url ); if ( ! empty( $parsed_url['host'] ) ) { $url = ''; if ( ! empty( $parsed_url['scheme'] ) ) { $url = $parsed_url['scheme'] . ':'; } $url .= '//' . $parsed_url['host']; if ( ! empty( $parsed_url['port'] ) ) { $url .= ':' . $parsed_url['port']; } if ( ! empty( $parsed_url['path'] ) ) { $url .= $parsed_url['path']; } if ( ! empty( $parsed_url['query'] ) ) { $url .= '?' . $parsed_url['query']; } } return $url; } function redirect_guess_404_permalink() { global $wpdb; if ( false === apply_filters( 'do_redirect_guess_404_permalink', true ) ) { return false; } $pre = apply_filters( 'pre_redirect_guess_404_permalink', null ); if ( null !== $pre ) { return $pre; } if ( get_query_var( 'name' ) ) { $publicly_viewable_statuses = array_filter( get_post_stati(), 'is_post_status_viewable' ); $publicly_viewable_post_types = array_filter( get_post_types( array( 'exclude_from_search' => false ) ), 'is_post_type_viewable' ); $strict_guess = apply_filters( 'strict_redirect_guess_404_permalink', false ); if ( $strict_guess ) { $where = $wpdb->prepare( 'post_name = %s', get_query_var( 'name' ) ); } else { $where = $wpdb->prepare( 'post_name LIKE %s', $wpdb->esc_like( get_query_var( 'name' ) ) . '%' ); } if ( get_query_var( 'post_type' ) ) { if ( is_array( get_query_var( 'post_type' ) ) ) { $post_types = array_intersect( get_query_var( 'post_type' ), $publicly_viewable_post_types ); if ( empty( $post_types ) ) { return false; } $where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')"; } else { if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) { return false; } $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) ); } } else { $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')"; } if ( get_query_var( 'year' ) ) { $where .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) ); } if ( get_query_var( 'monthnum' ) ) { $where .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) ); } if ( get_query_var( 'day' ) ) { $where .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) ); } $post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status IN ('" . implode( "', '", esc_sql( $publicly_viewable_statuses ) ) . "')" ); if ( ! $post_id ) { return false; } if ( get_query_var( 'feed' ) ) { return get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) ); } elseif ( get_query_var( 'page' ) > 1 ) { return trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' ); } else { return get_permalink( $post_id ); } } return false; } function wp_redirect_admin_locations() { global $wp_rewrite; if ( ! ( is_404() && $wp_rewrite->using_permalinks() ) ) { return; } $admins = array( home_url( 'wp-admin', 'relative' ), home_url( 'dashboard', 'relative' ), home_url( 'admin', 'relative' ), site_url( 'dashboard', 'relative' ), site_url( 'admin', 'relative' ), ); if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins, true ) ) { wp_redirect( admin_url() ); exit; } $logins = array( home_url( 'wp-login.php', 'relative' ), home_url( 'login.php', 'relative' ), home_url( 'login', 'relative' ), site_url( 'login', 'relative' ), ); if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $logins, true ) ) { wp_redirect( wp_login_url() ); exit; } }
###require ABSPATH . WPINC . '/shortcodes.php';
$shortcode_tags = array(); function add_shortcode( $tag, $callback ) { global $shortcode_tags; if ( '' === trim( $tag ) ) { _doing_it_wrong( __FUNCTION__, __( 'Invalid shortcode name: Empty name given.' ), '4.4.0' ); return; } if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ), $tag, '& / < > [ ] =' ), '4.4.0' ); return; } $shortcode_tags[ $tag ] = $callback; } function remove_shortcode( $tag ) { global $shortcode_tags; unset( $shortcode_tags[ $tag ] ); } function remove_all_shortcodes() { global $shortcode_tags; $shortcode_tags = array(); } function shortcode_exists( $tag ) { global $shortcode_tags; return array_key_exists( $tag, $shortcode_tags ); } function has_shortcode( $content, $tag ) { if ( ! str_contains( $content, '[' ) ) { return false; } if ( shortcode_exists( $tag ) ) { preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER ); if ( empty( $matches ) ) { return false; } foreach ( $matches as $shortcode ) { if ( $tag === $shortcode[2] ) { return true; } elseif ( ! empty( $shortcode[5] ) && has_shortcode( $shortcode[5], $tag ) ) { return true; } } } return false; } function get_shortcode_tags_in_content( $content ) { if ( ! str_contains( $content, '[' ) ) { return array(); } preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER ); if ( empty( $matches ) ) { return array(); } $tags = array(); foreach ( $matches as $shortcode ) { $tags[] = $shortcode[2]; if ( ! empty( $shortcode[5] ) ) { $deep_tags = get_shortcode_tags_in_content( $shortcode[5] ); if ( ! empty( $deep_tags ) ) { $tags = array_merge( $tags, $deep_tags ); } } } return $tags; } function apply_shortcodes( $content, $ignore_html = false ) { return do_shortcode( $content, $ignore_html ); } function do_shortcode( $content, $ignore_html = false ) { global $shortcode_tags; if ( ! str_contains( $content, '[' ) ) { return $content; } if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) { return $content; } preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches ); $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); if ( empty( $tagnames ) ) { return $content; } $has_filter = has_filter( 'wp_get_attachment_image_context', '_filter_do_shortcode_context' ); $filter_added = false; if ( ! $has_filter ) { $filter_added = add_filter( 'wp_get_attachment_image_context', '_filter_do_shortcode_context' ); } $content = do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ); $pattern = get_shortcode_regex( $tagnames ); $content = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $content ); $content = unescape_invalid_shortcodes( $content ); if ( $filter_added ) { remove_filter( 'wp_get_attachment_image_context', '_filter_do_shortcode_context' ); } return $content; } function _filter_do_shortcode_context() { return 'do_shortcode'; } function get_shortcode_regex( $tagnames = null ) { global $shortcode_tags; if ( empty( $tagnames ) ) { $tagnames = array_keys( $shortcode_tags ); } $tagregexp = implode( '|', array_map( 'preg_quote', $tagnames ) ); return '\\[' . '(\\[?)' . "($tagregexp)" . '(?![\\w-])' . '(' . '[^\\]\\/]*' . '(?:' . '\\/(?!\\])' . '[^\\]\\/]*' . ')*?' . ')' . '(?:' . '(\\/)' . '\\]' . '|' . '\\]' . '(?:' . '(' . '[^\\[]*+' . '(?:' . '\\[(?!\\/\\2\\])' . '[^\\[]*+' . ')*+' . ')' . '\\[\\/\\2\\]' . ')?' . ')' . '(\\]?)'; } function do_shortcode_tag( $m ) { global $shortcode_tags; if ( '[' === $m[1] && ']' === $m[6] ) { return substr( $m[0], 1, -1 ); } $tag = $m[2]; $attr = shortcode_parse_atts( $m[3] ); if ( ! is_callable( $shortcode_tags[ $tag ] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Attempting to parse a shortcode without a valid callback: %s' ), $tag ), '4.3.0' ); return $m[0]; } $return = apply_filters( 'pre_do_shortcode_tag', false, $tag, $attr, $m ); if ( false !== $return ) { return $return; } $content = isset( $m[5] ) ? $m[5] : null; $output = $m[1] . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . $m[6]; return apply_filters( 'do_shortcode_tag', $output, $tag, $attr, $m ); } function do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ) { $trans = array( '[' => '[', ']' => ']', ); $content = strtr( $content, $trans ); $trans = array( '[' => '[', ']' => ']', ); $pattern = get_shortcode_regex( $tagnames ); $textarr = wp_html_split( $content ); foreach ( $textarr as &$element ) { if ( '' === $element || '<' !== $element[0] ) { continue; } $noopen = ! str_contains( $element, '[' ); $noclose = ! str_contains( $element, ']' ); if ( $noopen || $noclose ) { if ( $noopen xor $noclose ) { $element = strtr( $element, $trans ); } continue; } if ( $ignore_html || str_starts_with( $element, '<!--' ) || str_starts_with( $element, '<![CDATA[' ) ) { $element = strtr( $element, $trans ); continue; } $attributes = wp_kses_attr_parse( $element ); if ( false === $attributes ) { if ( 1 === preg_match( '%^<\s*\[\[?[^\[\]]+\]%', $element ) ) { $element = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $element ); } $element = strtr( $element, $trans ); continue; } $front = array_shift( $attributes ); $back = array_pop( $attributes ); $matches = array(); preg_match( '%[a-zA-Z0-9]+%', $front, $matches ); $elname = $matches[0]; foreach ( $attributes as &$attr ) { $open = strpos( $attr, '[' ); $close = strpos( $attr, ']' ); if ( false === $open || false === $close ) { continue; } $double = strpos( $attr, '"' ); $single = strpos( $attr, "'" ); if ( ( false === $single || $open < $single ) && ( false === $double || $open < $double ) ) { $attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr ); } else { $count = 0; $new_attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr, -1, $count ); if ( $count > 0 ) { $new_attr = wp_kses_one_attr( $new_attr, $elname ); if ( '' !== trim( $new_attr ) ) { $attr = $new_attr; } } } } $element = $front . implode( '', $attributes ) . $back; $element = strtr( $element, $trans ); } $content = implode( '', $textarr ); return $content; } function unescape_invalid_shortcodes( $content ) { $trans = array( '[' => '[', ']' => ']', ); $content = strtr( $content, $trans ); return $content; } function get_shortcode_atts_regex() { return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|\'([^\']*)\'(?:\s|$)|(\S+)(?:\s|$)/'; } function shortcode_parse_atts( $text ) { $atts = array(); $pattern = get_shortcode_atts_regex(); $text = preg_replace( "/[\x{00a0}\x{200b}]+/u", ' ', $text ); if ( preg_match_all( $pattern, $text, $match, PREG_SET_ORDER ) ) { foreach ( $match as $m ) { if ( ! empty( $m[1] ) ) { $atts[ strtolower( $m[1] ) ] = stripcslashes( $m[2] ); } elseif ( ! empty( $m[3] ) ) { $atts[ strtolower( $m[3] ) ] = stripcslashes( $m[4] ); } elseif ( ! empty( $m[5] ) ) { $atts[ strtolower( $m[5] ) ] = stripcslashes( $m[6] ); } elseif ( isset( $m[7] ) && strlen( $m[7] ) ) { $atts[] = stripcslashes( $m[7] ); } elseif ( isset( $m[8] ) && strlen( $m[8] ) ) { $atts[] = stripcslashes( $m[8] ); } elseif ( isset( $m[9] ) ) { $atts[] = stripcslashes( $m[9] ); } } foreach ( $atts as &$value ) { if ( str_contains( $value, '<' ) ) { if ( 1 !== preg_match( '/^[^<]*+(?:<[^>]*+>[^<]*+)*+$/', $value ) ) { $value = ''; } } } } return $atts; } function shortcode_atts( $pairs, $atts, $shortcode = '' ) { $atts = (array) $atts; $out = array(); foreach ( $pairs as $name => $default ) { if ( array_key_exists( $name, $atts ) ) { $out[ $name ] = $atts[ $name ]; } else { $out[ $name ] = $default; } } if ( $shortcode ) { $out = apply_filters( "shortcode_atts_{$shortcode}", $out, $pairs, $atts, $shortcode ); } return $out; } function strip_shortcodes( $content ) { global $shortcode_tags; if ( ! str_contains( $content, '[' ) ) { return $content; } if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) { return $content; } preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches ); $tags_to_remove = array_keys( $shortcode_tags ); $tags_to_remove = apply_filters( 'strip_shortcodes_tagnames', $tags_to_remove, $content ); $tagnames = array_intersect( $tags_to_remove, $matches[1] ); if ( empty( $tagnames ) ) { return $content; } $content = do_shortcodes_in_html_tags( $content, true, $tagnames ); $pattern = get_shortcode_regex( $tagnames ); $content = preg_replace_callback( "/$pattern/", 'strip_shortcode_tag', $content ); $content = unescape_invalid_shortcodes( $content ); return $content; } function strip_shortcode_tag( $m ) { if ( '[' === $m[1] && ']' === $m[6] ) { return substr( $m[0], 1, -1 ); } return $m[1] . $m[6]; }
###require ABSPATH . WPINC . '/embed.php';
function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) { global $wp_embed; $wp_embed->register_handler( $id, $regex, $callback, $priority ); } function wp_embed_unregister_handler( $id, $priority = 10 ) { global $wp_embed; $wp_embed->unregister_handler( $id, $priority ); } function wp_embed_defaults( $url = '' ) { if ( ! empty( $GLOBALS['content_width'] ) ) { $width = (int) $GLOBALS['content_width']; } if ( empty( $width ) ) { $width = 500; } $height = min( (int) ceil( $width * 1.5 ), 1000 ); return apply_filters( 'embed_defaults', compact( 'width', 'height' ), $url ); } function wp_oembed_get( $url, $args = '' ) { $oembed = _wp_oembed_get_object(); return $oembed->get_html( $url, $args ); } function _wp_oembed_get_object() { static $wp_oembed = null; if ( is_null( $wp_oembed ) ) { $wp_oembed = new WP_oEmbed(); } return $wp_oembed; } function wp_oembed_add_provider( $format, $provider, $regex = false ) { if ( did_action( 'plugins_loaded' ) ) { $oembed = _wp_oembed_get_object(); $oembed->providers[ $format ] = array( $provider, $regex ); } else { WP_oEmbed::_add_provider_early( $format, $provider, $regex ); } } function wp_oembed_remove_provider( $format ) { if ( did_action( 'plugins_loaded' ) ) { $oembed = _wp_oembed_get_object(); if ( isset( $oembed->providers[ $format ] ) ) { unset( $oembed->providers[ $format ] ); return true; } } else { WP_oEmbed::_remove_provider_early( $format ); } return false; } function wp_maybe_load_embeds() { if ( ! apply_filters( 'load_default_embeds', true ) ) { return; } wp_embed_register_handler( 'youtube_embed_url', '#https?://(www\.)?youtube\.com/(?:v|embed)/([^/]+)#i', 'wp_embed_handler_youtube' ); wp_embed_register_handler( 'audio', '#^https?://.+?\.(' . implode( '|', wp_get_audio_extensions() ) . ')$#i', apply_filters( 'wp_audio_embed_handler', 'wp_embed_handler_audio' ), 9999 ); wp_embed_register_handler( 'video', '#^https?://.+?\.(' . implode( '|', wp_get_video_extensions() ) . ')$#i', apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' ), 9999 ); } function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { global $wp_embed; $embed = $wp_embed->autoembed( sprintf( 'https://youtube.com/watch?v=%s', urlencode( $matches[2] ) ) ); return apply_filters( 'wp_embed_handler_youtube', $embed, $attr, $url, $rawattr ); } function wp_embed_handler_audio( $matches, $attr, $url, $rawattr ) { $audio = sprintf( '[audio src="%s" /]', esc_url( $url ) ); return apply_filters( 'wp_embed_handler_audio', $audio, $attr, $url, $rawattr ); } function wp_embed_handler_video( $matches, $attr, $url, $rawattr ) { $dimensions = ''; if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) { $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] ); $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] ); } $video = sprintf( '[video %s src="%s" /]', $dimensions, esc_url( $url ) ); return apply_filters( 'wp_embed_handler_video', $video, $attr, $url, $rawattr ); } function wp_oembed_register_route() { $controller = new WP_oEmbed_Controller(); $controller->register_routes(); } function wp_oembed_add_discovery_links() { if ( doing_action( 'wp_head' ) ) { if ( ! has_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 ) ) { return; } remove_action( 'wp_head', 'wp_oembed_add_discovery_links' ); } $output = ''; if ( is_singular() && is_post_embeddable() ) { $output .= '<link rel="alternate" title="' . _x( 'oEmbed (JSON)', 'oEmbed resource link name' ) . '" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n"; if ( class_exists( 'SimpleXMLElement' ) ) { $output .= '<link rel="alternate" title="' . _x( 'oEmbed (XML)', 'oEmbed resource link name' ) . '" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n"; } } echo apply_filters( 'oembed_discovery_links', $output ); } function wp_oembed_add_host_js() {} function wp_maybe_enqueue_oembed_host_js( $html ) { if ( has_action( 'wp_head', 'wp_oembed_add_host_js' ) && preg_match( '/<blockquote\s[^>]*?wp-embedded-content/', $html ) ) { wp_enqueue_script( 'wp-embed' ); } return $html; } function get_post_embed_url( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $embed_url = trailingslashit( get_permalink( $post ) ) . user_trailingslashit( 'embed' ); $path_conflict = get_page_by_path( str_replace( home_url(), '', $embed_url ), OBJECT, get_post_types( array( 'public' => true ) ) ); if ( ! get_option( 'permalink_structure' ) || $path_conflict ) { $embed_url = add_query_arg( array( 'embed' => 'true' ), get_permalink( $post ) ); } return sanitize_url( apply_filters( 'post_embed_url', $embed_url, $post ) ); } function get_oembed_endpoint_url( $permalink = '', $format = 'json' ) { $url = rest_url( 'oembed/1.0/embed' ); if ( '' !== $permalink ) { $url = add_query_arg( array( 'url' => urlencode( $permalink ), 'format' => ( 'json' !== $format ) ? $format : false, ), $url ); } return apply_filters( 'oembed_endpoint_url', $url, $permalink, $format ); } function get_post_embed_html( $width, $height, $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $embed_url = get_post_embed_url( $post ); $secret = wp_generate_password( 10, false ); $embed_url .= "#?secret={$secret}"; $output = sprintf( '<blockquote class="wp-embedded-content" data-secret="%1$s"><a href="%2$s">%3$s</a></blockquote>', esc_attr( $secret ), esc_url( get_permalink( $post ) ), get_the_title( $post ) ); $output .= sprintf( '<iframe sandbox="allow-scripts" security="restricted" src="%1$s" width="%2$d" height="%3$d" title="%4$s" data-secret="%5$s" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe>', esc_url( $embed_url ), absint( $width ), absint( $height ), esc_attr( sprintf( __( '“%1$s” — %2$s' ), get_the_title( $post ), get_bloginfo( 'name' ) ) ), esc_attr( $secret ) ); $js_path = '/js/wp-embed' . wp_scripts_get_suffix() . '.js'; $output .= wp_get_inline_script_tag( trim( file_get_contents( ABSPATH . WPINC . $js_path ) ) . "\n//# sourceURL=" . esc_url_raw( includes_url( $js_path ) ) ); return apply_filters( 'embed_html', $output, $post, $width, $height ); } function get_oembed_response_data( $post, $width ) { $post = get_post( $post ); $width = absint( $width ); if ( ! $post ) { return false; } if ( ! is_post_publicly_viewable( $post ) ) { return false; } if ( ! is_post_embeddable( $post ) ) { return false; } $min_max_width = apply_filters( 'oembed_min_max_width', array( 'min' => 200, 'max' => 600, ) ); $width = min( max( $min_max_width['min'], $width ), $min_max_width['max'] ); $height = max( (int) ceil( $width / 16 * 9 ), 200 ); $data = array( 'version' => '1.0', 'provider_name' => get_bloginfo( 'name' ), 'provider_url' => get_home_url(), 'author_name' => get_bloginfo( 'name' ), 'author_url' => get_home_url(), 'title' => get_the_title( $post ), 'type' => 'link', ); $author = get_userdata( $post->post_author ); if ( $author ) { $data['author_name'] = $author->display_name; $data['author_url'] = get_author_posts_url( $author->ID ); } return apply_filters( 'oembed_response_data', $data, $post, $width, $height ); } function get_oembed_response_data_for_url( $url, $args ) { $switched_blog = false; if ( is_multisite() ) { $url_parts = wp_parse_args( wp_parse_url( $url ), array( 'host' => '', 'port' => null, 'path' => '/', ) ); $qv = array( 'domain' => $url_parts['host'] . ( $url_parts['port'] ? ':' . $url_parts['port'] : '' ), 'path' => '/', 'update_site_meta_cache' => false, ); if ( ! is_subdomain_install() ) { $path = explode( '/', ltrim( $url_parts['path'], '/' ) ); $path = reset( $path ); if ( $path ) { $qv['path'] = get_network()->path . $path . '/'; } } $sites = get_sites( $qv ); $site = reset( $sites ); if ( ! empty( $site->deleted ) || ! empty( $site->spam ) || ! empty( $site->archived ) ) { return false; } if ( $site && get_current_blog_id() !== (int) $site->blog_id ) { switch_to_blog( $site->blog_id ); $switched_blog = true; } } $post_id = url_to_postid( $url ); $post_id = apply_filters( 'oembed_request_post_id', $post_id, $url ); if ( ! $post_id ) { if ( $switched_blog ) { restore_current_blog(); } return false; } $width = isset( $args['width'] ) ? $args['width'] : 0; $data = get_oembed_response_data( $post_id, $width ); if ( $switched_blog ) { restore_current_blog(); } return $data ? (object) $data : false; } function get_oembed_response_data_rich( $data, $post, $width, $height ) { $data['width'] = absint( $width ); $data['height'] = absint( $height ); $data['type'] = 'rich'; $data['html'] = get_post_embed_html( $width, $height, $post ); $thumbnail_id = false; if ( has_post_thumbnail( $post->ID ) ) { $thumbnail_id = get_post_thumbnail_id( $post->ID ); } if ( 'attachment' === get_post_type( $post ) ) { if ( wp_attachment_is_image( $post ) ) { $thumbnail_id = $post->ID; } elseif ( wp_attachment_is( 'video', $post ) ) { $thumbnail_id = get_post_thumbnail_id( $post ); $data['type'] = 'video'; } } if ( $thumbnail_id ) { list( $thumbnail_url, $thumbnail_width, $thumbnail_height ) = wp_get_attachment_image_src( $thumbnail_id, array( $width, 0 ) ); $data['thumbnail_url'] = $thumbnail_url; $data['thumbnail_width'] = $thumbnail_width; $data['thumbnail_height'] = $thumbnail_height; } return $data; } function wp_oembed_ensure_format( $format ) { if ( ! in_array( $format, array( 'json', 'xml' ), true ) ) { return 'json'; } return $format; } function _oembed_rest_pre_serve_request( $served, $result, $request, $server ) { $params = $request->get_params(); if ( '/oembed/1.0/embed' !== $request->get_route() || 'GET' !== $request->get_method() ) { return $served; } if ( ! isset( $params['format'] ) || 'xml' !== $params['format'] ) { return $served; } $data = $server->response_to_data( $result, false ); if ( ! class_exists( 'SimpleXMLElement' ) ) { status_header( 501 ); die( get_status_header_desc( 501 ) ); } $result = _oembed_create_xml( $data ); if ( ! $result ) { status_header( 501 ); die( get_status_header_desc( 501 ) ); } if ( ! headers_sent() ) { $server->send_header( 'Content-Type', 'text/xml; charset=' . get_option( 'blog_charset' ) ); } echo $result; return true; } function _oembed_create_xml( $data, $node = null ) { if ( ! is_array( $data ) || empty( $data ) ) { return false; } if ( null === $node ) { $node = new SimpleXMLElement( '<oembed></oembed>' ); } foreach ( $data as $key => $value ) { if ( is_numeric( $key ) ) { $key = 'oembed'; } if ( is_array( $value ) ) { $item = $node->addChild( $key ); _oembed_create_xml( $value, $item ); } else { $node->addChild( $key, esc_html( $value ) ); } } return $node->asXML(); } function wp_filter_oembed_iframe_title_attribute( $result, $data, $url ) { if ( false === $result || ! in_array( $data->type, array( 'rich', 'video' ), true ) ) { return $result; } $title = ! empty( $data->title ) ? $data->title : ''; $pattern = '`<iframe([^>]*)>`i'; if ( preg_match( $pattern, $result, $matches ) ) { $attrs = wp_kses_hair( $matches[1], wp_allowed_protocols() ); foreach ( $attrs as $attr => $item ) { $lower_attr = strtolower( $attr ); if ( $lower_attr === $attr ) { continue; } if ( ! isset( $attrs[ $lower_attr ] ) ) { $attrs[ $lower_attr ] = $item; unset( $attrs[ $attr ] ); } } } if ( ! empty( $attrs['title']['value'] ) ) { $title = $attrs['title']['value']; } $title = apply_filters( 'oembed_iframe_title_attribute', $title, $result, $data, $url ); if ( '' === $title ) { return $result; } if ( isset( $attrs['title'] ) ) { unset( $attrs['title'] ); $attr_string = implode( ' ', wp_list_pluck( $attrs, 'whole' ) ); $result = str_replace( $matches[0], '<iframe ' . trim( $attr_string ) . '>', $result ); } return str_ireplace( '<iframe ', sprintf( '<iframe title="%s" ', esc_attr( $title ) ), $result ); } function wp_filter_oembed_result( $result, $data, $url ) { if ( false === $result || ! in_array( $data->type, array( 'rich', 'video' ), true ) ) { return $result; } $wp_oembed = _wp_oembed_get_object(); if ( false !== $wp_oembed->get_provider( $url, array( 'discover' => false ) ) ) { return $result; } $allowed_html = array( 'a' => array( 'href' => true, ), 'blockquote' => array(), 'iframe' => array( 'src' => true, 'width' => true, 'height' => true, 'frameborder' => true, 'marginwidth' => true, 'marginheight' => true, 'scrolling' => true, 'title' => true, ), ); $html = wp_kses( $result, $allowed_html ); preg_match( '|(<blockquote>.*?</blockquote>)?.*(<iframe.*?></iframe>)|ms', $html, $content ); if ( empty( $content[2] ) ) { return false; } $html = $content[1] . $content[2]; preg_match( '/ src=([\'"])(.*?)\1/', $html, $results ); if ( ! empty( $results ) ) { $secret = wp_generate_password( 10, false ); $url = esc_url( "{$results[2]}#?secret=$secret" ); $q = $results[1]; $html = str_replace( $results[0], ' src=' . $q . $url . $q . ' data-secret=' . $q . $secret . $q, $html ); $html = str_replace( '<blockquote', "<blockquote data-secret=\"$secret\"", $html ); } $allowed_html['blockquote']['data-secret'] = true; $allowed_html['iframe']['data-secret'] = true; $html = wp_kses( $html, $allowed_html ); if ( ! empty( $content[1] ) ) { $html = str_replace( '<iframe', '<iframe style="position: absolute; visibility: hidden;"', $html ); $html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html ); } $html = str_ireplace( '<iframe', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $html ); return $html; } function wp_embed_excerpt_more( $more_string ) { if ( ! is_embed() ) { return $more_string; } $link = sprintf( '<a href="%1$s" class="wp-embed-more" target="_top">%2$s</a>', esc_url( get_permalink() ), sprintf( __( 'Continue reading %s' ), '<span class="screen-reader-text">' . get_the_title() . '</span>' ) ); return ' … ' . $link; } function the_excerpt_embed() { $output = get_the_excerpt(); echo apply_filters( 'the_excerpt_embed', $output ); } function wp_embed_excerpt_attachment( $content ) { if ( is_attachment() ) { return prepend_attachment( '' ); } return $content; } function enqueue_embed_scripts() { do_action( 'enqueue_embed_scripts' ); } function wp_enqueue_embed_styles() { if ( ! has_action( 'embed_head', 'print_embed_styles' ) ) { return; } remove_action( 'embed_head', 'print_embed_styles' ); $suffix = wp_scripts_get_suffix(); $handle = 'wp-embed-template'; wp_register_style( $handle, false ); wp_add_inline_style( $handle, file_get_contents( ABSPATH . WPINC . "/css/wp-embed-template$suffix.css" ) ); wp_enqueue_style( $handle ); } function print_embed_scripts() { $js_path = '/js/wp-embed-template' . wp_scripts_get_suffix() . '.js'; wp_print_inline_script_tag( trim( file_get_contents( ABSPATH . WPINC . $js_path ) ) . "\n//# sourceURL=" . esc_url_raw( includes_url( $js_path ) ) ); } function _oembed_filter_feed_content( $content ) { $p = new WP_HTML_Tag_Processor( $content ); while ( $p->next_tag( array( 'tag_name' => 'iframe' ) ) ) { if ( $p->has_class( 'wp-embedded-content' ) ) { $p->remove_attribute( 'style' ); } } return $p->get_updated_html(); } function print_embed_comments_button() { if ( is_404() || ! ( get_comments_number() || comments_open() ) ) { return; } ?>
<div class="wp-embed-comments">
<a href="<?php comments_link(); ?>" target="_top">
<span class="dashicons dashicons-admin-comments"></span>
<?php
printf( _n( '%s <span class="screen-reader-text">Comment</span>', '%s <span class="screen-reader-text">Comments</span>', get_comments_number() ), number_format_i18n( get_comments_number() ) ); ?>
</a>
</div>
<?php
} function print_embed_sharing_button() { if ( is_404() ) { return; } ?>
<div class="wp-embed-share">
<button type="button" class="wp-embed-share-dialog-open" aria-label="<?php esc_attr_e( 'Open sharing dialog' ); ?>">
<span class="dashicons dashicons-share"></span>
</button>
</div>
<?php
} function print_embed_sharing_dialog() { if ( is_404() ) { return; } $unique_suffix = get_the_ID() . '-' . wp_rand(); $share_tab_wordpress_id = 'wp-embed-share-tab-wordpress-' . $unique_suffix; $share_tab_html_id = 'wp-embed-share-tab-html-' . $unique_suffix; $description_wordpress_id = 'wp-embed-share-description-wordpress-' . $unique_suffix; $description_html_id = 'wp-embed-share-description-html-' . $unique_suffix; ?>
<div class="wp-embed-share-dialog hidden" role="dialog" aria-label="<?php esc_attr_e( 'Sharing options' ); ?>">
<div class="wp-embed-share-dialog-content">
<div class="wp-embed-share-dialog-text">
<ul class="wp-embed-share-tabs" role="tablist">
<li class="wp-embed-share-tab-button wp-embed-share-tab-button-wordpress" role="presentation">
<button type="button" role="tab" aria-controls="<?php echo $share_tab_wordpress_id; ?>" aria-selected="true" tabindex="0"><?php esc_html_e( 'WordPress Embed' ); ?></button>
</li>
<li class="wp-embed-share-tab-button wp-embed-share-tab-button-html" role="presentation">
<button type="button" role="tab" aria-controls="<?php echo $share_tab_html_id; ?>" aria-selected="false" tabindex="-1"><?php esc_html_e( 'HTML Embed' ); ?></button>
</li>
</ul>
<div id="<?php echo $share_tab_wordpress_id; ?>" class="wp-embed-share-tab" role="tabpanel" aria-hidden="false">
<input type="text" value="<?php the_permalink(); ?>" class="wp-embed-share-input" aria-label="<?php esc_attr_e( 'URL' ); ?>" aria-describedby="<?php echo $description_wordpress_id; ?>" tabindex="0" readonly/>
<p class="wp-embed-share-description" id="<?php echo $description_wordpress_id; ?>">
<?php _e( 'Copy and paste this URL into your WordPress site to embed' ); ?>
</p>
</div>
<div id="<?php echo $share_tab_html_id; ?>" class="wp-embed-share-tab" role="tabpanel" aria-hidden="true">
<textarea class="wp-embed-share-input" aria-label="<?php esc_attr_e( 'HTML' ); ?>" aria-describedby="<?php echo $description_html_id; ?>" tabindex="0" readonly><?php echo esc_textarea( get_post_embed_html( 600, 400 ) ); ?></textarea>
<p class="wp-embed-share-description" id="<?php echo $description_html_id; ?>">
<?php _e( 'Copy and paste this code into your site to embed' ); ?>
</p>
</div>
</div>
<button type="button" class="wp-embed-share-dialog-close" aria-label="<?php esc_attr_e( 'Close sharing dialog' ); ?>">
<span class="dashicons dashicons-no"></span>
</button>
</div>
</div>
<?php
} function the_embed_site_title() { $site_title = sprintf( '<a href="%s" target="_top"><img src="%s" srcset="%s 2x" width="32" height="32" alt="" class="wp-embed-site-icon" /><span>%s</span></a>', esc_url( home_url() ), esc_url( get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ) ), esc_url( get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ) ), esc_html( get_bloginfo( 'name' ) ) ); $site_title = '<div class="wp-embed-site-title">' . $site_title . '</div>'; echo apply_filters( 'embed_site_title_html', $site_title ); } function wp_filter_pre_oembed_result( $result, $url, $args ) { $data = get_oembed_response_data_for_url( $url, $args ); if ( $data ) { return _wp_oembed_get_object()->data2html( $data, $url ); } return $result; }
###require ABSPATH . WPINC . '/class-wp-embed.php';
class WP_Embed { public $handlers = array(); public $post_ID; public $usecache = true; public $linkifunknown = true; public $last_attr = array(); public $last_url = ''; public $return_false_on_fail = false; public function __construct() { add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 ); add_filter( 'widget_text_content', array( $this, 'run_shortcode' ), 8 ); add_filter( 'widget_block_content', array( $this, 'run_shortcode' ), 8 ); add_shortcode( 'embed', '__return_false' ); add_filter( 'the_content', array( $this, 'autoembed' ), 8 ); add_filter( 'widget_text_content', array( $this, 'autoembed' ), 8 ); add_filter( 'widget_block_content', array( $this, 'autoembed' ), 8 ); add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) ); add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) ); } public function run_shortcode( $content ) { global $shortcode_tags; $orig_shortcode_tags = $shortcode_tags; remove_all_shortcodes(); add_shortcode( 'embed', array( $this, 'shortcode' ) ); $content = do_shortcode( $content, true ); $shortcode_tags = $orig_shortcode_tags; return $content; } public function maybe_run_ajax_cache() { $post = get_post(); if ( ! $post || empty( $_GET['message'] ) ) { return; } ?>
<script type="text/javascript">
jQuery( function($) {
$.get("<?php echo esc_url( admin_url( 'admin-ajax.php', 'relative' ) ) . '?action=oembed-cache&post=' . $post->ID; ?>");
} );
</script>
<?php
} public function register_handler( $id, $regex, $callback, $priority = 10 ) { $this->handlers[ $priority ][ $id ] = array( 'regex' => $regex, 'callback' => $callback, ); } public function unregister_handler( $id, $priority = 10 ) { unset( $this->handlers[ $priority ][ $id ] ); } public function get_embed_handler_html( $attr, $url ) { $rawattr = $attr; $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) ); ksort( $this->handlers ); foreach ( $this->handlers as $priority => $handlers ) { foreach ( $handlers as $id => $handler ) { if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) { $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ); if ( false !== $return ) { return apply_filters( 'embed_handler_html', $return, $url, $attr ); } } } } return false; } public function shortcode( $attr, $url = '' ) { $post = get_post(); if ( empty( $url ) && ! empty( $attr['src'] ) ) { $url = $attr['src']; } $this->last_url = $url; if ( empty( $url ) ) { $this->last_attr = $attr; return ''; } $rawattr = $attr; $attr = wp_parse_args( $attr, wp_embed_defaults( $url ) ); $this->last_attr = $attr; $url = str_replace( '&', '&', $url ); $embed_handler_html = $this->get_embed_handler_html( $rawattr, $url ); if ( false !== $embed_handler_html ) { return $embed_handler_html; } $post_id = ( ! empty( $post->ID ) ) ? $post->ID : null; if ( ! empty( $this->post_ID ) ) { $post_id = $this->post_ID; } $key_suffix = md5( $url . serialize( $attr ) ); $cachekey = '_oembed_' . $key_suffix; $cachekey_time = '_oembed_time_' . $key_suffix; $ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, $url, $attr, $post_id ); $cache = ''; $cache_time = 0; $cached_post_id = $this->find_oembed_post_id( $key_suffix ); if ( $post_id ) { $cache = get_post_meta( $post_id, $cachekey, true ); $cache_time = get_post_meta( $post_id, $cachekey_time, true ); if ( ! $cache_time ) { $cache_time = 0; } } elseif ( $cached_post_id ) { $cached_post = get_post( $cached_post_id ); $cache = $cached_post->post_content; $cache_time = strtotime( $cached_post->post_modified_gmt ); } $cached_recently = ( time() - $cache_time ) < $ttl; if ( $this->usecache || $cached_recently ) { if ( '{{unknown}}' === $cache ) { return $this->maybe_make_link( $url ); } if ( ! empty( $cache ) ) { return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_id ); } } $attr['discover'] = apply_filters( 'embed_oembed_discover', true ); $html = wp_oembed_get( $url, $attr ); if ( $post_id ) { if ( $html ) { update_post_meta( $post_id, $cachekey, $html ); update_post_meta( $post_id, $cachekey_time, time() ); } elseif ( ! $cache ) { update_post_meta( $post_id, $cachekey, '{{unknown}}' ); } } else { $has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ); if ( $has_kses ) { kses_remove_filters(); } $insert_post_args = array( 'post_name' => $key_suffix, 'post_status' => 'publish', 'post_type' => 'oembed_cache', ); if ( $html ) { if ( $cached_post_id ) { wp_update_post( wp_slash( array( 'ID' => $cached_post_id, 'post_content' => $html, ) ) ); } else { wp_insert_post( wp_slash( array_merge( $insert_post_args, array( 'post_content' => $html, ) ) ) ); } } elseif ( ! $cache ) { wp_insert_post( wp_slash( array_merge( $insert_post_args, array( 'post_content' => '{{unknown}}', ) ) ) ); } if ( $has_kses ) { kses_init_filters(); } } if ( $html ) { return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_id ); } return $this->maybe_make_link( $url ); } public function delete_oembed_caches( $post_id ) { $post_metas = get_post_custom_keys( $post_id ); if ( empty( $post_metas ) ) { return; } foreach ( $post_metas as $post_meta_key ) { if ( str_starts_with( $post_meta_key, '_oembed_' ) ) { delete_post_meta( $post_id, $post_meta_key ); } } } public function cache_oembed( $post_id ) { $post = get_post( $post_id ); $post_types = get_post_types( array( 'show_ui' => true ) ); $cache_oembed_types = apply_filters( 'embed_cache_oembed_types', $post_types ); if ( empty( $post->ID ) || ! in_array( $post->post_type, $cache_oembed_types, true ) ) { return; } if ( ! empty( $post->post_content ) ) { $this->post_ID = $post->ID; $this->usecache = false; $content = $this->run_shortcode( $post->post_content ); $this->autoembed( $content ); $this->usecache = true; } } public function autoembed( $content ) { $content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) ); if ( preg_match( '#(^|\s|>)https?://#i', $content ) ) { $content = preg_replace_callback( '|^(\s*)(https?://[^\s<>"]+)(\s*)$|im', array( $this, 'autoembed_callback' ), $content ); $content = preg_replace_callback( '|(<p(?: [^>]*)?>\s*)(https?://[^\s<>"]+)(\s*<\/p>)|i', array( $this, 'autoembed_callback' ), $content ); } return str_replace( '<!-- wp-line-break -->', "\n", $content ); } public function autoembed_callback( $matches ) { $oldval = $this->linkifunknown; $this->linkifunknown = false; $return = $this->shortcode( array(), $matches[2] ); $this->linkifunknown = $oldval; return $matches[1] . $return . $matches[3]; } public function maybe_make_link( $url ) { if ( $this->return_false_on_fail ) { return false; } $output = ( $this->linkifunknown ) ? '<a href="' . esc_url( $url ) . '">' . esc_html( $url ) . '</a>' : $url; return apply_filters( 'embed_maybe_make_link', $output, $url ); } public function find_oembed_post_id( $cache_key ) { $cache_group = 'oembed_cache_post'; $oembed_post_id = wp_cache_get( $cache_key, $cache_group ); if ( $oembed_post_id && 'oembed_cache' === get_post_type( $oembed_post_id ) ) { return $oembed_post_id; } $oembed_post_query = new WP_Query( array( 'post_type' => 'oembed_cache', 'post_status' => 'publish', 'name' => $cache_key, 'posts_per_page' => 1, 'no_found_rows' => true, 'cache_results' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'lazy_load_term_meta' => false, ) ); if ( ! empty( $oembed_post_query->posts ) ) { $oembed_post_id = $oembed_post_query->posts[0]->ID; wp_cache_set( $cache_key, $oembed_post_id, $cache_group ); return $oembed_post_id; } return null; } }
###require ABSPATH . WPINC . '/class-wp-oembed.php';
class WP_oEmbed { public $providers = array(); public static $early_providers = array(); private $compat_methods = array( '_fetch_with_format', '_parse_json', '_parse_xml', '_parse_xml_body' ); public function __construct() { $host = urlencode( home_url() ); $providers = array( '#https?://((m|www)\.)?youtube\.com/watch.*#i' => array( 'https://www.youtube.com/oembed', true ), '#https?://((m|www)\.)?youtube\.com/playlist.*#i' => array( 'https://www.youtube.com/oembed', true ), '#https?://((m|www)\.)?youtube\.com/shorts/*#i' => array( 'https://www.youtube.com/oembed', true ), '#https?://((m|www)\.)?youtube\.com/live/*#i' => array( 'https://www.youtube.com/oembed', true ), '#https?://youtu\.be/.*#i' => array( 'https://www.youtube.com/oembed', true ), '#https?://(.+\.)?vimeo\.com/.*#i' => array( 'https://vimeo.com/api/oembed.{format}', true ), '#https?://(www\.)?dailymotion\.com/.*#i' => array( 'https://www.dailymotion.com/services/oembed', true ), '#https?://dai\.ly/.*#i' => array( 'https://www.dailymotion.com/services/oembed', true ), '#https?://(www\.)?flickr\.com/.*#i' => array( 'https://www.flickr.com/services/oembed/', true ), '#https?://flic\.kr/.*#i' => array( 'https://www.flickr.com/services/oembed/', true ), '#https?://(.+\.)?smugmug\.com/.*#i' => array( 'https://api.smugmug.com/services/oembed/', true ), '#https?://(www\.)?scribd\.com/(doc|document)/.*#i' => array( 'https://www.scribd.com/services/oembed', true ), '#https?://wordpress\.tv/.*#i' => array( 'https://wordpress.tv/oembed/', true ), '#https?://(.+\.)?crowdsignal\.net/.*#i' => array( 'https://api.crowdsignal.com/oembed', true ), '#https?://(.+\.)?polldaddy\.com/.*#i' => array( 'https://api.crowdsignal.com/oembed', true ), '#https?://poll\.fm/.*#i' => array( 'https://api.crowdsignal.com/oembed', true ), '#https?://(.+\.)?survey\.fm/.*#i' => array( 'https://api.crowdsignal.com/oembed', true ), '#https?://(www\.)?twitter\.com/\w{1,15}/status(es)?/.*#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?twitter\.com/\w{1,15}$#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?twitter\.com/\w{1,15}/likes$#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?twitter\.com/\w{1,15}/lists/.*#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?twitter\.com/\w{1,15}/timelines/.*#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?twitter\.com/i/moments/.*#i' => array( 'https://publish.twitter.com/oembed', true ), '#https?://(www\.)?soundcloud\.com/.*#i' => array( 'https://soundcloud.com/oembed', true ), '#https?://(open|play)\.spotify\.com/.*#i' => array( 'https://embed.spotify.com/oembed/', true ), '#https?://(.+\.)?imgur\.com/.*#i' => array( 'https://api.imgur.com/oembed', true ), '#https?://(www\.)?issuu\.com/.+/docs/.+#i' => array( 'https://issuu.com/oembed_wp', true ), '#https?://(www\.)?mixcloud\.com/.*#i' => array( 'https://app.mixcloud.com/oembed/', true ), '#https?://(www\.|embed\.)?ted\.com/talks/.*#i' => array( 'https://www.ted.com/services/v1/oembed.{format}', true ), '#https?://(www\.)?(animoto|video214)\.com/play/.*#i' => array( 'https://animoto.com/oembeds/create', true ), '#https?://(.+)\.tumblr\.com/.*#i' => array( 'https://www.tumblr.com/oembed/1.0', true ), '#https?://(www\.)?kickstarter\.com/projects/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ), '#https?://kck\.st/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ), '#https?://cloudup\.com/.*#i' => array( 'https://cloudup.com/oembed', true ), '#https?://(www\.)?reverbnation\.com/.*#i' => array( 'https://www.reverbnation.com/oembed', true ), '#https?://videopress\.com/v/.*#' => array( 'https://public-api.wordpress.com/oembed/?for=' . $host, true ), '#https?://(www\.)?reddit\.com/r/[^/]+/comments/.*#i' => array( 'https://www.reddit.com/oembed', true ), '#https?://(www\.)?speakerdeck\.com/.*#i' => array( 'https://speakerdeck.com/oembed.{format}', true ), '#https?://([a-z0-9-]+\.)?amazon\.(com|com\.mx|com\.br|ca)/.*#i' => array( 'https://read.amazon.com/kp/api/oembed', true ), '#https?://([a-z0-9-]+\.)?amazon\.(co\.uk|de|fr|it|es|in|nl|ru)/.*#i' => array( 'https://read.amazon.co.uk/kp/api/oembed', true ), '#https?://([a-z0-9-]+\.)?amazon\.(co\.jp|com\.au)/.*#i' => array( 'https://read.amazon.com.au/kp/api/oembed', true ), '#https?://([a-z0-9-]+\.)?amazon\.cn/.*#i' => array( 'https://read.amazon.cn/kp/api/oembed', true ), '#https?://(www\.)?a\.co/.*#i' => array( 'https://read.amazon.com/kp/api/oembed', true ), '#https?://(www\.)?amzn\.to/.*#i' => array( 'https://read.amazon.com/kp/api/oembed', true ), '#https?://(www\.)?amzn\.eu/.*#i' => array( 'https://read.amazon.co.uk/kp/api/oembed', true ), '#https?://(www\.)?amzn\.in/.*#i' => array( 'https://read.amazon.in/kp/api/oembed', true ), '#https?://(www\.)?amzn\.asia/.*#i' => array( 'https://read.amazon.com.au/kp/api/oembed', true ), '#https?://(www\.)?z\.cn/.*#i' => array( 'https://read.amazon.cn/kp/api/oembed', true ), '#https?://www\.someecards\.com/.+-cards/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ), '#https?://www\.someecards\.com/usercards/viewcard/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ), '#https?://some\.ly\/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ), '#https?://(www\.)?tiktok\.com/.*/video/.*#i' => array( 'https://www.tiktok.com/oembed', true ), '#https?://(www\.)?tiktok\.com/@.*#i' => array( 'https://www.tiktok.com/oembed', true ), '#https?://([a-z]{2}|www)\.pinterest\.com(\.(au|mx))?/.*#i' => array( 'https://www.pinterest.com/oembed.json', true ), '#https?://(www\.)?wolframcloud\.com/obj/.+#i' => array( 'https://www.wolframcloud.com/oembed', true ), '#https?://pca\.st/.+#i' => array( 'https://pca.st/oembed.json', true ), '#https?://((play|www)\.)?anghami\.com/.*#i' => array( 'https://api.anghami.com/rest/v1/oembed.view', true ), '#https?://bsky.app/profile/.*/post/.*#i' => array( 'https://embed.bsky.app/oembed', true ), '#https?://(www\.)?canva\.com/design/.*/view.*#i' => array( 'https://canva.com/_oembed', true ), ); if ( ! empty( self::$early_providers['add'] ) ) { foreach ( self::$early_providers['add'] as $format => $data ) { $providers[ $format ] = $data; } } if ( ! empty( self::$early_providers['remove'] ) ) { foreach ( self::$early_providers['remove'] as $format ) { unset( $providers[ $format ] ); } } self::$early_providers = array(); $this->providers = apply_filters( 'oembed_providers', $providers ); add_filter( 'oembed_dataparse', array( $this, '_strip_newlines' ), 10, 3 ); } public function __call( $name, $arguments ) { if ( in_array( $name, $this->compat_methods, true ) ) { return $this->$name( ...$arguments ); } return false; } public function get_provider( $url, $args = '' ) { $args = wp_parse_args( $args ); $provider = false; if ( ! isset( $args['discover'] ) ) { $args['discover'] = true; } foreach ( $this->providers as $matchmask => $data ) { list( $providerurl, $regex ) = $data; if ( ! $regex ) { $matchmask = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $matchmask ), '#' ) ) . '#i'; $matchmask = preg_replace( '|^#http\\\://|', '#https?\://', $matchmask ); } if ( preg_match( $matchmask, $url ) ) { $provider = str_replace( '{format}', 'json', $providerurl ); break; } } if ( ! $provider && $args['discover'] ) { $provider = $this->discover( $url ); } return $provider; } public static function _add_provider_early( $format, $provider, $regex = false ) { if ( empty( self::$early_providers['add'] ) ) { self::$early_providers['add'] = array(); } self::$early_providers['add'][ $format ] = array( $provider, $regex ); } public static function _remove_provider_early( $format ) { if ( empty( self::$early_providers['remove'] ) ) { self::$early_providers['remove'] = array(); } self::$early_providers['remove'][] = $format; } public function get_data( $url, $args = '' ) { $args = wp_parse_args( $args ); $provider = $this->get_provider( $url, $args ); if ( ! $provider ) { return false; } $data = $this->fetch( $provider, $url, $args ); if ( false === $data ) { return false; } return $data; } public function get_html( $url, $args = '' ) { $pre = apply_filters( 'pre_oembed_result', null, $url, $args ); if ( null !== $pre ) { return $pre; } $data = $this->get_data( $url, $args ); if ( false === $data ) { return false; } return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args ); } public function discover( $url ) { $providers = array(); $args = array( 'limit_response_size' => 153600, ); $args = apply_filters( 'oembed_remote_get_args', $args, $url ); $request = wp_safe_remote_get( $url, $args ); $html = wp_remote_retrieve_body( $request ); if ( $html ) { $linktypes = apply_filters( 'oembed_linktypes', array( 'application/json+oembed' => 'json', 'text/xml+oembed' => 'xml', 'application/xml+oembed' => 'xml', ) ); $html_head_end = stripos( $html, '</head>' ); if ( $html_head_end ) { $html = substr( $html, 0, $html_head_end ); } $tagfound = false; foreach ( $linktypes as $linktype => $format ) { if ( stripos( $html, $linktype ) ) { $tagfound = true; break; } } if ( $tagfound && preg_match_all( '#<link([^<>]+)/?>#iU', $html, $links ) ) { foreach ( $links[1] as $link ) { $atts = shortcode_parse_atts( $link ); if ( ! empty( $atts['type'] ) && ! empty( $linktypes[ $atts['type'] ] ) && ! empty( $atts['href'] ) ) { $providers[ $linktypes[ $atts['type'] ] ] = htmlspecialchars_decode( $atts['href'] ); if ( 'json' === $linktypes[ $atts['type'] ] ) { break; } } } } } if ( ! empty( $providers['json'] ) ) { return $providers['json']; } elseif ( ! empty( $providers['xml'] ) ) { return $providers['xml']; } else { return false; } } public function fetch( $provider, $url, $args = '' ) { $args = wp_parse_args( $args, wp_embed_defaults( $url ) ); $provider = add_query_arg( 'maxwidth', (int) $args['width'], $provider ); $provider = add_query_arg( 'maxheight', (int) $args['height'], $provider ); $provider = add_query_arg( 'url', urlencode( $url ), $provider ); $provider = add_query_arg( 'dnt', 1, $provider ); $provider = apply_filters( 'oembed_fetch_url', $provider, $url, $args ); foreach ( array( 'json', 'xml' ) as $format ) { $result = $this->_fetch_with_format( $provider, $format ); if ( is_wp_error( $result ) && 'not-implemented' === $result->get_error_code() ) { continue; } return ( $result && ! is_wp_error( $result ) ) ? $result : false; } return false; } private function _fetch_with_format( $provider_url_with_args, $format ) { $provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args ); $args = apply_filters( 'oembed_remote_get_args', array(), $provider_url_with_args ); $response = wp_safe_remote_get( $provider_url_with_args, $args ); if ( 501 === wp_remote_retrieve_response_code( $response ) ) { return new WP_Error( 'not-implemented' ); } $body = wp_remote_retrieve_body( $response ); if ( ! $body ) { return false; } $parse_method = "_parse_$format"; return $this->$parse_method( $body ); } private function _parse_json( $response_body ) { $data = json_decode( trim( $response_body ) ); return ( $data && is_object( $data ) ) ? $data : false; } private function _parse_xml( $response_body ) { if ( ! function_exists( 'libxml_disable_entity_loader' ) ) { return false; } if ( PHP_VERSION_ID < 80000 ) { $loader = libxml_disable_entity_loader( true ); } $errors = libxml_use_internal_errors( true ); $return = $this->_parse_xml_body( $response_body ); libxml_use_internal_errors( $errors ); if ( PHP_VERSION_ID < 80000 && isset( $loader ) ) { libxml_disable_entity_loader( $loader ); } return $return; } private function _parse_xml_body( $response_body ) { if ( ! function_exists( 'simplexml_import_dom' ) || ! class_exists( 'DOMDocument', false ) ) { return false; } $dom = new DOMDocument(); $success = $dom->loadXML( $response_body ); if ( ! $success ) { return false; } if ( isset( $dom->doctype ) ) { return false; } foreach ( $dom->childNodes as $child ) { if ( XML_DOCUMENT_TYPE_NODE === $child->nodeType ) { return false; } } $xml = simplexml_import_dom( $dom ); if ( ! $xml ) { return false; } $return = new stdClass(); foreach ( $xml as $key => $value ) { $return->$key = (string) $value; } return $return; } public function data2html( $data, $url ) { if ( ! is_object( $data ) || empty( $data->type ) ) { return false; } $return = false; switch ( $data->type ) { case 'photo': if ( empty( $data->url ) || empty( $data->width ) || empty( $data->height ) ) { break; } if ( ! is_string( $data->url ) || ! is_numeric( $data->width ) || ! is_numeric( $data->height ) ) { break; } $title = ! empty( $data->title ) && is_string( $data->title ) ? $data->title : ''; $return = '<a href="' . esc_url( $url ) . '"><img src="' . esc_url( $data->url ) . '" alt="' . esc_attr( $title ) . '" width="' . esc_attr( $data->width ) . '" height="' . esc_attr( $data->height ) . '" /></a>'; break; case 'video': case 'rich': if ( ! empty( $data->html ) && is_string( $data->html ) ) { $return = $data->html; } break; case 'link': if ( ! empty( $data->title ) && is_string( $data->title ) ) { $return = '<a href="' . esc_url( $url ) . '">' . esc_html( $data->title ) . '</a>'; } break; default: $return = false; } return apply_filters( 'oembed_dataparse', $return, $data, $url ); } public function _strip_newlines( $html, $data, $url ) { if ( ! str_contains( $html, "\n" ) ) { return $html; } $count = 1; $found = array(); $token = '__PRE__'; $search = array( "\t", "\n", "\r", ' ' ); $replace = array( '__TAB__', '__NL__', '__CR__', '__SPACE__' ); $tokenized = str_replace( $search, $replace, $html ); preg_match_all( '#(<pre[^>]*>.+?</pre>)#i', $tokenized, $matches, PREG_SET_ORDER ); foreach ( $matches as $i => $match ) { $tag_html = str_replace( $replace, $search, $match[0] ); $tag_token = $token . $i; $found[ $tag_token ] = $tag_html; $html = str_replace( $tag_html, $tag_token, $html, $count ); } $replaced = str_replace( $replace, $search, $html ); $stripped = str_replace( array( "\r\n", "\n" ), '', $replaced ); $pre = array_values( $found ); $tokens = array_keys( $found ); return str_replace( $tokens, $pre, $stripped ); } }
###require ABSPATH . WPINC . '/class-wp-oembed-controller.php';
final class WP_oEmbed_Controller { public function register_routes() { $maxwidth = apply_filters( 'oembed_default_width', 600 ); register_rest_route( 'oembed/1.0', '/embed', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => '__return_true', 'args' => array( 'url' => array( 'description' => __( 'The URL of the resource for which to fetch oEmbed data.' ), 'required' => true, 'type' => 'string', 'format' => 'uri', ), 'format' => array( 'default' => 'json', 'sanitize_callback' => 'wp_oembed_ensure_format', ), 'maxwidth' => array( 'default' => $maxwidth, 'sanitize_callback' => 'absint', ), ), ), ) ); register_rest_route( 'oembed/1.0', '/proxy', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_proxy_item' ), 'permission_callback' => array( $this, 'get_proxy_item_permissions_check' ), 'args' => array( 'url' => array( 'description' => __( 'The URL of the resource for which to fetch oEmbed data.' ), 'required' => true, 'type' => 'string', 'format' => 'uri', ), 'format' => array( 'description' => __( 'The oEmbed format to use.' ), 'type' => 'string', 'default' => 'json', 'enum' => array( 'json', 'xml', ), ), 'maxwidth' => array( 'description' => __( 'The maximum width of the embed frame in pixels.' ), 'type' => 'integer', 'default' => $maxwidth, 'sanitize_callback' => 'absint', ), 'maxheight' => array( 'description' => __( 'The maximum height of the embed frame in pixels.' ), 'type' => 'integer', 'sanitize_callback' => 'absint', ), 'discover' => array( 'description' => __( 'Whether to perform an oEmbed discovery request for unsanctioned providers.' ), 'type' => 'boolean', 'default' => true, ), ), ), ) ); } public function get_item( $request ) { $post_id = url_to_postid( $request['url'] ); $post_id = apply_filters( 'oembed_request_post_id', $post_id, $request['url'] ); $data = get_oembed_response_data( $post_id, $request['maxwidth'] ); if ( ! $data ) { return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); } return $data; } public function get_proxy_item_permissions_check() { if ( ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to make proxied oEmbed requests.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_proxy_item( $request ) { global $wp_embed, $wp_scripts; $args = $request->get_params(); unset( $args['_wpnonce'] ); $cache_key = 'oembed_' . md5( serialize( $args ) ); $data = get_transient( $cache_key ); if ( ! empty( $data ) ) { return $data; } $url = $request['url']; unset( $args['url'] ); if ( isset( $args['maxwidth'] ) ) { $args['width'] = $args['maxwidth']; } if ( isset( $args['maxheight'] ) ) { $args['height'] = $args['maxheight']; } $data = get_oembed_response_data_for_url( $url, $args ); if ( $data ) { return $data; } $data = _wp_oembed_get_object()->get_data( $url, $args ); if ( false === $data ) { $html = $wp_embed->get_embed_handler_html( $args, $url ); if ( $html ) { $enqueued_scripts = array(); foreach ( $wp_scripts->queue as $script ) { $enqueued_scripts[] = $wp_scripts->registered[ $script ]->src; } return (object) array( 'provider_name' => __( 'Embed Handler' ), 'html' => $html, 'scripts' => $enqueued_scripts, ); } return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); } $data->html = apply_filters( 'oembed_result', _wp_oembed_get_object()->data2html( (object) $data, $url ), $url, $args ); $ttl = apply_filters( 'rest_oembed_ttl', DAY_IN_SECONDS, $url, $args ); set_transient( $cache_key, $data, $ttl ); return $data; } }
###require ABSPATH . WPINC . '/media.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } function wp_get_additional_image_sizes() { global $_wp_additional_image_sizes; if ( ! $_wp_additional_image_sizes ) { $_wp_additional_image_sizes = array(); } return $_wp_additional_image_sizes; } function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) { global $content_width; $_wp_additional_image_sizes = wp_get_additional_image_sizes(); if ( ! $context ) { $context = is_admin() ? 'edit' : 'display'; } if ( is_array( $size ) ) { $max_width = $size[0]; $max_height = $size[1]; } elseif ( 'thumb' === $size || 'thumbnail' === $size ) { $max_width = (int) get_option( 'thumbnail_size_w' ); $max_height = (int) get_option( 'thumbnail_size_h' ); if ( ! $max_width && ! $max_height ) { $max_width = 128; $max_height = 96; } } elseif ( 'medium' === $size ) { $max_width = (int) get_option( 'medium_size_w' ); $max_height = (int) get_option( 'medium_size_h' ); } elseif ( 'medium_large' === $size ) { $max_width = (int) get_option( 'medium_large_size_w' ); $max_height = (int) get_option( 'medium_large_size_h' ); if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } } elseif ( 'large' === $size ) { $max_width = (int) get_option( 'large_size_w' ); $max_height = (int) get_option( 'large_size_h' ); if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } } elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ), true ) ) { $max_width = (int) $_wp_additional_image_sizes[ $size ]['width']; $max_height = (int) $_wp_additional_image_sizes[ $size ]['height']; if ( (int) $content_width > 0 && 'edit' === $context ) { $max_width = min( (int) $content_width, $max_width ); } } else { $max_width = $width; $max_height = $height; } list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context ); return wp_constrain_dimensions( $width, $height, $max_width, $max_height ); } function image_hwstring( $width, $height ) { $out = ''; if ( $width ) { $out .= 'width="' . (int) $width . '" '; } if ( $height ) { $out .= 'height="' . (int) $height . '" '; } return $out; } function image_downsize( $id, $size = 'medium' ) { $is_image = wp_attachment_is_image( $id ); $out = apply_filters( 'image_downsize', false, $id, $size ); if ( $out ) { return $out; } $img_url = wp_get_attachment_url( $id ); $meta = wp_get_attachment_metadata( $id ); $width = 0; $height = 0; $is_intermediate = false; $img_url_basename = wp_basename( $img_url ); if ( ! $is_image ) { if ( ! empty( $meta['sizes']['full'] ) ) { $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url ); $img_url_basename = $meta['sizes']['full']['file']; $width = $meta['sizes']['full']['width']; $height = $meta['sizes']['full']['height']; } else { return false; } } $intermediate = image_get_intermediate_size( $id, $size ); if ( $intermediate ) { $img_url = str_replace( $img_url_basename, $intermediate['file'], $img_url ); $width = $intermediate['width']; $height = $intermediate['height']; $is_intermediate = true; } elseif ( 'thumbnail' === $size && ! empty( $meta['thumb'] ) && is_string( $meta['thumb'] ) ) { $imagefile = get_attached_file( $id ); $thumbfile = str_replace( wp_basename( $imagefile ), wp_basename( $meta['thumb'] ), $imagefile ); if ( file_exists( $thumbfile ) ) { $info = wp_getimagesize( $thumbfile ); if ( $info ) { $img_url = str_replace( $img_url_basename, wp_basename( $thumbfile ), $img_url ); $width = $info[0]; $height = $info[1]; $is_intermediate = true; } } } if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) { $width = $meta['width']; $height = $meta['height']; } if ( $img_url ) { list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size ); return array( $img_url, $width, $height, $is_intermediate ); } return false; } function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { global $_wp_additional_image_sizes; $_wp_additional_image_sizes[ $name ] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => $crop, ); } function has_image_size( $name ) { $sizes = wp_get_additional_image_sizes(); return isset( $sizes[ $name ] ); } function remove_image_size( $name ) { global $_wp_additional_image_sizes; if ( isset( $_wp_additional_image_sizes[ $name ] ) ) { unset( $_wp_additional_image_sizes[ $name ] ); return true; } return false; } function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { add_image_size( 'post-thumbnail', $width, $height, $crop ); } function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) { list( $img_src, $width, $height ) = image_downsize( $id, $size ); $hwstring = image_hwstring( $width, $height ); $title = $title ? 'title="' . esc_attr( $title ) . '" ' : ''; $size_class = is_array( $size ) ? implode( 'x', $size ) : $size; $class = 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size_class ) . ' wp-image-' . $id; $class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size ); $html = '<img src="' . esc_url( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />'; return apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); } function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) { if ( ! $max_width && ! $max_height ) { return array( $current_width, $current_height ); } $width_ratio = 1.0; $height_ratio = 1.0; $did_width = false; $did_height = false; if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { $width_ratio = $max_width / $current_width; $did_width = true; } if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) { $height_ratio = $max_height / $current_height; $did_height = true; } $smaller_ratio = min( $width_ratio, $height_ratio ); $larger_ratio = max( $width_ratio, $height_ratio ); if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) { $ratio = $smaller_ratio; } else { $ratio = $larger_ratio; } $w = max( 1, (int) round( $current_width * $ratio ) ); $h = max( 1, (int) round( $current_height * $ratio ) ); if ( $did_width && $w === $max_width - 1 ) { $w = $max_width; } if ( $did_height && $h === $max_height - 1 ) { $h = $max_height; } return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height ); } function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) { if ( $orig_w <= 0 || $orig_h <= 0 ) { return false; } if ( $dest_w <= 0 && $dest_h <= 0 ) { return false; } $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); if ( null !== $output ) { return $output; } if ( empty( $dest_h ) ) { if ( $orig_w < $dest_w ) { return false; } } elseif ( empty( $dest_w ) ) { if ( $orig_h < $dest_h ) { return false; } } else { if ( $orig_w < $dest_w && $orig_h < $dest_h ) { return false; } } if ( $crop ) { $aspect_ratio = $orig_w / $orig_h; $new_w = min( $dest_w, $orig_w ); $new_h = min( $dest_h, $orig_h ); if ( ! $new_w ) { $new_w = (int) round( $new_h * $aspect_ratio ); } if ( ! $new_h ) { $new_h = (int) round( $new_w / $aspect_ratio ); } $size_ratio = max( $new_w / $orig_w, $new_h / $orig_h ); $crop_w = round( $new_w / $size_ratio ); $crop_h = round( $new_h / $size_ratio ); if ( ! is_array( $crop ) || count( $crop ) !== 2 ) { $crop = array( 'center', 'center' ); } list( $x, $y ) = $crop; if ( 'left' === $x ) { $s_x = 0; } elseif ( 'right' === $x ) { $s_x = $orig_w - $crop_w; } else { $s_x = floor( ( $orig_w - $crop_w ) / 2 ); } if ( 'top' === $y ) { $s_y = 0; } elseif ( 'bottom' === $y ) { $s_y = $orig_h - $crop_h; } else { $s_y = floor( ( $orig_h - $crop_h ) / 2 ); } } else { $crop_w = $orig_w; $crop_h = $orig_h; $s_x = 0; $s_y = 0; list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); } if ( wp_fuzzy_number_match( $new_w, $orig_w ) && wp_fuzzy_number_match( $new_h, $orig_h ) ) { $proceed = (bool) apply_filters( 'wp_image_resize_identical_dimensions', false, $orig_w, $orig_h ); if ( ! $proceed ) { return false; } } return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); } function image_make_intermediate_size( $file, $width, $height, $crop = false ) { if ( $width || $height ) { $editor = wp_get_image_editor( $file ); if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) { return false; } $resized_file = $editor->save(); if ( ! is_wp_error( $resized_file ) && $resized_file ) { unset( $resized_file['path'] ); return $resized_file; } } return false; } function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) { if ( $source_width > $target_width ) { $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width ); $expected_size = array( $target_width, $target_height ); } else { $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width ); $expected_size = array( $source_width, $source_height ); } $matched = ( wp_fuzzy_number_match( $constrained_size[0], $expected_size[0] ) && wp_fuzzy_number_match( $constrained_size[1], $expected_size[1] ) ); return $matched; } function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { $imagedata = wp_get_attachment_metadata( $post_id ); if ( ! $size || ! is_array( $imagedata ) || empty( $imagedata['sizes'] ) ) { return false; } $data = array(); if ( is_array( $size ) ) { $candidates = array(); if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) { $imagedata['height'] = $imagedata['sizes']['full']['height']; $imagedata['width'] = $imagedata['sizes']['full']['width']; } foreach ( $imagedata['sizes'] as $_size => $data ) { if ( (int) $data['width'] === (int) $size[0] && (int) $data['height'] === (int) $size[1] ) { $candidates[ $data['width'] * $data['height'] ] = $data; break; } if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { if ( 0 === $size[0] || 0 === $size[1] ) { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] ); } else { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ); } if ( $same_ratio ) { $candidates[ $data['width'] * $data['height'] ] = $data; } } } if ( ! empty( $candidates ) ) { if ( 1 < count( $candidates ) ) { ksort( $candidates ); } $data = array_shift( $candidates ); } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $size[0] <= $imagedata['sizes']['thumbnail']['width'] && $size[1] <= $imagedata['sizes']['thumbnail']['width'] ) { $data = $imagedata['sizes']['thumbnail']; } else { return false; } list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); } elseif ( ! empty( $imagedata['sizes'][ $size ] ) ) { $data = $imagedata['sizes'][ $size ]; } if ( empty( $data ) ) { return false; } if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) { $file_url = wp_get_attachment_url( $post_id ); $data['path'] = path_join( dirname( $imagedata['file'] ), $data['file'] ); $data['url'] = path_join( dirname( $file_url ), $data['file'] ); } return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); } function get_intermediate_image_sizes() { $default_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' ); $additional_sizes = wp_get_additional_image_sizes(); if ( ! empty( $additional_sizes ) ) { $default_sizes = array_merge( $default_sizes, array_keys( $additional_sizes ) ); } return apply_filters( 'intermediate_image_sizes', $default_sizes ); } function wp_get_registered_image_subsizes() { $additional_sizes = wp_get_additional_image_sizes(); $all_sizes = array(); foreach ( get_intermediate_image_sizes() as $size_name ) { $size_data = array( 'width' => 0, 'height' => 0, 'crop' => false, ); if ( isset( $additional_sizes[ $size_name ]['width'] ) ) { $size_data['width'] = (int) $additional_sizes[ $size_name ]['width']; } else { $size_data['width'] = (int) get_option( "{$size_name}_size_w" ); } if ( isset( $additional_sizes[ $size_name ]['height'] ) ) { $size_data['height'] = (int) $additional_sizes[ $size_name ]['height']; } else { $size_data['height'] = (int) get_option( "{$size_name}_size_h" ); } if ( empty( $size_data['width'] ) && empty( $size_data['height'] ) ) { continue; } if ( isset( $additional_sizes[ $size_name ]['crop'] ) ) { $size_data['crop'] = $additional_sizes[ $size_name ]['crop']; } else { $size_data['crop'] = get_option( "{$size_name}_crop" ); } if ( ! is_array( $size_data['crop'] ) || empty( $size_data['crop'] ) ) { $size_data['crop'] = (bool) $size_data['crop']; } $all_sizes[ $size_name ] = $size_data; } return $all_sizes; } function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) { $image = image_downsize( $attachment_id, $size ); if ( ! $image ) { $src = false; if ( $icon ) { $src = wp_mime_type_icon( $attachment_id, '.svg' ); if ( $src ) { $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); $src_file = $icon_dir . '/' . wp_basename( $src ); list( $width, $height ) = wp_getimagesize( $src_file ); $ext = strtolower( substr( $src_file, -4 ) ); if ( '.svg' === $ext ) { $width = 48; $height = 64; } else { list( $width, $height ) = wp_getimagesize( $src_file ); } } } if ( $src && $width && $height ) { $image = array( $src, $width, $height, false ); } } return apply_filters( 'wp_get_attachment_image_src', $image, $attachment_id, $size, $icon ); } function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) { $html = ''; $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); if ( $image ) { list( $src, $width, $height ) = $image; $attachment = get_post( $attachment_id ); $size_class = $size; if ( is_array( $size_class ) ) { $size_class = implode( 'x', $size_class ); } $default_attr = array( 'src' => $src, 'class' => "attachment-$size_class size-$size_class", 'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), ); $context = apply_filters( 'wp_get_attachment_image_context', 'wp_get_attachment_image' ); $attr = wp_parse_args( $attr, $default_attr ); if ( ! isset( $attr['width'] ) || ! is_numeric( $attr['width'] ) ) { $attr['width'] = $width; } if ( ! isset( $attr['height'] ) || ! is_numeric( $attr['height'] ) ) { $attr['height'] = $height; } $loading_optimization_attr = wp_get_loading_optimization_attributes( 'img', $attr, $context ); $attr = array_merge( $attr, $loading_optimization_attr ); if ( empty( $attr['decoding'] ) || ! in_array( $attr['decoding'], array( 'async', 'sync', 'auto' ), true ) ) { unset( $attr['decoding'] ); } if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } if ( empty( $attr['srcset'] ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( is_array( $image_meta ) ) { $size_array = array( absint( $width ), absint( $height ) ); $srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id ); $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id ); if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) { $attr['srcset'] = $srcset; if ( empty( $attr['sizes'] ) ) { $attr['sizes'] = $sizes; } } } } $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); if ( $add_auto_sizes && isset( $attr['loading'] ) && 'lazy' === $attr['loading'] && isset( $attr['sizes'] ) && ! wp_sizes_attribute_includes_valid_auto( $attr['sizes'] ) ) { $attr['sizes'] = 'auto, ' . $attr['sizes']; } $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size ); if ( isset( $attr['width'] ) && is_numeric( $attr['width'] ) ) { $width = absint( $attr['width'] ); } if ( isset( $attr['height'] ) && is_numeric( $attr['height'] ) ) { $height = absint( $attr['height'] ); } unset( $attr['width'], $attr['height'] ); $attr = array_map( 'esc_attr', $attr ); $hwstring = image_hwstring( $width, $height ); $html = rtrim( "<img $hwstring" ); foreach ( $attr as $name => $value ) { $html .= " $name=" . '"' . $value . '"'; } $html .= ' />'; } return apply_filters( 'wp_get_attachment_image', $html, $attachment_id, $size, $icon, $attr ); } function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) { $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); return isset( $image[0] ) ? $image[0] : false; } function _wp_get_attachment_relative_path( $file ) { $dirname = dirname( $file ); if ( '.' === $dirname ) { return ''; } if ( str_contains( $dirname, 'wp-content/uploads' ) ) { $dirname = substr( $dirname, strpos( $dirname, 'wp-content/uploads' ) + 18 ); $dirname = ltrim( $dirname, '/' ); } return $dirname; } function _wp_get_image_size_from_meta( $size_name, $image_meta ) { if ( 'full' === $size_name ) { return array( absint( $image_meta['width'] ), absint( $image_meta['height'] ), ); } elseif ( ! empty( $image_meta['sizes'][ $size_name ] ) ) { return array( absint( $image_meta['sizes'][ $size_name ]['width'] ), absint( $image_meta['sizes'][ $size_name ]['height'] ), ); } return false; } function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size ); if ( ! $image ) { return false; } if ( ! is_array( $image_meta ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; $size_array = array( absint( $image[1] ), absint( $image[2] ), ); return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id ); } function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) { $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id ); if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) { return false; } $image_sizes = $image_meta['sizes']; $image_width = (int) $size_array[0]; $image_height = (int) $size_array[1]; if ( $image_width < 1 ) { return false; } $image_basename = wp_basename( $image_meta['file'] ); if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) { $image_sizes[] = array( 'width' => $image_meta['width'], 'height' => $image_meta['height'], 'file' => $image_basename, ); } elseif ( str_contains( $image_src, $image_meta['file'] ) ) { return false; } $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); if ( $dirname ) { $dirname = trailingslashit( $dirname ); } $upload_dir = wp_get_upload_dir(); $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname; if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) ) { $parsed = parse_url( $image_baseurl ); $domain = isset( $parsed['host'] ) ? $parsed['host'] : ''; if ( isset( $parsed['port'] ) ) { $domain .= ':' . $parsed['port']; } if ( $_SERVER['HTTP_HOST'] === $domain ) { $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); } } $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash ); $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 2048, $size_array ); $sources = array(); $src_matched = false; foreach ( $image_sizes as $image ) { $is_src = false; if ( ! is_array( $image ) ) { continue; } if ( ! $src_matched && str_contains( $image_src, $dirname . $image['file'] ) ) { $src_matched = true; $is_src = true; } if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { continue; } if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) { continue; } if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) { $source = array( 'url' => $image_baseurl . $image['file'], 'descriptor' => 'w', 'value' => $image['width'], ); if ( $is_src ) { $sources = array( $image['width'] => $source ) + $sources; } else { $sources[ $image['width'] ] = $source; } } } $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id ); if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) { return false; } $srcset = ''; foreach ( $sources as $source ) { $srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', '; } return rtrim( $srcset, ', ' ); } function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size ); if ( ! $image ) { return false; } if ( ! is_array( $image_meta ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; $size_array = array( absint( $image[1] ), absint( $image[2] ), ); return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id ); } function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0 ) { $width = 0; if ( is_array( $size ) ) { $width = absint( $size[0] ); } elseif ( is_string( $size ) ) { if ( ! $image_meta && $attachment_id ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } if ( is_array( $image_meta ) ) { $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); if ( $size_array ) { $width = absint( $size_array[0] ); } } } if ( ! $width ) { return false; } $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id ); } function wp_image_file_matches_image_meta( $image_location, $image_meta, $attachment_id = 0 ) { $match = false; if ( isset( $image_meta['file'] ) && strlen( $image_meta['file'] ) > 4 ) { list( $image_location ) = explode( '?', $image_location ); if ( strrpos( $image_location, $image_meta['file'] ) === strlen( $image_location ) - strlen( $image_meta['file'] ) ) { $match = true; } else { $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); if ( $dirname ) { $dirname = trailingslashit( $dirname ); } if ( ! empty( $image_meta['original_image'] ) ) { $relative_path = $dirname . $image_meta['original_image']; if ( strrpos( $image_location, $relative_path ) === strlen( $image_location ) - strlen( $relative_path ) ) { $match = true; } } if ( ! $match && ! empty( $image_meta['sizes'] ) ) { foreach ( $image_meta['sizes'] as $image_size_data ) { $relative_path = $dirname . $image_size_data['file']; if ( strrpos( $image_location, $relative_path ) === strlen( $image_location ) - strlen( $relative_path ) ) { $match = true; break; } } } } } return apply_filters( 'wp_image_file_matches_image_meta', $match, $image_location, $image_meta, $attachment_id ); } function wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id = 0 ) { $dimensions = false; if ( isset( $image_meta['file'] ) && str_contains( $image_src, wp_basename( $image_meta['file'] ) ) ) { $dimensions = array( (int) $image_meta['width'], (int) $image_meta['height'], ); } if ( ! $dimensions && ! empty( $image_meta['sizes'] ) ) { $src_filename = wp_basename( $image_src ); foreach ( $image_meta['sizes'] as $image_size_data ) { if ( $src_filename === $image_size_data['file'] ) { $dimensions = array( (int) $image_size_data['width'], (int) $image_size_data['height'], ); break; } } } return apply_filters( 'wp_image_src_get_dimensions', $dimensions, $image_src, $image_meta, $attachment_id ); } function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { if ( empty( $image_meta['sizes'] ) ) { return $image; } $image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; list( $image_src ) = explode( '?', $image_src ); if ( ! $image_src ) { return $image; } if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && ! str_contains( wp_basename( $image_src ), $img_edit_hash[0] ) ) { return $image; } $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; if ( $width && $height ) { $size_array = array( $width, $height ); } else { $size_array = wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id ); if ( ! $size_array ) { return $image; } } $srcset = wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id ); if ( $srcset ) { $sizes = strpos( $image, ' sizes=' ); if ( ! $sizes ) { $sizes = wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id ); } } if ( $srcset && $sizes ) { $attr = sprintf( ' srcset="%s"', esc_attr( $srcset ) ); if ( is_string( $sizes ) ) { $attr .= sprintf( ' sizes="%s"', esc_attr( $sizes ) ); } return preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $attr . ' />', $image ); } return $image; } function wp_lazy_loading_enabled( $tag_name, $context ) { $default = ( 'img' === $tag_name || 'iframe' === $tag_name ); return (bool) apply_filters( 'wp_lazy_loading_enabled', $default, $tag_name, $context ); } function wp_filter_content_tags( $content, $context = null ) { if ( null === $context ) { $context = current_filter(); } $add_iframe_loading_attr = wp_lazy_loading_enabled( 'iframe', $context ); if ( ! preg_match_all( '/<(img|iframe)\s[^>]+>/', $content, $matches, PREG_SET_ORDER ) ) { return $content; } $images = array(); $iframes = array(); foreach ( $matches as $match ) { list( $tag, $tag_name ) = $match; switch ( $tag_name ) { case 'img': if ( preg_match( '/wp-image-([0-9]+)/i', $tag, $class_id ) ) { $attachment_id = absint( $class_id[1] ); if ( $attachment_id ) { $images[ $tag ] = $attachment_id; break; } } $images[ $tag ] = 0; break; case 'iframe': $iframes[ $tag ] = 0; break; } } $attachment_ids = array_unique( array_filter( array_values( $images ) ) ); if ( count( $attachment_ids ) > 1 ) { _prime_post_caches( $attachment_ids, false, true ); } foreach ( $matches as $match ) { if ( isset( $images[ $match[0] ] ) ) { $filtered_image = $match[0]; $attachment_id = $images[ $match[0] ]; if ( $attachment_id > 0 && ! str_contains( $filtered_image, ' width=' ) && ! str_contains( $filtered_image, ' height=' ) ) { $filtered_image = wp_img_tag_add_width_and_height_attr( $filtered_image, $context, $attachment_id ); } if ( $attachment_id > 0 && ! str_contains( $filtered_image, ' srcset=' ) ) { $filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id ); } $filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context ); $filtered_image = wp_img_tag_add_auto_sizes( $filtered_image ); $filtered_image = apply_filters( 'wp_content_img_tag', $filtered_image, $context, $attachment_id ); if ( $filtered_image !== $match[0] ) { $content = str_replace( $match[0], $filtered_image, $content ); } unset( $images[ $match[0] ] ); } if ( isset( $iframes[ $match[0] ] ) ) { $filtered_iframe = $match[0]; if ( $add_iframe_loading_attr && ! str_contains( $filtered_iframe, ' loading=' ) ) { $filtered_iframe = wp_iframe_tag_add_loading_attr( $filtered_iframe, $context ); } if ( $filtered_iframe !== $match[0] ) { $content = str_replace( $match[0], $filtered_iframe, $content ); } unset( $iframes[ $match[0] ] ); } } return $content; } function wp_img_tag_add_auto_sizes( string $image ): string { if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) { return $image; } $processor = new WP_HTML_Tag_Processor( $image ); if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) { return $image; } $loading = $processor->get_attribute( 'loading' ); if ( ! is_string( $loading ) || 'lazy' !== strtolower( trim( $loading, " \t\f\r\n" ) ) ) { return $image; } $width = $processor->get_attribute( 'width' ); if ( ! is_string( $width ) || '' === $width ) { return $image; } $sizes = $processor->get_attribute( 'sizes' ); if ( ! is_string( $sizes ) ) { return $image; } if ( wp_sizes_attribute_includes_valid_auto( $sizes ) ) { return $image; } $processor->set_attribute( 'sizes', "auto, $sizes" ); return $processor->get_updated_html(); } function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool { list( $first_size ) = explode( ',', $sizes_attr, 2 ); return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) ); } function wp_enqueue_img_auto_sizes_contain_css_fix(): void { $priority = has_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix' ); if ( false === $priority ) { return; } remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', $priority ); $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); if ( ! $add_auto_sizes ) { return; } $handle = 'wp-img-auto-sizes-contain'; wp_register_style( $handle, false ); wp_add_inline_style( $handle, 'img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px}' ); array_unshift( wp_styles()->queue, $handle ); } function wp_img_tag_add_loading_optimization_attrs( $image, $context ) { $src = preg_match( '/ src=["\']?([^"\']*)/i', $image, $matche_src ) ? $matche_src[1] : null; $width = preg_match( '/ width=["\']([0-9]+)["\']/', $image, $match_width ) ? (int) $match_width[1] : null; $height = preg_match( '/ height=["\']([0-9]+)["\']/', $image, $match_height ) ? (int) $match_height[1] : null; $loading_val = preg_match( '/ loading=["\']([A-Za-z]+)["\']/', $image, $match_loading ) ? $match_loading[1] : null; $fetchpriority_val = preg_match( '/ fetchpriority=["\']([A-Za-z]+)["\']/', $image, $match_fetchpriority ) ? $match_fetchpriority[1] : null; $decoding_val = preg_match( '/ decoding=["\']([A-Za-z]+)["\']/', $image, $match_decoding ) ? $match_decoding[1] : null; $optimization_attrs = wp_get_loading_optimization_attributes( 'img', array( 'src' => $src, 'width' => $width, 'height' => $height, 'loading' => $loading_val, 'fetchpriority' => $fetchpriority_val, 'decoding' => $decoding_val, ), $context ); if ( ! str_contains( $image, ' src="' ) ) { return $image; } if ( empty( $decoding_val ) ) { $filtered_decoding_attr = apply_filters( 'wp_img_tag_add_decoding_attr', isset( $optimization_attrs['decoding'] ) ? $optimization_attrs['decoding'] : false, $image, $context ); if ( isset( $optimization_attrs['decoding'] ) && ! $filtered_decoding_attr ) { unset( $optimization_attrs['decoding'] ); } elseif ( in_array( $filtered_decoding_attr, array( 'async', 'sync', 'auto' ), true ) ) { $optimization_attrs['decoding'] = $filtered_decoding_attr; } if ( ! empty( $optimization_attrs['decoding'] ) ) { $image = str_replace( '<img', '<img decoding="' . esc_attr( $optimization_attrs['decoding'] ) . '"', $image ); } } if ( ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) { return $image; } $loading_attrs_enabled = wp_lazy_loading_enabled( 'img', $context ); if ( empty( $loading_val ) && $loading_attrs_enabled ) { $filtered_loading_attr = apply_filters( 'wp_img_tag_add_loading_attr', isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false, $image, $context ); if ( isset( $optimization_attrs['loading'] ) && ! $filtered_loading_attr ) { unset( $optimization_attrs['loading'] ); } elseif ( in_array( $filtered_loading_attr, array( 'lazy', 'eager' ), true ) ) { if ( isset( $optimization_attrs['fetchpriority'] ) && 'high' === $optimization_attrs['fetchpriority'] && ( isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false ) !== $filtered_loading_attr && 'lazy' === $filtered_loading_attr ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); } $optimization_attrs['loading'] = $filtered_loading_attr; } if ( ! empty( $optimization_attrs['loading'] ) ) { $image = str_replace( '<img', '<img loading="' . esc_attr( $optimization_attrs['loading'] ) . '"', $image ); } } if ( empty( $fetchpriority_val ) && ! empty( $optimization_attrs['fetchpriority'] ) ) { $image = str_replace( '<img', '<img fetchpriority="' . esc_attr( $optimization_attrs['fetchpriority'] ) . '"', $image ); } return $image; } function wp_img_tag_add_width_and_height_attr( $image, $context, $attachment_id ) { $image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; list( $image_src ) = explode( '?', $image_src ); if ( ! $image_src ) { return $image; } $add = apply_filters( 'wp_img_tag_add_width_and_height_attr', true, $image, $context, $attachment_id ); if ( true === $add ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); $size_array = wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id ); if ( $size_array && $size_array[0] && $size_array[1] ) { $style_width = preg_match( '/style="width:\s*(\d+)px;"/', $image, $match_width ) ? (int) $match_width[1] : 0; if ( $style_width ) { $size_array[1] = (int) round( $size_array[1] * $style_width / $size_array[0] ); $size_array[0] = $style_width; } $hw = trim( image_hwstring( $size_array[0], $size_array[1] ) ); return str_replace( '<img', "<img {$hw}", $image ); } } return $image; } function wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id ) { $add = apply_filters( 'wp_img_tag_add_srcset_and_sizes_attr', true, $image, $context, $attachment_id ); if ( true === $add ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); return wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ); } return $image; } function wp_iframe_tag_add_loading_attr( $iframe, $context ) { $optimization_attrs = wp_get_loading_optimization_attributes( 'iframe', array( 'width' => str_contains( $iframe, ' width="' ) ? 100 : null, 'height' => str_contains( $iframe, ' height="' ) ? 100 : null, 'loading' => null, ), $context ); if ( ! str_contains( $iframe, ' src="' ) || ! str_contains( $iframe, ' width="' ) || ! str_contains( $iframe, ' height="' ) ) { return $iframe; } $value = isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false; $value = apply_filters( 'wp_iframe_tag_add_loading_attr', $value, $iframe, $context ); if ( $value ) { if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) { $value = 'lazy'; } return str_replace( '<iframe', '<iframe loading="' . esc_attr( $value ) . '"', $iframe ); } return $iframe; } function _wp_post_thumbnail_class_filter( $attr ) { $attr['class'] .= ' wp-post-image'; return $attr; } function _wp_post_thumbnail_class_filter_add( $attr ) { add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); } function _wp_post_thumbnail_class_filter_remove( $attr ) { remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); } function _wp_post_thumbnail_context_filter( $context ) { return 'the_post_thumbnail'; } function _wp_post_thumbnail_context_filter_add() { add_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); } function _wp_post_thumbnail_context_filter_remove() { remove_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); } add_shortcode( 'wp_caption', 'img_caption_shortcode' ); add_shortcode( 'caption', 'img_caption_shortcode' ); function img_caption_shortcode( $attr, $content = '' ) { if ( ! isset( $attr['caption'] ) ) { if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) { $content = $matches[1]; $attr['caption'] = trim( $matches[2] ); } } elseif ( str_contains( $attr['caption'], '<' ) ) { $attr['caption'] = wp_kses( $attr['caption'], 'post' ); } $output = apply_filters( 'img_caption_shortcode', '', $attr, $content ); if ( ! empty( $output ) ) { return $output; } $atts = shortcode_atts( array( 'id' => '', 'caption_id' => '', 'align' => 'alignnone', 'width' => '', 'caption' => '', 'class' => '', ), $attr, 'caption' ); $atts['width'] = (int) $atts['width']; if ( $atts['width'] < 1 || empty( $atts['caption'] ) ) { return $content; } $id = ''; $caption_id = ''; $describedby = ''; if ( $atts['id'] ) { $atts['id'] = sanitize_html_class( $atts['id'] ); $id = 'id="' . esc_attr( $atts['id'] ) . '" '; } if ( $atts['caption_id'] ) { $atts['caption_id'] = sanitize_html_class( $atts['caption_id'] ); } elseif ( $atts['id'] ) { $atts['caption_id'] = 'caption-' . str_replace( '_', '-', $atts['id'] ); } if ( $atts['caption_id'] ) { $caption_id = 'id="' . esc_attr( $atts['caption_id'] ) . '" '; $describedby = 'aria-describedby="' . esc_attr( $atts['caption_id'] ) . '" '; } $class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] ); $html5 = current_theme_supports( 'html5', 'caption' ); $width = $html5 ? $atts['width'] : ( 10 + $atts['width'] ); $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content ); $style = ''; if ( $caption_width ) { $style = 'style="width: ' . (int) $caption_width . 'px" '; } if ( $html5 ) { $html = sprintf( '<figure %s%s%sclass="%s">%s%s</figure>', $id, $describedby, $style, esc_attr( $class ), do_shortcode( $content ), sprintf( '<figcaption %sclass="wp-caption-text">%s</figcaption>', $caption_id, $atts['caption'] ) ); } else { $html = sprintf( '<div %s%sclass="%s">%s%s</div>', $id, $style, esc_attr( $class ), str_replace( '<img ', '<img ' . $describedby, do_shortcode( $content ) ), sprintf( '<p %sclass="wp-caption-text">%s</p>', $caption_id, $atts['caption'] ) ); } return $html; } add_shortcode( 'gallery', 'gallery_shortcode' ); function gallery_shortcode( $attr ) { $post = get_post(); static $instance = 0; ++$instance; if ( ! empty( $attr['ids'] ) ) { if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; } $output = apply_filters( 'post_gallery', '', $attr, $instance ); if ( ! empty( $output ) ) { return $output; } $html5 = current_theme_supports( 'html5', 'gallery' ); $atts = shortcode_atts( array( 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post ? $post->ID : 0, 'itemtag' => $html5 ? 'figure' : 'dl', 'icontag' => $html5 ? 'div' : 'dt', 'captiontag' => $html5 ? 'figcaption' : 'dd', 'columns' => 3, 'size' => 'thumbnail', 'include' => '', 'exclude' => '', 'link' => '', ), $attr, 'gallery' ); $id = (int) $atts['id']; if ( ! empty( $atts['include'] ) ) { $_attachments = get_posts( array( 'include' => $atts['include'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[ $val->ID ] = $_attachments[ $key ]; } } elseif ( ! empty( $atts['exclude'] ) ) { $post_parent_id = $id; $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); } else { $post_parent_id = $id; $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); } if ( ! empty( $post_parent_id ) ) { $post_parent = get_post( $post_parent_id ); if ( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } } if ( empty( $attachments ) ) { return ''; } if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) { if ( ! empty( $atts['link'] ) ) { if ( 'none' === $atts['link'] ) { $output .= wp_get_attachment_image( $att_id, $atts['size'], false, $attr ); } else { $output .= wp_get_attachment_link( $att_id, $atts['size'], false ); } } else { $output .= wp_get_attachment_link( $att_id, $atts['size'], true ); } $output .= "\n"; } return $output; } $itemtag = tag_escape( $atts['itemtag'] ); $captiontag = tag_escape( $atts['captiontag'] ); $icontag = tag_escape( $atts['icontag'] ); $valid_tags = wp_kses_allowed_html( 'post' ); if ( ! isset( $valid_tags[ $itemtag ] ) ) { $itemtag = 'dl'; } if ( ! isset( $valid_tags[ $captiontag ] ) ) { $captiontag = 'dd'; } if ( ! isset( $valid_tags[ $icontag ] ) ) { $icontag = 'dt'; } $columns = (int) $atts['columns']; $itemwidth = $columns > 0 ? floor( 100 / $columns ) : 100; $float = is_rtl() ? 'right' : 'left'; $selector = "gallery-{$instance}"; $gallery_style = ''; if ( apply_filters( 'use_default_gallery_style', ! $html5 ) ) { $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; $gallery_style = "
<style{$type_attr}>
#{$selector} {
margin: auto;
}
#{$selector} .gallery-item {
float: {$float};
margin-top: 10px;
text-align: center;
width: {$itemwidth}%;
}
#{$selector} img {
border: 2px solid #cfcfcf;
}
#{$selector} .gallery-caption {
margin-left: 0;
}
/* see gallery_shortcode() in wp-includes/media.php */
</style>\n\t\t"; } $size_class = sanitize_html_class( is_array( $atts['size'] ) ? implode( 'x', $atts['size'] ) : $atts['size'] ); $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; $output = apply_filters( 'gallery_style', $gallery_style . $gallery_div ); $i = 0; foreach ( $attachments as $id => $attachment ) { $attr = ( trim( $attachment->post_excerpt ) ) ? array( 'aria-describedby' => "$selector-$id" ) : ''; if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) { $image_output = wp_get_attachment_link( $id, $atts['size'], false, false, false, $attr ); } elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) { $image_output = wp_get_attachment_image( $id, $atts['size'], false, $attr ); } else { $image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr ); } $image_meta = wp_get_attachment_metadata( $id ); $orientation = ''; if ( isset( $image_meta['height'], $image_meta['width'] ) ) { $orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape'; } $output .= "<{$itemtag} class='gallery-item'>"; $output .= "
<{$icontag} class='gallery-icon {$orientation}'>
$image_output
</{$icontag}>"; if ( $captiontag && trim( $attachment->post_excerpt ) ) { $output .= "
<{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'>
" . wptexturize( $attachment->post_excerpt ) . "
</{$captiontag}>"; } $output .= "</{$itemtag}>"; if ( ! $html5 && $columns > 0 && 0 === ++$i % $columns ) { $output .= '<br style="clear: both" />'; } } if ( ! $html5 && $columns > 0 && 0 !== $i % $columns ) { $output .= "
<br style='clear: both' />"; } $output .= "
</div>\n"; return $output; } function wp_underscore_playlist_templates() { ?>
<script type="text/html" id="tmpl-wp-playlist-current-item">
<# if ( data.thumb && data.thumb.src ) { #>
<img src="{{ data.thumb.src }}" alt="" />
<# } #>
<div class="wp-playlist-caption">
<span class="wp-playlist-item-meta wp-playlist-item-title">
<# if ( data.meta.album || data.meta.artist ) { #>
<?php
printf( _x( '“%s”', 'playlist item title' ), '{{ data.title }}' ); ?>
<# } else { #>
{{ data.title }}
<# } #>
</span>
<# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #>
<# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #>
</div>
</script>
<script type="text/html" id="tmpl-wp-playlist-item">
<div class="wp-playlist-item">
<a class="wp-playlist-caption" href="{{ data.src }}">
{{ data.index ? ( data.index + '. ' ) : '' }}
<# if ( data.caption ) { #>
{{ data.caption }}
<# } else { #>
<# if ( data.artists && data.meta.artist ) { #>
<span class="wp-playlist-item-title">
<?php
printf( _x( '“%s”', 'playlist item title' ), '{{{ data.title }}}' ); ?>
</span>
<span class="wp-playlist-item-artist"> — {{ data.meta.artist }}</span>
<# } else { #>
<span class="wp-playlist-item-title">{{{ data.title }}}</span>
<# } #>
<# } #>
</a>
<# if ( data.meta.length_formatted ) { #>
<div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div>
<# } #>
</div>
</script>
<?php
} function wp_playlist_scripts( $type ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-playlist' ); add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 ); add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 ); } function wp_playlist_shortcode( $attr ) { global $content_width; $post = get_post(); static $instance = 0; ++$instance; static $is_loaded = false; if ( ! empty( $attr['ids'] ) ) { if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; } $output = apply_filters( 'post_playlist', '', $attr, $instance ); if ( ! empty( $output ) ) { return $output; } $atts = shortcode_atts( array( 'type' => 'audio', 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post ? $post->ID : 0, 'include' => '', 'exclude' => '', 'style' => 'light', 'tracklist' => true, 'tracknumbers' => true, 'images' => true, 'artists' => true, ), $attr, 'playlist' ); $id = (int) $atts['id']; if ( 'audio' !== $atts['type'] ) { $atts['type'] = 'video'; } $args = array( 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => $atts['type'], 'order' => $atts['order'], 'orderby' => $atts['orderby'], ); if ( ! empty( $atts['include'] ) ) { $args['include'] = $atts['include']; $_attachments = get_posts( $args ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[ $val->ID ] = $_attachments[ $key ]; } } elseif ( ! empty( $atts['exclude'] ) ) { $args['post_parent'] = $id; $args['exclude'] = $atts['exclude']; $attachments = get_children( $args ); } else { $args['post_parent'] = $id; $attachments = get_children( $args ); } if ( ! empty( $args['post_parent'] ) ) { $post_parent = get_post( $id ); if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } } if ( empty( $attachments ) ) { return ''; } if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) { $output .= wp_get_attachment_link( $att_id ) . "\n"; } return $output; } $outer = 22; $default_width = 640; $default_height = 360; $theme_width = empty( $content_width ) ? $default_width : ( $content_width - $outer ); $theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width ); $data = array( 'type' => $atts['type'], 'tracklist' => wp_validate_boolean( $atts['tracklist'] ), 'tracknumbers' => wp_validate_boolean( $atts['tracknumbers'] ), 'images' => wp_validate_boolean( $atts['images'] ), 'artists' => wp_validate_boolean( $atts['artists'] ), ); $tracks = array(); foreach ( $attachments as $attachment ) { $url = wp_get_attachment_url( $attachment->ID ); $ftype = wp_check_filetype( $url, wp_get_mime_types() ); $track = array( 'src' => $url, 'type' => $ftype['type'], 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, ); $track['meta'] = array(); $meta = wp_get_attachment_metadata( $attachment->ID ); if ( ! empty( $meta ) ) { foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) { if ( ! empty( $meta[ $key ] ) ) { $track['meta'][ $key ] = $meta[ $key ]; } } if ( 'video' === $atts['type'] ) { if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $width = $meta['width']; $height = $meta['height']; $theme_height = round( ( $height * $theme_width ) / $width ); } else { $width = $default_width; $height = $default_height; } $track['dimensions'] = array( 'original' => compact( 'width', 'height' ), 'resized' => array( 'width' => $theme_width, 'height' => $theme_height, ), ); } } if ( $atts['images'] ) { $thumb_id = get_post_thumbnail_id( $attachment->ID ); if ( ! empty( $thumb_id ) ) { list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' ); $track['image'] = compact( 'src', 'width', 'height' ); list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' ); $track['thumb'] = compact( 'src', 'width', 'height' ); } else { $src = wp_mime_type_icon( $attachment->ID, '.svg' ); $width = 48; $height = 64; $track['image'] = compact( 'src', 'width', 'height' ); $track['thumb'] = compact( 'src', 'width', 'height' ); } } $tracks[] = $track; } $data['tracks'] = $tracks; $safe_type = esc_attr( $atts['type'] ); $safe_style = esc_attr( $atts['style'] ); ob_start(); if ( ! $is_loaded ) { do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] ); $is_loaded = true; } ?>
<div class="wp-playlist wp-<?php echo $safe_type; ?>-playlist wp-playlist-<?php echo $safe_style; ?>">
<?php if ( 'audio' === $atts['type'] ) : ?>
<div class="wp-playlist-current-item"></div>
<?php endif; ?>
<<?php echo $safe_type; ?> controls="controls" preload="none" width="<?php echo (int) $theme_width; ?>"
<?php
if ( 'video' === $safe_type ) { echo ' height="', (int) $theme_height, '"'; } ?>
></<?php echo $safe_type; ?>>
<div class="wp-playlist-next"></div>
<div class="wp-playlist-prev"></div>
<noscript>
<ol>
<?php
foreach ( $attachments as $att_id => $attachment ) { printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) ); } ?>
</ol>
</noscript>
<script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ); ?></script>
</div>
<?php
return ob_get_clean(); } add_shortcode( 'playlist', 'wp_playlist_shortcode' ); function wp_mediaelement_fallback( $url ) { return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url ); } function wp_get_audio_extensions() { return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'flac', 'm4a', 'wav' ) ); } function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) { $fields = array( 'artist' => __( 'Artist' ), 'album' => __( 'Album' ), ); if ( 'display' === $context ) { $fields['genre'] = __( 'Genre' ); $fields['year'] = __( 'Year' ); $fields['length_formatted'] = _x( 'Length', 'video or audio' ); } elseif ( 'js' === $context ) { $fields['bitrate'] = __( 'Bitrate' ); $fields['bitrate_mode'] = __( 'Bitrate Mode' ); } return apply_filters( 'wp_get_attachment_id3_keys', $fields, $attachment, $context ); } function wp_audio_shortcode( $attr, $content = '' ) { $post_id = get_post() ? get_the_ID() : 0; static $instance = 0; ++$instance; $override = apply_filters( 'wp_audio_shortcode_override', '', $attr, $content, $instance ); if ( '' !== $override ) { return $override; } $audio = null; $default_types = wp_get_audio_extensions(); $defaults_atts = array( 'src' => '', 'loop' => '', 'autoplay' => '', 'muted' => 'false', 'preload' => 'none', 'class' => 'wp-audio-shortcode', 'style' => 'width: 100%;', ); foreach ( $default_types as $type ) { $defaults_atts[ $type ] = ''; } $atts = shortcode_atts( $defaults_atts, $attr, 'audio' ); $primary = false; if ( ! empty( $atts['src'] ) ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '<a class="wp-embedded-audio" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } $primary = true; array_unshift( $default_types, 'src' ); } else { foreach ( $default_types as $ext ) { if ( ! empty( $atts[ $ext ] ) ) { $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() ); if ( strtolower( $type['ext'] ) === $ext ) { $primary = true; } } } } if ( ! $primary ) { $audios = get_attached_media( 'audio', $post_id ); if ( empty( $audios ) ) { return; } $audio = reset( $audios ); $atts['src'] = wp_get_attachment_url( $audio->ID ); if ( empty( $atts['src'] ) ) { return; } array_unshift( $default_types, 'src' ); } $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ); if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); } $atts['class'] = apply_filters( 'wp_audio_shortcode_class', $atts['class'], $atts ); $html_atts = array( 'class' => $atts['class'], 'id' => sprintf( 'audio-%d-%d', $post_id, $instance ), 'loop' => wp_validate_boolean( $atts['loop'] ), 'autoplay' => wp_validate_boolean( $atts['autoplay'] ), 'muted' => wp_validate_boolean( $atts['muted'] ), 'preload' => $atts['preload'], 'style' => $atts['style'], ); foreach ( array( 'loop', 'autoplay', 'preload', 'muted' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } } $attr_strings = array(); foreach ( $html_atts as $attribute_name => $attribute_value ) { if ( in_array( $attribute_name, array( 'loop', 'autoplay', 'muted' ), true ) && true === $attribute_value ) { $attr_strings[] = esc_attr( $attribute_name ); } elseif ( 'preload' === $attribute_name && ! empty( $attribute_value ) ) { $allowed_preload_values = array( 'none', 'metadata', 'auto' ); if ( in_array( $attribute_value, $allowed_preload_values, true ) ) { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } else { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } $html = sprintf( '<audio %s controls="controls">', implode( ' ', $attr_strings ) ); $fileurl = ''; $source = '<source type="%s" src="%s" />'; foreach ( $default_types as $fallback ) { if ( ! empty( $atts[ $fallback ] ) ) { if ( empty( $fileurl ) ) { $fileurl = $atts[ $fallback ]; } $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() ); $url = add_query_arg( '_', $instance, $atts[ $fallback ] ); $html .= sprintf( $source, $type['type'], esc_url( $url ) ); } } if ( 'mediaelement' === $library ) { $html .= wp_mediaelement_fallback( $fileurl ); } $html .= '</audio>'; return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id, $library ); } add_shortcode( 'audio', 'wp_audio_shortcode' ); function wp_get_video_extensions() { return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'flv' ) ); } function wp_video_shortcode( $attr, $content = '' ) { global $content_width; $post_id = get_post() ? get_the_ID() : 0; static $instance = 0; ++$instance; $override = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instance ); if ( '' !== $override ) { return $override; } $video = null; $default_types = wp_get_video_extensions(); $defaults_atts = array( 'src' => '', 'poster' => '', 'loop' => '', 'autoplay' => '', 'muted' => 'false', 'preload' => 'metadata', 'width' => 640, 'height' => 360, 'class' => 'wp-video-shortcode', ); foreach ( $default_types as $type ) { $defaults_atts[ $type ] = ''; } $atts = shortcode_atts( $defaults_atts, $attr, 'video' ); if ( is_admin() ) { if ( $atts['width'] > $defaults_atts['width'] ) { $atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] ); $atts['width'] = $defaults_atts['width']; } } else { if ( ! empty( $content_width ) && $atts['width'] > $content_width ) { $atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] ); $atts['width'] = $content_width; } } $is_vimeo = false; $is_youtube = false; $yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#'; $vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#'; $primary = false; if ( ! empty( $atts['src'] ) ) { $is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) ); $is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) ); if ( ! $is_youtube && ! $is_vimeo ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } } if ( $is_vimeo ) { wp_enqueue_script( 'mediaelement-vimeo' ); } $primary = true; array_unshift( $default_types, 'src' ); } else { foreach ( $default_types as $ext ) { if ( ! empty( $atts[ $ext ] ) ) { $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() ); if ( strtolower( $type['ext'] ) === $ext ) { $primary = true; } } } } if ( ! $primary ) { $videos = get_attached_media( 'video', $post_id ); if ( empty( $videos ) ) { return; } $video = reset( $videos ); $atts['src'] = wp_get_attachment_url( $video->ID ); if ( empty( $atts['src'] ) ) { return; } array_unshift( $default_types, 'src' ); } $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' ); if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); wp_enqueue_script( 'mediaelement-vimeo' ); } if ( 'mediaelement' === $library ) { if ( $is_youtube ) { $atts['src'] = remove_query_arg( 'feature', $atts['src'] ); $atts['src'] = set_url_scheme( $atts['src'], 'https' ); } elseif ( $is_vimeo ) { $parsed_vimeo_url = wp_parse_url( $atts['src'] ); $vimeo_src = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path']; $loop = $atts['loop'] ? '1' : '0'; $atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src ); } } $atts['class'] = apply_filters( 'wp_video_shortcode_class', $atts['class'], $atts ); $html_atts = array( 'class' => $atts['class'], 'id' => sprintf( 'video-%d-%d', $post_id, $instance ), 'width' => absint( $atts['width'] ), 'height' => absint( $atts['height'] ), 'poster' => esc_url( $atts['poster'] ), 'loop' => wp_validate_boolean( $atts['loop'] ), 'autoplay' => wp_validate_boolean( $atts['autoplay'] ), 'muted' => wp_validate_boolean( $atts['muted'] ), 'preload' => $atts['preload'], ); foreach ( array( 'poster', 'loop', 'autoplay', 'preload', 'muted' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } } $attr_strings = array(); foreach ( $html_atts as $attribute_name => $attribute_value ) { if ( in_array( $attribute_name, array( 'loop', 'autoplay', 'muted' ), true ) && true === $attribute_value ) { $attr_strings[] = esc_attr( $attribute_name ); } elseif ( 'preload' === $attribute_name && ! empty( $attribute_value ) ) { $allowed_preload_values = array( 'none', 'metadata', 'auto' ); if ( in_array( $attribute_value, $allowed_preload_values, true ) ) { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } elseif ( ! empty( $attribute_value ) ) { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } $html = sprintf( '<video %s controls="controls">', implode( ' ', $attr_strings ) ); $fileurl = ''; $source = '<source type="%s" src="%s" />'; foreach ( $default_types as $fallback ) { if ( ! empty( $atts[ $fallback ] ) ) { if ( empty( $fileurl ) ) { $fileurl = $atts[ $fallback ]; } if ( 'src' === $fallback && $is_youtube ) { $type = array( 'type' => 'video/youtube' ); } elseif ( 'src' === $fallback && $is_vimeo ) { $type = array( 'type' => 'video/vimeo' ); } else { $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() ); } $url = add_query_arg( '_', $instance, $atts[ $fallback ] ); $html .= sprintf( $source, $type['type'], esc_url( $url ) ); } } if ( ! empty( $content ) ) { if ( str_contains( $content, "\n" ) ) { $content = str_replace( array( "\r\n", "\n", "\t" ), '', $content ); } $html .= trim( $content ); } if ( 'mediaelement' === $library ) { $html .= wp_mediaelement_fallback( $fileurl ); } $html .= '</video>'; $width_rule = ''; if ( ! empty( $atts['width'] ) ) { $width_rule = sprintf( 'width: %dpx;', $atts['width'] ); } $output = sprintf( '<div style="%s" class="wp-video">%s</div>', $width_rule, $html ); return apply_filters( 'wp_video_shortcode', $output, $atts, $video, $post_id, $library ); } add_shortcode( 'video', 'wp_video_shortcode' ); function get_previous_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( true, $size, $text ); } function previous_image_link( $size = 'thumbnail', $text = false ) { echo get_previous_image_link( $size, $text ); } function get_next_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( false, $size, $text ); } function next_image_link( $size = 'thumbnail', $text = false ) { echo get_next_image_link( $size, $text ); } function get_adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { $post = get_post(); $attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID', ) ) ); foreach ( $attachments as $k => $attachment ) { if ( (int) $attachment->ID === (int) $post->ID ) { break; } } $output = ''; $attachment_id = 0; if ( $attachments ) { $k = $prev ? $k - 1 : $k + 1; if ( isset( $attachments[ $k ] ) ) { $attachment_id = $attachments[ $k ]->ID; $attr = array( 'alt' => get_the_title( $attachment_id ) ); $output = wp_get_attachment_link( $attachment_id, $size, true, false, $text, $attr ); } } $adjacent = $prev ? 'previous' : 'next'; return apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text ); } function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { echo get_adjacent_image_link( $prev, $size, $text ); } function get_attachment_taxonomies( $attachment, $output = 'names' ) { if ( is_int( $attachment ) ) { $attachment = get_post( $attachment ); } elseif ( is_array( $attachment ) ) { $attachment = (object) $attachment; } if ( ! is_object( $attachment ) ) { return array(); } $file = get_attached_file( $attachment->ID ); $filename = wp_basename( $file ); $objects = array( 'attachment' ); if ( str_contains( $filename, '.' ) ) { $objects[] = 'attachment:' . substr( $filename, strrpos( $filename, '.' ) + 1 ); } if ( ! empty( $attachment->post_mime_type ) ) { $objects[] = 'attachment:' . $attachment->post_mime_type; if ( str_contains( $attachment->post_mime_type, '/' ) ) { foreach ( explode( '/', $attachment->post_mime_type ) as $token ) { if ( ! empty( $token ) ) { $objects[] = "attachment:$token"; } } } } $taxonomies = array(); foreach ( $objects as $object ) { $taxes = get_object_taxonomies( $object, $output ); if ( $taxes ) { $taxonomies = array_merge( $taxonomies, $taxes ); } } if ( 'names' === $output ) { $taxonomies = array_unique( $taxonomies ); } return $taxonomies; } function get_taxonomies_for_attachments( $output = 'names' ) { $taxonomies = array(); foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { foreach ( $taxonomy->object_type as $object_type ) { if ( 'attachment' === $object_type || str_starts_with( $object_type, 'attachment:' ) ) { if ( 'names' === $output ) { $taxonomies[] = $taxonomy->name; } else { $taxonomies[ $taxonomy->name ] = $taxonomy; } break; } } } return $taxonomies; } function is_gd_image( $image ) { if ( $image instanceof GdImage || is_resource( $image ) && 'gd' === get_resource_type( $image ) ) { return true; } return false; } function wp_imagecreatetruecolor( $width, $height ) { $img = imagecreatetruecolor( $width, $height ); if ( is_gd_image( $img ) && function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) { imagealphablending( $img, false ); imagesavealpha( $img, true ); } return $img; } function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { $example_width = (int) $example_width; $example_height = (int) $example_height; $max_width = (int) $max_width; $max_height = (int) $max_height; return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height ); } function wp_max_upload_size() { $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); return apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); } function wp_get_image_editor( $path, $args = array() ) { $args['path'] = $path; if ( ! isset( $args['mime_type'] ) ) { $file_info = wp_check_filetype( $args['path'] ); if ( isset( $file_info ) && $file_info['type'] ) { $args['mime_type'] = $file_info['type']; } } if ( isset( $args['mime_type'] ) ) { $output_format = wp_get_image_editor_output_format( $path, $args['mime_type'] ); if ( isset( $output_format[ $args['mime_type'] ] ) ) { $args['output_mime_type'] = $output_format[ $args['mime_type'] ]; } } $implementation = _wp_image_editor_choose( $args ); if ( $implementation ) { $editor = new $implementation( $path ); $loaded = $editor->load(); if ( is_wp_error( $loaded ) ) { return $loaded; } return $editor; } return new WP_Error( 'image_no_editor', __( 'No editor could be selected.' ) ); } function wp_image_editor_supports( $args = array() ) { return (bool) _wp_image_editor_choose( $args ); } function _wp_image_editor_choose( $args = array() ) { require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; require_once ABSPATH . WPINC . '/class-avif-info.php'; $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); $editors = wp_cache_get( 'wp_image_editor_choose', 'image_editor' ); if ( ! is_array( $editors ) ) { $editors = array(); } $cache_key = md5( serialize( array( $args, $implementations ) ) ); if ( isset( $editors[ $cache_key ] ) ) { return $editors[ $cache_key ]; } $editor = false; foreach ( $implementations as $implementation ) { if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) { continue; } if ( isset( $args['mime_type'] ) && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['mime_type'] ) ) { continue; } if ( isset( $args['methods'] ) && array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { continue; } if ( isset( $args['mime_type'] ) && isset( $args['output_mime_type'] ) && $args['mime_type'] !== $args['output_mime_type'] && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['output_mime_type'] ) ) { $editor = $implementation; continue; } $editor = $implementation; break; } $editors[ $cache_key ] = $editor; wp_cache_set( 'wp_image_editor_choose', $editors, 'image_editor', DAY_IN_SECONDS ); return $editor; } function wp_plupload_default_settings() { $wp_scripts = wp_scripts(); $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); if ( $data && str_contains( $data, '_wpPluploadSettings' ) ) { return; } $max_upload_size = wp_max_upload_size(); $allowed_extensions = array_keys( get_allowed_mime_types() ); $extensions = array(); foreach ( $allowed_extensions as $extension ) { $extensions = array_merge( $extensions, explode( '|', $extension ) ); } $defaults = array( 'file_data_name' => 'async-upload', 'url' => admin_url( 'async-upload.php', 'relative' ), 'filters' => array( 'max_file_size' => $max_upload_size . 'b', 'mime_types' => array( array( 'extensions' => implode( ',', $extensions ) ) ), ), ); if ( wp_is_mobile() && str_contains( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) ) { $defaults['multi_selection'] = false; } if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { $defaults['webp_upload_error'] = true; } if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) { $defaults['avif_upload_error'] = true; } if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $defaults['heic_upload_error'] = true; } $defaults = apply_filters( 'plupload_default_settings', $defaults ); $params = array( 'action' => 'upload-attachment', ); $params = apply_filters( 'plupload_default_params', $params ); $params['_wpnonce'] = wp_create_nonce( 'media-form' ); $defaults['multipart_params'] = $params; $settings = array( 'defaults' => $defaults, 'browser' => array( 'mobile' => wp_is_mobile(), 'supported' => _device_can_upload(), ), 'limitExceeded' => is_multisite() && ! is_upload_space_available(), ); $script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) . ';'; if ( $data ) { $script = "$data\n$script"; } $wp_scripts->add_data( 'wp-plupload', 'data', $script ); } function wp_prepare_attachment_for_js( $attachment ) { $attachment = get_post( $attachment ); if ( ! $attachment ) { return; } if ( 'attachment' !== $attachment->post_type ) { return; } $meta = wp_get_attachment_metadata( $attachment->ID ); if ( str_contains( $attachment->post_mime_type, '/' ) ) { list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); } else { list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); } $attachment_url = wp_get_attachment_url( $attachment->ID ); $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); $response = array( 'id' => $attachment->ID, 'title' => $attachment->post_title, 'filename' => wp_basename( get_attached_file( $attachment->ID ) ), 'url' => $attachment_url, 'link' => get_attachment_link( $attachment->ID ), 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), 'author' => $attachment->post_author, 'description' => $attachment->post_content, 'caption' => $attachment->post_excerpt, 'name' => $attachment->post_name, 'status' => $attachment->post_status, 'uploadedTo' => $attachment->post_parent, 'date' => strtotime( $attachment->post_date_gmt ) * 1000, 'modified' => strtotime( $attachment->post_modified_gmt ) * 1000, 'menuOrder' => $attachment->menu_order, 'mime' => $attachment->post_mime_type, 'type' => $type, 'subtype' => $subtype, 'icon' => wp_mime_type_icon( $attachment->ID, '.svg' ), 'dateFormatted' => mysql2date( __( 'F j, Y' ), $attachment->post_date ), 'nonces' => array( 'update' => false, 'delete' => false, 'edit' => false, ), 'editLink' => false, 'meta' => false, ); $author = new WP_User( $attachment->post_author ); if ( $author->exists() ) { $author_name = $author->display_name ? $author->display_name : $author->nickname; $response['authorName'] = html_entity_decode( $author_name, ENT_QUOTES, get_bloginfo( 'charset' ) ); $response['authorLink'] = get_edit_user_link( $author->ID ); } else { $response['authorName'] = __( '(no author)' ); } if ( $attachment->post_parent ) { $post_parent = get_post( $attachment->post_parent ); if ( $post_parent && current_user_can( 'read_post', $attachment->post_parent ) ) { $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' ); $response['uploadedToLink'] = get_edit_post_link( $attachment->post_parent, 'raw' ); } } $attached_file = get_attached_file( $attachment->ID ); if ( isset( $meta['filesize'] ) ) { $bytes = $meta['filesize']; } elseif ( file_exists( $attached_file ) ) { $bytes = wp_filesize( $attached_file ); } else { $bytes = ''; } if ( $bytes ) { $response['filesizeInBytes'] = $bytes; $response['filesizeHumanReadable'] = size_format( $bytes ); } $context = get_post_meta( $attachment->ID, '_wp_attachment_context', true ); $response['context'] = ( $context ) ? $context : ''; if ( current_user_can( 'edit_post', $attachment->ID ) ) { $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); $response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID ); $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); } if ( current_user_can( 'delete_post', $attachment->ID ) ) { $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID ); } if ( $meta && ( 'image' === $type || ! empty( $meta['sizes'] ) ) ) { $sizes = array(); $possible_sizes = apply_filters( 'image_size_names_choose', array( 'thumbnail' => __( 'Thumbnail' ), 'medium' => __( 'Medium' ), 'large' => __( 'Large' ), 'full' => __( 'Full Size' ), ) ); unset( $possible_sizes['full'] ); foreach ( $possible_sizes as $size => $label ) { $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ); if ( $downsize ) { if ( empty( $downsize[3] ) ) { continue; } $sizes[ $size ] = array( 'height' => $downsize[2], 'width' => $downsize[1], 'url' => $downsize[0], 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', ); } elseif ( isset( $meta['sizes'][ $size ] ) ) { $size_meta = $meta['sizes'][ $size ]; list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' ); $sizes[ $size ] = array( 'height' => $height, 'width' => $width, 'url' => $base_url . $size_meta['file'], 'orientation' => $height > $width ? 'portrait' : 'landscape', ); } } if ( 'image' === $type ) { if ( ! empty( $meta['original_image'] ) ) { $response['originalImageURL'] = wp_get_original_image_url( $attachment->ID ); $response['originalImageName'] = wp_basename( wp_get_original_image_path( $attachment->ID ) ); } $sizes['full'] = array( 'url' => $attachment_url ); if ( isset( $meta['height'], $meta['width'] ) ) { $sizes['full']['height'] = $meta['height']; $sizes['full']['width'] = $meta['width']; $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape'; } $response = array_merge( $response, $sizes['full'] ); } elseif ( $meta['sizes']['full']['file'] ) { $sizes['full'] = array( 'url' => $base_url . $meta['sizes']['full']['file'], 'height' => $meta['sizes']['full']['height'], 'width' => $meta['sizes']['full']['width'], 'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape', ); } $response = array_merge( $response, array( 'sizes' => $sizes ) ); } if ( $meta && 'video' === $type ) { if ( isset( $meta['width'] ) ) { $response['width'] = (int) $meta['width']; } if ( isset( $meta['height'] ) ) { $response['height'] = (int) $meta['height']; } } if ( $meta && ( 'audio' === $type || 'video' === $type ) ) { if ( isset( $meta['length_formatted'] ) ) { $response['fileLength'] = $meta['length_formatted']; $response['fileLengthHumanReadable'] = human_readable_duration( $meta['length_formatted'] ); } $response['meta'] = array(); foreach ( wp_get_attachment_id3_keys( $attachment, 'js' ) as $key => $label ) { $response['meta'][ $key ] = false; if ( ! empty( $meta[ $key ] ) ) { $response['meta'][ $key ] = $meta[ $key ]; } } $id = get_post_thumbnail_id( $attachment->ID ); if ( ! empty( $id ) ) { list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' ); $response['image'] = compact( 'src', 'width', 'height' ); list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' ); $response['thumb'] = compact( 'src', 'width', 'height' ); } else { $src = wp_mime_type_icon( $attachment->ID, '.svg' ); $width = 48; $height = 64; $response['image'] = compact( 'src', 'width', 'height' ); $response['thumb'] = compact( 'src', 'width', 'height' ); } } if ( function_exists( 'get_compat_media_markup' ) ) { $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) ); } if ( function_exists( 'get_media_states' ) ) { $media_states = get_media_states( $attachment ); if ( ! empty( $media_states ) ) { $response['mediaStates'] = implode( ', ', $media_states ); } } return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); } function wp_enqueue_media( $args = array() ) { if ( did_action( 'wp_enqueue_media' ) ) { return; } global $content_width, $wpdb, $wp_locale; $defaults = array( 'post' => null, ); $args = wp_parse_args( $args, $defaults ); $tabs = array( 'type' => '', 'type_url' => '', 'gallery' => '', 'library' => '', ); $tabs = apply_filters( 'media_upload_tabs', $tabs ); unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] ); $props = array( 'link' => get_option( 'image_default_link_type' ), 'align' => get_option( 'image_default_align' ), 'size' => get_option( 'image_default_size' ), ); $exts = array_merge( wp_get_audio_extensions(), wp_get_video_extensions() ); $mimes = get_allowed_mime_types(); $ext_mimes = array(); foreach ( $exts as $ext ) { foreach ( $mimes as $ext_preg => $mime_match ) { if ( preg_match( '#' . $ext . '#i', $ext_preg ) ) { $ext_mimes[ $ext ] = $mime_match; break; } } } $show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true ); if ( null === $show_audio_playlist ) { $show_audio_playlist = $wpdb->get_var( "SELECT ID
FROM $wpdb->posts
WHERE post_type = 'attachment'
AND post_mime_type LIKE 'audio%'
LIMIT 1" ); } $show_video_playlist = apply_filters( 'media_library_show_video_playlist', true ); if ( null === $show_video_playlist ) { $show_video_playlist = $wpdb->get_var( "SELECT ID
FROM $wpdb->posts
WHERE post_type = 'attachment'
AND post_mime_type LIKE 'video%'
LIMIT 1" ); } $months = apply_filters( 'media_library_months_with_files', null ); if ( ! is_array( $months ) ) { $months = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
FROM $wpdb->posts
WHERE post_type = %s
ORDER BY post_date DESC", 'attachment' ) ); } foreach ( $months as $month_year ) { $month_year->text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month_year->month ), $month_year->year ); } $infinite_scrolling = apply_filters( 'media_library_infinite_scrolling', false ); $settings = array( 'tabs' => $tabs, 'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url( 'media-upload.php' ) ), 'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ), 'captions' => ! apply_filters( 'disable_captions', '' ), 'nonce' => array( 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ), 'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ), ), 'post' => array( 'id' => 0, ), 'defaultProps' => $props, 'attachmentCounts' => array( 'audio' => ( $show_audio_playlist ) ? 1 : 0, 'video' => ( $show_video_playlist ) ? 1 : 0, ), 'oEmbedProxyUrl' => rest_url( 'oembed/1.0/proxy' ), 'embedExts' => $exts, 'embedMimes' => $ext_mimes, 'contentWidth' => $content_width, 'months' => $months, 'mediaTrash' => MEDIA_TRASH ? 1 : 0, 'infiniteScrolling' => ( $infinite_scrolling ) ? 1 : 0, ); $post = null; if ( isset( $args['post'] ) ) { $post = get_post( $args['post'] ); $settings['post'] = array( 'id' => $post->ID, 'nonce' => wp_create_nonce( 'update-post_' . $post->ID ), ); $thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ); if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) { if ( wp_attachment_is( 'audio', $post ) ) { $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ); } elseif ( wp_attachment_is( 'video', $post ) ) { $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ); } } if ( $thumbnail_support ) { $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true ); $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1; } } if ( $post ) { $post_type_object = get_post_type_object( $post->post_type ); } else { $post_type_object = get_post_type_object( 'post' ); } $strings = array( 'mediaFrameDefaultTitle' => __( 'Media' ), 'url' => __( 'URL' ), 'addMedia' => __( 'Add media' ), 'search' => __( 'Search' ), 'select' => __( 'Select' ), 'cancel' => __( 'Cancel' ), 'update' => __( 'Update' ), 'replace' => __( 'Replace' ), 'remove' => __( 'Remove' ), 'back' => __( 'Back' ), 'selected' => __( '%d selected' ), 'dragInfo' => __( 'Drag and drop to reorder media files.' ), 'uploadFilesTitle' => __( 'Upload files' ), 'uploadImagesTitle' => __( 'Upload images' ), 'mediaLibraryTitle' => __( 'Media Library' ), 'insertMediaTitle' => __( 'Add media' ), 'createNewGallery' => __( 'Create a new gallery' ), 'createNewPlaylist' => __( 'Create a new playlist' ), 'createNewVideoPlaylist' => __( 'Create a new video playlist' ), 'returnToLibrary' => __( '← Go to library' ), 'allMediaItems' => __( 'All media items' ), 'allDates' => __( 'All dates' ), 'noItemsFound' => __( 'No items found.' ), 'insertIntoPost' => $post_type_object->labels->insert_into_item, 'unattached' => _x( 'Unattached', 'media items' ), 'mine' => _x( 'Mine', 'media items' ), 'trash' => _x( 'Trash', 'noun' ), 'uploadedToThisPost' => $post_type_object->labels->uploaded_to_this_item, 'warnDelete' => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ), 'warnBulkDelete' => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ), 'warnBulkTrash' => __( "You are about to trash these items.\n 'Cancel' to stop, 'OK' to delete." ), 'bulkSelect' => __( 'Bulk select' ), 'trashSelected' => __( 'Move to Trash' ), 'restoreSelected' => __( 'Restore from Trash' ), 'deletePermanently' => __( 'Delete permanently' ), 'errorDeleting' => __( 'Error in deleting the attachment.' ), 'apply' => __( 'Apply' ), 'filterByDate' => __( 'Filter by date' ), 'filterByType' => __( 'Filter by type' ), 'searchLabel' => __( 'Search media' ), 'searchMediaLabel' => __( 'Search media' ), 'searchMediaPlaceholder' => __( 'Search media items...' ), 'mediaFound' => __( 'Number of media items found: %d' ), 'noMedia' => __( 'No media items found.' ), 'noMediaTryNewSearch' => __( 'No media items found. Try a different search.' ), 'attachmentDetails' => __( 'Attachment details' ), 'insertFromUrlTitle' => __( 'Insert from URL' ), 'setFeaturedImageTitle' => $post_type_object->labels->featured_image, 'setFeaturedImage' => $post_type_object->labels->set_featured_image, 'createGalleryTitle' => __( 'Create gallery' ), 'editGalleryTitle' => __( 'Edit gallery' ), 'cancelGalleryTitle' => __( '← Cancel gallery' ), 'insertGallery' => __( 'Insert gallery' ), 'updateGallery' => __( 'Update gallery' ), 'addToGallery' => __( 'Add to gallery' ), 'addToGalleryTitle' => __( 'Add to gallery' ), 'reverseOrder' => __( 'Reverse order' ), 'imageDetailsTitle' => __( 'Image details' ), 'imageReplaceTitle' => __( 'Replace image' ), 'imageDetailsCancel' => __( 'Cancel edit' ), 'editImage' => __( 'Edit image' ), 'chooseImage' => __( 'Choose image' ), 'selectAndCrop' => __( 'Select and crop' ), 'skipCropping' => __( 'Skip cropping' ), 'cropImage' => __( 'Crop image' ), 'cropYourImage' => __( 'Crop your image' ), 'cropping' => __( 'Cropping…' ), 'suggestedDimensions' => __( 'Suggested image dimensions: %1$s by %2$s pixels.' ), 'cropError' => __( 'There has been an error cropping your image.' ), 'audioDetailsTitle' => __( 'Audio details' ), 'audioReplaceTitle' => __( 'Replace audio' ), 'audioAddSourceTitle' => __( 'Add audio source' ), 'audioDetailsCancel' => __( 'Cancel edit' ), 'videoDetailsTitle' => __( 'Video details' ), 'videoReplaceTitle' => __( 'Replace video' ), 'videoAddSourceTitle' => __( 'Add video source' ), 'videoDetailsCancel' => __( 'Cancel edit' ), 'videoSelectPosterImageTitle' => __( 'Select poster image' ), 'videoAddTrackTitle' => __( 'Add subtitles' ), 'playlistDragInfo' => __( 'Drag and drop to reorder tracks.' ), 'createPlaylistTitle' => __( 'Create audio playlist' ), 'editPlaylistTitle' => __( 'Edit audio playlist' ), 'cancelPlaylistTitle' => __( '← Cancel audio playlist' ), 'insertPlaylist' => __( 'Insert audio playlist' ), 'updatePlaylist' => __( 'Update audio playlist' ), 'addToPlaylist' => __( 'Add to audio playlist' ), 'addToPlaylistTitle' => __( 'Add to Audio Playlist' ), 'videoPlaylistDragInfo' => __( 'Drag and drop to reorder videos.' ), 'createVideoPlaylistTitle' => __( 'Create video playlist' ), 'editVideoPlaylistTitle' => __( 'Edit video playlist' ), 'cancelVideoPlaylistTitle' => __( '← Cancel video playlist' ), 'insertVideoPlaylist' => __( 'Insert video playlist' ), 'updateVideoPlaylist' => __( 'Update video playlist' ), 'addToVideoPlaylist' => __( 'Add to video playlist' ), 'addToVideoPlaylistTitle' => __( 'Add to video Playlist' ), 'filterAttachments' => __( 'Filter media' ), 'attachmentsList' => __( 'Media list' ), ); $settings = apply_filters( 'media_view_settings', $settings, $post ); $strings = apply_filters( 'media_view_strings', $strings, $post ); $strings['settings'] = $settings; wp_enqueue_script( 'media-editor' ); wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings ); wp_enqueue_script( 'media-audiovideo' ); wp_enqueue_style( 'media-views' ); if ( is_admin() ) { wp_enqueue_script( 'mce-view' ); wp_enqueue_script( 'image-edit' ); } wp_enqueue_style( 'imgareaselect' ); wp_plupload_default_settings(); require_once ABSPATH . WPINC . '/media-template.php'; add_action( 'admin_footer', 'wp_print_media_templates' ); add_action( 'wp_footer', 'wp_print_media_templates' ); add_action( 'customize_controls_print_footer_scripts', 'wp_print_media_templates' ); do_action( 'wp_enqueue_media' ); } function get_attached_media( $type, $post = 0 ) { $post = get_post( $post ); if ( ! $post ) { return array(); } $args = array( 'post_parent' => $post->ID, 'post_type' => 'attachment', 'post_mime_type' => $type, 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC', ); $args = apply_filters( 'get_attached_media_args', $args, $type, $post ); $children = get_children( $args ); return (array) apply_filters( 'get_attached_media', $children, $type, $post ); } function get_media_embedded_in_content( $content, $types = null ) { $html = array(); $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe' ) ); if ( ! empty( $types ) ) { if ( ! is_array( $types ) ) { $types = array( $types ); } $allowed_media_types = array_intersect( $allowed_media_types, $types ); } $tags = implode( '|', $allowed_media_types ); if ( preg_match_all( '#<(?P<tag>' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { foreach ( $matches[0] as $match ) { $html[] = $match; } } return $html; } function get_post_galleries( $post, $html = true ) { $post = get_post( $post ); if ( ! $post ) { return array(); } if ( ! has_shortcode( $post->post_content, 'gallery' ) && ! has_block( 'gallery', $post->post_content ) ) { return array(); } $galleries = array(); if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $shortcode ) { if ( 'gallery' === $shortcode[2] ) { $srcs = array(); $shortcode_attrs = shortcode_parse_atts( $shortcode[3] ); if ( ! isset( $shortcode_attrs['id'] ) ) { $shortcode[3] .= ' id="' . (int) $post->ID . '"'; } $gallery = do_shortcode_tag( $shortcode ); if ( $html ) { $galleries[] = $gallery; } else { preg_match_all( '#src=([\'"])(.+?)\1#is', $gallery, $src, PREG_SET_ORDER ); if ( ! empty( $src ) ) { foreach ( $src as $s ) { $srcs[] = $s[2]; } } $galleries[] = array_merge( $shortcode_attrs, array( 'src' => array_values( array_unique( $srcs ) ), ) ); } } } } if ( has_block( 'gallery', $post->post_content ) ) { $post_blocks = parse_blocks( $post->post_content ); while ( $block = array_shift( $post_blocks ) ) { $has_inner_blocks = ! empty( $block['innerBlocks'] ); if ( ! $block['blockName'] ) { continue; } if ( 'core/gallery' !== $block['blockName'] ) { if ( $has_inner_blocks ) { array_push( $post_blocks, ...$block['innerBlocks'] ); } continue; } if ( $has_inner_blocks && $html ) { $block_html = wp_list_pluck( $block['innerBlocks'], 'innerHTML' ); $galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>'; continue; } $srcs = array(); if ( $has_inner_blocks ) { $attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' ); $ids = wp_list_pluck( $attrs, 'id' ); foreach ( $ids as $id ) { $url = wp_get_attachment_url( $id ); if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) { $srcs[] = $url; } } $galleries[] = array( 'ids' => implode( ',', $ids ), 'src' => $srcs, ); continue; } if ( $html ) { $galleries[] = $block['innerHTML']; continue; } $ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array(); if ( ! empty( $ids ) ) { foreach ( $ids as $id ) { $url = wp_get_attachment_url( $id ); if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) { $srcs[] = $url; } } $galleries[] = array( 'ids' => implode( ',', $ids ), 'src' => $srcs, ); continue; } preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER ); if ( ! empty( $found_srcs[0] ) ) { foreach ( $found_srcs as $src ) { if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) { $srcs[] = $src[2]; } } } $galleries[] = array( 'src' => $srcs ); } } return apply_filters( 'get_post_galleries', $galleries, $post ); } function get_post_gallery( $post = 0, $html = true ) { $galleries = get_post_galleries( $post, $html ); $gallery = reset( $galleries ); return apply_filters( 'get_post_gallery', $gallery, $post, $galleries ); } function get_post_galleries_images( $post = 0 ) { $galleries = get_post_galleries( $post, false ); return wp_list_pluck( $galleries, 'src' ); } function get_post_gallery_images( $post = 0 ) { $gallery = get_post_gallery( $post, false ); return empty( $gallery['src'] ) ? array() : $gallery['src']; } function wp_maybe_generate_attachment_metadata( $attachment ) { if ( empty( $attachment ) || empty( $attachment->ID ) ) { return; } $attachment_id = (int) $attachment->ID; $file = get_attached_file( $attachment_id ); $meta = wp_get_attachment_metadata( $attachment_id ); if ( empty( $meta ) && file_exists( $file ) ) { $_meta = get_post_meta( $attachment_id ); $_lock = 'wp_generating_att_' . $attachment_id; if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $_lock ) ) { set_transient( $_lock, $file ); wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); delete_transient( $_lock ); } } } function attachment_url_to_postid( $url ) { global $wpdb; $post_id = apply_filters( 'pre_attachment_url_to_postid', null, $url ); if ( null !== $post_id ) { return (int) $post_id; } $dir = wp_get_upload_dir(); $path = $url; $site_url = parse_url( $dir['url'] ); $image_path = parse_url( $path ); if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) { $path = str_replace( $image_path['scheme'], $site_url['scheme'], $path ); } if ( str_starts_with( $path, $dir['baseurl'] . '/' ) ) { $path = substr( $path, strlen( $dir['baseurl'] . '/' ) ); } $sql = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s", $path ); $results = $wpdb->get_results( $sql ); $post_id = null; if ( $results ) { $post_id = reset( $results )->post_id; if ( count( $results ) > 1 ) { foreach ( $results as $result ) { if ( $path === $result->meta_value ) { $post_id = $result->post_id; break; } } } } return (int) apply_filters( 'attachment_url_to_postid', $post_id, $url ); } function wpview_media_sandbox_styles() { $version = 'ver=' . get_bloginfo( 'version' ); $mediaelement = includes_url( "js/mediaelement/mediaelementplayer-legacy.min.css?$version" ); $wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" ); return array( $mediaelement, $wpmediaelement ); } function wp_register_media_personal_data_exporter( $exporters ) { $exporters['wordpress-media'] = array( 'exporter_friendly_name' => __( 'WordPress Media' ), 'callback' => 'wp_media_personal_data_exporter', ); return $exporters; } function wp_media_personal_data_exporter( $email_address, $page = 1 ) { $number = 50; $page = (int) $page; $data_to_export = array(); $user = get_user_by( 'email', $email_address ); if ( false === $user ) { return array( 'data' => $data_to_export, 'done' => true, ); } $post_query = new WP_Query( array( 'author' => $user->ID, 'posts_per_page' => $number, 'paged' => $page, 'post_type' => 'attachment', 'post_status' => 'any', 'orderby' => 'ID', 'order' => 'ASC', ) ); foreach ( (array) $post_query->posts as $post ) { $attachment_url = wp_get_attachment_url( $post->ID ); if ( $attachment_url ) { $post_data_to_export = array( array( 'name' => __( 'URL' ), 'value' => $attachment_url, ), ); $data_to_export[] = array( 'group_id' => 'media', 'group_label' => __( 'Media' ), 'group_description' => __( 'User’s media data.' ), 'item_id' => "post-{$post->ID}", 'data' => $post_data_to_export, ); } } $done = $post_query->max_num_pages <= $page; return array( 'data' => $data_to_export, 'done' => $done, ); } function _wp_add_additional_image_sizes() { add_image_size( '1536x1536', 1536, 1536 ); add_image_size( '2048x2048', 2048, 2048 ); } function wp_show_heic_upload_error( $plupload_settings ) { if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $plupload_init['heic_upload_error'] = true; } return $plupload_settings; } function wp_getimagesize( $filename, ?array &$image_info = null ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) { if ( 2 === func_num_args() ) { $info = getimagesize( $filename, $image_info ); } else { $info = getimagesize( $filename ); } } else { if ( 2 === func_num_args() ) { $info = @getimagesize( $filename, $image_info ); } else { $info = @getimagesize( $filename ); } } if ( ! empty( $info ) && ! ( empty( $info[0] ) && empty( $info[1] ) ) ) { return $info; } $image_mime_type = wp_get_image_mime( $filename ); if ( false === $image_mime_type ) { return false; } if ( 'image/webp' === $image_mime_type ) { $webp_info = wp_get_webp_info( $filename ); $width = $webp_info['width']; $height = $webp_info['height']; if ( $width && $height ) { return array( $width, $height, IMAGETYPE_WEBP, sprintf( 'width="%d" height="%d"', $width, $height ), 'mime' => 'image/webp', ); } } if ( 'image/avif' === $image_mime_type ) { $avif_info = wp_get_avif_info( $filename ); $width = $avif_info['width']; $height = $avif_info['height']; if ( $width && $height ) { return array( $width, $height, IMAGETYPE_AVIF, sprintf( 'width="%d" height="%d"', $width, $height ), 'mime' => 'image/avif', ); } } if ( wp_is_heic_image_mime_type( $image_mime_type ) ) { $editor = wp_get_image_editor( $filename ); if ( is_wp_error( $editor ) ) { return false; } if ( $editor instanceof WP_Image_Editor_Imagick ) { $size = $editor->get_size(); return array( $size['width'], $size['height'], IMAGETYPE_HEIF, sprintf( 'width="%d" height="%d"', $size['width'], $size['height'] ), 'mime' => 'image/heic', ); } } return false; } function wp_get_avif_info( $filename ) { $results = array( 'width' => false, 'height' => false, 'bit_depth' => false, 'num_channels' => false, ); if ( 'image/avif' !== wp_get_image_mime( $filename ) ) { return $results; } require_once ABSPATH . WPINC . '/class-avif-info.php'; $handle = fopen( $filename, 'rb' ); if ( $handle ) { $parser = new Avifinfo\Parser( $handle ); $success = $parser->parse_ftyp() && $parser->parse_file(); fclose( $handle ); if ( $success ) { $results = $parser->features->primary_item_features; } } return $results; } function wp_get_webp_info( $filename ) { $width = false; $height = false; $type = false; if ( 'image/webp' !== wp_get_image_mime( $filename ) ) { return compact( 'width', 'height', 'type' ); } $magic = file_get_contents( $filename, false, null, 0, 40 ); if ( false === $magic ) { return compact( 'width', 'height', 'type' ); } if ( strlen( $magic ) < 40 ) { return compact( 'width', 'height', 'type' ); } switch ( substr( $magic, 12, 4 ) ) { case 'VP8 ': $parts = unpack( 'v2', substr( $magic, 26, 4 ) ); $width = (int) ( $parts[1] & 0x3FFF ); $height = (int) ( $parts[2] & 0x3FFF ); $type = 'lossy'; break; case 'VP8L': $parts = unpack( 'C4', substr( $magic, 21, 4 ) ); $width = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1; $height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1; $type = 'lossless'; break; case 'VP8X': $width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" ); $width = (int) ( $width[1] & 0xFFFFFF ) + 1; $height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" ); $height = (int) ( $height[1] & 0xFFFFFF ) + 1; $type = 'animated-alpha'; break; } return compact( 'width', 'height', 'type' ); } function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { global $wp_query; $loading_attrs = apply_filters( 'pre_wp_get_loading_optimization_attributes', false, $tag_name, $attr, $context ); if ( is_array( $loading_attrs ) ) { return $loading_attrs; } $loading_attrs = array(); if ( 'template' === $context ) { return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) { return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } if ( 'the_content' !== $context && doing_filter( 'the_content' ) || 'widget_text_content' !== $context && doing_filter( 'widget_text_content' ) || 'widget_block_content' !== $context && doing_filter( 'widget_block_content' ) ) { return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } if ( 'img' === $tag_name ) { if ( isset( $attr['decoding'] ) ) { $loading_attrs['decoding'] = $attr['decoding']; } else { $loading_attrs['decoding'] = 'async'; } } if ( ! isset( $attr['width'], $attr['height'] ) ) { return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } $maybe_in_viewport = null; $increase_count = false; $maybe_increase_count = false; if ( isset( $attr['loading'] ) ) { if ( 'lazy' === $attr['loading'] ) { $maybe_in_viewport = false; } else { $maybe_in_viewport = true; } } if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) { if ( false === $maybe_in_viewport ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); $loading_attrs['fetchpriority'] = 'high'; } else { $maybe_in_viewport = true; } } if ( null === $maybe_in_viewport ) { $header_enforced_contexts = array( 'template_part_' . WP_TEMPLATE_PART_AREA_HEADER => true, 'get_header_image_tag' => true, ); $header_enforced_contexts = apply_filters( 'wp_loading_optimization_force_header_contexts', $header_enforced_contexts ); if ( isset( $header_enforced_contexts[ $context ] ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } elseif ( ! is_admin() && in_the_loop() && is_main_query() ) { $content_media_count = wp_increase_content_media_count( 0 ); $increase_count = true; if ( $content_media_count < wp_omit_loading_attr_threshold() ) { $maybe_in_viewport = true; } else { $maybe_in_viewport = false; } } elseif ( $wp_query->before_loop && $wp_query->is_main_query() && did_action( 'get_header' ) && ! did_action( 'get_footer' ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } } if ( $maybe_in_viewport ) { $loading_attrs = wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ); } else { if ( wp_lazy_loading_enabled( $tag_name, $context ) ) { $loading_attrs['loading'] = 'lazy'; } } if ( $increase_count ) { wp_increase_content_media_count(); } elseif ( $maybe_increase_count ) { $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 ); if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) { wp_increase_content_media_count(); } } return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } function wp_omit_loading_attr_threshold( $force = false ) { static $omit_threshold; if ( ! isset( $omit_threshold ) || $force ) { $omit_threshold = apply_filters( 'wp_omit_loading_attr_threshold', 3 ); } return $omit_threshold; } function wp_increase_content_media_count( $amount = 1 ) { static $content_media_count = 0; $content_media_count += $amount; return $content_media_count; } function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ) { if ( 'img' !== $tag_name ) { return $loading_attrs; } if ( isset( $attr['fetchpriority'] ) ) { if ( 'high' === $attr['fetchpriority'] ) { $loading_attrs['fetchpriority'] = 'high'; wp_high_priority_element_flag( false ); } return $loading_attrs; } if ( isset( $loading_attrs['loading'] ) && 'lazy' === $loading_attrs['loading'] ) { return $loading_attrs; } if ( ! wp_high_priority_element_flag() ) { return $loading_attrs; } $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 ); if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) { $loading_attrs['fetchpriority'] = 'high'; wp_high_priority_element_flag( false ); } return $loading_attrs; } function wp_high_priority_element_flag( $value = null ) { static $high_priority_element = true; if ( is_bool( $value ) ) { $high_priority_element = $value; } return $high_priority_element; } function wp_get_image_editor_output_format( $filename, $mime_type ) { $output_format = array( 'image/heic' => 'image/jpeg', 'image/heif' => 'image/jpeg', 'image/heic-sequence' => 'image/jpeg', 'image/heif-sequence' => 'image/jpeg', ); return apply_filters( 'image_editor_output_format', $output_format, $filename, $mime_type ); }
###require ABSPATH . WPINC . '/http.php';
function _wp_http_get_object() { static $http = null; if ( is_null( $http ) ) { $http = new WP_Http(); } return $http; } function wp_safe_remote_request( $url, $args = array() ) { $args['reject_unsafe_urls'] = true; $http = _wp_http_get_object(); return $http->request( $url, $args ); } function wp_safe_remote_get( $url, $args = array() ) { $args['reject_unsafe_urls'] = true; $http = _wp_http_get_object(); return $http->get( $url, $args ); } function wp_safe_remote_post( $url, $args = array() ) { $args['reject_unsafe_urls'] = true; $http = _wp_http_get_object(); return $http->post( $url, $args ); } function wp_safe_remote_head( $url, $args = array() ) { $args['reject_unsafe_urls'] = true; $http = _wp_http_get_object(); return $http->head( $url, $args ); } function wp_remote_request( $url, $args = array() ) { $http = _wp_http_get_object(); return $http->request( $url, $args ); } function wp_remote_get( $url, $args = array() ) { $http = _wp_http_get_object(); return $http->get( $url, $args ); } function wp_remote_post( $url, $args = array() ) { $http = _wp_http_get_object(); return $http->post( $url, $args ); } function wp_remote_head( $url, $args = array() ) { $http = _wp_http_get_object(); return $http->head( $url, $args ); } function wp_remote_retrieve_headers( $response ) { if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) { return array(); } return $response['headers']; } function wp_remote_retrieve_header( $response, $header ) { if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) { return ''; } if ( isset( $response['headers'][ $header ] ) ) { return $response['headers'][ $header ]; } return ''; } function wp_remote_retrieve_response_code( $response ) { if ( is_wp_error( $response ) || ! isset( $response['response'] ) || ! is_array( $response['response'] ) ) { return ''; } return $response['response']['code']; } function wp_remote_retrieve_response_message( $response ) { if ( is_wp_error( $response ) || ! isset( $response['response'] ) || ! is_array( $response['response'] ) ) { return ''; } return $response['response']['message']; } function wp_remote_retrieve_body( $response ) { if ( is_wp_error( $response ) || ! isset( $response['body'] ) ) { return ''; } return $response['body']; } function wp_remote_retrieve_cookies( $response ) { if ( is_wp_error( $response ) || empty( $response['cookies'] ) ) { return array(); } return $response['cookies']; } function wp_remote_retrieve_cookie( $response, $name ) { $cookies = wp_remote_retrieve_cookies( $response ); if ( empty( $cookies ) ) { return ''; } foreach ( $cookies as $cookie ) { if ( $cookie->name === $name ) { return $cookie; } } return ''; } function wp_remote_retrieve_cookie_value( $response, $name ) { $cookie = wp_remote_retrieve_cookie( $response, $name ); if ( ! ( $cookie instanceof WP_Http_Cookie ) ) { return ''; } return $cookie->value; } function wp_http_supports( $capabilities = array(), $url = null ) { $capabilities = wp_parse_args( $capabilities ); $count = count( $capabilities ); if ( $count && count( array_filter( array_keys( $capabilities ), 'is_numeric' ) ) === $count ) { $capabilities = array_combine( array_values( $capabilities ), array_fill( 0, $count, true ) ); } if ( $url && ! isset( $capabilities['ssl'] ) ) { $scheme = parse_url( $url, PHP_URL_SCHEME ); if ( 'https' === $scheme || 'ssl' === $scheme ) { $capabilities['ssl'] = true; } } return WpOrg\Requests\Requests::has_capabilities( $capabilities ); } function get_http_origin() { $origin = ''; if ( ! empty( $_SERVER['HTTP_ORIGIN'] ) ) { $origin = $_SERVER['HTTP_ORIGIN']; } return apply_filters( 'http_origin', $origin ); } function get_allowed_http_origins() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $allowed_origins = array_unique( array( 'http://' . $admin_origin['host'], 'https://' . $admin_origin['host'], 'http://' . $home_origin['host'], 'https://' . $home_origin['host'], ) ); return apply_filters( 'allowed_http_origins', $allowed_origins ); } function is_allowed_http_origin( $origin = null ) { $origin_arg = $origin; if ( null === $origin ) { $origin = get_http_origin(); } if ( $origin && ! in_array( $origin, get_allowed_http_origins(), true ) ) { $origin = ''; } return apply_filters( 'allowed_http_origin', $origin, $origin_arg ); } function send_origin_headers() { $origin = get_http_origin(); if ( is_allowed_http_origin( $origin ) ) { header( 'Access-Control-Allow-Origin: ' . $origin ); header( 'Access-Control-Allow-Credentials: true' ); if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) { exit; } return $origin; } if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) { status_header( 403 ); exit; } return false; } function wp_http_validate_url( $url ) { if ( ! is_string( $url ) || '' === $url || is_numeric( $url ) ) { return false; } $original_url = $url; $url = wp_kses_bad_protocol( $url, array( 'http', 'https' ) ); if ( ! $url || strtolower( $url ) !== strtolower( $original_url ) ) { return false; } $parsed_url = parse_url( $url ); if ( ! $parsed_url || empty( $parsed_url['host'] ) ) { return false; } if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) ) { return false; } if ( false !== strpbrk( $parsed_url['host'], ':#?[]' ) ) { return false; } $parsed_home = parse_url( get_option( 'home' ) ); $same_host = isset( $parsed_home['host'] ) && strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] ); $host = trim( $parsed_url['host'], '.' ); if ( ! $same_host ) { if ( preg_match( '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', $host ) ) { $ip = $host; } else { $ip = gethostbyname( $host ); if ( $ip === $host ) { return false; } } if ( $ip ) { $parts = array_map( 'intval', explode( '.', $ip ) ); if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0] || ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] ) || ( 192 === $parts[0] && 168 === $parts[1] ) ) { if ( ! apply_filters( 'http_request_host_is_external', false, $host, $url ) ) { return false; } } } } if ( empty( $parsed_url['port'] ) ) { return $url; } $port = $parsed_url['port']; $allowed_ports = apply_filters( 'http_allowed_safe_ports', array( 80, 443, 8080 ), $host, $url ); if ( is_array( $allowed_ports ) && in_array( $port, $allowed_ports, true ) ) { return $url; } if ( $parsed_home && $same_host && isset( $parsed_home['port'] ) && $parsed_home['port'] === $port ) { return $url; } return false; } function allowed_http_request_hosts( $is_external, $host ) { if ( ! $is_external && wp_validate_redirect( 'http://' . $host ) ) { $is_external = true; } return $is_external; } function ms_allowed_http_request_hosts( $is_external, $host ) { global $wpdb; static $queried = array(); if ( $is_external ) { return $is_external; } if ( get_network()->domain === $host ) { return true; } if ( isset( $queried[ $host ] ) ) { return $queried[ $host ]; } $queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) ); return $queried[ $host ]; } function wp_parse_url( $url, $component = -1 ) { $to_unset = array(); $url = (string) $url; if ( str_starts_with( $url, '//' ) ) { $to_unset[] = 'scheme'; $url = 'placeholder:' . $url; } elseif ( str_starts_with( $url, '/' ) ) { $to_unset[] = 'scheme'; $to_unset[] = 'host'; $url = 'placeholder://placeholder' . $url; } $parts = parse_url( $url ); if ( false === $parts ) { return $parts; } foreach ( $to_unset as $key ) { unset( $parts[ $key ] ); } return _get_component_from_parsed_url_array( $parts, $component ); } function _get_component_from_parsed_url_array( $url_parts, $component = -1 ) { if ( -1 === $component ) { return $url_parts; } $key = _wp_translate_php_url_constant_to_key( $component ); if ( false !== $key && is_array( $url_parts ) && isset( $url_parts[ $key ] ) ) { return $url_parts[ $key ]; } else { return null; } } function _wp_translate_php_url_constant_to_key( $constant ) { $translation = array( PHP_URL_SCHEME => 'scheme', PHP_URL_HOST => 'host', PHP_URL_PORT => 'port', PHP_URL_USER => 'user', PHP_URL_PASS => 'pass', PHP_URL_PATH => 'path', PHP_URL_QUERY => 'query', PHP_URL_FRAGMENT => 'fragment', ); if ( isset( $translation[ $constant ] ) ) { return $translation[ $constant ]; } else { return false; } }
###require ABSPATH . WPINC . '/html-api/html5-named-character-references.php';
global $html5_named_character_references; $html5_named_character_references = WP_Token_Map::from_precomputed_table( array( "storage_version" => "6.6.0-trunk", "key_length" => 2, "groups" => "AE\x00AM\x00Aa\x00Ab\x00Ac\x00Af\x00Ag\x00Al\x00Am\x00An\x00Ao\x00Ap\x00Ar\x00As\x00At\x00Au\x00Ba\x00Bc\x00Be\x00Bf\x00Bo\x00Br\x00Bs\x00Bu\x00CH\x00CO\x00Ca\x00Cc\x00Cd\x00Ce\x00Cf\x00Ch\x00Ci\x00Cl\x00Co\x00Cr\x00Cs\x00Cu\x00DD\x00DJ\x00DS\x00DZ\x00Da\x00Dc\x00De\x00Df\x00Di\x00Do\x00Ds\x00EN\x00ET\x00Ea\x00Ec\x00Ed\x00Ef\x00Eg\x00El\x00Em\x00Eo\x00Ep\x00Eq\x00Es\x00Et\x00Eu\x00Ex\x00Fc\x00Ff\x00Fi\x00Fo\x00Fs\x00GJ\x00GT\x00Ga\x00Gb\x00Gc\x00Gd\x00Gf\x00Gg\x00Go\x00Gr\x00Gs\x00Gt\x00HA\x00Ha\x00Hc\x00Hf\x00Hi\x00Ho\x00Hs\x00Hu\x00IE\x00IJ\x00IO\x00Ia\x00Ic\x00Id\x00If\x00Ig\x00Im\x00In\x00Io\x00Is\x00It\x00Iu\x00Jc\x00Jf\x00Jo\x00Js\x00Ju\x00KH\x00KJ\x00Ka\x00Kc\x00Kf\x00Ko\x00Ks\x00LJ\x00LT\x00La\x00Lc\x00Le\x00Lf\x00Ll\x00Lm\x00Lo\x00Ls\x00Lt\x00Ma\x00Mc\x00Me\x00Mf\x00Mi\x00Mo\x00Ms\x00Mu\x00NJ\x00Na\x00Nc\x00Ne\x00Nf\x00No\x00Ns\x00Nt\x00Nu\x00OE\x00Oa\x00Oc\x00Od\x00Of\x00Og\x00Om\x00Oo\x00Op\x00Or\x00Os\x00Ot\x00Ou\x00Ov\x00Pa\x00Pc\x00Pf\x00Ph\x00Pi\x00Pl\x00Po\x00Pr\x00Ps\x00QU\x00Qf\x00Qo\x00Qs\x00RB\x00RE\x00Ra\x00Rc\x00Re\x00Rf\x00Rh\x00Ri\x00Ro\x00Rr\x00Rs\x00Ru\x00SH\x00SO\x00Sa\x00Sc\x00Sf\x00Sh\x00Si\x00Sm\x00So\x00Sq\x00Ss\x00St\x00Su\x00TH\x00TR\x00TS\x00Ta\x00Tc\x00Tf\x00Th\x00Ti\x00To\x00Tr\x00Ts\x00Ua\x00Ub\x00Uc\x00Ud\x00Uf\x00Ug\x00Um\x00Un\x00Uo\x00Up\x00Ur\x00Us\x00Ut\x00Uu\x00VD\x00Vb\x00Vc\x00Vd\x00Ve\x00Vf\x00Vo\x00Vs\x00Vv\x00Wc\x00We\x00Wf\x00Wo\x00Ws\x00Xf\x00Xi\x00Xo\x00Xs\x00YA\x00YI\x00YU\x00Ya\x00Yc\x00Yf\x00Yo\x00Ys\x00Yu\x00ZH\x00Za\x00Zc\x00Zd\x00Ze\x00Zf\x00Zo\x00Zs\x00aa\x00ab\x00ac\x00ae\x00af\x00ag\x00al\x00am\x00an\x00ao\x00ap\x00ar\x00as\x00at\x00au\x00aw\x00bN\x00ba\x00bb\x00bc\x00bd\x00be\x00bf\x00bi\x00bk\x00bl\x00bn\x00bo\x00bp\x00br\x00bs\x00bu\x00ca\x00cc\x00cd\x00ce\x00cf\x00ch\x00ci\x00cl\x00co\x00cr\x00cs\x00ct\x00cu\x00cw\x00cy\x00dA\x00dH\x00da\x00db\x00dc\x00dd\x00de\x00df\x00dh\x00di\x00dj\x00dl\x00do\x00dr\x00ds\x00dt\x00du\x00dw\x00dz\x00eD\x00ea\x00ec\x00ed\x00ee\x00ef\x00eg\x00el\x00em\x00en\x00eo\x00ep\x00eq\x00er\x00es\x00et\x00eu\x00ex\x00fa\x00fc\x00fe\x00ff\x00fi\x00fj\x00fl\x00fn\x00fo\x00fp\x00fr\x00fs\x00gE\x00ga\x00gb\x00gc\x00gd\x00ge\x00gf\x00gg\x00gi\x00gj\x00gl\x00gn\x00go\x00gr\x00gs\x00gt\x00gv\x00hA\x00ha\x00hb\x00hc\x00he\x00hf\x00hk\x00ho\x00hs\x00hy\x00ia\x00ic\x00ie\x00if\x00ig\x00ii\x00ij\x00im\x00in\x00io\x00ip\x00iq\x00is\x00it\x00iu\x00jc\x00jf\x00jm\x00jo\x00js\x00ju\x00ka\x00kc\x00kf\x00kg\x00kh\x00kj\x00ko\x00ks\x00lA\x00lB\x00lE\x00lH\x00la\x00lb\x00lc\x00ld\x00le\x00lf\x00lg\x00lh\x00lj\x00ll\x00lm\x00ln\x00lo\x00lp\x00lr\x00ls\x00lt\x00lu\x00lv\x00mD\x00ma\x00mc\x00md\x00me\x00mf\x00mh\x00mi\x00ml\x00mn\x00mo\x00mp\x00ms\x00mu\x00nG\x00nL\x00nR\x00nV\x00na\x00nb\x00nc\x00nd\x00ne\x00nf\x00ng\x00nh\x00ni\x00nj\x00nl\x00nm\x00no\x00np\x00nr\x00ns\x00nt\x00nu\x00nv\x00nw\x00oS\x00oa\x00oc\x00od\x00oe\x00of\x00og\x00oh\x00oi\x00ol\x00om\x00oo\x00op\x00or\x00os\x00ot\x00ou\x00ov\x00pa\x00pc\x00pe\x00pf\x00ph\x00pi\x00pl\x00pm\x00po\x00pr\x00ps\x00pu\x00qf\x00qi\x00qo\x00qp\x00qs\x00qu\x00rA\x00rB\x00rH\x00ra\x00rb\x00rc\x00rd\x00re\x00rf\x00rh\x00ri\x00rl\x00rm\x00rn\x00ro\x00rp\x00rr\x00rs\x00rt\x00ru\x00rx\x00sa\x00sb\x00sc\x00sd\x00se\x00sf\x00sh\x00si\x00sl\x00sm\x00so\x00sp\x00sq\x00sr\x00ss\x00st\x00su\x00sw\x00sz\x00ta\x00tb\x00tc\x00td\x00te\x00tf\x00th\x00ti\x00to\x00tp\x00tr\x00ts\x00tw\x00uA\x00uH\x00ua\x00ub\x00uc\x00ud\x00uf\x00ug\x00uh\x00ul\x00um\x00uo\x00up\x00ur\x00us\x00ut\x00uu\x00uw\x00vA\x00vB\x00vD\x00va\x00vc\x00vd\x00ve\x00vf\x00vl\x00vn\x00vo\x00vp\x00vr\x00vs\x00vz\x00wc\x00we\x00wf\x00wo\x00wp\x00wr\x00ws\x00xc\x00xd\x00xf\x00xh\x00xi\x00xl\x00xm\x00xn\x00xo\x00xr\x00xs\x00xu\x00xv\x00xw\x00ya\x00yc\x00ye\x00yf\x00yi\x00yo\x00ys\x00yu\x00za\x00zc\x00zd\x00ze\x00zf\x00zh\x00zi\x00zo\x00zs\x00zw\x00", "large_words" => array( "\x04lig;\x02Æ\x03lig\x02Æ", "\x02P;\x01&\x01P\x01&", "\x05cute;\x02Á\x04cute\x02Á", "\x05reve;\x02Ă", "\x04irc;\x02Â\x03irc\x02Â\x02y;\x02А", "\x02r;\x04𝔄", "\x05rave;\x02À\x04rave\x02À", "\x04pha;\x02Α", "\x04acr;\x02Ā", "\x02d;\x03⩓", "\x04gon;\x02Ą\x03pf;\x04𝔸", "\x0cplyFunction;\x03", "\x04ing;\x02Å\x03ing\x02Å", "\x05sign;\x03≔\x03cr;\x04𝒜", "\x05ilde;\x02Ã\x04ilde\x02Ã", "\x03ml;\x02Ä\x02ml\x02Ä", "\x08ckslash;\x03∖\x05rwed;\x03⌆\x03rv;\x03⫧", "\x02y;\x02Б", "\x09rnoullis;\x03ℬ\x06cause;\x03∵\x03ta;\x02Β", "\x02r;\x04𝔅", "\x03pf;\x04𝔹", "\x04eve;\x02˘", "\x03cr;\x03ℬ", "\x05mpeq;\x03≎", "\x03cy;\x02Ч", "\x03PY;\x02©\x02PY\x02©", "\x13pitalDifferentialD;\x03ⅅ\x06yleys;\x03ℭ\x05cute;\x02Ć\x02p;\x03⋒", "\x06onint;\x03∰\x05aron;\x02Č\x05edil;\x02Ç\x04edil\x02Ç\x04irc;\x02Ĉ", "\x03ot;\x02Ċ", "\x08nterDot;\x02·\x06dilla;\x02¸", "\x02r;\x03ℭ", "\x02i;\x02Χ", "\x0arcleMinus;\x03⊖\x0arcleTimes;\x03⊗\x09rclePlus;\x03⊕\x08rcleDot;\x03⊙", "\x17ockwiseContourIntegral;\x03∲\x14oseCurlyDoubleQuote;\x03”\x0eoseCurlyQuote;\x03’", "\x1eunterClockwiseContourIntegral;\x03∳\x0entourIntegral;\x03∮\x08ngruent;\x03≡\x08product;\x03∐\x05lone;\x03⩴\x05nint;\x03∯\x04lon;\x03∷\x03pf;\x03ℂ", "\x04oss;\x03⨯", "\x03cr;\x04𝒞", "\x05pCap;\x03≍\x02p;\x03⋓", "\x07otrahd;\x03⤑\x01;\x03ⅅ", "\x03cy;\x02Ђ", "\x03cy;\x02Ѕ", "\x03cy;\x02Џ", "\x05gger;\x03‡\x04shv;\x03⫤\x03rr;\x03↡", "\x05aron;\x02Ď\x02y;\x02Д", "\x04lta;\x02Δ\x02l;\x03∇", "\x02r;\x04𝔇", "\x15acriticalDoubleAcute;\x02˝\x0facriticalAcute;\x02´\x0facriticalGrave;\x01`\x0facriticalTilde;\x02˜\x0dacriticalDot;\x02˙\x0cfferentialD;\x03ⅆ\x06amond;\x03⋄", "\x17ubleLongLeftRightArrow;\x03⟺\x14ubleContourIntegral;\x03∯\x13ubleLeftRightArrow;\x03⇔\x13ubleLongRightArrow;\x03⟹\x12ubleLongLeftArrow;\x03⟸\x12wnLeftRightVector;\x03⥐\x11wnRightTeeVector;\x03⥟\x11wnRightVectorBar;\x03⥗\x10ubleUpDownArrow;\x03⇕\x10ubleVerticalBar;\x03∥\x10wnLeftTeeVector;\x03⥞\x10wnLeftVectorBar;\x03⥖\x0fubleRightArrow;\x03⇒\x0fwnArrowUpArrow;\x03⇵\x0eubleDownArrow;\x03⇓\x0eubleLeftArrow;\x03⇐\x0ewnRightVector;\x03⇁\x0dubleRightTee;\x03⊨\x0dwnLeftVector;\x03↽\x0cubleLeftTee;\x03⫤\x0cubleUpArrow;\x03⇑\x0bwnArrowBar;\x03⤓\x0bwnTeeArrow;\x03↧\x08ubleDot;\x02¨\x08wnArrow;\x03↓\x08wnBreve;\x02̑\x08wnarrow;\x03⇓\x07tEqual;\x03≐\x06wnTee;\x03⊤\x05tDot;\x03⃜\x03pf;\x04𝔻\x02t;\x02¨", "\x05trok;\x02Đ\x03cr;\x04𝒟", "\x02G;\x02Ŋ", "\x02H;\x02Ð\x01H\x02Ð", "\x05cute;\x02É\x04cute\x02É", "\x05aron;\x02Ě\x04irc;\x02Ê\x03irc\x02Ê\x02y;\x02Э", "\x03ot;\x02Ė", "\x02r;\x04𝔈", "\x05rave;\x02È\x04rave\x02È", "\x06ement;\x03∈", "\x13ptyVerySmallSquare;\x03▫\x0fptySmallSquare;\x03◻\x04acr;\x02Ē", "\x04gon;\x02Ę\x03pf;\x04𝔼", "\x06silon;\x02Ε", "\x0auilibrium;\x03⇌\x09ualTilde;\x03≂\x04ual;\x03⩵", "\x03cr;\x03ℰ\x03im;\x03⩳", "\x02a;\x02Η", "\x03ml;\x02Ë\x02ml\x02Ë", "\x0bponentialE;\x03ⅇ\x05ists;\x03∃", "\x02y;\x02Ф", "\x02r;\x04𝔉", "\x14lledVerySmallSquare;\x03▪\x10lledSmallSquare;\x03◼", "\x09uriertrf;\x03ℱ\x05rAll;\x03∀\x03pf;\x04𝔽", "\x03cr;\x03ℱ", "\x03cy;\x02Ѓ", "\x01;\x01>", "\x05mmad;\x02Ϝ\x04mma;\x02Γ", "\x05reve;\x02Ğ", "\x05edil;\x02Ģ\x04irc;\x02Ĝ\x02y;\x02Г", "\x03ot;\x02Ġ", "\x02r;\x04𝔊", "\x01;\x03⋙", "\x03pf;\x04𝔾", "\x10eaterSlantEqual;\x03⩾\x0featerEqualLess;\x03⋛\x0featerFullEqual;\x03≧\x0deaterGreater;\x03⪢\x0beaterEqual;\x03≥\x0beaterTilde;\x03≳\x0aeaterLess;\x03≷", "\x03cr;\x04𝒢", "\x01;\x03≫", "\x05RDcy;\x02Ъ", "\x04cek;\x02ˇ\x02t;\x01^", "\x04irc;\x02Ĥ", "\x02r;\x03ℌ", "\x0blbertSpace;\x03ℋ", "\x0drizontalLine;\x03─\x03pf;\x03ℍ", "\x05trok;\x02Ħ\x03cr;\x03ℋ", "\x0bmpDownHump;\x03≎\x08mpEqual;\x03≏", "\x03cy;\x02Е", "\x04lig;\x02IJ", "\x03cy;\x02Ё", "\x05cute;\x02Í\x04cute\x02Í", "\x04irc;\x02Î\x03irc\x02Î\x02y;\x02И", "\x03ot;\x02İ", "\x02r;\x03ℑ", "\x05rave;\x02Ì\x04rave\x02Ì", "\x09aginaryI;\x03ⅈ\x06plies;\x03⇒\x04acr;\x02Ī\x01;\x03ℑ", "\x0dvisibleComma;\x03\x0dvisibleTimes;\x03\x0btersection;\x03⋂\x07tegral;\x03∫\x02t;\x03∬", "\x04gon;\x02Į\x03pf;\x04𝕀\x03ta;\x02Ι", "\x03cr;\x03ℐ", "\x05ilde;\x02Ĩ", "\x04kcy;\x02І\x03ml;\x02Ï\x02ml\x02Ï", "\x04irc;\x02Ĵ\x02y;\x02Й", "\x02r;\x04𝔍", "\x03pf;\x04𝕁", "\x05ercy;\x02Ј\x03cr;\x04𝒥", "\x04kcy;\x02Є", "\x03cy;\x02Х", "\x03cy;\x02Ќ", "\x04ppa;\x02Κ", "\x05edil;\x02Ķ\x02y;\x02К", "\x02r;\x04𝔎", "\x03pf;\x04𝕂", "\x03cr;\x04𝒦", "\x03cy;\x02Љ", "\x01;\x01<", "\x09placetrf;\x03ℒ\x05cute;\x02Ĺ\x05mbda;\x02Λ\x03ng;\x03⟪\x03rr;\x03↞", "\x05aron;\x02Ľ\x05edil;\x02Ļ\x02y;\x02Л", "\x12ftArrowRightArrow;\x03⇆\x10ftDoubleBracket;\x03⟦\x10ftDownTeeVector;\x03⥡\x10ftDownVectorBar;\x03⥙\x10ftTriangleEqual;\x03⊴\x0fftAngleBracket;\x03⟨\x0fftUpDownVector;\x03⥑\x0fssEqualGreater;\x03⋚\x0eftRightVector;\x03⥎\x0eftTriangleBar;\x03⧏\x0eftUpTeeVector;\x03⥠\x0eftUpVectorBar;\x03⥘\x0dftDownVector;\x03⇃\x0dftRightArrow;\x03↔\x0dftrightarrow;\x03⇔\x0dssSlantEqual;\x03⩽\x0cftTeeVector;\x03⥚\x0cftVectorBar;\x03⥒\x0cssFullEqual;\x03≦\x0bftArrowBar;\x03⇤\x0bftTeeArrow;\x03↤\x0bftTriangle;\x03⊲\x0bftUpVector;\x03↿\x0aftCeiling;\x03⌈\x0assGreater;\x03≶\x09ftVector;\x03↼\x08ftArrow;\x03←\x08ftFloor;\x03⌊\x08ftarrow;\x03⇐\x08ssTilde;\x03≲\x07ssLess;\x03⪡\x06ftTee;\x03⊣", "\x02r;\x04𝔏", "\x09eftarrow;\x03⇚\x01;\x03⋘", "\x05idot;\x02Ŀ", "\x11ngLeftRightArrow;\x03⟷\x11ngleftrightarrow;\x03⟺\x0ewerRightArrow;\x03↘\x0dngRightArrow;\x03⟶\x0dngrightarrow;\x03⟹\x0dwerLeftArrow;\x03↙\x0cngLeftArrow;\x03⟵\x0cngleftarrow;\x03⟸\x03pf;\x04𝕃", "\x05trok;\x02Ł\x03cr;\x03ℒ\x02h;\x03↰", "\x01;\x03≪", "\x02p;\x03⤅", "\x02y;\x02М", "\x0adiumSpace;\x03 \x08llintrf;\x03ℳ", "\x02r;\x04𝔐", "\x08nusPlus;\x03∓", "\x03pf;\x04𝕄", "\x03cr;\x03ℳ", "\x01;\x02Μ", "\x03cy;\x02Њ", "\x05cute;\x02Ń", "\x05aron;\x02Ň\x05edil;\x02Ņ\x02y;\x02Н", "\x14gativeVeryThinSpace;\x03\x13stedGreaterGreater;\x03≫\x12gativeMediumSpace;\x03\x11gativeThickSpace;\x03\x10gativeThinSpace;\x03\x0dstedLessLess;\x03≪\x06wLine;\x01\xa", "\x02r;\x04𝔑", "\x16tNestedGreaterGreater;\x05⪢̸\x15tSquareSupersetEqual;\x03⋣\x14tPrecedesSlantEqual;\x03⋠\x14tRightTriangleEqual;\x03⋭\x14tSucceedsSlantEqual;\x03⋡\x13tDoubleVerticalBar;\x03∦\x13tGreaterSlantEqual;\x05⩾̸\x13tLeftTriangleEqual;\x03⋬\x13tSquareSubsetEqual;\x03⋢\x12tGreaterFullEqual;\x05≧̸\x12tRightTriangleBar;\x05⧐̸\x11tLeftTriangleBar;\x05⧏̸\x10tGreaterGreater;\x05≫̸\x10tLessSlantEqual;\x05⩽̸\x10tNestedLessLess;\x05⪡̸\x10tReverseElement;\x03∌\x10tSquareSuperset;\x05⊐̸\x10tTildeFullEqual;\x03≇\x0fnBreakingSpace;\x02 \x0ftPrecedesEqual;\x05⪯̸\x0ftRightTriangle;\x03⋫\x0ftSucceedsEqual;\x05⪰̸\x0ftSucceedsTilde;\x05≿̸\x0ftSupersetEqual;\x03⊉\x0etGreaterEqual;\x03≱\x0etGreaterTilde;\x03≵\x0etHumpDownHump;\x05≎̸\x0etLeftTriangle;\x03⋪\x0etSquareSubset;\x05⊏̸\x0dtGreaterLess;\x03≹\x0dtLessGreater;\x03≸\x0dtSubsetEqual;\x03⊈\x0dtVerticalBar;\x03∤\x0ctEqualTilde;\x05≂̸\x0ctTildeEqual;\x03≄\x0ctTildeTilde;\x03≉\x0btCongruent;\x03≢\x0btHumpEqual;\x05≏̸\x0btLessEqual;\x03≰\x0btLessTilde;\x03≴\x0atLessLess;\x05≪̸\x0atPrecedes;\x03⊀\x0atSucceeds;\x03⊁\x0atSuperset;\x06⊃⃒\x09tElement;\x03∉\x09tGreater;\x03≯\x08tCupCap;\x03≭\x08tExists;\x03∄\x08tSubset;\x06⊂⃒\x07tEqual;\x03≠\x07tTilde;\x03≁\x06Break;\x03\x06tLess;\x03≮\x03pf;\x03ℕ\x02t;\x03⫬", "\x03cr;\x04𝒩", "\x05ilde;\x02Ñ\x04ilde\x02Ñ", "\x01;\x02Ν", "\x04lig;\x02Œ", "\x05cute;\x02Ó\x04cute\x02Ó", "\x04irc;\x02Ô\x03irc\x02Ô\x02y;\x02О", "\x05blac;\x02Ő", "\x02r;\x04𝔒", "\x05rave;\x02Ò\x04rave\x02Ò", "\x06icron;\x02Ο\x04acr;\x02Ō\x04ega;\x02Ω", "\x03pf;\x04𝕆", "\x13enCurlyDoubleQuote;\x03“\x0denCurlyQuote;\x03‘", "\x01;\x03⩔", "\x05lash;\x02Ø\x04lash\x02Ø\x03cr;\x04𝒪", "\x05ilde;\x02Õ\x05imes;\x03⨷\x04ilde\x02Õ", "\x03ml;\x02Ö\x02ml\x02Ö", "\x0eerParenthesis;\x03⏜\x0aerBracket;\x03⎴\x08erBrace;\x03⏞\x06erBar;\x03‾", "\x07rtialD;\x03∂", "\x02y;\x02П", "\x02r;\x04𝔓", "\x02i;\x02Φ", "\x01;\x02Π", "\x08usMinus;\x02±", "\x0cincareplane;\x03ℌ\x03pf;\x03ℙ", "\x11ecedesSlantEqual;\x03≼\x0cecedesEqual;\x03⪯\x0cecedesTilde;\x03≾\x0boportional;\x03∝\x09oportion;\x03∷\x07ecedes;\x03≺\x06oduct;\x03∏\x04ime;\x03″\x01;\x03⪻", "\x03cr;\x04𝒫\x02i;\x02Ψ", "\x03OT;\x01\"\x02OT\x01\"", "\x02r;\x04𝔔", "\x03pf;\x03ℚ", "\x03cr;\x04𝒬", "\x04arr;\x03⤐", "\x02G;\x02®\x01G\x02®", "\x05cute;\x02Ŕ\x05rrtl;\x03⤖\x03ng;\x03⟫\x03rr;\x03↠", "\x05aron;\x02Ř\x05edil;\x02Ŗ\x02y;\x02Р", "\x13verseUpEquilibrium;\x03⥯\x11verseEquilibrium;\x03⇋\x0dverseElement;\x03∋\x01;\x03ℜ", "\x02r;\x03ℜ", "\x02o;\x02Ρ", "\x12ghtArrowLeftArrow;\x03⇄\x11ghtDoubleBracket;\x03⟧\x11ghtDownTeeVector;\x03⥝\x11ghtDownVectorBar;\x03⥕\x11ghtTriangleEqual;\x03⊵\x10ghtAngleBracket;\x03⟩\x10ghtUpDownVector;\x03⥏\x0fghtTriangleBar;\x03⧐\x0fghtUpTeeVector;\x03⥜\x0fghtUpVectorBar;\x03⥔\x0eghtDownVector;\x03⇂\x0dghtTeeVector;\x03⥛\x0dghtVectorBar;\x03⥓\x0cghtArrowBar;\x03⇥\x0cghtTeeArrow;\x03↦\x0cghtTriangle;\x03⊳\x0cghtUpVector;\x03↾\x0bghtCeiling;\x03⌉\x0aghtVector;\x03⇀\x09ghtArrow;\x03→\x09ghtFloor;\x03⌋\x09ghtarrow;\x03⇒\x07ghtTee;\x03⊢", "\x0bundImplies;\x03⥰\x03pf;\x03ℝ", "\x0aightarrow;\x03⇛", "\x03cr;\x03ℛ\x02h;\x03↱", "\x0aleDelayed;\x03⧴", "\x05CHcy;\x02Щ\x03cy;\x02Ш", "\x05FTcy;\x02Ь", "\x05cute;\x02Ś", "\x05aron;\x02Š\x05edil;\x02Ş\x04irc;\x02Ŝ\x02y;\x02С\x01;\x03⪼", "\x02r;\x04𝔖", "\x0eortRightArrow;\x03→\x0dortDownArrow;\x03↓\x0dortLeftArrow;\x03←\x0bortUpArrow;\x03↑", "\x04gma;\x02Σ", "\x0aallCircle;\x03∘", "\x03pf;\x04𝕊", "\x12uareSupersetEqual;\x03⊒\x11uareIntersection;\x03⊓\x10uareSubsetEqual;\x03⊑\x0duareSuperset;\x03⊐\x0buareSubset;\x03⊏\x0auareUnion;\x03⊔\x05uare;\x03□\x03rt;\x03√", "\x03cr;\x04𝒮", "\x03ar;\x03⋆", "\x11cceedsSlantEqual;\x03≽\x0ccceedsEqual;\x03⪰\x0ccceedsTilde;\x03≿\x0cpersetEqual;\x03⊇\x0absetEqual;\x03⊆\x07cceeds;\x03≻\x07chThat;\x03∋\x07perset;\x03⊃\x05bset;\x03⋐\x05pset;\x03⋑\x02b;\x03⋐\x02m;\x03∑\x02p;\x03⋑", "\x04ORN;\x02Þ\x03ORN\x02Þ", "\x04ADE;\x03™", "\x04Hcy;\x02Ћ\x03cy;\x02Ц", "\x02b;\x01\x9\x02u;\x02Τ", "\x05aron;\x02Ť\x05edil;\x02Ţ\x02y;\x02Т", "\x02r;\x04𝔗", "\x09ickSpace;\x06 \x08erefore;\x03∴\x08inSpace;\x03 \x04eta;\x02Θ", "\x0dldeFullEqual;\x03≅\x09ldeEqual;\x03≃\x09ldeTilde;\x03≈\x04lde;\x03∼", "\x03pf;\x04𝕋", "\x08ipleDot;\x03⃛", "\x05trok;\x02Ŧ\x03cr;\x04𝒯", "\x07rrocir;\x03⥉\x05cute;\x02Ú\x04cute\x02Ú\x03rr;\x03↟", "\x05reve;\x02Ŭ\x04rcy;\x02Ў", "\x04irc;\x02Û\x03irc\x02Û\x02y;\x02У", "\x05blac;\x02Ű", "\x02r;\x04𝔘", "\x05rave;\x02Ù\x04rave\x02Ù", "\x04acr;\x02Ū", "\x0fderParenthesis;\x03⏝\x0bderBracket;\x03⎵\x09derBrace;\x03⏟\x08ionPlus;\x03⊎\x07derBar;\x01_\x04ion;\x03⋃", "\x04gon;\x02Ų\x03pf;\x04𝕌", "\x0fArrowDownArrow;\x03⇅\x0eperRightArrow;\x03↗\x0dperLeftArrow;\x03↖\x0cEquilibrium;\x03⥮\x0aDownArrow;\x03↕\x0adownarrow;\x03⇕\x09ArrowBar;\x03⤒\x09TeeArrow;\x03↥\x06Arrow;\x03↑\x06arrow;\x03⇑\x06silon;\x02Υ\x04Tee;\x03⊥\x03si;\x02ϒ", "\x04ing;\x02Ů", "\x03cr;\x04𝒰", "\x05ilde;\x02Ũ", "\x03ml;\x02Ü\x02ml\x02Ü", "\x04ash;\x03⊫", "\x03ar;\x03⫫", "\x02y;\x02В", "\x05ashl;\x03⫦\x04ash;\x03⊩", "\x10rticalSeparator;\x03❘\x0crticalTilde;\x03≀\x0cryThinSpace;\x03 \x0brticalLine;\x01|\x0articalBar;\x03∣\x05rbar;\x03‖\x03rt;\x03‖\x02e;\x03⋁", "\x02r;\x04𝔙", "\x03pf;\x04𝕍", "\x03cr;\x04𝒱", "\x05dash;\x03⊪", "\x04irc;\x02Ŵ", "\x04dge;\x03⋀", "\x02r;\x04𝔚", "\x03pf;\x04𝕎", "\x03cr;\x04𝒲", "\x02r;\x04𝔛", "\x01;\x02Ξ", "\x03pf;\x04𝕏", "\x03cr;\x04𝒳", "\x03cy;\x02Я", "\x03cy;\x02Ї", "\x03cy;\x02Ю", "\x05cute;\x02Ý\x04cute\x02Ý", "\x04irc;\x02Ŷ\x02y;\x02Ы", "\x02r;\x04𝔜", "\x03pf;\x04𝕐", "\x03cr;\x04𝒴", "\x03ml;\x02Ÿ", "\x03cy;\x02Ж", "\x05cute;\x02Ź", "\x05aron;\x02Ž\x02y;\x02З", "\x03ot;\x02Ż", "\x0droWidthSpace;\x03\x03ta;\x02Ζ", "\x02r;\x03ℨ", "\x03pf;\x03ℤ", "\x03cr;\x04𝒵", "\x05cute;\x02á\x04cute\x02á", "\x05reve;\x02ă", "\x04irc;\x02â\x04ute;\x02´\x03irc\x02â\x03ute\x02´\x02E;\x05∾̳\x02d;\x03∿\x02y;\x02а\x01;\x03∾", "\x04lig;\x02æ\x03lig\x02æ", "\x02r;\x04𝔞\x01;\x03", "\x05rave;\x02à\x04rave\x02à", "\x06efsym;\x03ℵ\x04eph;\x03ℵ\x04pha;\x02α", "\x04acr;\x02ā\x04alg;\x03⨿\x02p;\x01&\x01p\x01&", "\x07dslope;\x03⩘\x07gmsdaa;\x03⦨\x07gmsdab;\x03⦩\x07gmsdac;\x03⦪\x07gmsdad;\x03⦫\x07gmsdae;\x03⦬\x07gmsdaf;\x03⦭\x07gmsdag;\x03⦮\x07gmsdah;\x03⦯\x07grtvbd;\x03⦝\x06grtvb;\x03⊾\x06gzarr;\x03⍼\x05dand;\x03⩕\x05gmsd;\x03∡\x05gsph;\x03∢\x04gle;\x03∠\x04grt;\x03∟\x04gst;\x02Å\x03dd;\x03⩜\x03dv;\x03⩚\x03ge;\x03⦤\x02d;\x03∧\x02g;\x03∠", "\x04gon;\x02ą\x03pf;\x04𝕒", "\x07proxeq;\x03≊\x05acir;\x03⩯\x05prox;\x03≈\x03id;\x03≋\x03os;\x01'\x02E;\x03⩰\x02e;\x03≊\x01;\x03≈", "\x04ing;\x02å\x03ing\x02å", "\x06ympeq;\x03≍\x04ymp;\x03≈\x03cr;\x04𝒶\x02t;\x01*", "\x05ilde;\x02ã\x04ilde\x02ã", "\x03ml;\x02ä\x02ml\x02ä", "\x07conint;\x03∳\x04int;\x03⨑", "\x03ot;\x03⫭", "\x0ackepsilon;\x02϶\x08ckprime;\x03‵\x08cksimeq;\x03⋍\x07ckcong;\x03≌\x07rwedge;\x03⌅\x06cksim;\x03∽\x05rvee;\x03⊽\x05rwed;\x03⌅", "\x07rktbrk;\x03⎶\x03rk;\x03⎵", "\x04ong;\x03≌\x02y;\x02б", "\x04quo;\x03„", "\x06cause;\x03∵\x06mptyv;\x03⦰\x06tween;\x03≬\x05caus;\x03∵\x05rnou;\x03ℬ\x04psi;\x02϶\x03ta;\x02β\x03th;\x03ℶ", "\x02r;\x04𝔟", "\x0egtriangledown;\x03▽\x0cgtriangleup;\x03△\x08gotimes;\x03⨂\x07goplus;\x03⨁\x07gsqcup;\x03⨆\x07guplus;\x03⨄\x07gwedge;\x03⋀\x06gcirc;\x03◯\x06godot;\x03⨀\x06gstar;\x03★\x05gcap;\x03⋂\x05gcup;\x03⋃\x05gvee;\x03⋁", "\x05arow;\x03⤍", "\x11acktriangleright;\x03▸\x10acktriangledown;\x03▾\x10acktriangleleft;\x03◂\x0cacktriangle;\x03▴\x0backlozenge;\x03⧫\x0aacksquare;\x03▪\x04ank;\x03␣\x04k12;\x03▒\x04k14;\x03░\x04k34;\x03▓\x04ock;\x03█", "\x06equiv;\x06≡⃥\x03ot;\x03⌐\x02e;\x04=⃥", "\x07xminus;\x03⊟\x07xtimes;\x03⊠\x06xplus;\x03⊞\x05ttom;\x03⊥\x05wtie;\x03⋈\x05xbox;\x03⧉\x04xDL;\x03╗\x04xDR;\x03╔\x04xDl;\x03╖\x04xDr;\x03╓\x04xHD;\x03╦\x04xHU;\x03╩\x04xHd;\x03╤\x04xHu;\x03╧\x04xUL;\x03╝\x04xUR;\x03╚\x04xUl;\x03╜\x04xUr;\x03╙\x04xVH;\x03╬\x04xVL;\x03╣\x04xVR;\x03╠\x04xVh;\x03╫\x04xVl;\x03╢\x04xVr;\x03╟\x04xdL;\x03╕\x04xdR;\x03╒\x04xdl;\x03┐\x04xdr;\x03┌\x04xhD;\x03╥\x04xhU;\x03╨\x04xhd;\x03┬\x04xhu;\x03┴\x04xuL;\x03╛\x04xuR;\x03╘\x04xul;\x03┘\x04xur;\x03└\x04xvH;\x03╪\x04xvL;\x03╡\x04xvR;\x03╞\x04xvh;\x03┼\x04xvl;\x03┤\x04xvr;\x03├\x03pf;\x04𝕓\x03xH;\x03═\x03xV;\x03║\x03xh;\x03─\x03xv;\x03│\x02t;\x03⊥", "\x05rime;\x03‵", "\x05vbar;\x02¦\x04eve;\x02˘\x04vbar\x02¦", "\x07olhsub;\x03⟈\x04emi;\x03⁏\x04ime;\x03⋍\x04olb;\x03⧅\x03cr;\x04𝒷\x03im;\x03∽\x03ol;\x01\\", "\x05llet;\x03•\x05mpeq;\x03≏\x04mpE;\x03⪮\x04mpe;\x03≏\x03ll;\x03•\x03mp;\x03≎", "\x07pbrcup;\x03⩉\x05cute;\x02ć\x05pand;\x03⩄\x05pcap;\x03⩋\x05pcup;\x03⩇\x05pdot;\x03⩀\x04ret;\x03⁁\x04ron;\x02ˇ\x03ps;\x06∩︀\x02p;\x03∩", "\x06upssm;\x03⩐\x05aron;\x02č\x05edil;\x02ç\x04aps;\x03⩍\x04edil\x02ç\x04irc;\x02ĉ\x04ups;\x03⩌", "\x03ot;\x02ċ", "\x08nterdot;\x02·\x06mptyv;\x03⦲\x04dil;\x02¸\x03dil\x02¸\x03nt;\x02¢\x02nt\x02¢", "\x02r;\x04𝔠", "\x08eckmark;\x03✓\x04eck;\x03✓\x03cy;\x02ч\x02i;\x02χ", "\x0frclearrowright;\x03↻\x0erclearrowleft;\x03↺\x0arcledcirc;\x03⊚\x0arcleddash;\x03⊝\x09rcledast;\x03⊛\x07rcledR;\x02®\x07rcledS;\x03Ⓢ\x07rfnint;\x03⨐\x06rscir;\x03⧂\x05rceq;\x03≗\x05rmid;\x03⫯\x03rE;\x03⧃\x03rc;\x02ˆ\x03re;\x03≗\x02r;\x03○", "\x07ubsuit;\x03♣\x04ubs;\x03♣", "\x09mplement;\x03∁\x08mplexes;\x03ℂ\x06loneq;\x03≔\x06ngdot;\x03⩭\x05lone;\x03≔\x05mmat;\x01@\x05mpfn;\x03∘\x05nint;\x03∮\x05prod;\x03∐\x05pysr;\x03℗\x04lon;\x01:\x04mma;\x01,\x03mp;\x03∁\x03ng;\x03≅\x03pf;\x04𝕔\x03py;\x02©\x02py\x02©", "\x04arr;\x03↵\x04oss;\x03✗", "\x04ube;\x03⫑\x04upe;\x03⫒\x03cr;\x04𝒸\x03ub;\x03⫏\x03up;\x03⫐", "\x04dot;\x03⋯", "\x0ervearrowright;\x03↷\x0drvearrowleft;\x03↶\x0arlyeqprec;\x03⋞\x0arlyeqsucc;\x03⋟\x09rlywedge;\x03⋏\x07pbrcap;\x03⩈\x07rlyvee;\x03⋎\x06darrl;\x03⤸\x06darrr;\x03⤵\x06larrp;\x03⤽\x06rarrm;\x03⤼\x05larr;\x03↶\x05pcap;\x03⩆\x05pcup;\x03⩊\x05pdot;\x03⊍\x05rarr;\x03↷\x05rren;\x02¤\x04epr;\x03⋞\x04esc;\x03⋟\x04por;\x03⩅\x04rren\x02¤\x04vee;\x03⋎\x04wed;\x03⋏\x03ps;\x06∪︀\x02p;\x03∪", "\x07conint;\x03∲\x04int;\x03∱", "\x05lcty;\x03⌭", "\x03rr;\x03⇓", "\x03ar;\x03⥥", "\x05gger;\x03†\x05leth;\x03ℸ\x04shv;\x03⊣\x03rr;\x03↓\x03sh;\x03‐", "\x06karow;\x03⤏\x04lac;\x02˝", "\x05aron;\x02ď\x02y;\x02д", "\x06agger;\x03‡\x06otseq;\x03⩷\x04arr;\x03⇊\x01;\x03ⅆ", "\x06mptyv;\x03⦱\x04lta;\x02δ\x02g;\x02°\x01g\x02°", "\x05isht;\x03⥿\x02r;\x04𝔡", "\x04arl;\x03⇃\x04arr;\x03⇂", "\x0cvideontimes;\x03⋇\x0aamondsuit;\x03♦\x06amond;\x03⋄\x06gamma;\x02ϝ\x05vide;\x02÷\x05vonx;\x03⋇\x04ams;\x03♦\x04sin;\x03⋲\x04vide\x02÷\x03am;\x03⋄\x02e;\x02¨\x02v;\x02÷", "\x03cy;\x02ђ", "\x05corn;\x03⌞\x05crop;\x03⌍", "\x0fwnharpoonright;\x03⇂\x0ewnharpoonleft;\x03⇃\x0dublebarwedge;\x03⌆\x0dwndownarrows;\x03⇊\x08tsquare;\x03⊡\x08wnarrow;\x03↓\x07teqdot;\x03≑\x07tminus;\x03∸\x06tplus;\x03∔\x05llar;\x01$\x04teq;\x03≐\x03pf;\x04𝕕\x02t;\x02˙", "\x07bkarow;\x03⤐\x05corn;\x03⌟\x05crop;\x03⌌", "\x05trok;\x02đ\x03cr;\x04𝒹\x03cy;\x02ѕ\x03ol;\x03⧶", "\x04dot;\x03⋱\x04rif;\x03▾\x03ri;\x03▿", "\x04arr;\x03⇵\x04har;\x03⥯", "\x06angle;\x03⦦", "\x07igrarr;\x03⟿\x03cy;\x02џ", "\x04Dot;\x03⩷\x03ot;\x03≑", "\x05cute;\x02é\x05ster;\x03⩮\x04cute\x02é", "\x05aron;\x02ě\x05olon;\x03≕\x04irc;\x02ê\x03ir;\x03≖\x03irc\x02ê\x02y;\x02э", "\x03ot;\x02ė", "\x01;\x03ⅇ", "\x04Dot;\x03≒\x02r;\x04𝔢", "\x05rave;\x02è\x05sdot;\x03⪘\x04rave\x02è\x02s;\x03⪖\x01;\x03⪚", "\x07inters;\x03⏧\x05sdot;\x03⪗\x02l;\x03ℓ\x02s;\x03⪕\x01;\x03⪙", "\x07ptyset;\x03∅\x05ptyv;\x03∅\x05sp13;\x03 \x05sp14;\x03 \x04acr;\x02ē\x04pty;\x03∅\x03sp;\x03 ", "\x03sp;\x03 \x02g;\x02ŋ", "\x04gon;\x02ę\x03pf;\x04𝕖", "\x06silon;\x02ε\x05arsl;\x03⧣\x04lus;\x03⩱\x04siv;\x02ϵ\x03ar;\x03⋕\x03si;\x02ε", "\x0aslantless;\x03⪕\x09slantgtr;\x03⪖\x07vparsl;\x03⧥\x06colon;\x03≕\x06uivDD;\x03⩸\x05circ;\x03≖\x05uals;\x01=\x05uest;\x03≟\x04sim;\x03≂\x04uiv;\x03≡", "\x04Dot;\x03≓\x04arr;\x03⥱", "\x04dot;\x03≐\x03cr;\x03ℯ\x03im;\x03≂", "\x02a;\x02η\x02h;\x02ð\x01h\x02ð", "\x03ml;\x02ë\x03ro;\x03€\x02ml\x02ë", "\x0bponentiale;\x03ⅇ\x0apectation;\x03ℰ\x04ist;\x03∃\x03cl;\x01!", "\x0cllingdotseq;\x03≒", "\x02y;\x02ф", "\x05male;\x03♀", "\x05ilig;\x03ffi\x05llig;\x03ffl\x04lig;\x03ff\x02r;\x04𝔣", "\x04lig;\x03fi", "\x04lig;\x02fj", "\x04lig;\x03fl\x04tns;\x03▱\x03at;\x03♭", "\x03of;\x02ƒ", "\x05rall;\x03∀\x04rkv;\x03⫙\x03pf;\x04𝕗\x03rk;\x03⋔", "\x07artint;\x03⨍", "\x05ac12;\x02½\x05ac13;\x03⅓\x05ac14;\x02¼\x05ac15;\x03⅕\x05ac16;\x03⅙\x05ac18;\x03⅛\x05ac23;\x03⅔\x05ac25;\x03⅖\x05ac34;\x02¾\x05ac35;\x03⅗\x05ac38;\x03⅜\x05ac45;\x03⅘\x05ac56;\x03⅚\x05ac58;\x03⅝\x05ac78;\x03⅞\x04ac12\x02½\x04ac14\x02¼\x04ac34\x02¾\x04asl;\x03⁄\x04own;\x03⌢", "\x03cr;\x04𝒻", "\x02l;\x03⪌\x01;\x03≧", "\x05cute;\x02ǵ\x05mmad;\x02ϝ\x04mma;\x02γ\x02p;\x03⪆", "\x05reve;\x02ğ", "\x04irc;\x02ĝ\x02y;\x02г", "\x03ot;\x02ġ", "\x07qslant;\x03⩾\x07sdotol;\x03⪄\x06sdoto;\x03⪂\x05sdot;\x03⪀\x05sles;\x03⪔\x04scc;\x03⪩\x03qq;\x03≧\x03sl;\x06⋛︀\x02l;\x03⋛\x02q;\x03≥\x02s;\x03⩾\x01;\x03≥", "\x02r;\x04𝔤", "\x02g;\x03⋙\x01;\x03≫", "\x04mel;\x03ℷ", "\x03cy;\x02ѓ", "\x02E;\x03⪒\x02a;\x03⪥\x02j;\x03⪤\x01;\x03≷", "\x07approx;\x03⪊\x04eqq;\x03≩\x04sim;\x03⋧\x03ap;\x03⪊\x03eq;\x03⪈\x02E;\x03≩\x02e;\x03⪈", "\x03pf;\x04𝕘", "\x04ave;\x01`", "\x04ime;\x03⪎\x04iml;\x03⪐\x03cr;\x03ℊ\x03im;\x03≳", "\x09reqqless;\x03⪌\x08rapprox;\x03⪆\x08reqless;\x03⋛\x06quest;\x03⩼\x06rless;\x03≷\x05lPar;\x03⦕\x05rarr;\x03⥸\x05rdot;\x03⋗\x05rsim;\x03≳\x04cir;\x03⩺\x04dot;\x03⋗\x03cc;\x03⪧\x01;\x01>", "\x08ertneqq;\x06≩︀\x03nE;\x06≩︀", "\x03rr;\x03⇔", "\x06rrcir;\x03⥈\x05irsp;\x03 \x05milt;\x03ℋ\x05rdcy;\x02ъ\x04rrw;\x03↭\x03lf;\x02½\x03rr;\x03↔", "\x03ar;\x03ℏ", "\x04irc;\x02ĥ", "\x08artsuit;\x03♥\x05arts;\x03♥\x05llip;\x03…\x05rcon;\x03⊹", "\x02r;\x04𝔥", "\x07searow;\x03⤥\x07swarow;\x03⤦", "\x0dokrightarrow;\x03↪\x0cokleftarrow;\x03↩\x05mtht;\x03∻\x05rbar;\x03―\x04arr;\x03⇿\x03pf;\x04𝕙", "\x05lash;\x03ℏ\x05trok;\x02ħ\x03cr;\x04𝒽", "\x05bull;\x03⁃\x05phen;\x03‐", "\x05cute;\x02í\x04cute\x02í", "\x04irc;\x02î\x03irc\x02î\x02y;\x02и\x01;\x03", "\x04xcl;\x02¡\x03cy;\x02е\x03xcl\x02¡", "\x02f;\x03⇔\x02r;\x04𝔦", "\x05rave;\x02ì\x04rave\x02ì", "\x05iint;\x03⨌\x05nfin;\x03⧜\x04int;\x03∭\x04ota;\x03℩\x01;\x03ⅈ", "\x04lig;\x02ij", "\x07agline;\x03ℐ\x07agpart;\x03ℑ\x04acr;\x02ī\x04age;\x03ℑ\x04ath;\x02ı\x04ped;\x02Ƶ\x03of;\x03⊷", "\x07fintie;\x03⧝\x07tegers;\x03ℤ\x07tercal;\x03⊺\x07tlarhk;\x03⨗\x06tprod;\x03⨼\x05care;\x03℅\x05odot;\x02ı\x05tcal;\x03⊺\x04fin;\x03∞\x02t;\x03∫\x01;\x03∈", "\x04gon;\x02į\x03cy;\x02ё\x03pf;\x04𝕚\x03ta;\x02ι", "\x04rod;\x03⨼", "\x05uest;\x02¿\x04uest\x02¿", "\x06indot;\x03⋵\x05insv;\x03⋳\x04inE;\x03⋹\x04ins;\x03⋴\x04inv;\x03∈\x03cr;\x04𝒾\x03in;\x03∈", "\x05ilde;\x02ĩ\x01;\x03", "\x04kcy;\x02і\x03ml;\x02ï\x02ml\x02ï", "\x04irc;\x02ĵ\x02y;\x02й", "\x02r;\x04𝔧", "\x04ath;\x02ȷ", "\x03pf;\x04𝕛", "\x05ercy;\x02ј\x03cr;\x04𝒿", "\x04kcy;\x02є", "\x05ppav;\x02ϰ\x04ppa;\x02κ", "\x05edil;\x02ķ\x02y;\x02к", "\x02r;\x04𝔨", "\x05reen;\x02ĸ", "\x03cy;\x02х", "\x03cy;\x02ќ", "\x03pf;\x04𝕜", "\x03cr;\x04𝓀", "\x05tail;\x03⤛\x04arr;\x03⇚\x03rr;\x03⇐", "\x04arr;\x03⤎", "\x02g;\x03⪋\x01;\x03≦", "\x03ar;\x03⥢", "\x07emptyv;\x03⦴\x06rrbfs;\x03⤟\x06rrsim;\x03⥳\x05cute;\x02ĺ\x05gran;\x03ℒ\x05mbda;\x02λ\x05ngle;\x03⟨\x05rrfs;\x03⤝\x05rrhk;\x03↩\x05rrlp;\x03↫\x05rrpl;\x03⤹\x05rrtl;\x03↢\x05tail;\x03⤙\x04ngd;\x03⦑\x04quo;\x02«\x04rrb;\x03⇤\x04tes;\x06⪭︀\x03ng;\x03⟨\x03quo\x02«\x03rr;\x03←\x03te;\x03⪭\x02p;\x03⪅\x02t;\x03⪫", "\x06rksld;\x03⦏\x06rkslu;\x03⦍\x05race;\x01{\x05rack;\x01[\x04arr;\x03⤌\x04brk;\x03❲\x04rke;\x03⦋", "\x05aron;\x02ľ\x05edil;\x02ļ\x04eil;\x03⌈\x03ub;\x01{\x02y;\x02л", "\x07rushar;\x03⥋\x06rdhar;\x03⥧\x05quor;\x03„\x04quo;\x03“\x03ca;\x03⤶\x03sh;\x03↲", "\x12ftrightsquigarrow;\x03↭\x10ftrightharpoons;\x03⇋\x0eftharpoondown;\x03↽\x0eftrightarrows;\x03⇆\x0dftleftarrows;\x03⇇\x0dftrightarrow;\x03↔\x0dftthreetimes;\x03⋋\x0cftarrowtail;\x03↢\x0cftharpoonup;\x03↼\x09ssapprox;\x03⪅\x09sseqqgtr;\x03⪋\x08ftarrow;\x03←\x08sseqgtr;\x03⋚\x07qslant;\x03⩽\x07sdotor;\x03⪃\x06sdoto;\x03⪁\x06ssdot;\x03⋖\x06ssgtr;\x03≶\x06sssim;\x03≲\x05sdot;\x03⩿\x05sges;\x03⪓\x04scc;\x03⪨\x03qq;\x03≦\x03sg;\x06⋚︀\x02g;\x03⋚\x02q;\x03≤\x02s;\x03⩽\x01;\x03≤", "\x05isht;\x03⥼\x05loor;\x03⌊\x02r;\x04𝔩", "\x02E;\x03⪑\x01;\x03≶", "\x05arul;\x03⥪\x04ard;\x03↽\x04aru;\x03↼\x04blk;\x03▄", "\x03cy;\x02љ", "\x07corner;\x03⌞\x05hard;\x03⥫\x04arr;\x03⇇\x04tri;\x03◺\x01;\x03≪", "\x09oustache;\x03⎰\x05idot;\x02ŀ\x05oust;\x03⎰", "\x07approx;\x03⪉\x04eqq;\x03≨\x04sim;\x03⋦\x03ap;\x03⪉\x03eq;\x03⪇\x02E;\x03≨\x02e;\x03⪇", "\x11ngleftrightarrow;\x03⟷\x0dngrightarrow;\x03⟶\x0doparrowright;\x03↬\x0cngleftarrow;\x03⟵\x0coparrowleft;\x03↫\x09ngmapsto;\x03⟼\x06times;\x03⨴\x06zenge;\x03◊\x05plus;\x03⨭\x05wast;\x03∗\x05wbar;\x01_\x04ang;\x03⟬\x04arr;\x03⇽\x04brk;\x03⟦\x04par;\x03⦅\x03pf;\x04𝕝\x03zf;\x03⧫\x02z;\x03◊", "\x05arlt;\x03⦓\x03ar;\x01(", "\x07corner;\x03⌟\x05hard;\x03⥭\x04arr;\x03⇆\x04har;\x03⇋\x04tri;\x03⊿\x02m;\x03", "\x05aquo;\x03‹\x05quor;\x03‚\x05trok;\x02ł\x04ime;\x03⪍\x04img;\x03⪏\x04quo;\x03‘\x03cr;\x04𝓁\x03im;\x03≲\x03qb;\x01[\x02h;\x03↰", "\x06quest;\x03⩻\x05hree;\x03⋋\x05imes;\x03⋉\x05larr;\x03⥶\x05rPar;\x03⦖\x04cir;\x03⩹\x04dot;\x03⋖\x04rie;\x03⊴\x04rif;\x03◂\x03cc;\x03⪦\x03ri;\x03◃\x01;\x01<", "\x07rdshar;\x03⥊\x06ruhar;\x03⥦", "\x08ertneqq;\x06≨︀\x03nE;\x06≨︀", "\x04Dot;\x03∺", "\x09pstodown;\x03↧\x09pstoleft;\x03↤\x07pstoup;\x03↥\x06ltese;\x03✠\x05psto;\x03↦\x05rker;\x03▮\x03cr;\x02¯\x03le;\x03♂\x03lt;\x03✠\x02cr\x02¯\x02p;\x03↦", "\x05omma;\x03⨩\x02y;\x02м", "\x04ash;\x03—", "\x0casuredangle;\x03∡", "\x02r;\x04𝔪", "\x02o;\x03℧", "\x06nusdu;\x03⨪\x05dast;\x01*\x05dcir;\x03⫰\x05ddot;\x02·\x05nusb;\x03⊟\x05nusd;\x03∸\x04cro;\x02µ\x04ddot\x02·\x04nus;\x03−\x03cro\x02µ\x02d;\x03∣", "\x03cp;\x03⫛\x03dr;\x03…", "\x05plus;\x03∓", "\x05dels;\x03⊧\x03pf;\x04𝕞", "\x01;\x03∓", "\x05tpos;\x03∾\x03cr;\x04𝓂", "\x07ltimap;\x03⊸\x04map;\x03⊸\x01;\x02μ", "\x03tv;\x05≫̸\x02g;\x05⋙̸\x02t;\x06≫⃒", "\x0eeftrightarrow;\x03⇎\x09eftarrow;\x03⇍\x03tv;\x05≪̸\x02l;\x05⋘̸\x02t;\x06≪⃒", "\x0aightarrow;\x03⇏", "\x05Dash;\x03⊯\x05dash;\x03⊮", "\x07turals;\x03ℕ\x06pprox;\x03≉\x06tural;\x03♮\x05cute;\x02ń\x04bla;\x03∇\x04pid;\x05≋̸\x04pos;\x02ʼn\x04tur;\x03♮\x03ng;\x06∠⃒\x03pE;\x05⩰̸\x02p;\x03≉", "\x05umpe;\x05≏̸\x04ump;\x05≎̸\x03sp;\x02 \x02sp\x02 ", "\x07ongdot;\x05⩭̸\x05aron;\x02ň\x05edil;\x02ņ\x04ong;\x03≇\x03ap;\x03⩃\x03up;\x03⩂\x02y;\x02н", "\x04ash;\x03–", "\x06arrow;\x03↗\x06xists;\x03∄\x05arhk;\x03⤤\x05quiv;\x03≢\x05sear;\x03⤨\x05xist;\x03∄\x04Arr;\x03⇗\x04arr;\x03↗\x04dot;\x05≐̸\x04sim;\x05≂̸\x01;\x03≠", "\x02r;\x04𝔫", "\x08eqslant;\x05⩾̸\x04eqq;\x05≧̸\x04sim;\x03≵\x03eq;\x03≱\x03es;\x05⩾̸\x03tr;\x03≯\x02E;\x05≧̸\x02e;\x03≱\x02t;\x03≯", "\x04Arr;\x03⇎\x04arr;\x03↮\x04par;\x03⫲", "\x03sd;\x03⋺\x02s;\x03⋼\x02v;\x03∋\x01;\x03∋", "\x03cy;\x02њ", "\x0eeftrightarrow;\x03↮\x09eftarrow;\x03↚\x08eqslant;\x05⩽̸\x05trie;\x03⋬\x04Arr;\x03⇍\x04arr;\x03↚\x04eqq;\x05≦̸\x04ess;\x03≮\x04sim;\x03≴\x04tri;\x03⋪\x03dr;\x03‥\x03eq;\x03≰\x03es;\x05⩽̸\x02E;\x05≦̸\x02e;\x03≰\x02t;\x03≮", "\x03id;\x03∤", "\x07tindot;\x05⋵̸\x06tinva;\x03∉\x06tinvb;\x03⋷\x06tinvc;\x03⋶\x06tniva;\x03∌\x06tnivb;\x03⋾\x06tnivc;\x03⋽\x05tinE;\x05⋹̸\x04tin;\x03∉\x04tni;\x03∌\x03pf;\x04𝕟\x02t;\x02¬\x01t\x02¬", "\x08arallel;\x03∦\x06olint;\x03⨔\x06receq;\x05⪯̸\x05arsl;\x06⫽⃥\x05rcue;\x03⋠\x04art;\x05∂̸\x04rec;\x03⊀\x03ar;\x03∦\x03re;\x05⪯̸\x02r;\x03⊀", "\x0aightarrow;\x03↛\x05arrc;\x05⤳̸\x05arrw;\x05↝̸\x05trie;\x03⋭\x04Arr;\x03⇏\x04arr;\x03↛\x04tri;\x03⋫", "\x0dhortparallel;\x03∦\x09ubseteqq;\x05⫅̸\x09upseteqq;\x05⫆̸\x08hortmid;\x03∤\x08ubseteq;\x03⊈\x08upseteq;\x03⊉\x06qsube;\x03⋢\x06qsupe;\x03⋣\x06ubset;\x06⊂⃒\x06ucceq;\x05⪰̸\x06upset;\x06⊃⃒\x05ccue;\x03⋡\x05imeq;\x03≄\x04ime;\x03≄\x04mid;\x03∤\x04par;\x03∦\x04ubE;\x05⫅̸\x04ube;\x03⊈\x04ucc;\x03⊁\x04upE;\x05⫆̸\x04upe;\x03⊉\x03ce;\x05⪰̸\x03cr;\x04𝓃\x03im;\x03≁\x03ub;\x03⊄\x03up;\x03⊅\x02c;\x03⊁", "\x0frianglerighteq;\x03⋭\x0erianglelefteq;\x03⋬\x0driangleright;\x03⋫\x0criangleleft;\x03⋪\x05ilde;\x02ñ\x04ilde\x02ñ\x03gl;\x03≹\x03lg;\x03≸", "\x05mero;\x03№\x04msp;\x03 \x02m;\x01#\x01;\x02ν", "\x06infin;\x03⧞\x06ltrie;\x06⊴⃒\x06rtrie;\x06⊵⃒\x05Dash;\x03⊭\x05Harr;\x03⤄\x05dash;\x03⊬\x05lArr;\x03⤂\x05rArr;\x03⤃\x04sim;\x06∼⃒\x03ap;\x06≍⃒\x03ge;\x06≥⃒\x03gt;\x04>⃒\x03le;\x06≤⃒\x03lt;\x04<⃒", "\x06arrow;\x03↖\x05arhk;\x03⤣\x05near;\x03⤧\x04Arr;\x03⇖\x04arr;\x03↖", "\x01;\x03Ⓢ", "\x05cute;\x02ó\x04cute\x02ó\x03st;\x03⊛", "\x04irc;\x02ô\x03ir;\x03⊚\x03irc\x02ô\x02y;\x02о", "\x05blac;\x02ő\x05sold;\x03⦼\x04ash;\x03⊝\x03iv;\x03⨸\x03ot;\x03⊙", "\x04lig;\x02œ", "\x04cir;\x03⦿\x02r;\x04𝔬", "\x05rave;\x02ò\x04rave\x02ò\x03on;\x02˛\x02t;\x03⧁", "\x04bar;\x03⦵\x02m;\x02Ω", "\x03nt;\x03∮", "\x06cross;\x03⦻\x04arr;\x03↺\x04cir;\x03⦾\x04ine;\x03‾\x02t;\x03⧀", "\x06icron;\x02ο\x05inus;\x03⊖\x04acr;\x02ō\x04ega;\x02ω\x03id;\x03⦶", "\x03pf;\x04𝕠", "\x04erp;\x03⦹\x04lus;\x03⊕\x03ar;\x03⦷", "\x06derof;\x03ℴ\x06slope;\x03⩗\x05igof;\x03⊶\x04arr;\x03↻\x04der;\x03ℴ\x03df;\x02ª\x03dm;\x02º\x03or;\x03⩖\x02d;\x03⩝\x02df\x02ª\x02dm\x02º\x02v;\x03⩛\x01;\x03∨", "\x05lash;\x02ø\x04lash\x02ø\x03cr;\x03ℴ\x03ol;\x03⊘", "\x07imesas;\x03⨶\x05ilde;\x02õ\x05imes;\x03⊗\x04ilde\x02õ", "\x03ml;\x02ö\x02ml\x02ö", "\x04bar;\x03⌽", "\x07rallel;\x03∥\x05rsim;\x03⫳\x04rsl;\x03⫽\x03ra;\x02¶\x03rt;\x03∂\x02r;\x03∥\x02ra\x02¶", "\x02y;\x02п", "\x06rtenk;\x03‱\x05rcnt;\x01%\x05riod;\x01.\x05rmil;\x03‰\x03rp;\x03⊥", "\x02r;\x04𝔭", "\x05mmat;\x03ℳ\x04one;\x03☎\x03iv;\x02ϕ\x02i;\x02φ", "\x08tchfork;\x03⋔\x02v;\x02ϖ\x01;\x02π", "\x07usacir;\x03⨣\x06anckh;\x03ℎ\x06uscir;\x03⨢\x06ussim;\x03⨦\x06ustwo;\x03⨧\x05anck;\x03ℏ\x05ankv;\x03ℏ\x05usdo;\x03∔\x05usdu;\x03⨥\x05usmn;\x02±\x04usb;\x03⊞\x04use;\x03⩲\x04usmn\x02±\x03us;\x01+", "\x01;\x02±", "\x07intint;\x03⨕\x04und;\x02£\x03pf;\x04𝕡\x03und\x02£", "\x0aeccurlyeq;\x03≼\x0aecnapprox;\x03⪹\x09ecapprox;\x03⪷\x07ecneqq;\x03⪵\x07ecnsim;\x03⋨\x07ofalar;\x03⌮\x07ofline;\x03⌒\x07ofsurf;\x03⌓\x06ecsim;\x03≾\x05eceq;\x03⪯\x05imes;\x03ℙ\x05nsim;\x03⋨\x05opto;\x03∝\x05urel;\x03⊰\x04cue;\x03≼\x04ime;\x03′\x04nap;\x03⪹\x04sim;\x03≾\x03ap;\x03⪷\x03ec;\x03≺\x03nE;\x03⪵\x03od;\x03∏\x03op;\x03∝\x02E;\x03⪳\x02e;\x03⪯\x01;\x03≺", "\x03cr;\x04𝓅\x02i;\x02ψ", "\x05ncsp;\x03 ", "\x02r;\x04𝔮", "\x03nt;\x03⨌", "\x03pf;\x04𝕢", "\x05rime;\x03⁗", "\x03cr;\x04𝓆", "\x0aaternions;\x03ℍ\x06atint;\x03⨖\x06esteq;\x03≟\x04est;\x01?\x03ot;\x01\"\x02ot\x01\"", "\x05tail;\x03⤜\x04arr;\x03⇛\x03rr;\x03⇒", "\x04arr;\x03⤏", "\x03ar;\x03⥤", "\x08tionals;\x03ℚ\x07emptyv;\x03⦳\x06rrbfs;\x03⤠\x06rrsim;\x03⥴\x05cute;\x02ŕ\x05ngle;\x03⟩\x05rrap;\x03⥵\x05rrfs;\x03⤞\x05rrhk;\x03↪\x05rrlp;\x03↬\x05rrpl;\x03⥅\x05rrtl;\x03↣\x05tail;\x03⤚\x04dic;\x03√\x04ngd;\x03⦒\x04nge;\x03⦥\x04quo;\x02»\x04rrb;\x03⇥\x04rrc;\x03⤳\x04rrw;\x03↝\x04tio;\x03∶\x03ce;\x05∽̱\x03ng;\x03⟩\x03quo\x02»\x03rr;\x03→", "\x06rksld;\x03⦎\x06rkslu;\x03⦐\x05race;\x01}\x05rack;\x01]\x04arr;\x03⤍\x04brk;\x03❳\x04rke;\x03⦌", "\x05aron;\x02ř\x05edil;\x02ŗ\x04eil;\x03⌉\x03ub;\x01}\x02y;\x02р", "\x06ldhar;\x03⥩\x05quor;\x03”\x04quo;\x03”\x03ca;\x03⤷\x03sh;\x03↳", "\x07alpart;\x03ℜ\x06aline;\x03ℛ\x04als;\x03ℝ\x03al;\x03ℜ\x03ct;\x03▭\x02g;\x02®\x01g\x02®", "\x05isht;\x03⥽\x05loor;\x03⌋\x02r;\x04𝔯", "\x05arul;\x03⥬\x04ard;\x03⇁\x04aru;\x03⇀\x03ov;\x02ϱ\x02o;\x02ρ", "\x10ghtleftharpoons;\x03⇌\x0fghtharpoondown;\x03⇁\x0fghtrightarrows;\x03⇉\x0eghtleftarrows;\x03⇄\x0eghtsquigarrow;\x03↝\x0eghtthreetimes;\x03⋌\x0dghtarrowtail;\x03↣\x0dghtharpoonup;\x03⇀\x0bsingdotseq;\x03≓\x09ghtarrow;\x03→\x03ng;\x02˚", "\x04arr;\x03⇄\x04har;\x03⇌\x02m;\x03", "\x09oustache;\x03⎱\x05oust;\x03⎱", "\x04mid;\x03⫮", "\x06times;\x03⨵\x05plus;\x03⨮\x04ang;\x03⟭\x04arr;\x03⇾\x04brk;\x03⟧\x04par;\x03⦆\x03pf;\x04𝕣", "\x07polint;\x03⨒\x05argt;\x03⦔\x03ar;\x01)", "\x04arr;\x03⇉", "\x05aquo;\x03›\x05quor;\x03’\x04quo;\x03’\x03cr;\x04𝓇\x03qb;\x01]\x02h;\x03↱", "\x07riltri;\x03⧎\x05hree;\x03⋌\x05imes;\x03⋊\x04rie;\x03⊵\x04rif;\x03▸\x03ri;\x03▹", "\x06luhar;\x03⥨", "\x01;\x03℞", "\x05cute;\x02ś", "\x04quo;\x03‚", "\x07polint;\x03⨓\x05aron;\x02š\x05edil;\x02ş\x05nsim;\x03⋩\x04cue;\x03≽\x04irc;\x02ŝ\x04nap;\x03⪺\x04sim;\x03≿\x03ap;\x03⪸\x03nE;\x03⪶\x02E;\x03⪴\x02e;\x03⪰\x02y;\x02с\x01;\x03≻", "\x04otb;\x03⊡\x04ote;\x03⩦\x03ot;\x03⋅", "\x07tminus;\x03∖\x06arrow;\x03↘\x05arhk;\x03⤥\x05swar;\x03⤩\x04Arr;\x03⇘\x04arr;\x03↘\x04tmn;\x03∖\x03ct;\x02§\x03mi;\x01;\x03xt;\x03✶\x02ct\x02§", "\x05rown;\x03⌢\x02r;\x04𝔰", "\x0cortparallel;\x03∥\x07ortmid;\x03∣\x05chcy;\x02щ\x04arp;\x03♯\x03cy;\x02ш\x02y;\x02\x01y\x02", "\x06mplus;\x03⨤\x06mrarr;\x03⥲\x05gmaf;\x02ς\x05gmav;\x02ς\x05mdot;\x03⩪\x04gma;\x02σ\x04meq;\x03≃\x04mgE;\x03⪠\x04mlE;\x03⪟\x04mne;\x03≆\x03me;\x03≃\x03mg;\x03⪞\x03ml;\x03⪝\x02m;\x03∼", "\x04arr;\x03←", "\x0callsetminus;\x03∖\x07eparsl;\x03⧤\x05ashp;\x03⨳\x04ile;\x03⌣\x04tes;\x06⪬︀\x03id;\x03∣\x03te;\x03⪬\x02t;\x03⪪", "\x05ftcy;\x02ь\x05lbar;\x03⌿\x03lb;\x03⧄\x03pf;\x04𝕤\x02l;\x01/", "\x08adesuit;\x03♠\x05ades;\x03♠\x03ar;\x03∥", "\x09subseteq;\x03⊑\x09supseteq;\x03⊒\x07subset;\x03⊏\x07supset;\x03⊐\x05caps;\x06⊓︀\x05cups;\x06⊔︀\x05sube;\x03⊑\x05supe;\x03⊒\x05uare;\x03□\x05uarf;\x03▪\x04cap;\x03⊓\x04cup;\x03⊔\x04sub;\x03⊏\x04sup;\x03⊐\x03uf;\x03▪\x02u;\x03□", "\x04arr;\x03→", "\x05etmn;\x03∖\x05mile;\x03⌣\x05tarf;\x03⋆\x03cr;\x04𝓈", "\x0eraightepsilon;\x02ϵ\x0araightphi;\x02ϕ\x04arf;\x03★\x04rns;\x02¯\x03ar;\x03☆", "\x0acccurlyeq;\x03≽\x0accnapprox;\x03⪺\x09bsetneqq;\x03⫋\x09ccapprox;\x03⪸\x09psetneqq;\x03⫌\x08bseteqq;\x03⫅\x08bsetneq;\x03⊊\x08pseteqq;\x03⫆\x08psetneq;\x03⊋\x07bseteq;\x03⊆\x07ccneqq;\x03⪶\x07ccnsim;\x03⋩\x07pseteq;\x03⊇\x06bedot;\x03⫃\x06bmult;\x03⫁\x06bplus;\x03⪿\x06brarr;\x03⥹\x06ccsim;\x03≿\x06pdsub;\x03⫘\x06pedot;\x03⫄\x06phsol;\x03⟉\x06phsub;\x03⫗\x06plarr;\x03⥻\x06pmult;\x03⫂\x06pplus;\x03⫀\x05bdot;\x03⪽\x05bset;\x03⊂\x05bsim;\x03⫇\x05bsub;\x03⫕\x05bsup;\x03⫓\x05cceq;\x03⪰\x05pdot;\x03⪾\x05pset;\x03⊃\x05psim;\x03⫈\x05psub;\x03⫔\x05psup;\x03⫖\x04bnE;\x03⫋\x04bne;\x03⊊\x04pnE;\x03⫌\x04pne;\x03⊋\x03bE;\x03⫅\x03be;\x03⊆\x03cc;\x03≻\x03ng;\x03♪\x03p1;\x02¹\x03p2;\x02²\x03p3;\x02³\x03pE;\x03⫆\x03pe;\x03⊇\x02b;\x03⊂\x02m;\x03∑\x02p1\x02¹\x02p2\x02²\x02p3\x02³\x02p;\x03⊃", "\x06arrow;\x03↙\x05arhk;\x03⤦\x05nwar;\x03⤪\x04Arr;\x03⇙\x04arr;\x03↙", "\x04lig;\x02ß\x03lig\x02ß", "\x05rget;\x03⌖\x02u;\x02τ", "\x03rk;\x03⎴", "\x05aron;\x02ť\x05edil;\x02ţ\x02y;\x02т", "\x03ot;\x03⃛", "\x05lrec;\x03⌕", "\x02r;\x04𝔱", "\x0aickapprox;\x03≈\x08erefore;\x03∴\x07etasym;\x02ϑ\x07icksim;\x03∼\x05ere4;\x03∴\x05etav;\x02ϑ\x05insp;\x03 \x05ksim;\x03∼\x04eta;\x02θ\x04kap;\x03≈\x04orn;\x02þ\x03orn\x02þ", "\x07mesbar;\x03⨱\x05mesb;\x03⊠\x05mesd;\x03⨰\x04lde;\x02˜\x04mes;\x02×\x03mes\x02×\x03nt;\x03∭", "\x06pfork;\x03⫚\x05pbot;\x03⌶\x05pcir;\x03⫱\x03ea;\x03⤨\x03pf;\x04𝕥\x03sa;\x03⤩\x02p;\x03⊤", "\x05rime;\x03‴", "\x0eianglerighteq;\x03⊵\x0dianglelefteq;\x03⊴\x0ciangleright;\x03▹\x0biangledown;\x03▿\x0biangleleft;\x03◃\x08iangleq;\x03≜\x07iangle;\x03▵\x07iminus;\x03⨺\x07pezium;\x03⏢\x06iplus;\x03⨹\x06itime;\x03⨻\x05idot;\x03◬\x04ade;\x03™\x04isb;\x03⧍\x03ie;\x03≜", "\x05trok;\x02ŧ\x04hcy;\x02ћ\x03cr;\x04𝓉\x03cy;\x02ц", "\x10oheadrightarrow;\x03↠\x0foheadleftarrow;\x03↞\x04ixt;\x03≬", "\x03rr;\x03⇑", "\x03ar;\x03⥣", "\x05cute;\x02ú\x04cute\x02ú\x03rr;\x03↑", "\x05reve;\x02ŭ\x04rcy;\x02ў", "\x04irc;\x02û\x03irc\x02û\x02y;\x02у", "\x05blac;\x02ű\x04arr;\x03⇅\x04har;\x03⥮", "\x05isht;\x03⥾\x02r;\x04𝔲", "\x05rave;\x02ù\x04rave\x02ù", "\x04arl;\x03↿\x04arr;\x03↾\x04blk;\x03▀", "\x07corner;\x03⌜\x05corn;\x03⌜\x05crop;\x03⌏\x04tri;\x03◸", "\x04acr;\x02ū\x02l;\x02¨\x01l\x02¨", "\x04gon;\x02ų\x03pf;\x04𝕦", "\x0dharpoonright;\x03↾\x0charpoonleft;\x03↿\x0adownarrow;\x03↕\x09uparrows;\x03⇈\x06arrow;\x03↑\x06silon;\x02υ\x04lus;\x03⊎\x04sih;\x02ϒ\x03si;\x02υ", "\x07corner;\x03⌝\x05corn;\x03⌝\x05crop;\x03⌎\x04ing;\x02ů\x04tri;\x03◹", "\x03cr;\x04𝓊", "\x05ilde;\x02ũ\x04dot;\x03⋰\x04rif;\x03▴\x03ri;\x03▵", "\x04arr;\x03⇈\x03ml;\x02ü\x02ml\x02ü", "\x06angle;\x03⦧", "\x03rr;\x03⇕", "\x04arv;\x03⫩\x03ar;\x03⫨", "\x04ash;\x03⊨", "\x0frtriangleright;\x03⊳\x0ertriangleleft;\x03⊲\x0crsubsetneqq;\x06⫋︀\x0crsupsetneqq;\x06⫌︀\x0brsubsetneq;\x06⊊︀\x0brsupsetneq;\x06⊋︀\x09repsilon;\x02ϵ\x09rnothing;\x03∅\x08rpropto;\x03∝\x07rkappa;\x02ϰ\x07rsigma;\x02ς\x07rtheta;\x02ϑ\x05ngrt;\x03⦜\x05rphi;\x02ϕ\x05rrho;\x02ϱ\x04rpi;\x02ϖ\x03rr;\x03↕", "\x02y;\x02в", "\x04ash;\x03⊢", "\x05ebar;\x03⊻\x05llip;\x03⋮\x05rbar;\x01|\x04eeq;\x03≚\x03rt;\x01|\x02e;\x03∨", "\x02r;\x04𝔳", "\x04tri;\x03⊲", "\x04sub;\x06⊂⃒\x04sup;\x06⊃⃒", "\x03pf;\x04𝕧", "\x04rop;\x03∝", "\x04tri;\x03⊳", "\x05ubnE;\x06⫋︀\x05ubne;\x06⊊︀\x05upnE;\x06⫌︀\x05upne;\x06⊋︀\x03cr;\x04𝓋", "\x06igzag;\x03⦚", "\x04irc;\x02ŵ", "\x05dbar;\x03⩟\x05dgeq;\x03≙\x05ierp;\x03℘\x04dge;\x03∧", "\x02r;\x04𝔴", "\x03pf;\x04𝕨", "\x01;\x03℘", "\x05eath;\x03≀\x01;\x03≀", "\x03cr;\x04𝓌", "\x04irc;\x03◯\x03ap;\x03⋂\x03up;\x03⋃", "\x04tri;\x03▽", "\x02r;\x04𝔵", "\x04Arr;\x03⟺\x04arr;\x03⟷", "\x01;\x02ξ", "\x04Arr;\x03⟸\x04arr;\x03⟵", "\x03ap;\x03⟼", "\x03is;\x03⋻", "\x05plus;\x03⨁\x05time;\x03⨂\x04dot;\x03⨀\x03pf;\x04𝕩", "\x04Arr;\x03⟹\x04arr;\x03⟶", "\x05qcup;\x03⨆\x03cr;\x04𝓍", "\x05plus;\x03⨄\x04tri;\x03△", "\x03ee;\x03⋁", "\x05edge;\x03⋀", "\x05cute;\x02ý\x04cute\x02ý\x03cy;\x02я", "\x04irc;\x02ŷ\x02y;\x02ы", "\x02n;\x02¥\x01n\x02¥", "\x02r;\x04𝔶", "\x03cy;\x02ї", "\x03pf;\x04𝕪", "\x03cr;\x04𝓎", "\x03cy;\x02ю\x03ml;\x02ÿ\x02ml\x02ÿ", "\x05cute;\x02ź", "\x05aron;\x02ž\x02y;\x02з", "\x03ot;\x02ż", "\x05etrf;\x03ℨ\x03ta;\x02ζ", "\x02r;\x04𝔷", "\x03cy;\x02ж", "\x06grarr;\x03⇝", "\x03pf;\x04𝕫", "\x03cr;\x04𝓏", "\x03nj;\x03\x02j;\x03", ), "small_words" => "GT\x00LT\x00gt\x00lt\x00", "small_mappings" => array( ">", "<", ">", "<", ) ) );
###require ABSPATH . WPINC . '/html-api/class-wp-html-attribute-token.php';
class WP_HTML_Attribute_Token { public $name; public $value_starts_at; public $value_length; public $start; public $length; public $is_true; public function __construct( $name, $value_start, $value_length, $start, $length, $is_true ) { $this->name = $name; $this->value_starts_at = $value_start; $this->value_length = $value_length; $this->start = $start; $this->length = $length; $this->is_true = $is_true; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-span.php';
class WP_HTML_Span { public $start; public $length; public function __construct( int $start, int $length ) { $this->start = $start; $this->length = $length; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-doctype-info.php';
class WP_HTML_Doctype_Info { public $name = null; public $public_identifier = null; public $system_identifier = null; public $indicated_compatibility_mode; private function __construct( ?string $name, ?string $public_identifier, ?string $system_identifier, bool $force_quirks_flag ) { $this->name = $name; $this->public_identifier = $public_identifier; $this->system_identifier = $system_identifier; if ( $force_quirks_flag ) { $this->indicated_compatibility_mode = 'quirks'; return; } if ( 'html' === $name && null === $public_identifier && null === $system_identifier ) { $this->indicated_compatibility_mode = 'no-quirks'; return; } if ( 'html' !== $name ) { $this->indicated_compatibility_mode = 'quirks'; return; } $system_identifier_is_missing = null === $system_identifier; $public_identifier = null === $public_identifier ? '' : strtolower( $public_identifier ); $system_identifier = null === $system_identifier ? '' : strtolower( $system_identifier ); if ( '-//w3o//dtd w3 html strict 3.0//en//' === $public_identifier || '-/w3c/dtd html 4.0 transitional/en' === $public_identifier || 'html' === $public_identifier ) { $this->indicated_compatibility_mode = 'quirks'; return; } if ( 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd' === $system_identifier ) { $this->indicated_compatibility_mode = 'quirks'; return; } if ( '' === $public_identifier ) { $this->indicated_compatibility_mode = 'no-quirks'; return; } if ( str_starts_with( $public_identifier, '+//silmaril//dtd html pro v0r11 19970101//' ) || str_starts_with( $public_identifier, '-//as//dtd html 3.0 aswedit + extensions//' ) || str_starts_with( $public_identifier, '-//advasoft ltd//dtd html 3.0 aswedit + extensions//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.1e//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.2 final//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html//' ) || str_starts_with( $public_identifier, '-//metrius//dtd metrius presentational//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html strict//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 tables//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html strict//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 tables//' ) || str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd html//' ) || str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd strict html//' ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html 2.0//" ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended 1.0//" ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended relaxed 1.0//" ) || str_starts_with( $public_identifier, '-//sq//dtd html 2.0 hotmetal + extensions//' ) || str_starts_with( $public_identifier, '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//' ) || str_starts_with( $public_identifier, '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//' ) || str_starts_with( $public_identifier, '-//spyglass//dtd html 2.0 extended//' ) || str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava html//' ) || str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava strict html//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3 1995-03-24//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 draft//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 final//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2s draft//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 transitional//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html experimental 19960712//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html experimental 970421//' ) || str_starts_with( $public_identifier, '-//w3c//dtd w3 html//' ) || str_starts_with( $public_identifier, '-//w3o//dtd w3 html 3.0//' ) || str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html 2.0//' ) || str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html//' ) ) { $this->indicated_compatibility_mode = 'quirks'; return; } if ( $system_identifier_is_missing && ( str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' ) ) ) { $this->indicated_compatibility_mode = 'quirks'; return; } if ( str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 transitional//' ) ) { $this->indicated_compatibility_mode = 'limited-quirks'; return; } if ( ! $system_identifier_is_missing && ( str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' ) ) ) { $this->indicated_compatibility_mode = 'limited-quirks'; return; } $this->indicated_compatibility_mode = 'no-quirks'; } public static function from_doctype_token( string $doctype_html ): ?self { $doctype_name = null; $doctype_public_id = null; $doctype_system_id = null; $end = strlen( $doctype_html ) - 1; if ( $end < 9 || 0 !== substr_compare( $doctype_html, '<!DOCTYPE', 0, 9, true ) ) { return null; } $at = 9; if ( '>' !== $doctype_html[ $end ] || ( strcspn( $doctype_html, '>', $at ) + $at ) < $end ) { return null; } $doctype_html = str_replace( "\r\n", "\n", $doctype_html ); $doctype_html = str_replace( "\r", "\n", $doctype_html ); $end = strlen( $doctype_html ) - 1; $at += strspn( $doctype_html, " \t\n\f\r", $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } $name_length = strcspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); $doctype_name = str_replace( "\0", "\u{FFFD}", strtolower( substr( $doctype_html, $at, $name_length ) ) ); $at += $name_length; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } if ( $at + 6 >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } if ( 0 === substr_compare( $doctype_html, 'PUBLIC', $at, 6, true ) ) { $at += 6; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } goto parse_doctype_public_identifier; } if ( 0 === substr_compare( $doctype_html, 'SYSTEM', $at, 6, true ) ) { $at += 6; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } goto parse_doctype_system_identifier; } return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); parse_doctype_public_identifier: $closer_quote = $doctype_html[ $at ]; if ( '"' !== $closer_quote && "'" !== $closer_quote ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; $identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at ); $doctype_public_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) ); $at += $identifier_length; if ( $at >= $end || $closer_quote !== $doctype_html[ $at ] ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } parse_doctype_system_identifier: $closer_quote = $doctype_html[ $at ]; if ( '"' !== $closer_quote && "'" !== $closer_quote ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; $identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at ); $doctype_system_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) ); $at += $identifier_length; if ( $at >= $end || $closer_quote !== $doctype_html[ $at ] ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-text-replacement.php';
class WP_HTML_Text_Replacement { public $start; public $length; public $text; public function __construct( int $start, int $length, string $text ) { $this->start = $start; $this->length = $length; $this->text = $text; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-decoder.php';
class WP_HTML_Decoder { public static function attribute_starts_with( $haystack, $search_text, $case_sensitivity = 'case-sensitive' ): bool { $search_length = strlen( $search_text ); $loose_case = 'ascii-case-insensitive' === $case_sensitivity; $haystack_end = strlen( $haystack ); $search_at = 0; $haystack_at = 0; while ( $search_at < $search_length && $haystack_at < $haystack_end ) { $chars_match = $loose_case ? strtolower( $haystack[ $haystack_at ] ) === strtolower( $search_text[ $search_at ] ) : $haystack[ $haystack_at ] === $search_text[ $search_at ]; $is_introducer = '&' === $haystack[ $haystack_at ]; $next_chunk = $is_introducer ? self::read_character_reference( 'attribute', $haystack, $haystack_at, $token_length ) : null; if ( null === $next_chunk && ! $chars_match ) { return false; } if ( null === $next_chunk && $chars_match ) { ++$haystack_at; ++$search_at; continue; } if ( 0 !== substr_compare( $search_text, $next_chunk, $search_at, strlen( $next_chunk ), $loose_case ) ) { return false; } $haystack_at += $token_length; $search_at += strlen( $next_chunk ); } return true; } public static function decode_text_node( $text ): string { return static::decode( 'data', $text ); } public static function decode_attribute( $text ): string { return static::decode( 'attribute', $text ); } public static function decode( $context, $text ): string { $decoded = ''; $end = strlen( $text ); $at = 0; $was_at = 0; while ( $at < $end ) { $next_character_reference_at = strpos( $text, '&', $at ); if ( false === $next_character_reference_at ) { break; } $character_reference = self::read_character_reference( $context, $text, $next_character_reference_at, $token_length ); if ( isset( $character_reference ) ) { $at = $next_character_reference_at; $decoded .= substr( $text, $was_at, $at - $was_at ); $decoded .= $character_reference; $at += $token_length; $was_at = $at; continue; } ++$at; } if ( 0 === $was_at ) { return $text; } if ( $was_at < $end ) { $decoded .= substr( $text, $was_at, $end - $was_at ); } return $decoded; } public static function read_character_reference( $context, $text, $at = 0, &$match_byte_length = null ) { global $html5_named_character_references; $length = strlen( $text ); if ( $at + 1 >= $length ) { return null; } if ( '&' !== $text[ $at ] ) { return null; } if ( '#' === $text[ $at + 1 ] ) { if ( $at + 2 >= $length ) { return null; } $digits_at = $at + 2; if ( 'x' === $text[ $digits_at ] || 'X' === $text[ $digits_at ] ) { $numeric_base = 16; $numeric_digits = '0123456789abcdefABCDEF'; $max_digits = 6; ++$digits_at; } else { $numeric_base = 10; $numeric_digits = '0123456789'; $max_digits = 7; } $zero_count = strspn( $text, '0', $digits_at ); $digit_count = strspn( $text, $numeric_digits, $digits_at + $zero_count ); $after_digits = $digits_at + $zero_count + $digit_count; $has_semicolon = $after_digits < $length && ';' === $text[ $after_digits ]; $end_of_span = $has_semicolon ? $after_digits + 1 : $after_digits; if ( 0 === $digit_count && 0 === $zero_count ) { return null; } if ( 0 === $digit_count ) { $match_byte_length = $end_of_span - $at; return '�'; } if ( $digit_count > $max_digits ) { $match_byte_length = $end_of_span - $at; return '�'; } $digits = substr( $text, $digits_at + $zero_count, $digit_count ); $code_point = intval( $digits, $numeric_base ); if ( $code_point >= 0x80 && $code_point <= 0x9F ) { $windows_1252_mapping = array( 0x20AC, 0x81, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F, 0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178, ); $code_point = $windows_1252_mapping[ $code_point - 0x80 ]; } $match_byte_length = $end_of_span - $at; return self::code_point_to_utf8_bytes( $code_point ); } $name_at = $at + 1; if ( $name_at + 2 > $length ) { return null; } $name_length = 0; $replacement = $html5_named_character_references->read_token( $text, $name_at, $name_length ); if ( false === $replacement ) { return null; } $after_name = $name_at + $name_length; if ( ';' === $text[ $name_at + $name_length - 1 ] ) { $match_byte_length = $after_name - $at; return $replacement; } $ambiguous_follower = ( $after_name < $length && $name_at < $length && ( ctype_alnum( $text[ $after_name ] ) || '=' === $text[ $after_name ] ) ); if ( ! $ambiguous_follower ) { $match_byte_length = $after_name - $at; return $replacement; } if ( 'attribute' === $context ) { return null; } $match_byte_length = $after_name - $at; return $replacement; } public static function code_point_to_utf8_bytes( $code_point ): string { if ( $code_point <= 0 || ( $code_point >= 0xD800 && $code_point <= 0xDFFF ) || $code_point > 0x10FFFF ) { return '�'; } if ( $code_point <= 0x7F ) { return chr( $code_point ); } if ( $code_point <= 0x7FF ) { $byte1 = chr( ( $code_point >> 6 ) | 0xC0 ); $byte2 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}"; } if ( $code_point <= 0xFFFF ) { $byte1 = chr( ( $code_point >> 12 ) | 0xE0 ); $byte2 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); $byte3 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}"; } $byte1 = chr( ( $code_point >> 18 ) | 0xF0 ); $byte2 = chr( ( $code_point >> 12 ) & 0x3F | 0x80 ); $byte3 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); $byte4 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}{$byte4}"; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-tag-processor.php';
class WP_HTML_Tag_Processor { const MAX_BOOKMARKS = 10; const MAX_SEEK_OPS = 1000; protected $html; private $last_query; private $sought_tag_name; private $sought_class_name; private $sought_match_offset; private $stop_on_tag_closers; protected $parser_state = self::STATE_READY; protected $compat_mode = self::NO_QUIRKS_MODE; private $parsing_namespace = 'html'; protected $comment_type = null; protected $text_node_classification = self::TEXT_IS_GENERIC; private $bytes_already_parsed = 0; private $token_starts_at; private $token_length; private $tag_name_starts_at; private $tag_name_length; private $text_starts_at; private $text_length; private $is_closing_tag; private $attributes = array(); private $duplicate_attributes = null; private $classname_updates = array(); protected $bookmarks = array(); const ADD_CLASS = true; const REMOVE_CLASS = false; const SKIP_CLASS = null; protected $lexical_updates = array(); protected $seek_count = 0; private $skip_newline_at = null; public function __construct( $html ) { if ( ! is_string( $html ) ) { _doing_it_wrong( __METHOD__, __( 'The HTML parameter must be a string.' ), '6.9.0' ); $html = ''; } $this->html = $html; } public function change_parsing_namespace( string $new_namespace ): bool { if ( ! in_array( $new_namespace, array( 'html', 'math', 'svg' ), true ) ) { return false; } $this->parsing_namespace = $new_namespace; return true; } public function next_tag( $query = null ): bool { $this->parse_query( $query ); $already_found = 0; do { if ( false === $this->next_token() ) { return false; } if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { continue; } if ( $this->matches() ) { ++$already_found; } } while ( $already_found < $this->sought_match_offset ); return true; } public function next_token(): bool { return $this->base_class_next_token(); } private function base_class_next_token(): bool { $was_at = $this->bytes_already_parsed; $this->after_tag(); if ( self::STATE_COMPLETE === $this->parser_state || self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { return false; } $this->parser_state = self::STATE_READY; if ( $this->bytes_already_parsed >= strlen( $this->html ) ) { $this->parser_state = self::STATE_COMPLETE; return false; } if ( false === $this->parse_next_tag() ) { if ( self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { $this->bytes_already_parsed = $was_at; } return false; } if ( self::STATE_INCOMPLETE_INPUT !== $this->parser_state && self::STATE_COMPLETE !== $this->parser_state && self::STATE_MATCHED_TAG !== $this->parser_state ) { return true; } while ( $this->parse_next_attribute() ) { continue; } if ( self::STATE_INCOMPLETE_INPUT === $this->parser_state || $this->bytes_already_parsed >= strlen( $this->html ) ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } $tag_ends_at = strpos( $this->html, '>', $this->bytes_already_parsed ); if ( false === $tag_ends_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } $this->parser_state = self::STATE_MATCHED_TAG; $this->bytes_already_parsed = $tag_ends_at + 1; $this->token_length = $this->bytes_already_parsed - $this->token_starts_at; if ( $this->is_closing_tag || 'html' !== $this->parsing_namespace || 1 !== strspn( $this->html, 'iIlLnNpPsStTxX', $this->tag_name_starts_at, 1 ) ) { return true; } $tag_name = $this->get_tag(); if ( 'LISTING' === $tag_name || 'PRE' === $tag_name ) { $this->skip_newline_at = $this->bytes_already_parsed; return true; } $tag_name_starts_at = $this->tag_name_starts_at; $tag_name_length = $this->tag_name_length; $tag_ends_at = $this->token_starts_at + $this->token_length; $attributes = $this->attributes; $duplicate_attributes = $this->duplicate_attributes; switch ( $tag_name ) { case 'SCRIPT': $found_closer = $this->skip_script_data(); break; case 'TEXTAREA': case 'TITLE': $found_closer = $this->skip_rcdata( $tag_name ); break; case 'IFRAME': case 'NOEMBED': case 'NOFRAMES': case 'STYLE': case 'XMP': $found_closer = $this->skip_rawtext( $tag_name ); break; default: return true; } if ( ! $found_closer ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } $this->token_starts_at = $was_at; $this->token_length = $this->bytes_already_parsed - $this->token_starts_at; $this->text_starts_at = $tag_ends_at; $this->text_length = $this->tag_name_starts_at - $this->text_starts_at; $this->tag_name_starts_at = $tag_name_starts_at; $this->tag_name_length = $tag_name_length; $this->attributes = $attributes; $this->duplicate_attributes = $duplicate_attributes; return true; } public function paused_at_incomplete_token(): bool { return self::STATE_INCOMPLETE_INPUT === $this->parser_state; } public function class_list() { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return; } $class = $this->get_attribute( 'class' ); if ( ! is_string( $class ) ) { return; } $seen = array(); $is_quirks = self::QUIRKS_MODE === $this->compat_mode; $at = 0; while ( $at < strlen( $class ) ) { $at += strspn( $class, " \t\f\r\n", $at ); if ( $at >= strlen( $class ) ) { return; } $length = strcspn( $class, " \t\f\r\n", $at ); if ( 0 === $length ) { return; } $name = str_replace( "\x00", "\u{FFFD}", substr( $class, $at, $length ) ); if ( $is_quirks ) { $name = strtolower( $name ); } $at += $length; if ( in_array( $name, $seen, true ) ) { continue; } $seen[] = $name; yield $name; } } public function has_class( $wanted_class ): ?bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $case_insensitive = self::QUIRKS_MODE === $this->compat_mode; $wanted_length = strlen( $wanted_class ); foreach ( $this->class_list() as $class_name ) { if ( strlen( $class_name ) === $wanted_length && 0 === substr_compare( $class_name, $wanted_class, 0, strlen( $wanted_class ), $case_insensitive ) ) { return true; } } return false; } public function set_bookmark( $name ): bool { if ( self::STATE_COMPLETE === $this->parser_state || self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { return false; } if ( ! array_key_exists( $name, $this->bookmarks ) && count( $this->bookmarks ) >= static::MAX_BOOKMARKS ) { _doing_it_wrong( __METHOD__, __( 'Too many bookmarks: cannot create any more.' ), '6.2.0' ); return false; } $this->bookmarks[ $name ] = new WP_HTML_Span( $this->token_starts_at, $this->token_length ); return true; } public function release_bookmark( $name ): bool { if ( ! array_key_exists( $name, $this->bookmarks ) ) { return false; } unset( $this->bookmarks[ $name ] ); return true; } private function skip_rawtext( string $tag_name ): bool { return $this->skip_rcdata( $tag_name ); } private function skip_rcdata( string $tag_name ): bool { $html = $this->html; $doc_length = strlen( $html ); $tag_length = strlen( $tag_name ); $at = $this->bytes_already_parsed; while ( false !== $at && $at < $doc_length ) { $at = strpos( $this->html, '</', $at ); $this->tag_name_starts_at = $at; if ( false === $at || ( $at + $tag_length ) >= $doc_length ) { return false; } $at += 2; for ( $i = 0; $i < $tag_length; $i++ ) { $tag_char = $tag_name[ $i ]; $html_char = $html[ $at + $i ]; if ( $html_char !== $tag_char && strtoupper( $html_char ) !== $tag_char ) { $at += $i; continue 2; } } $at += $tag_length; $this->bytes_already_parsed = $at; if ( $at >= strlen( $html ) ) { return false; } $c = $html[ $at ]; if ( ' ' !== $c && "\t" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) { continue; } while ( $this->parse_next_attribute() ) { continue; } $at = $this->bytes_already_parsed; if ( $at >= strlen( $this->html ) ) { return false; } if ( '>' === $html[ $at ] ) { $this->bytes_already_parsed = $at + 1; return true; } if ( $at + 1 >= strlen( $this->html ) ) { return false; } if ( '/' === $html[ $at ] && '>' === $html[ $at + 1 ] ) { $this->bytes_already_parsed = $at + 2; return true; } } return false; } private function skip_script_data(): bool { $state = 'unescaped'; $html = $this->html; $doc_length = strlen( $html ); $at = $this->bytes_already_parsed; while ( false !== $at && $at < $doc_length ) { $at += strcspn( $html, '-<', $at ); if ( $at + 8 >= $doc_length ) { return false; } if ( '-' === $html[ $at ] && '-' === $html[ $at + 1 ] && '>' === $html[ $at + 2 ] ) { $at += 3; $state = 'unescaped'; continue; } if ( '<' !== $html[ $at++ ] ) { continue; } if ( 'unescaped' === $state && '!' === $html[ $at ] && '-' === $html[ $at + 1 ] && '-' === $html[ $at + 2 ] ) { $at += 3; $at += strspn( $html, '-', $at ); if ( $at < $doc_length && '>' === $html[ $at ] ) { ++$at; continue; } $state = 'escaped'; continue; } if ( '/' === $html[ $at ] ) { $closer_potentially_starts_at = $at - 1; $is_closing = true; ++$at; } else { $is_closing = false; } if ( ! ( ( 's' === $html[ $at ] || 'S' === $html[ $at ] ) && ( 'c' === $html[ $at + 1 ] || 'C' === $html[ $at + 1 ] ) && ( 'r' === $html[ $at + 2 ] || 'R' === $html[ $at + 2 ] ) && ( 'i' === $html[ $at + 3 ] || 'I' === $html[ $at + 3 ] ) && ( 'p' === $html[ $at + 4 ] || 'P' === $html[ $at + 4 ] ) && ( 't' === $html[ $at + 5 ] || 'T' === $html[ $at + 5 ] ) ) ) { ++$at; continue; } $at += 6; $c = $html[ $at ]; if ( '>' !== $c && ' ' !== $c && "\n" !== $c && '/' !== $c && "\t" !== $c && "\f" !== $c && "\r" !== $c ) { continue; } if ( 'escaped' === $state && ! $is_closing ) { $state = 'double-escaped'; continue; } if ( 'double-escaped' === $state && $is_closing ) { $state = 'escaped'; continue; } if ( $is_closing ) { $this->bytes_already_parsed = $closer_potentially_starts_at; $this->tag_name_starts_at = $closer_potentially_starts_at; if ( $this->bytes_already_parsed >= $doc_length ) { return false; } while ( $this->parse_next_attribute() ) { continue; } if ( $this->bytes_already_parsed >= $doc_length ) { return false; } if ( '>' === $html[ $this->bytes_already_parsed ] ) { ++$this->bytes_already_parsed; return true; } } ++$at; } return false; } private function parse_next_tag(): bool { $this->after_tag(); $html = $this->html; $doc_length = strlen( $html ); $was_at = $this->bytes_already_parsed; $at = $was_at; while ( $at < $doc_length ) { $at = strpos( $html, '<', $at ); if ( false === $at ) { break; } if ( $at > $was_at ) { if ( 1 !== strspn( $html, '!/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1, 1 ) ) { ++$at; continue; } $this->parser_state = self::STATE_TEXT_NODE; $this->token_starts_at = $was_at; $this->token_length = $at - $was_at; $this->text_starts_at = $was_at; $this->text_length = $this->token_length; $this->bytes_already_parsed = $at; return true; } $this->token_starts_at = $at; if ( $at + 1 < $doc_length && '/' === $this->html[ $at + 1 ] ) { $this->is_closing_tag = true; ++$at; } else { $this->is_closing_tag = false; } $tag_name_prefix_length = strspn( $html, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1 ); if ( $tag_name_prefix_length > 0 ) { ++$at; $this->parser_state = self::STATE_MATCHED_TAG; $this->tag_name_starts_at = $at; $this->tag_name_length = $tag_name_prefix_length + strcspn( $html, " \t\f\r\n/>", $at + $tag_name_prefix_length ); $this->bytes_already_parsed = $at + $this->tag_name_length; return true; } if ( $at + 1 >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( ! $this->is_closing_tag && '!' === $html[ $at + 1 ] ) { if ( 0 === substr_compare( $html, '--', $at + 2, 2 ) ) { $closer_at = $at + 4; if ( $doc_length <= $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $span_of_dashes = strspn( $html, '-', $closer_at ); if ( '>' === $html[ $closer_at + $span_of_dashes ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT; $this->token_length = $closer_at + $span_of_dashes + 1 - $this->token_starts_at; if ( $span_of_dashes >= 2 ) { $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $span_of_dashes - 2; } $this->bytes_already_parsed = $closer_at + $span_of_dashes + 1; return true; } --$closer_at; while ( ++$closer_at < $doc_length ) { $closer_at = strpos( $html, '--', $closer_at ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( $closer_at + 2 < $doc_length && '>' === $html[ $closer_at + 2 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->token_length = $closer_at + 3 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 3; return true; } if ( $closer_at + 3 < $doc_length && '!' === $html[ $closer_at + 2 ] && '>' === $html[ $closer_at + 3 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->token_length = $closer_at + 4 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 4; return true; } } } if ( $doc_length > $at + 8 && ( 'D' === $html[ $at + 2 ] || 'd' === $html[ $at + 2 ] ) && ( 'O' === $html[ $at + 3 ] || 'o' === $html[ $at + 3 ] ) && ( 'C' === $html[ $at + 4 ] || 'c' === $html[ $at + 4 ] ) && ( 'T' === $html[ $at + 5 ] || 't' === $html[ $at + 5 ] ) && ( 'Y' === $html[ $at + 6 ] || 'y' === $html[ $at + 6 ] ) && ( 'P' === $html[ $at + 7 ] || 'p' === $html[ $at + 7 ] ) && ( 'E' === $html[ $at + 8 ] || 'e' === $html[ $at + 8 ] ) ) { $closer_at = strpos( $html, '>', $at + 9 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_DOCTYPE; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 9; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; return true; } if ( 'html' !== $this->parsing_namespace && strlen( $html ) > $at + 8 && '[' === $html[ $at + 2 ] && 'C' === $html[ $at + 3 ] && 'D' === $html[ $at + 4 ] && 'A' === $html[ $at + 5 ] && 'T' === $html[ $at + 6 ] && 'A' === $html[ $at + 7 ] && '[' === $html[ $at + 8 ] ) { $closer_at = strpos( $html, ']]>', $at + 9 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_CDATA_NODE; $this->text_starts_at = $at + 9; $this->text_length = $closer_at - $this->text_starts_at; $this->token_length = $closer_at + 3 - $this->token_starts_at; $this->bytes_already_parsed = $closer_at + 3; return true; } $closer_at = strpos( $html, '>', $at + 1 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_INVALID_HTML; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; if ( $this->token_length >= 10 && '[' === $html[ $this->token_starts_at + 2 ] && 'C' === $html[ $this->token_starts_at + 3 ] && 'D' === $html[ $this->token_starts_at + 4 ] && 'A' === $html[ $this->token_starts_at + 5 ] && 'T' === $html[ $this->token_starts_at + 6 ] && 'A' === $html[ $this->token_starts_at + 7 ] && '[' === $html[ $this->token_starts_at + 8 ] && ']' === $html[ $closer_at - 1 ] && ']' === $html[ $closer_at - 2 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_CDATA_LOOKALIKE; $this->text_starts_at += 7; $this->text_length -= 9; } return true; } if ( '>' === $html[ $at + 1 ] ) { if ( ! $this->is_closing_tag ) { ++$at; continue; } $this->parser_state = self::STATE_PRESUMPTUOUS_TAG; $this->token_length = $at + 2 - $this->token_starts_at; $this->bytes_already_parsed = $at + 2; return true; } if ( ! $this->is_closing_tag && '?' === $html[ $at + 1 ] ) { $closer_at = strpos( $html, '>', $at + 2 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_INVALID_HTML; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; if ( $this->token_length >= 5 && '?' === $html[ $closer_at - 1 ] ) { $comment_text = substr( $html, $this->token_starts_at + 2, $this->token_length - 4 ); $pi_target_length = strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_' ); if ( 0 < $pi_target_length ) { $pi_target_length += strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:_-.', $pi_target_length ); $this->comment_type = self::COMMENT_AS_PI_NODE_LOOKALIKE; $this->tag_name_starts_at = $this->token_starts_at + 2; $this->tag_name_length = $pi_target_length; $this->text_starts_at += $pi_target_length; $this->text_length -= $pi_target_length + 1; } } return true; } if ( $this->is_closing_tag ) { if ( $at + 3 > $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $closer_at = strpos( $html, '>', $at + 2 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_FUNKY_COMMENT; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; return true; } ++$at; } $this->parser_state = self::STATE_TEXT_NODE; $this->token_starts_at = $was_at; $this->token_length = $doc_length - $was_at; $this->text_starts_at = $was_at; $this->text_length = $this->token_length; $this->bytes_already_parsed = $doc_length; return true; } private function parse_next_attribute(): bool { $doc_length = strlen( $this->html ); $this->bytes_already_parsed += strspn( $this->html, " \t\f\r\n/", $this->bytes_already_parsed ); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $name_length = '=' === $this->html[ $this->bytes_already_parsed ] ? 1 + strcspn( $this->html, "=/> \t\f\r\n", $this->bytes_already_parsed + 1 ) : strcspn( $this->html, "=/> \t\f\r\n", $this->bytes_already_parsed ); if ( 0 === $name_length || $this->bytes_already_parsed + $name_length >= $doc_length ) { return false; } $attribute_start = $this->bytes_already_parsed; $attribute_name = substr( $this->html, $attribute_start, $name_length ); $this->bytes_already_parsed += $name_length; if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->skip_whitespace(); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $has_value = '=' === $this->html[ $this->bytes_already_parsed ]; if ( $has_value ) { ++$this->bytes_already_parsed; $this->skip_whitespace(); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } switch ( $this->html[ $this->bytes_already_parsed ] ) { case "'": case '"': $quote = $this->html[ $this->bytes_already_parsed ]; $value_start = $this->bytes_already_parsed + 1; $end_quote_at = strpos( $this->html, $quote, $value_start ); $end_quote_at = false === $end_quote_at ? $doc_length : $end_quote_at; $value_length = $end_quote_at - $value_start; $attribute_end = $end_quote_at + 1; $this->bytes_already_parsed = $attribute_end; break; default: $value_start = $this->bytes_already_parsed; $value_length = strcspn( $this->html, "> \t\f\r\n", $value_start ); $attribute_end = $value_start + $value_length; $this->bytes_already_parsed = $attribute_end; } } else { $value_start = $this->bytes_already_parsed; $value_length = 0; $attribute_end = $attribute_start + $name_length; } if ( $attribute_end >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( $this->is_closing_tag ) { return true; } $comparable_name = strtolower( $attribute_name ); if ( ! isset( $this->attributes[ $comparable_name ] ) ) { $this->attributes[ $comparable_name ] = new WP_HTML_Attribute_Token( $attribute_name, $value_start, $value_length, $attribute_start, $attribute_end - $attribute_start, ! $has_value ); return true; } $duplicate_span = new WP_HTML_Span( $attribute_start, $attribute_end - $attribute_start ); if ( null === $this->duplicate_attributes ) { $this->duplicate_attributes = array( $comparable_name => array( $duplicate_span ) ); } elseif ( ! isset( $this->duplicate_attributes[ $comparable_name ] ) ) { $this->duplicate_attributes[ $comparable_name ] = array( $duplicate_span ); } else { $this->duplicate_attributes[ $comparable_name ][] = $duplicate_span; } return true; } private function skip_whitespace(): void { $this->bytes_already_parsed += strspn( $this->html, " \t\f\r\n", $this->bytes_already_parsed ); } private function after_tag(): void { $this->class_name_updates_to_attributes_updates(); if ( 1000 < count( $this->lexical_updates ) ) { $this->get_updated_html(); } foreach ( $this->lexical_updates as $name => $update ) { if ( $update->start >= $this->bytes_already_parsed ) { $this->get_updated_html(); break; } if ( is_int( $name ) ) { continue; } $this->lexical_updates[] = $update; unset( $this->lexical_updates[ $name ] ); } $this->token_starts_at = null; $this->token_length = null; $this->tag_name_starts_at = null; $this->tag_name_length = null; $this->text_starts_at = 0; $this->text_length = 0; $this->is_closing_tag = null; $this->attributes = array(); $this->comment_type = null; $this->text_node_classification = self::TEXT_IS_GENERIC; $this->duplicate_attributes = null; } private function class_name_updates_to_attributes_updates(): void { if ( count( $this->classname_updates ) === 0 ) { return; } $existing_class = $this->get_enqueued_attribute_value( 'class' ); if ( null === $existing_class || true === $existing_class ) { $existing_class = ''; } if ( false === $existing_class && isset( $this->attributes['class'] ) ) { $existing_class = WP_HTML_Decoder::decode_attribute( substr( $this->html, $this->attributes['class']->value_starts_at, $this->attributes['class']->value_length ) ); } if ( false === $existing_class ) { $existing_class = ''; } $class = ''; $at = 0; $modified = false; $seen = array(); $to_remove = array(); $is_quirks = self::QUIRKS_MODE === $this->compat_mode; if ( $is_quirks ) { foreach ( $this->classname_updates as $updated_name => $action ) { if ( self::REMOVE_CLASS === $action ) { $to_remove[] = strtolower( $updated_name ); } } } else { foreach ( $this->classname_updates as $updated_name => $action ) { if ( self::REMOVE_CLASS === $action ) { $to_remove[] = $updated_name; } } } $existing_class_length = strlen( $existing_class ); while ( $at < $existing_class_length ) { $ws_at = $at; $ws_length = strspn( $existing_class, " \t\f\r\n", $ws_at ); $at += $ws_length; $name_length = strcspn( $existing_class, " \t\f\r\n", $at ); if ( 0 === $name_length ) { break; } $name = substr( $existing_class, $at, $name_length ); $comparable_class_name = $is_quirks ? strtolower( $name ) : $name; $at += $name_length; if ( in_array( $comparable_class_name, $to_remove, true ) ) { $modified = true; continue; } if ( in_array( $comparable_class_name, $seen, true ) ) { continue; } $seen[] = $comparable_class_name; if ( '' !== $class ) { $class .= substr( $existing_class, $ws_at, $ws_length ); } $class .= $name; } foreach ( $this->classname_updates as $name => $operation ) { $comparable_name = $is_quirks ? strtolower( $name ) : $name; if ( self::ADD_CLASS === $operation && ! in_array( $comparable_name, $seen, true ) ) { $modified = true; $class .= strlen( $class ) > 0 ? ' ' : ''; $class .= $name; } } $this->classname_updates = array(); if ( ! $modified ) { return; } if ( strlen( $class ) > 0 ) { $this->set_attribute( 'class', $class ); } else { $this->remove_attribute( 'class' ); } } private function apply_attributes_updates( int $shift_this_point ): int { if ( ! count( $this->lexical_updates ) ) { return 0; } $accumulated_shift_for_given_point = 0; usort( $this->lexical_updates, array( self::class, 'sort_start_ascending' ) ); $bytes_already_copied = 0; $output_buffer = ''; foreach ( $this->lexical_updates as $diff ) { $shift = strlen( $diff->text ) - $diff->length; if ( $diff->start < $this->bytes_already_parsed ) { $this->bytes_already_parsed += $shift; } if ( $diff->start < $shift_this_point ) { $accumulated_shift_for_given_point += $shift; } $output_buffer .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied ); $output_buffer .= $diff->text; $bytes_already_copied = $diff->start + $diff->length; } $this->html = $output_buffer . substr( $this->html, $bytes_already_copied ); foreach ( $this->bookmarks as $bookmark_name => $bookmark ) { $bookmark_end = $bookmark->start + $bookmark->length; $head_delta = 0; $tail_delta = 0; foreach ( $this->lexical_updates as $diff ) { $diff_end = $diff->start + $diff->length; if ( $bookmark->start < $diff->start && $bookmark_end < $diff->start ) { break; } if ( $bookmark->start >= $diff->start && $bookmark_end < $diff_end ) { $this->release_bookmark( $bookmark_name ); continue 2; } $delta = strlen( $diff->text ) - $diff->length; if ( $bookmark->start >= $diff->start ) { $head_delta += $delta; } if ( $bookmark_end >= $diff_end ) { $tail_delta += $delta; } } $bookmark->start += $head_delta; $bookmark->length += $tail_delta - $head_delta; } $this->lexical_updates = array(); return $accumulated_shift_for_given_point; } public function has_bookmark( $bookmark_name ): bool { return array_key_exists( $bookmark_name, $this->bookmarks ); } public function seek( $bookmark_name ): bool { if ( ! array_key_exists( $bookmark_name, $this->bookmarks ) ) { _doing_it_wrong( __METHOD__, __( 'Unknown bookmark name.' ), '6.2.0' ); return false; } $existing_bookmark = $this->bookmarks[ $bookmark_name ]; if ( $this->token_starts_at === $existing_bookmark->start && $this->token_length === $existing_bookmark->length ) { return true; } if ( ++$this->seek_count > static::MAX_SEEK_OPS ) { _doing_it_wrong( __METHOD__, __( 'Too many calls to seek() - this can lead to performance issues.' ), '6.2.0' ); return false; } $this->get_updated_html(); $this->bytes_already_parsed = $this->bookmarks[ $bookmark_name ]->start; $this->parser_state = self::STATE_READY; return $this->next_token(); } private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HTML_Text_Replacement $b ): int { $by_start = $a->start - $b->start; if ( 0 !== $by_start ) { return $by_start; } $by_text = isset( $a->text, $b->text ) ? strcmp( $a->text, $b->text ) : 0; if ( 0 !== $by_text ) { return $by_text; } return $a->length - $b->length; } private function get_enqueued_attribute_value( string $comparable_name ) { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return false; } if ( ! isset( $this->lexical_updates[ $comparable_name ] ) ) { return false; } $enqueued_text = $this->lexical_updates[ $comparable_name ]->text; if ( '' === $enqueued_text ) { return null; } $equals_at = strpos( $enqueued_text, '=' ); if ( false === $equals_at ) { return true; } $enqueued_value = substr( $enqueued_text, $equals_at + 2, -1 ); return WP_HTML_Decoder::decode_attribute( $enqueued_value ); } public function get_attribute( $name ) { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $comparable = strtolower( $name ); if ( 'class' === $name ) { $this->class_name_updates_to_attributes_updates(); } $enqueued_value = $this->get_enqueued_attribute_value( $comparable ); if ( false !== $enqueued_value ) { return $enqueued_value; } if ( ! isset( $this->attributes[ $comparable ] ) ) { return null; } $attribute = $this->attributes[ $comparable ]; if ( true === $attribute->is_true ) { return true; } $raw_value = substr( $this->html, $attribute->value_starts_at, $attribute->value_length ); return WP_HTML_Decoder::decode_attribute( $raw_value ); } public function get_attribute_names_with_prefix( $prefix ): ?array { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return null; } $comparable = strtolower( $prefix ); $matches = array(); foreach ( array_keys( $this->attributes ) as $attr_name ) { if ( str_starts_with( $attr_name, $comparable ) ) { $matches[] = $attr_name; } } return $matches; } public function get_namespace(): string { return $this->parsing_namespace; } public function get_tag(): ?string { if ( null === $this->tag_name_starts_at ) { return null; } $tag_name = substr( $this->html, $this->tag_name_starts_at, $this->tag_name_length ); if ( self::STATE_MATCHED_TAG === $this->parser_state ) { return strtoupper( $tag_name ); } if ( self::STATE_COMMENT === $this->parser_state && self::COMMENT_AS_PI_NODE_LOOKALIKE === $this->get_comment_type() ) { return $tag_name; } return null; } public function get_qualified_tag_name(): ?string { $tag_name = $this->get_tag(); if ( null === $tag_name ) { return null; } if ( 'html' === $this->get_namespace() ) { return $tag_name; } $lower_tag_name = strtolower( $tag_name ); if ( 'math' === $this->get_namespace() ) { return $lower_tag_name; } if ( 'svg' === $this->get_namespace() ) { switch ( $lower_tag_name ) { case 'altglyph': return 'altGlyph'; case 'altglyphdef': return 'altGlyphDef'; case 'altglyphitem': return 'altGlyphItem'; case 'animatecolor': return 'animateColor'; case 'animatemotion': return 'animateMotion'; case 'animatetransform': return 'animateTransform'; case 'clippath': return 'clipPath'; case 'feblend': return 'feBlend'; case 'fecolormatrix': return 'feColorMatrix'; case 'fecomponenttransfer': return 'feComponentTransfer'; case 'fecomposite': return 'feComposite'; case 'feconvolvematrix': return 'feConvolveMatrix'; case 'fediffuselighting': return 'feDiffuseLighting'; case 'fedisplacementmap': return 'feDisplacementMap'; case 'fedistantlight': return 'feDistantLight'; case 'fedropshadow': return 'feDropShadow'; case 'feflood': return 'feFlood'; case 'fefunca': return 'feFuncA'; case 'fefuncb': return 'feFuncB'; case 'fefuncg': return 'feFuncG'; case 'fefuncr': return 'feFuncR'; case 'fegaussianblur': return 'feGaussianBlur'; case 'feimage': return 'feImage'; case 'femerge': return 'feMerge'; case 'femergenode': return 'feMergeNode'; case 'femorphology': return 'feMorphology'; case 'feoffset': return 'feOffset'; case 'fepointlight': return 'fePointLight'; case 'fespecularlighting': return 'feSpecularLighting'; case 'fespotlight': return 'feSpotLight'; case 'fetile': return 'feTile'; case 'feturbulence': return 'feTurbulence'; case 'foreignobject': return 'foreignObject'; case 'glyphref': return 'glyphRef'; case 'lineargradient': return 'linearGradient'; case 'radialgradient': return 'radialGradient'; case 'textpath': return 'textPath'; default: return $lower_tag_name; } } return $tag_name; } public function get_qualified_attribute_name( $attribute_name ): ?string { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $namespace = $this->get_namespace(); $lower_name = strtolower( $attribute_name ); if ( 'math' === $namespace && 'definitionurl' === $lower_name ) { return 'definitionURL'; } if ( 'svg' === $this->get_namespace() ) { switch ( $lower_name ) { case 'attributename': return 'attributeName'; case 'attributetype': return 'attributeType'; case 'basefrequency': return 'baseFrequency'; case 'baseprofile': return 'baseProfile'; case 'calcmode': return 'calcMode'; case 'clippathunits': return 'clipPathUnits'; case 'diffuseconstant': return 'diffuseConstant'; case 'edgemode': return 'edgeMode'; case 'filterunits': return 'filterUnits'; case 'glyphref': return 'glyphRef'; case 'gradienttransform': return 'gradientTransform'; case 'gradientunits': return 'gradientUnits'; case 'kernelmatrix': return 'kernelMatrix'; case 'kernelunitlength': return 'kernelUnitLength'; case 'keypoints': return 'keyPoints'; case 'keysplines': return 'keySplines'; case 'keytimes': return 'keyTimes'; case 'lengthadjust': return 'lengthAdjust'; case 'limitingconeangle': return 'limitingConeAngle'; case 'markerheight': return 'markerHeight'; case 'markerunits': return 'markerUnits'; case 'markerwidth': return 'markerWidth'; case 'maskcontentunits': return 'maskContentUnits'; case 'maskunits': return 'maskUnits'; case 'numoctaves': return 'numOctaves'; case 'pathlength': return 'pathLength'; case 'patterncontentunits': return 'patternContentUnits'; case 'patterntransform': return 'patternTransform'; case 'patternunits': return 'patternUnits'; case 'pointsatx': return 'pointsAtX'; case 'pointsaty': return 'pointsAtY'; case 'pointsatz': return 'pointsAtZ'; case 'preservealpha': return 'preserveAlpha'; case 'preserveaspectratio': return 'preserveAspectRatio'; case 'primitiveunits': return 'primitiveUnits'; case 'refx': return 'refX'; case 'refy': return 'refY'; case 'repeatcount': return 'repeatCount'; case 'repeatdur': return 'repeatDur'; case 'requiredextensions': return 'requiredExtensions'; case 'requiredfeatures': return 'requiredFeatures'; case 'specularconstant': return 'specularConstant'; case 'specularexponent': return 'specularExponent'; case 'spreadmethod': return 'spreadMethod'; case 'startoffset': return 'startOffset'; case 'stddeviation': return 'stdDeviation'; case 'stitchtiles': return 'stitchTiles'; case 'surfacescale': return 'surfaceScale'; case 'systemlanguage': return 'systemLanguage'; case 'tablevalues': return 'tableValues'; case 'targetx': return 'targetX'; case 'targety': return 'targetY'; case 'textlength': return 'textLength'; case 'viewbox': return 'viewBox'; case 'viewtarget': return 'viewTarget'; case 'xchannelselector': return 'xChannelSelector'; case 'ychannelselector': return 'yChannelSelector'; case 'zoomandpan': return 'zoomAndPan'; } } if ( 'html' !== $namespace ) { switch ( $lower_name ) { case 'xlink:actuate': return 'xlink actuate'; case 'xlink:arcrole': return 'xlink arcrole'; case 'xlink:href': return 'xlink href'; case 'xlink:role': return 'xlink role'; case 'xlink:show': return 'xlink show'; case 'xlink:title': return 'xlink title'; case 'xlink:type': return 'xlink type'; case 'xml:lang': return 'xml lang'; case 'xml:space': return 'xml space'; case 'xmlns': return 'xmlns'; case 'xmlns:xlink': return 'xmlns xlink'; } } return $attribute_name; } public function has_self_closing_flag(): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return false; } return '/' === $this->html[ $this->token_starts_at + $this->token_length - 2 ]; } public function is_tag_closer(): bool { return ( self::STATE_MATCHED_TAG === $this->parser_state && $this->is_closing_tag && 'BR' !== $this->get_tag() ); } public function get_token_type(): ?string { switch ( $this->parser_state ) { case self::STATE_MATCHED_TAG: return '#tag'; case self::STATE_DOCTYPE: return '#doctype'; default: return $this->get_token_name(); } } public function get_token_name(): ?string { switch ( $this->parser_state ) { case self::STATE_MATCHED_TAG: return $this->get_tag(); case self::STATE_TEXT_NODE: return '#text'; case self::STATE_CDATA_NODE: return '#cdata-section'; case self::STATE_COMMENT: return '#comment'; case self::STATE_DOCTYPE: return 'html'; case self::STATE_PRESUMPTUOUS_TAG: return '#presumptuous-tag'; case self::STATE_FUNKY_COMMENT: return '#funky-comment'; } return null; } public function get_comment_type(): ?string { if ( self::STATE_COMMENT !== $this->parser_state ) { return null; } return $this->comment_type; } public function get_full_comment_text(): ?string { if ( self::STATE_FUNKY_COMMENT === $this->parser_state ) { return $this->get_modifiable_text(); } if ( self::STATE_COMMENT !== $this->parser_state ) { return null; } switch ( $this->get_comment_type() ) { case self::COMMENT_AS_HTML_COMMENT: case self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT: return $this->get_modifiable_text(); case self::COMMENT_AS_CDATA_LOOKALIKE: return "[CDATA[{$this->get_modifiable_text()}]]"; case self::COMMENT_AS_PI_NODE_LOOKALIKE: return "?{$this->get_tag()}{$this->get_modifiable_text()}?"; case self::COMMENT_AS_INVALID_HTML: $preceding_character = $this->html[ $this->text_starts_at - 1 ]; $comment_start = '?' === $preceding_character ? '?' : ''; return "{$comment_start}{$this->get_modifiable_text()}"; } return null; } public function subdivide_text_appropriately(): bool { if ( self::STATE_TEXT_NODE !== $this->parser_state ) { return false; } $this->text_node_classification = self::TEXT_IS_GENERIC; $leading_nulls = strspn( $this->html, "\x00", $this->text_starts_at, $this->text_length ); if ( $leading_nulls > 0 ) { $this->token_length = $leading_nulls; $this->text_length = $leading_nulls; $this->bytes_already_parsed = $this->token_starts_at + $leading_nulls; $this->text_node_classification = self::TEXT_IS_NULL_SEQUENCE; return true; } $at = $this->text_starts_at; $end = $this->text_starts_at + $this->text_length; while ( $at < $end ) { $skipped = strspn( $this->html, " \t\f\r\n", $at, $end - $at ); $at += $skipped; if ( $at < $end && '&' === $this->html[ $at ] ) { $matched_byte_length = null; $replacement = WP_HTML_Decoder::read_character_reference( 'data', $this->html, $at, $matched_byte_length ); if ( isset( $replacement ) && 1 === strspn( $replacement, " \t\f\r\n" ) ) { $at += $matched_byte_length; continue; } } break; } if ( $at > $this->text_starts_at ) { $new_length = $at - $this->text_starts_at; $this->text_length = $new_length; $this->token_length = $new_length; $this->bytes_already_parsed = $at; $this->text_node_classification = self::TEXT_IS_WHITESPACE; return true; } return false; } public function get_modifiable_text(): string { $has_enqueued_update = isset( $this->lexical_updates['modifiable text'] ); if ( ! $has_enqueued_update && ( null === $this->text_starts_at || 0 === $this->text_length ) ) { return ''; } $text = $has_enqueued_update ? $this->lexical_updates['modifiable text']->text : substr( $this->html, $this->text_starts_at, $this->text_length ); $text = str_replace( "\r\n", "\n", $text ); $text = str_replace( "\r", "\n", $text ); if ( self::STATE_CDATA_NODE === $this->parser_state || self::STATE_COMMENT === $this->parser_state || self::STATE_DOCTYPE === $this->parser_state || self::STATE_FUNKY_COMMENT === $this->parser_state ) { return str_replace( "\x00", "\u{FFFD}", $text ); } $tag_name = $this->get_token_name(); if ( 'SCRIPT' === $tag_name || 'IFRAME' === $tag_name || 'NOEMBED' === $tag_name || 'NOFRAMES' === $tag_name || 'STYLE' === $tag_name || 'XMP' === $tag_name ) { return str_replace( "\x00", "\u{FFFD}", $text ); } $decoded = WP_HTML_Decoder::decode_text_node( $text ); if ( ( "\n" === ( $decoded[0] ?? '' ) ) && ( ( $this->skip_newline_at === $this->token_starts_at && '#text' === $tag_name ) || 'TEXTAREA' === $tag_name ) ) { $decoded = substr( $decoded, 1 ); } return ( '#text' === $tag_name && 'html' === $this->get_namespace() ) ? str_replace( "\x00", '', $decoded ) : str_replace( "\x00", "\u{FFFD}", $decoded ); } public function set_modifiable_text( string $plaintext_content ): bool { if ( self::STATE_TEXT_NODE === $this->parser_state ) { $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, strtr( $plaintext_content, array( '<' => '<', '>' => '>', '&' => '&', '"' => '"', "'" => ''', ) ) ); return true; } if ( self::STATE_COMMENT === $this->parser_state && self::COMMENT_AS_HTML_COMMENT === $this->comment_type ) { if ( 1 === preg_match( '/--!?>/', $plaintext_content ) ) { return false; } $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; } if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return false; } switch ( $this->get_tag() ) { case 'SCRIPT': if ( false !== stripos( $plaintext_content, '</script' ) || false !== stripos( $plaintext_content, '<script' ) ) { return false; } $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; case 'STYLE': $plaintext_content = preg_replace_callback( '~</(?P<TAG_NAME>style)~i', static function ( $tag_match ) { return "\\3c\\2f{$tag_match['TAG_NAME']}"; }, $plaintext_content ); $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; case 'TEXTAREA': case 'TITLE': $plaintext_content = preg_replace_callback( "~</(?P<TAG_NAME>{$this->get_tag()})~i", static function ( $tag_match ) { return "</{$tag_match['TAG_NAME']}"; }, $plaintext_content ); $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; } return false; } public function set_attribute( $name, $value ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } $name_length = strlen( $name ); if ( 0 === $name_length || strcspn( $name, '"\'>&</ =' ) !== $name_length || strcspn( $name, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" ) !== $name_length || wp_has_noncharacters( $name ) ) { _doing_it_wrong( __METHOD__, __( 'Invalid attribute name.' ), '6.2.0' ); return false; } if ( false === $value ) { return $this->remove_attribute( $name ); } if ( true === $value ) { $updated_attribute = $name; } else { $comparable_name = strtolower( $name ); $escaped_new_value = in_array( $comparable_name, wp_kses_uri_attributes(), true ) ? esc_url( $value ) : strtr( $value, array( '<' => '<', '>' => '>', '&' => '&', '"' => '"', "'" => ''', ) ); if ( '' === $escaped_new_value && '' !== $value ) { return false; } $updated_attribute = "{$name}=\"{$escaped_new_value}\""; } $comparable_name = strtolower( $name ); if ( isset( $this->attributes[ $comparable_name ] ) ) { $existing_attribute = $this->attributes[ $comparable_name ]; $this->lexical_updates[ $comparable_name ] = new WP_HTML_Text_Replacement( $existing_attribute->start, $existing_attribute->length, $updated_attribute ); } else { $this->lexical_updates[ $comparable_name ] = new WP_HTML_Text_Replacement( $this->tag_name_starts_at + $this->tag_name_length, 0, ' ' . $updated_attribute ); } if ( 'class' === $comparable_name && ! empty( $this->classname_updates ) ) { $this->classname_updates = array(); } return true; } public function remove_attribute( $name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } $name = strtolower( $name ); if ( 'class' === $name && count( $this->classname_updates ) !== 0 ) { $this->classname_updates = array(); } if ( ! isset( $this->attributes[ $name ] ) ) { if ( isset( $this->lexical_updates[ $name ] ) ) { unset( $this->lexical_updates[ $name ] ); } return false; } $this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement( $this->attributes[ $name ]->start, $this->attributes[ $name ]->length, '' ); foreach ( $this->duplicate_attributes[ $name ] ?? array() as $attribute_token ) { $this->lexical_updates[] = new WP_HTML_Text_Replacement( $attribute_token->start, $attribute_token->length, '' ); } return true; } public function add_class( $class_name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } if ( self::QUIRKS_MODE !== $this->compat_mode ) { $this->classname_updates[ $class_name ] = self::ADD_CLASS; return true; } $class_name_length = strlen( $class_name ); foreach ( $this->classname_updates as $updated_name => $action ) { if ( strlen( $updated_name ) === $class_name_length && 0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true ) ) { $this->classname_updates[ $updated_name ] = self::ADD_CLASS; return true; } } $this->classname_updates[ $class_name ] = self::ADD_CLASS; return true; } public function remove_class( $class_name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } if ( self::QUIRKS_MODE !== $this->compat_mode ) { $this->classname_updates[ $class_name ] = self::REMOVE_CLASS; return true; } $class_name_length = strlen( $class_name ); foreach ( $this->classname_updates as $updated_name => $action ) { if ( strlen( $updated_name ) === $class_name_length && 0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true ) ) { $this->classname_updates[ $updated_name ] = self::REMOVE_CLASS; return true; } } $this->classname_updates[ $class_name ] = self::REMOVE_CLASS; return true; } public function __toString(): string { return $this->get_updated_html(); } public function get_updated_html(): string { $requires_no_updating = 0 === count( $this->classname_updates ) && 0 === count( $this->lexical_updates ); if ( $requires_no_updating ) { return $this->html; } $before_current_tag = $this->token_starts_at ?? 0; $this->class_name_updates_to_attributes_updates(); $before_current_tag += $this->apply_attributes_updates( $before_current_tag ); $this->bytes_already_parsed = $before_current_tag; $this->base_class_next_token(); return $this->html; } private function parse_query( $query ) { if ( null !== $query && $query === $this->last_query ) { return; } $this->last_query = $query; $this->sought_tag_name = null; $this->sought_class_name = null; $this->sought_match_offset = 1; $this->stop_on_tag_closers = false; if ( is_string( $query ) ) { $this->sought_tag_name = $query; return; } if ( null === $query ) { return; } if ( ! is_array( $query ) ) { _doing_it_wrong( __METHOD__, __( 'The query argument must be an array or a tag name.' ), '6.2.0' ); return; } if ( isset( $query['tag_name'] ) && is_string( $query['tag_name'] ) ) { $this->sought_tag_name = $query['tag_name']; } if ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) ) { $this->sought_class_name = $query['class_name']; } if ( isset( $query['match_offset'] ) && is_int( $query['match_offset'] ) && 0 < $query['match_offset'] ) { $this->sought_match_offset = $query['match_offset']; } if ( isset( $query['tag_closers'] ) ) { $this->stop_on_tag_closers = 'visit' === $query['tag_closers']; } } private function matches(): bool { if ( $this->is_closing_tag && ! $this->stop_on_tag_closers ) { return false; } if ( isset( $this->sought_tag_name ) && ( strlen( $this->sought_tag_name ) !== $this->tag_name_length || 0 !== substr_compare( $this->html, $this->sought_tag_name, $this->tag_name_starts_at, $this->tag_name_length, true ) ) ) { return false; } if ( null !== $this->sought_class_name && ! $this->has_class( $this->sought_class_name ) ) { return false; } return true; } public function get_doctype_info(): ?WP_HTML_Doctype_Info { if ( self::STATE_DOCTYPE !== $this->parser_state ) { return null; } return WP_HTML_Doctype_Info::from_doctype_token( substr( $this->html, $this->token_starts_at, $this->token_length ) ); } const STATE_READY = 'STATE_READY'; const STATE_COMPLETE = 'STATE_COMPLETE'; const STATE_INCOMPLETE_INPUT = 'STATE_INCOMPLETE_INPUT'; const STATE_MATCHED_TAG = 'STATE_MATCHED_TAG'; const STATE_TEXT_NODE = 'STATE_TEXT_NODE'; const STATE_CDATA_NODE = 'STATE_CDATA_NODE'; const STATE_COMMENT = 'STATE_COMMENT'; const STATE_DOCTYPE = 'STATE_DOCTYPE'; const STATE_PRESUMPTUOUS_TAG = 'STATE_PRESUMPTUOUS_TAG'; const STATE_FUNKY_COMMENT = 'STATE_WP_FUNKY'; const COMMENT_AS_ABRUPTLY_CLOSED_COMMENT = 'COMMENT_AS_ABRUPTLY_CLOSED_COMMENT'; const COMMENT_AS_CDATA_LOOKALIKE = 'COMMENT_AS_CDATA_LOOKALIKE'; const COMMENT_AS_HTML_COMMENT = 'COMMENT_AS_HTML_COMMENT'; const COMMENT_AS_PI_NODE_LOOKALIKE = 'COMMENT_AS_PI_NODE_LOOKALIKE'; const COMMENT_AS_INVALID_HTML = 'COMMENT_AS_INVALID_HTML'; const NO_QUIRKS_MODE = 'no-quirks-mode'; const QUIRKS_MODE = 'quirks-mode'; const TEXT_IS_GENERIC = 'TEXT_IS_GENERIC'; const TEXT_IS_NULL_SEQUENCE = 'TEXT_IS_NULL_SEQUENCE'; const TEXT_IS_WHITESPACE = 'TEXT_IS_WHITESPACE'; public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-unsupported-exception.php';
class WP_HTML_Unsupported_Exception extends Exception { public $token_name; public $token_at; public $token; public $stack_of_open_elements = array(); public $active_formatting_elements = array(); public function __construct( string $message, string $token_name, int $token_at, string $token, array $stack_of_open_elements, array $active_formatting_elements ) { parent::__construct( $message ); $this->token_name = $token_name; $this->token_at = $token_at; $this->token = $token; $this->stack_of_open_elements = $stack_of_open_elements; $this->active_formatting_elements = $active_formatting_elements; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-active-formatting-elements.php';
class WP_HTML_Active_Formatting_Elements { private $stack = array(); public function contains_node( WP_HTML_Token $token ) { foreach ( $this->walk_up() as $item ) { if ( $token->bookmark_name === $item->bookmark_name ) { return true; } } return false; } public function count() { return count( $this->stack ); } public function current_node() { $current_node = end( $this->stack ); return $current_node ? $current_node : null; } public function insert_marker(): void { $this->push( new WP_HTML_Token( null, 'marker', false ) ); } public function push( WP_HTML_Token $token ) { $this->stack[] = $token; } public function remove_node( WP_HTML_Token $token ) { foreach ( $this->walk_up() as $position_from_end => $item ) { if ( $token->bookmark_name !== $item->bookmark_name ) { continue; } $position_from_start = $this->count() - $position_from_end - 1; array_splice( $this->stack, $position_from_start, 1 ); return true; } return false; } public function walk_down() { $count = count( $this->stack ); for ( $i = 0; $i < $count; $i++ ) { yield $this->stack[ $i ]; } } public function walk_up() { for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { yield $this->stack[ $i ]; } } public function clear_up_to_last_marker(): void { foreach ( $this->walk_up() as $item ) { array_pop( $this->stack ); if ( 'marker' === $item->node_name ) { break; } } } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-open-elements.php';
class WP_HTML_Open_Elements { public $stack = array(); private $has_p_in_button_scope = false; private $pop_handler = null; private $push_handler = null; public function set_pop_handler( Closure $handler ): void { $this->pop_handler = $handler; } public function set_push_handler( Closure $handler ): void { $this->push_handler = $handler; } public function at( int $nth ): ?WP_HTML_Token { foreach ( $this->walk_down() as $item ) { if ( 0 === --$nth ) { return $item; } } return null; } public function contains( string $node_name ): bool { foreach ( $this->walk_up() as $item ) { if ( $node_name === $item->node_name ) { return true; } } return false; } public function contains_node( WP_HTML_Token $token ): bool { foreach ( $this->walk_up() as $item ) { if ( $token === $item ) { return true; } } return false; } public function count(): int { return count( $this->stack ); } public function current_node(): ?WP_HTML_Token { $current_node = end( $this->stack ); return $current_node ? $current_node : null; } public function current_node_is( string $identity ): bool { $current_node = end( $this->stack ); if ( false === $current_node ) { return false; } $current_node_name = $current_node->node_name; return ( $current_node_name === $identity || ( '#doctype' === $identity && 'html' === $current_node_name ) || ( '#tag' === $identity && ctype_upper( $current_node_name ) ) ); } public function has_element_in_specific_scope( string $tag_name, $termination_list ): bool { foreach ( $this->walk_up() as $node ) { $namespaced_name = 'html' === $node->namespace ? $node->node_name : "{$node->namespace} {$node->node_name}"; if ( $namespaced_name === $tag_name ) { return true; } if ( '(internal: H1 through H6 - do not use)' === $tag_name && in_array( $namespaced_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { return true; } if ( in_array( $namespaced_name, $termination_list, true ) ) { return false; } } return false; } public function has_element_in_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'TEMPLATE', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } public function has_element_in_list_item_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'BUTTON', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'OL', 'TEMPLATE', 'UL', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } public function has_element_in_button_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'BUTTON', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'TEMPLATE', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } public function has_element_in_table_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'HTML', 'TABLE', 'TEMPLATE', ) ); } public function has_element_in_select_scope( string $tag_name ): bool { foreach ( $this->walk_up() as $node ) { if ( $node->node_name === $tag_name ) { return true; } if ( 'OPTION' !== $node->node_name && 'OPTGROUP' !== $node->node_name ) { return false; } } return false; } public function has_p_in_button_scope(): bool { return $this->has_p_in_button_scope; } public function pop(): bool { $item = array_pop( $this->stack ); if ( null === $item ) { return false; } $this->after_element_pop( $item ); return true; } public function pop_until( string $html_tag_name ): bool { foreach ( $this->walk_up() as $item ) { $this->pop(); if ( 'html' !== $item->namespace ) { continue; } if ( '(internal: H1 through H6 - do not use)' === $html_tag_name && in_array( $item->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { return true; } if ( $html_tag_name === $item->node_name ) { return true; } } return false; } public function push( WP_HTML_Token $stack_item ): void { $this->stack[] = $stack_item; $this->after_element_push( $stack_item ); } public function remove_node( WP_HTML_Token $token ): bool { foreach ( $this->walk_up() as $position_from_end => $item ) { if ( $token->bookmark_name !== $item->bookmark_name ) { continue; } $position_from_start = $this->count() - $position_from_end - 1; array_splice( $this->stack, $position_from_start, 1 ); $this->after_element_pop( $item ); return true; } return false; } public function walk_down() { $count = count( $this->stack ); for ( $i = 0; $i < $count; $i++ ) { yield $this->stack[ $i ]; } } public function walk_up( ?WP_HTML_Token $above_this_node = null ) { $has_found_node = null === $above_this_node; for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { $node = $this->stack[ $i ]; if ( ! $has_found_node ) { $has_found_node = $node === $above_this_node; continue; } yield $node; } } public function after_element_push( WP_HTML_Token $item ): void { $namespaced_name = 'html' === $item->namespace ? $item->node_name : "{$item->namespace} {$item->node_name}"; switch ( $namespaced_name ) { case 'APPLET': case 'BUTTON': case 'CAPTION': case 'HTML': case 'TABLE': case 'TD': case 'TH': case 'MARQUEE': case 'OBJECT': case 'TEMPLATE': case 'math MI': case 'math MO': case 'math MN': case 'math MS': case 'math MTEXT': case 'math ANNOTATION-XML': case 'svg FOREIGNOBJECT': case 'svg DESC': case 'svg TITLE': $this->has_p_in_button_scope = false; break; case 'P': $this->has_p_in_button_scope = true; break; } if ( null !== $this->push_handler ) { ( $this->push_handler )( $item ); } } public function after_element_pop( WP_HTML_Token $item ): void { switch ( $item->node_name ) { case 'APPLET': case 'BUTTON': case 'CAPTION': case 'HTML': case 'P': case 'TABLE': case 'TD': case 'TH': case 'MARQUEE': case 'OBJECT': case 'TEMPLATE': case 'math MI': case 'math MO': case 'math MN': case 'math MS': case 'math MTEXT': case 'math ANNOTATION-XML': case 'svg FOREIGNOBJECT': case 'svg DESC': case 'svg TITLE': $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); break; } if ( null !== $this->pop_handler ) { ( $this->pop_handler )( $item ); } } public function clear_to_table_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TABLE' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } public function clear_to_table_body_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TBODY' === $item->node_name || 'TFOOT' === $item->node_name || 'THEAD' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } public function clear_to_table_row_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TR' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-token.php';
class WP_HTML_Token { public $bookmark_name = null; public $node_name = null; public $has_self_closing_flag = false; public $namespace = 'html'; public $integration_node_type = null; public $on_destroy = null; public function __construct( ?string $bookmark_name, string $node_name, bool $has_self_closing_flag, ?callable $on_destroy = null ) { $this->bookmark_name = $bookmark_name; $this->namespace = 'html'; $this->node_name = $node_name; $this->has_self_closing_flag = $has_self_closing_flag; $this->on_destroy = $on_destroy; } public function __destruct() { if ( is_callable( $this->on_destroy ) ) { call_user_func( $this->on_destroy, $this->bookmark_name ); } } public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-stack-event.php';
class WP_HTML_Stack_Event { const POP = 'pop'; const PUSH = 'push'; public $token; public $operation; public $provenance; public function __construct( WP_HTML_Token $token, string $operation, string $provenance ) { $this->token = $token; $this->operation = $operation; $this->provenance = $provenance; } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php';
class WP_HTML_Processor_State { const INSERTION_MODE_INITIAL = 'insertion-mode-initial'; const INSERTION_MODE_BEFORE_HTML = 'insertion-mode-before-html'; const INSERTION_MODE_BEFORE_HEAD = 'insertion-mode-before-head'; const INSERTION_MODE_IN_HEAD = 'insertion-mode-in-head'; const INSERTION_MODE_IN_HEAD_NOSCRIPT = 'insertion-mode-in-head-noscript'; const INSERTION_MODE_AFTER_HEAD = 'insertion-mode-after-head'; const INSERTION_MODE_IN_BODY = 'insertion-mode-in-body'; const INSERTION_MODE_IN_TABLE = 'insertion-mode-in-table'; const INSERTION_MODE_IN_TABLE_TEXT = 'insertion-mode-in-table-text'; const INSERTION_MODE_IN_CAPTION = 'insertion-mode-in-caption'; const INSERTION_MODE_IN_COLUMN_GROUP = 'insertion-mode-in-column-group'; const INSERTION_MODE_IN_TABLE_BODY = 'insertion-mode-in-table-body'; const INSERTION_MODE_IN_ROW = 'insertion-mode-in-row'; const INSERTION_MODE_IN_CELL = 'insertion-mode-in-cell'; const INSERTION_MODE_IN_SELECT = 'insertion-mode-in-select'; const INSERTION_MODE_IN_SELECT_IN_TABLE = 'insertion-mode-in-select-in-table'; const INSERTION_MODE_IN_TEMPLATE = 'insertion-mode-in-template'; const INSERTION_MODE_AFTER_BODY = 'insertion-mode-after-body'; const INSERTION_MODE_IN_FRAMESET = 'insertion-mode-in-frameset'; const INSERTION_MODE_AFTER_FRAMESET = 'insertion-mode-after-frameset'; const INSERTION_MODE_AFTER_AFTER_BODY = 'insertion-mode-after-after-body'; const INSERTION_MODE_AFTER_AFTER_FRAMESET = 'insertion-mode-after-after-frameset'; public $stack_of_template_insertion_modes = array(); public $stack_of_open_elements; public $active_formatting_elements; public $current_token = null; public $insertion_mode = self::INSERTION_MODE_INITIAL; public $context_node = null; public $encoding = null; public $encoding_confidence = 'tentative'; public $head_element = null; public $form_element = null; public $frameset_ok = true; public function __construct() { $this->stack_of_open_elements = new WP_HTML_Open_Elements(); $this->active_formatting_elements = new WP_HTML_Active_Formatting_Elements(); } }
###require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php';
class WP_HTML_Processor extends WP_HTML_Tag_Processor { const MAX_BOOKMARKS = 100; private $state; private $bookmark_counter = 0; private $last_error = null; private $unsupported_exception = null; private $release_internal_bookmark_on_destruct = null; private $element_queue = array(); private $breadcrumbs = array(); private $current_element = null; private $context_node = null; public static function create_fragment( $html, $context = '<body>', $encoding = 'UTF-8' ) { if ( '<body>' !== $context || 'UTF-8' !== $encoding ) { return null; } if ( ! is_string( $html ) ) { _doing_it_wrong( __METHOD__, __( 'The HTML parameter must be a string.' ), '6.9.0' ); return null; } $context_processor = static::create_full_parser( "<!DOCTYPE html>{$context}", $encoding ); if ( null === $context_processor ) { return null; } while ( $context_processor->next_tag() ) { if ( ! $context_processor->is_virtual() ) { $context_processor->set_bookmark( 'final_node' ); } } if ( ! $context_processor->has_bookmark( 'final_node' ) || ! $context_processor->seek( 'final_node' ) ) { _doing_it_wrong( __METHOD__, __( 'No valid context element was detected.' ), '6.8.0' ); return null; } return $context_processor->create_fragment_at_current_node( $html ); } public static function create_full_parser( $html, $known_definite_encoding = 'UTF-8' ) { if ( 'UTF-8' !== $known_definite_encoding ) { return null; } if ( ! is_string( $html ) ) { _doing_it_wrong( __METHOD__, __( 'The HTML parameter must be a string.' ), '6.9.0' ); return null; } $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); $processor->state->encoding = $known_definite_encoding; $processor->state->encoding_confidence = 'certain'; return $processor; } public function __construct( $html, $use_the_static_create_methods_instead = null ) { parent::__construct( $html ); if ( self::CONSTRUCTOR_UNLOCK_CODE !== $use_the_static_create_methods_instead ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Call %s to create an HTML Processor instead of calling the constructor directly.' ), '<code>WP_HTML_Processor::create_fragment()</code>' ), '6.4.0' ); } $this->state = new WP_HTML_Processor_State(); $this->state->stack_of_open_elements->set_push_handler( function ( WP_HTML_Token $token ): void { $is_virtual = ! isset( $this->state->current_token ) || $this->is_tag_closer(); $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::PUSH, $provenance ); $this->change_parsing_namespace( $token->integration_node_type ? 'html' : $token->namespace ); } ); $this->state->stack_of_open_elements->set_pop_handler( function ( WP_HTML_Token $token ): void { $is_virtual = ! isset( $this->state->current_token ) || ! $this->is_tag_closer(); $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::POP, $provenance ); $adjusted_current_node = $this->get_adjusted_current_node(); if ( $adjusted_current_node ) { $this->change_parsing_namespace( $adjusted_current_node->integration_node_type ? 'html' : $adjusted_current_node->namespace ); } else { $this->change_parsing_namespace( 'html' ); } } ); $this->release_internal_bookmark_on_destruct = function ( string $name ): void { parent::release_bookmark( $name ); }; } private function create_fragment_at_current_node( string $html ) { if ( $this->get_token_type() !== '#tag' || $this->is_tag_closer() ) { _doing_it_wrong( __METHOD__, __( 'The context element must be a start tag.' ), '6.8.0' ); return null; } $tag_name = $this->current_element->token->node_name; $namespace = $this->current_element->token->namespace; if ( 'html' === $namespace && self::is_void( $tag_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The context element cannot be a void element, found "%s".' ), $tag_name ), '6.8.0' ); return null; } if ( 'html' === $namespace && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP', 'PLAINTEXT' ), true ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The context element "%s" is not supported.' ), $tag_name ), '6.8.0' ); return null; } $fragment_processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); $fragment_processor->compat_mode = $this->compat_mode; $fragment_processor->bookmarks['root-node'] = new WP_HTML_Span( 0, 0 ); $root_node = new WP_HTML_Token( 'root-node', 'HTML', false ); $fragment_processor->state->stack_of_open_elements->push( $root_node ); $fragment_processor->bookmarks['context-node'] = new WP_HTML_Span( 0, 0 ); $fragment_processor->context_node = clone $this->current_element->token; $fragment_processor->context_node->bookmark_name = 'context-node'; $fragment_processor->context_node->on_destroy = null; $fragment_processor->breadcrumbs = array( 'HTML', $fragment_processor->context_node->node_name ); if ( 'TEMPLATE' === $fragment_processor->context_node->node_name ) { $fragment_processor->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; } $fragment_processor->reset_insertion_mode_appropriately(); foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) { if ( 'FORM' === $element->node_name && 'html' === $element->namespace ) { $fragment_processor->state->form_element = clone $element; $fragment_processor->state->form_element->bookmark_name = null; $fragment_processor->state->form_element->on_destroy = null; break; } } $fragment_processor->state->encoding_confidence = 'irrelevant'; $fragment_processor->change_parsing_namespace( $this->current_element->token->integration_node_type ? 'html' : $namespace ); return $fragment_processor; } private function bail( string $message ) { $here = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $token = substr( $this->html, $here->start, $here->length ); $open_elements = array(); foreach ( $this->state->stack_of_open_elements->stack as $item ) { $open_elements[] = $item->node_name; } $active_formats = array(); foreach ( $this->state->active_formatting_elements->walk_down() as $item ) { $active_formats[] = $item->node_name; } $this->last_error = self::ERROR_UNSUPPORTED; $this->unsupported_exception = new WP_HTML_Unsupported_Exception( $message, $this->state->current_token->node_name, $here->start, $token, $open_elements, $active_formats ); throw $this->unsupported_exception; } public function get_last_error(): ?string { return $this->last_error; } public function get_unsupported_exception() { return $this->unsupported_exception; } public function next_tag( $query = null ): bool { $visit_closers = isset( $query['tag_closers'] ) && 'visit' === $query['tag_closers']; if ( null === $query ) { while ( $this->next_token() ) { if ( '#tag' !== $this->get_token_type() ) { continue; } if ( ! $this->is_tag_closer() || $visit_closers ) { return true; } } return false; } if ( is_string( $query ) ) { $query = array( 'breadcrumbs' => array( $query ) ); } if ( ! is_array( $query ) ) { _doing_it_wrong( __METHOD__, __( 'Please pass a query array to this function.' ), '6.4.0' ); return false; } if ( isset( $query['tag_name'] ) ) { $query['tag_name'] = strtoupper( $query['tag_name'] ); } $needs_class = ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) ) ? $query['class_name'] : null; if ( ! ( array_key_exists( 'breadcrumbs', $query ) && is_array( $query['breadcrumbs'] ) ) ) { while ( $this->next_token() ) { if ( '#tag' !== $this->get_token_type() ) { continue; } if ( isset( $query['tag_name'] ) && $query['tag_name'] !== $this->get_token_name() ) { continue; } if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) { continue; } if ( ! $this->is_tag_closer() || $visit_closers ) { return true; } } return false; } $breadcrumbs = $query['breadcrumbs']; $match_offset = isset( $query['match_offset'] ) ? (int) $query['match_offset'] : 1; while ( $match_offset > 0 && $this->next_token() ) { if ( '#tag' !== $this->get_token_type() || $this->is_tag_closer() ) { continue; } if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) { continue; } if ( $this->matches_breadcrumbs( $breadcrumbs ) && 0 === --$match_offset ) { return true; } } return false; } public function next_token(): bool { return $this->next_visitable_token(); } private function next_visitable_token(): bool { $this->current_element = null; if ( isset( $this->last_error ) ) { return false; } if ( empty( $this->element_queue ) && $this->step() ) { return $this->next_visitable_token(); } $this->current_element = array_shift( $this->element_queue ); if ( ! isset( $this->current_element ) ) { while ( $this->state->stack_of_open_elements->pop() ) { continue; } return empty( $this->element_queue ) ? false : $this->next_visitable_token(); } $is_pop = WP_HTML_Stack_Event::POP === $this->current_element->operation; if ( 'root-node' === $this->current_element->token->bookmark_name ) { return $this->next_visitable_token(); } if ( $is_pop ) { array_pop( $this->breadcrumbs ); } else { $this->breadcrumbs[] = $this->current_element->token->node_name; } if ( $is_pop && ! $this->expects_closer( $this->current_element->token ) ) { return $this->next_visitable_token(); } return true; } public function is_tag_closer(): bool { return $this->is_virtual() ? ( WP_HTML_Stack_Event::POP === $this->current_element->operation && '#tag' === $this->get_token_type() ) : parent::is_tag_closer(); } private function is_virtual(): bool { return ( isset( $this->current_element->provenance ) && 'virtual' === $this->current_element->provenance ); } public function matches_breadcrumbs( $breadcrumbs ): bool { if ( 0 === count( $breadcrumbs ) ) { return true; } $crumb = end( $breadcrumbs ); if ( '*' !== $crumb && $this->get_tag() !== strtoupper( $crumb ) ) { return false; } for ( $i = count( $this->breadcrumbs ) - 1; $i >= 0; $i-- ) { $node = $this->breadcrumbs[ $i ]; $crumb = strtoupper( current( $breadcrumbs ) ); if ( '*' !== $crumb && $node !== $crumb ) { return false; } if ( false === prev( $breadcrumbs ) ) { return true; } } return false; } public function expects_closer( ?WP_HTML_Token $node = null ): ?bool { $token_name = $node->node_name ?? $this->get_token_name(); if ( ! isset( $token_name ) ) { return null; } $token_namespace = $node->namespace ?? $this->get_namespace(); $token_has_self_closing = $node->has_self_closing_flag ?? $this->has_self_closing_flag(); return ! ( '#' === $token_name[0] || 'html' === $token_name || ( 'html' === $token_namespace && self::is_void( $token_name ) ) || ( 'html' === $token_namespace && in_array( $token_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) || ( 'html' !== $token_namespace && $token_has_self_closing ) ); } public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool { if ( null !== $this->last_error ) { return false; } if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) { $top_node = $this->state->stack_of_open_elements->current_node(); if ( isset( $top_node ) && ! $this->expects_closer( $top_node ) ) { $this->state->stack_of_open_elements->pop(); } } if ( self::PROCESS_NEXT_NODE === $node_to_process ) { parent::next_token(); if ( WP_HTML_Tag_Processor::STATE_TEXT_NODE === $this->parser_state ) { parent::subdivide_text_appropriately(); } } if ( WP_HTML_Tag_Processor::STATE_INCOMPLETE_INPUT === $this->parser_state || WP_HTML_Tag_Processor::STATE_COMPLETE === $this->parser_state ) { return false; } $adjusted_current_node = $this->get_adjusted_current_node(); $is_closer = $this->is_tag_closer(); $is_start_tag = WP_HTML_Tag_Processor::STATE_MATCHED_TAG === $this->parser_state && ! $is_closer; $token_name = $this->get_token_name(); if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) { $this->state->current_token = new WP_HTML_Token( $this->bookmark_token(), $token_name, $this->has_self_closing_flag(), $this->release_internal_bookmark_on_destruct ); } $parse_in_current_insertion_mode = ( 0 === $this->state->stack_of_open_elements->count() || 'html' === $adjusted_current_node->namespace || ( 'math' === $adjusted_current_node->integration_node_type && ( ( $is_start_tag && ! in_array( $token_name, array( 'MGLYPH', 'MALIGNMARK' ), true ) ) || '#text' === $token_name ) ) || ( 'math' === $adjusted_current_node->namespace && 'ANNOTATION-XML' === $adjusted_current_node->node_name && $is_start_tag && 'SVG' === $token_name ) || ( 'html' === $adjusted_current_node->integration_node_type && ( $is_start_tag || '#text' === $token_name ) ) ); try { if ( ! $parse_in_current_insertion_mode ) { return $this->step_in_foreign_content(); } switch ( $this->state->insertion_mode ) { case WP_HTML_Processor_State::INSERTION_MODE_INITIAL: return $this->step_initial(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML: return $this->step_before_html(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD: return $this->step_before_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD: return $this->step_in_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT: return $this->step_in_head_noscript(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD: return $this->step_after_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY: return $this->step_in_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: return $this->step_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT: return $this->step_in_table_text(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: return $this->step_in_caption(); case WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP: return $this->step_in_column_group(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: return $this->step_in_table_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: return $this->step_in_row(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: return $this->step_in_cell(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: return $this->step_in_select(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE: return $this->step_in_select_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE: return $this->step_in_template(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY: return $this->step_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET: return $this->step_in_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET: return $this->step_after_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY: return $this->step_after_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET: return $this->step_after_after_frameset(); default: $this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." ); } } catch ( WP_HTML_Unsupported_Exception $e ) { return false; } } public function get_breadcrumbs(): array { return $this->breadcrumbs; } public function get_current_depth(): int { return count( $this->breadcrumbs ); } public static function normalize( string $html ): ?string { return static::create_fragment( $html )->serialize(); } public function serialize(): ?string { if ( WP_HTML_Tag_Processor::STATE_READY !== $this->parser_state ) { wp_trigger_error( __METHOD__, 'An HTML Processor which has already started processing cannot serialize its contents. Serialize immediately after creating the instance.', E_USER_WARNING ); return null; } $html = ''; while ( $this->next_token() ) { $html .= $this->serialize_token(); } if ( null !== $this->get_last_error() ) { wp_trigger_error( __METHOD__, "Cannot serialize HTML Processor with parsing error: {$this->get_last_error()}.", E_USER_WARNING ); return null; } return $html; } public function serialize_token(): string { $html = ''; $token_type = $this->get_token_type(); switch ( $token_type ) { case '#doctype': $doctype = $this->get_doctype_info(); if ( null === $doctype ) { break; } $html .= '<!DOCTYPE'; if ( $doctype->name ) { $html .= " {$doctype->name}"; } if ( null !== $doctype->public_identifier ) { $quote = str_contains( $doctype->public_identifier, '"' ) ? "'" : '"'; $html .= " PUBLIC {$quote}{$doctype->public_identifier}{$quote}"; } if ( null !== $doctype->system_identifier ) { if ( null === $doctype->public_identifier ) { $html .= ' SYSTEM'; } $quote = str_contains( $doctype->system_identifier, '"' ) ? "'" : '"'; $html .= " {$quote}{$doctype->system_identifier}{$quote}"; } $html .= '>'; break; case '#text': $html .= htmlspecialchars( $this->get_modifiable_text(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8' ); break; case '#presumptuous-tag': break; case '#funky-comment': case '#comment': $html .= "<!--{$this->get_full_comment_text()}-->"; break; case '#cdata-section': $html .= "<![CDATA[{$this->get_modifiable_text()}]]>"; break; } if ( '#tag' !== $token_type ) { return $html; } $tag_name = str_replace( "\x00", "\u{FFFD}", $this->get_tag() ); $in_html = 'html' === $this->get_namespace(); $qualified_name = $in_html ? strtolower( $tag_name ) : $this->get_qualified_tag_name(); if ( $this->is_tag_closer() ) { $html .= "</{$qualified_name}>"; return $html; } $attribute_names = $this->get_attribute_names_with_prefix( '' ); if ( ! isset( $attribute_names ) ) { $html .= "<{$qualified_name}>"; return $html; } $html .= "<{$qualified_name}"; foreach ( $attribute_names as $attribute_name ) { $html .= " {$this->get_qualified_attribute_name( $attribute_name )}"; $value = $this->get_attribute( $attribute_name ); if ( is_string( $value ) ) { $html .= '="' . htmlspecialchars( $value, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5 ) . '"'; } $html = str_replace( "\x00", "\u{FFFD}", $html ); } if ( ! $in_html && $this->has_self_closing_flag() ) { $html .= ' /'; } $html .= '>'; if ( $in_html && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) { $text = $this->get_modifiable_text(); switch ( $tag_name ) { case 'IFRAME': case 'NOEMBED': case 'NOFRAMES': $text = ''; break; case 'SCRIPT': case 'STYLE': break; default: $text = htmlspecialchars( $text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8' ); } $html .= "{$text}</{$qualified_name}>"; } return $html; } private function step_initial(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto initial_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': $doctype = $this->get_doctype_info(); if ( null !== $doctype && 'quirks' === $doctype->indicated_compatibility_mode ) { $this->compat_mode = WP_HTML_Tag_Processor::QUIRKS_MODE; } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML; $this->insert_html_element( $this->state->current_token ); return true; } initial_anything_else: $this->compat_mode = WP_HTML_Tag_Processor::QUIRKS_MODE; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_before_html(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case 'html': return $this->step(); case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto before_html_anything_else; break; case '+HTML': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return true; case '-HEAD': case '-BODY': case '-HTML': goto before_html_anything_else; break; } if ( $is_closer ) { return $this->step(); } before_html_anything_else: $this->insert_virtual_node( 'HTML' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_before_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto before_head_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+HEAD': $this->insert_html_element( $this->state->current_token ); $this->state->head_element = $this->state->current_token; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return true; case '-HEAD': case '-BODY': case '-HTML': goto before_head_anything_else; break; } if ( $is_closer ) { return $this->step(); } before_head_anything_else: $this->state->head_element = $this->insert_virtual_node( 'HEAD' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_in_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { $this->insert_html_element( $this->state->current_token ); return true; } goto in_head_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': $this->insert_html_element( $this->state->current_token ); return true; case '+META': $this->insert_html_element( $this->state->current_token ); if ( 'tentative' !== $this->state->encoding_confidence ) { return true; } $charset = $this->get_attribute( 'charset' ); if ( is_string( $charset ) ) { $this->bail( 'Cannot yet process META tags with charset to determine encoding.' ); } $http_equiv = $this->get_attribute( 'http-equiv' ); $content = $this->get_attribute( 'content' ); if ( is_string( $http_equiv ) && is_string( $content ) && 0 === strcasecmp( $http_equiv, 'Content-Type' ) ) { $this->bail( 'Cannot yet process META tags with http-equiv Content-Type to determine encoding.' ); } return true; case '+TITLE': $this->insert_html_element( $this->state->current_token ); return true; case '+NOFRAMES': case '+STYLE': $this->insert_html_element( $this->state->current_token ); return true; case '+NOSCRIPT': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT; return true; case '+SCRIPT': $this->insert_html_element( $this->state->current_token ); return true; case '-HEAD': $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; return true; case '-BODY': case '-HTML': goto in_head_anything_else; break; case '+TEMPLATE': $this->state->active_formatting_elements->insert_marker(); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; $this->insert_html_element( $this->state->current_token ); return true; case '-TEMPLATE': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { return $this->step(); } $this->generate_implied_end_tags_thoroughly(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'TEMPLATE' ) ) { } $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); array_pop( $this->state->stack_of_template_insertion_modes ); $this->reset_insertion_mode_appropriately(); return true; } if ( '+HEAD' === $op || $is_closer ) { return $this->step(); } in_head_anything_else: $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_in_head_noscript(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_head(); } goto in_head_noscript_anything_else; break; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '-NOSCRIPT': $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return true; case '#comment': case '#funky-comment': case '#presumptuous-tag': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+STYLE': return $this->step_in_head(); } if ( '+HEAD' === $op || '+NOSCRIPT' === $op || $is_closer ) { return $this->step(); } in_head_noscript_anything_else: $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_after_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { $this->insert_html_element( $this->state->current_token ); return true; } goto after_head_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+BODY': $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return true; case '+FRAMESET': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET; return true; case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': $this->bail( 'Cannot process elements after HEAD which reopen the HEAD element.' ); break; case '-TEMPLATE': return $this->step_in_head(); case '-BODY': case '-HTML': goto after_head_anything_else; break; } if ( '+HEAD' === $op || $is_closer ) { return $this->step(); } after_head_anything_else: $this->insert_virtual_node( 'BODY' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_in_body(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { return $this->step(); } $this->reconstruct_active_formatting_elements(); if ( parent::TEXT_IS_GENERIC === $this->text_node_classification ) { $this->state->frameset_ok = false; } $this->insert_html_element( $this->state->current_token ); return true; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { } return $this->step(); case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': case '-TEMPLATE': return $this->step_in_head(); case '+BODY': if ( 1 === $this->state->stack_of_open_elements->count() || 'BODY' !== ( $this->state->stack_of_open_elements->at( 2 )->node_name ?? null ) || $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { return $this->step(); } $this->state->frameset_ok = false; return $this->step(); case '+FRAMESET': if ( 1 === $this->state->stack_of_open_elements->count() || 'BODY' !== ( $this->state->stack_of_open_elements->at( 2 )->node_name ?? null ) || false === $this->state->frameset_ok ) { return $this->step(); } $this->bail( 'Cannot process non-ignored FRAMESET tags.' ); break; case '-BODY': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'BODY' ) ) { return $this->step(); } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY; return $this->step(); case '-HTML': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'BODY' ) ) { return $this->step(); } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+ADDRESS': case '+ARTICLE': case '+ASIDE': case '+BLOCKQUOTE': case '+CENTER': case '+DETAILS': case '+DIALOG': case '+DIR': case '+DIV': case '+DL': case '+FIELDSET': case '+FIGCAPTION': case '+FIGURE': case '+FOOTER': case '+HEADER': case '+HGROUP': case '+MAIN': case '+MENU': case '+NAV': case '+OL': case '+P': case '+SEARCH': case '+SECTION': case '+SUMMARY': case '+UL': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); return true; case '+H1': case '+H2': case '+H3': case '+H4': case '+H5': case '+H6': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } if ( in_array( $this->state->stack_of_open_elements->current_node()->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; case '+PRE': case '+LISTING': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; case '+FORM': $stack_contains_template = $this->state->stack_of_open_elements->contains( 'TEMPLATE' ); if ( isset( $this->state->form_element ) && ! $stack_contains_template ) { return $this->step(); } if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); if ( ! $stack_contains_template ) { $this->state->form_element = $this->state->current_token; } return true; case '+DD': case '+DT': case '+LI': $this->state->frameset_ok = false; $node = $this->state->stack_of_open_elements->current_node(); $is_li = 'LI' === $token_name; in_body_list_loop: if ( $is_li ? 'LI' === $node->node_name : ( 'DD' === $node->node_name || 'DT' === $node->node_name ) ) { $node_name = $is_li ? 'LI' : $node->node_name; $this->generate_implied_end_tags( $node_name ); if ( ! $this->state->stack_of_open_elements->current_node_is( $node_name ) ) { } $this->state->stack_of_open_elements->pop_until( $node_name ); goto in_body_list_done; } if ( 'ADDRESS' !== $node->node_name && 'DIV' !== $node->node_name && 'P' !== $node->node_name && self::is_special( $node ) ) { goto in_body_list_done; } else { foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $item ) { $node = $item; break; } goto in_body_list_loop; } in_body_list_done: if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); return true; case '+PLAINTEXT': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->bail( 'Cannot process PLAINTEXT elements.' ); break; case '+BUTTON': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'BUTTON' ) ) { $this->generate_implied_end_tags(); $this->state->stack_of_open_elements->pop_until( 'BUTTON' ); } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; case '-ADDRESS': case '-ARTICLE': case '-ASIDE': case '-BLOCKQUOTE': case '-BUTTON': case '-CENTER': case '-DETAILS': case '-DIALOG': case '-DIR': case '-DIV': case '-DL': case '-FIELDSET': case '-FIGCAPTION': case '-FIGURE': case '-FOOTER': case '-HEADER': case '-HGROUP': case '-LISTING': case '-MAIN': case '-MENU': case '-NAV': case '-OL': case '-PRE': case '-SEARCH': case '-SECTION': case '-SUMMARY': case '-UL': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { } $this->state->stack_of_open_elements->pop_until( $token_name ); return true; case '-FORM': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { $node = $this->state->form_element; $this->state->form_element = null; if ( null === $node || ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( $node !== $this->state->stack_of_open_elements->current_node() ) { $this->bail( 'Cannot close a FORM when other elements remain open as this would throw off the breadcrumbs for the following tokens.' ); } $this->state->stack_of_open_elements->remove_node( $node ); return true; } else { if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'FORM' ) ) { } $this->state->stack_of_open_elements->pop_until( 'FORM' ); return true; } break; case '-P': if ( ! $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->insert_html_element( $this->state->current_token ); } $this->close_a_p_element(); return true; case '-DD': case '-DT': case '-LI': if ( ( 'LI' === $token_name && ! $this->state->stack_of_open_elements->has_element_in_list_item_scope( 'LI' ) ) || ( 'LI' !== $token_name && ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) ) { return $this->step(); } $this->generate_implied_end_tags( $token_name ); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { } $this->state->stack_of_open_elements->pop_until( $token_name ); return true; case '-H1': case '-H2': case '-H3': case '-H4': case '-H5': case '-H6': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( '(internal: H1 through H6 - do not use)' ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { } $this->state->stack_of_open_elements->pop_until( '(internal: H1 through H6 - do not use)' ); return true; case '+A': foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { switch ( $item->node_name ) { case 'marker': break 2; case 'A': $this->run_adoption_agency_algorithm(); $this->state->active_formatting_elements->remove_node( $item ); $this->state->stack_of_open_elements->remove_node( $item ); break 2; } } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; case '+B': case '+BIG': case '+CODE': case '+EM': case '+FONT': case '+I': case '+S': case '+SMALL': case '+STRIKE': case '+STRONG': case '+TT': case '+U': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; case '+NOBR': $this->reconstruct_active_formatting_elements(); if ( $this->state->stack_of_open_elements->has_element_in_scope( 'NOBR' ) ) { $this->run_adoption_agency_algorithm(); $this->reconstruct_active_formatting_elements(); } $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; case '-A': case '-B': case '-BIG': case '-CODE': case '-EM': case '-FONT': case '-I': case '-NOBR': case '-S': case '-SMALL': case '-STRIKE': case '-STRONG': case '-TT': case '-U': $this->run_adoption_agency_algorithm(); return true; case '+APPLET': case '+MARQUEE': case '+OBJECT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->insert_marker(); $this->state->frameset_ok = false; return true; case '-APPLET': case '-MARQUEE': case '-OBJECT': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { } $this->state->stack_of_open_elements->pop_until( $token_name ); $this->state->active_formatting_elements->clear_up_to_last_marker(); return true; case '+TABLE': if ( WP_HTML_Tag_Processor::QUIRKS_MODE !== $this->compat_mode && $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; case '+AREA': case '+BR': case '+EMBED': case '+IMG': case '+KEYGEN': case '+WBR': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; case '+INPUT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { $this->state->frameset_ok = false; } return true; case '+PARAM': case '+SOURCE': case '+TRACK': $this->insert_html_element( $this->state->current_token ); return true; case '+HR': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; case '+IMAGE': $this->bail( "Cannot process an IMAGE tag. (Don't ask.)" ); break; case '+TEXTAREA': $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; case '+XMP': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->reconstruct_active_formatting_elements(); $this->state->frameset_ok = false; $this->insert_html_element( $this->state->current_token ); return true; case '+IFRAME': $this->state->frameset_ok = false; $this->insert_html_element( $this->state->current_token ); return true; case '+NOEMBED': $this->insert_html_element( $this->state->current_token ); return true; case '+SELECT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; switch ( $this->state->insertion_mode ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; break; default: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; break; } return true; case '+OPTGROUP': case '+OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; case '+RB': case '+RTC': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'RUBY' ) ) { $this->generate_implied_end_tags(); if ( $this->state->stack_of_open_elements->current_node_is( 'RUBY' ) ) { } } $this->insert_html_element( $this->state->current_token ); return true; case '+RP': case '+RT': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'RUBY' ) ) { $this->generate_implied_end_tags( 'RTC' ); $current_node_name = $this->state->stack_of_open_elements->current_node()->node_name; if ( 'RTC' === $current_node_name || 'RUBY' === $current_node_name ) { } } $this->insert_html_element( $this->state->current_token ); return true; case '+MATH': $this->reconstruct_active_formatting_elements(); $this->state->current_token->namespace = 'math'; $this->insert_html_element( $this->state->current_token ); if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; case '+SVG': $this->reconstruct_active_formatting_elements(); $this->state->current_token->namespace = 'svg'; $this->insert_html_element( $this->state->current_token ); if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; case '+CAPTION': case '+COL': case '+COLGROUP': case '+FRAME': case '+HEAD': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': return $this->step(); } if ( ! parent::is_tag_closer() ) { $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; } else { foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { if ( 'html' === $node->namespace && $token_name === $node->node_name ) { break; } if ( self::is_special( $node ) ) { return $this->step(); } } $this->generate_implied_end_tags( $token_name ); if ( $node !== $this->state->stack_of_open_elements->current_node() ) { } foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $node === $item ) { return true; } } } $this->bail( 'Should not have been able to reach end of IN BODY processing. Check HTML API code.' ); return false; } private function step_in_table(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': $current_node = $this->state->stack_of_open_elements->current_node(); $current_node_name = $current_node ? $current_node->node_name : null; if ( $current_node_name && ( 'TABLE' === $current_node_name || 'TBODY' === $current_node_name || 'TEMPLATE' === $current_node_name || 'TFOOT' === $current_node_name || 'THEAD' === $current_node_name || 'TR' === $current_node_name ) ) { if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { return $this->step(); } if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { $this->insert_html_element( $this->state->current_token ); return true; } $this->bail( 'Foster parenting is not supported.' ); break; } break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+CAPTION': $this->state->stack_of_open_elements->clear_to_table_context(); $this->state->active_formatting_elements->insert_marker(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; return true; case '+COLGROUP': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return true; case '+COL': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_virtual_node( 'COLGROUP' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+TBODY': case '+TFOOT': case '+THEAD': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return true; case '+TD': case '+TH': case '+TR': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_virtual_node( 'TBODY' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'TABLE' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'TABLE' ); $this->reset_insertion_mode_appropriately(); return true; case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TBODY': case '-TD': case '-TFOOT': case '-TH': case '-THEAD': case '-TR': return $this->step(); case '+STYLE': case '+SCRIPT': case '+TEMPLATE': case '-TEMPLATE': return $this->step_in_head(); case '+INPUT': $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { goto anything_else; } $this->insert_html_element( $this->state->current_token ); return true; case '+FORM': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) || isset( $this->state->form_element ) ) { return $this->step(); } $this->insert_html_element( $this->state->current_token ); $this->state->form_element = $this->state->current_token; $this->state->stack_of_open_elements->pop(); return true; } anything_else: $this->bail( 'Foster parenting is not supported.' ); } private function step_in_table_text(): bool { $this->bail( 'No support for parsing in the ' . WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT . ' state.' ); } private function step_in_caption(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '-CAPTION': case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'CAPTION' ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'CAPTION' ) ) { } $this->state->stack_of_open_elements->pop_until( 'CAPTION' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; if ( '-CAPTION' === $op ) { return true; } return $this->step( self::REPROCESS_CURRENT_NODE ); case '-BODY': case '-COL': case '-COLGROUP': case '-HTML': case '-TBODY': case '-TD': case '-TFOOT': case '-TH': case '-THEAD': case '-TR': return $this->step(); } return $this->step_in_body(); } private function step_in_column_group(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { $this->insert_html_element( $this->state->current_token ); return true; } goto in_column_group_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+COL': $this->insert_html_element( $this->state->current_token ); $this->state->stack_of_open_elements->pop(); return true; case '-COLGROUP': if ( ! $this->state->stack_of_open_elements->current_node_is( 'COLGROUP' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; case '-COL': return $this->step(); case '+TEMPLATE': case '-TEMPLATE': return $this->step_in_head(); } in_column_group_anything_else: if ( ! $this->state->stack_of_open_elements->current_node_is( 'COLGROUP' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_in_table_body(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '+TR': $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return true; case '+TH': case '+TD': $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->insert_virtual_node( 'TR' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return $this->step( self::REPROCESS_CURRENT_NODE ); case '-TBODY': case '-TFOOT': case '-THEAD': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TBODY' ) && ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'THEAD' ) && ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TFOOT' ) ) { return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TD': case '-TH': case '-TR': return $this->step(); } return $this->step_in_table(); } private function step_in_row(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '+TH': case '+TD': $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL; $this->state->active_formatting_elements->insert_marker(); return true; case '-TR': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return true; case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': case '+TR': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); case '-TBODY': case '-TFOOT': case '-THEAD': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { return $this->step(); } if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TD': case '-TH': return $this->step(); } return $this->step_in_table(); } private function step_in_cell(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '-TD': case '-TH': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $tag_name ) ) { } $this->state->stack_of_open_elements->pop_until( $tag_name ); $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return true; case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': $this->close_cell(); return $this->step( self::REPROCESS_CURRENT_NODE ); case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': return $this->step(); case '-TABLE': case '-TBODY': case '-TFOOT': case '-THEAD': case '-TR': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { return $this->step(); } $this->close_cell(); return $this->step( self::REPROCESS_CURRENT_NODE ); } return $this->step_in_body(); } private function step_in_select(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { return $this->step(); } $this->insert_html_element( $this->state->current_token ); return true; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; case '+OPTGROUP': case '+HR': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } if ( $this->state->stack_of_open_elements->current_node_is( 'OPTGROUP' ) ) { $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; case '-OPTGROUP': $current_node = $this->state->stack_of_open_elements->current_node(); if ( $current_node && 'OPTION' === $current_node->node_name ) { foreach ( $this->state->stack_of_open_elements->walk_up( $current_node ) as $parent ) { break; } if ( $parent && 'OPTGROUP' === $parent->node_name ) { $this->state->stack_of_open_elements->pop(); } } if ( $this->state->stack_of_open_elements->current_node_is( 'OPTGROUP' ) ) { $this->state->stack_of_open_elements->pop(); return true; } return $this->step(); case '-OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); return true; } return $this->step(); case '-SELECT': case '+SELECT': if ( ! $this->state->stack_of_open_elements->has_element_in_select_scope( 'SELECT' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return true; case '+INPUT': case '+KEYGEN': case '+TEXTAREA': if ( ! $this->state->stack_of_open_elements->has_element_in_select_scope( 'SELECT' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); case '+SCRIPT': case '+TEMPLATE': case '-TEMPLATE': return $this->step_in_head(); } return $this->step(); } private function step_in_select_in_table(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '+CAPTION': case '+TABLE': case '+TBODY': case '+TFOOT': case '+THEAD': case '+TR': case '+TD': case '+TH': $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); case '-CAPTION': case '-TABLE': case '-TBODY': case '-TFOOT': case '-THEAD': case '-TR': case '-TD': case '-TH': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $token_name ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); } return $this->step_in_select(); } private function step_in_template(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = $this->is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': case '#comment': case '#funky-comment': case '#presumptuous-tag': case 'html': return $this->step_in_body(); case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': case '-TEMPLATE': return $this->step_in_head(); case '+CAPTION': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+COL': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+TR': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); case '+TD': case '+TH': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return $this->step( self::REPROCESS_CURRENT_NODE ); } if ( ! $is_closer ) { array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } if ( $is_closer ) { return $this->step(); } if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { return false; } $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); array_pop( $this->state->stack_of_template_insertion_modes ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_after_body(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } goto after_body_anything_else; break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of BODY is unsupported.' ); break; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '-HTML': if ( isset( $this->context_node ) ) { return $this->step(); } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY; return $this->step(); } after_body_anything_else: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_in_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in frameset.' ); break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '+FRAMESET': $this->insert_html_element( $this->state->current_token ); return true; case '-FRAMESET': if ( $this->state->stack_of_open_elements->current_node_is( 'HTML' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop(); if ( ! isset( $this->context_node ) && ! $this->state->stack_of_open_elements->current_node_is( 'FRAMESET' ) ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET; } return true; case '+FRAME': $this->insert_html_element( $this->state->current_token ); $this->state->stack_of_open_elements->pop(); return true; case '+NOFRAMES': return $this->step_in_head(); } return $this->step(); } private function step_after_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in after frameset' ); break; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; case 'html': return $this->step(); case '+HTML': return $this->step_in_body(); case '-HTML': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET; return $this->step(); case '+NOFRAMES': return $this->step_in_head(); } return $this->step(); } private function step_after_after_body(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of HTML is unsupported.' ); break; case 'html': case '+HTML': return $this->step_in_body(); case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } goto after_after_body_anything_else; break; } after_after_body_anything_else: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } private function step_after_after_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of HTML is unsupported.' ); break; case 'html': case '+HTML': return $this->step_in_body(); case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in after after frameset.' ); break; case '+NOFRAMES': return $this->step_in_head(); } return $this->step(); } private function step_in_foreign_content(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; if ( '+FONT' === $op && ( null !== $this->get_attribute( 'color' ) || null !== $this->get_attribute( 'face' ) || null !== $this->get_attribute( 'size' ) ) ) { $op = '+FONT with attributes'; } switch ( $op ) { case '#text': if ( parent::TEXT_IS_GENERIC === $this->text_node_classification ) { $this->state->frameset_ok = false; } $this->insert_foreign_element( $this->state->current_token, false ); return true; case '#cdata-section': $current_token = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $cdata_content_start = $current_token->start + 9; $cdata_content_length = $current_token->length - 12; if ( strspn( $this->html, "\0 \t\n\f\r", $cdata_content_start, $cdata_content_length ) !== $cdata_content_length ) { $this->state->frameset_ok = false; } $this->insert_foreign_element( $this->state->current_token, false ); return true; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_foreign_element( $this->state->current_token, false ); return true; case 'html': return $this->step(); case '+B': case '+BIG': case '+BLOCKQUOTE': case '+BODY': case '+BR': case '+CENTER': case '+CODE': case '+DD': case '+DIV': case '+DL': case '+DT': case '+EM': case '+EMBED': case '+H1': case '+H2': case '+H3': case '+H4': case '+H5': case '+H6': case '+HEAD': case '+HR': case '+I': case '+IMG': case '+LI': case '+LISTING': case '+MENU': case '+META': case '+NOBR': case '+OL': case '+P': case '+PRE': case '+RUBY': case '+S': case '+SMALL': case '+SPAN': case '+STRONG': case '+STRIKE': case '+SUB': case '+SUP': case '+TABLE': case '+TT': case '+U': case '+UL': case '+VAR': case '+FONT with attributes': case '-BR': case '-P': foreach ( $this->state->stack_of_open_elements->walk_up() as $current_node ) { if ( 'math' === $current_node->integration_node_type || 'html' === $current_node->integration_node_type || 'html' === $current_node->namespace ) { break; } $this->state->stack_of_open_elements->pop(); } goto in_foreign_content_process_in_current_insertion_mode; } if ( ! $this->is_tag_closer() ) { $this->insert_foreign_element( $this->state->current_token, false ); if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; } if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) { $this->state->stack_of_open_elements->pop(); return true; } if ( $this->is_tag_closer() ) { $node = $this->state->stack_of_open_elements->current_node(); if ( $tag_name !== $node->node_name ) { } in_foreign_content_end_tag_loop: if ( $node === $this->state->stack_of_open_elements->at( 1 ) ) { return true; } if ( 0 === strcasecmp( $node->node_name, $tag_name ) ) { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $node === $item ) { return true; } } } foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $item ) { $node = $item; break; } if ( 'html' !== $node->namespace ) { goto in_foreign_content_end_tag_loop; } in_foreign_content_process_in_current_insertion_mode: switch ( $this->state->insertion_mode ) { case WP_HTML_Processor_State::INSERTION_MODE_INITIAL: return $this->step_initial(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML: return $this->step_before_html(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD: return $this->step_before_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD: return $this->step_in_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT: return $this->step_in_head_noscript(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD: return $this->step_after_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY: return $this->step_in_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: return $this->step_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT: return $this->step_in_table_text(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: return $this->step_in_caption(); case WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP: return $this->step_in_column_group(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: return $this->step_in_table_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: return $this->step_in_row(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: return $this->step_in_cell(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: return $this->step_in_select(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE: return $this->step_in_select_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE: return $this->step_in_template(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY: return $this->step_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET: return $this->step_in_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET: return $this->step_after_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY: return $this->step_after_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET: return $this->step_after_after_frameset(); default: $this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." ); } } $this->bail( 'Should not have been able to reach end of IN FOREIGN CONTENT processing. Check HTML API code.' ); return false; } private function bookmark_token() { if ( ! parent::set_bookmark( ++$this->bookmark_counter ) ) { $this->last_error = self::ERROR_EXCEEDED_MAX_BOOKMARKS; throw new Exception( 'could not allocate bookmark' ); } return "{$this->bookmark_counter}"; } public function get_namespace(): string { if ( ! isset( $this->current_element ) ) { return parent::get_namespace(); } return $this->current_element->token->namespace; } public function get_tag(): ?string { if ( null !== $this->last_error ) { return null; } if ( $this->is_virtual() ) { return $this->current_element->token->node_name; } $tag_name = parent::get_tag(); return ( 'IMAGE' === $tag_name && 'html' === $this->get_namespace() ) ? 'IMG' : $tag_name; } public function has_self_closing_flag(): bool { return $this->is_virtual() ? false : parent::has_self_closing_flag(); } public function get_token_name(): ?string { return $this->is_virtual() ? $this->current_element->token->node_name : parent::get_token_name(); } public function get_token_type(): ?string { if ( $this->is_virtual() ) { $node_name = $this->current_element->token->node_name; $starting_char = $node_name[0]; if ( 'A' <= $starting_char && 'Z' >= $starting_char ) { return '#tag'; } if ( 'html' === $node_name ) { return '#doctype'; } return $node_name; } return parent::get_token_type(); } public function get_attribute( $name ) { return $this->is_virtual() ? null : parent::get_attribute( $name ); } public function set_attribute( $name, $value ): bool { return $this->is_virtual() ? false : parent::set_attribute( $name, $value ); } public function remove_attribute( $name ): bool { return $this->is_virtual() ? false : parent::remove_attribute( $name ); } public function get_attribute_names_with_prefix( $prefix ): ?array { return $this->is_virtual() ? null : parent::get_attribute_names_with_prefix( $prefix ); } public function add_class( $class_name ): bool { return $this->is_virtual() ? false : parent::add_class( $class_name ); } public function remove_class( $class_name ): bool { return $this->is_virtual() ? false : parent::remove_class( $class_name ); } public function has_class( $wanted_class ): ?bool { return $this->is_virtual() ? null : parent::has_class( $wanted_class ); } public function class_list() { return $this->is_virtual() ? null : parent::class_list(); } public function get_modifiable_text(): string { return $this->is_virtual() ? '' : parent::get_modifiable_text(); } public function get_comment_type(): ?string { return $this->is_virtual() ? null : parent::get_comment_type(); } public function release_bookmark( $bookmark_name ): bool { return parent::release_bookmark( "_{$bookmark_name}" ); } public function seek( $bookmark_name ): bool { $this->get_updated_html(); $actual_bookmark_name = "_{$bookmark_name}"; $processor_started_at = $this->state->current_token ? $this->bookmarks[ $this->state->current_token->bookmark_name ]->start : 0; $bookmark_starts_at = $this->bookmarks[ $actual_bookmark_name ]->start; $direction = $bookmark_starts_at > $processor_started_at ? 'forward' : 'backward'; if ( 'backward' === $direction ) { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->remove_node( $item ); } foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { $this->state->active_formatting_elements->remove_node( $item ); } $this->state->frameset_ok = true; $this->state->stack_of_template_insertion_modes = array(); $this->state->head_element = null; $this->state->form_element = null; $this->state->current_token = null; $this->current_element = null; $this->element_queue = array(); if ( null === $this->context_node ) { $this->change_parsing_namespace( 'html' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_INITIAL; $this->breadcrumbs = array(); $this->bookmarks['initial'] = new WP_HTML_Span( 0, 0 ); parent::seek( 'initial' ); unset( $this->bookmarks['initial'] ); } else { $this->state->stack_of_open_elements->push( new WP_HTML_Token( 'root-node', 'HTML', false ) ); $this->change_parsing_namespace( $this->context_node->integration_node_type ? 'html' : $this->context_node->namespace ); if ( 'TEMPLATE' === $this->context_node->node_name ) { $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; } $this->reset_insertion_mode_appropriately(); $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 ); parent::seek( $this->context_node->bookmark_name ); } } do { if ( $this->is_virtual() ) { continue; } if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) { return true; } } while ( $this->next_token() ); return false; } public function set_bookmark( $bookmark_name ): bool { if ( $this->is_virtual() ) { _doing_it_wrong( __METHOD__, __( 'Cannot set bookmarks on tokens that do no appear in the original HTML text.' ), '6.8.0' ); return false; } return parent::set_bookmark( "_{$bookmark_name}" ); } public function has_bookmark( $bookmark_name ): bool { return parent::has_bookmark( "_{$bookmark_name}" ); } private function close_a_p_element(): void { $this->generate_implied_end_tags( 'P' ); $this->state->stack_of_open_elements->pop_until( 'P' ); } private function generate_implied_end_tags( ?string $except_for_this_element = null ): void { $elements_with_implied_end_tags = array( 'DD', 'DT', 'LI', 'OPTGROUP', 'OPTION', 'P', 'RB', 'RP', 'RT', 'RTC', ); $no_exclusions = ! isset( $except_for_this_element ); while ( ( $no_exclusions || ! $this->state->stack_of_open_elements->current_node_is( $except_for_this_element ) ) && in_array( $this->state->stack_of_open_elements->current_node()->node_name, $elements_with_implied_end_tags, true ) ) { $this->state->stack_of_open_elements->pop(); } } private function generate_implied_end_tags_thoroughly(): void { $elements_with_implied_end_tags = array( 'CAPTION', 'COLGROUP', 'DD', 'DT', 'LI', 'OPTGROUP', 'OPTION', 'P', 'RB', 'RP', 'RT', 'RTC', 'TBODY', 'TD', 'TFOOT', 'TH', 'THEAD', 'TR', ); while ( in_array( $this->state->stack_of_open_elements->current_node()->node_name, $elements_with_implied_end_tags, true ) ) { $this->state->stack_of_open_elements->pop(); } } private function get_adjusted_current_node(): ?WP_HTML_Token { if ( isset( $this->context_node ) && 1 === $this->state->stack_of_open_elements->count() ) { return $this->context_node; } return $this->state->stack_of_open_elements->current_node(); } private function reconstruct_active_formatting_elements(): bool { if ( 0 === $this->state->active_formatting_elements->count() ) { return false; } $last_entry = $this->state->active_formatting_elements->current_node(); if ( 'marker' === $last_entry->node_name || $this->state->stack_of_open_elements->contains_node( $last_entry ) ) { return false; } $this->bail( 'Cannot reconstruct active formatting elements when advancing and rewinding is required.' ); } private function reset_insertion_mode_appropriately(): void { $first_node = null; foreach ( $this->state->stack_of_open_elements->walk_down() as $first_node ) { break; } $last = false; foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { if ( $node === $first_node ) { $last = true; if ( isset( $this->context_node ) ) { $node = $this->context_node; } } if ( 'html' !== $node->namespace ) { continue; } switch ( $node->node_name ) { case 'SELECT': if ( ! $last ) { foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $ancestor ) { if ( 'html' !== $ancestor->namespace ) { continue; } switch ( $ancestor->node_name ) { case 'TEMPLATE': break 2; case 'TABLE': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; return; } } } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; return; case 'TD': case 'TH': if ( ! $last ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL; return; } break; case 'TR': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return; case 'TBODY': case 'THEAD': case 'TFOOT': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return; case 'CAPTION': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; return; case 'COLGROUP': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return; case 'TABLE': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return; case 'TEMPLATE': $this->state->insertion_mode = end( $this->state->stack_of_template_insertion_modes ); return; case 'HEAD': if ( ! $last ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return; } break; case 'BODY': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return; case 'FRAMESET': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET; return; case 'HTML': $this->state->insertion_mode = isset( $this->state->head_element ) ? WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD : WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return; } } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; } private function run_adoption_agency_algorithm(): void { $budget = 1000; $subject = $this->get_tag(); $current_node = $this->state->stack_of_open_elements->current_node(); if ( $current_node && $subject === $current_node->node_name && ! $this->state->active_formatting_elements->contains_node( $current_node ) ) { $this->state->stack_of_open_elements->pop(); return; } $outer_loop_counter = 0; while ( $budget-- > 0 ) { if ( $outer_loop_counter++ >= 8 ) { return; } $formatting_element = null; foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { if ( 'marker' === $item->node_name ) { break; } if ( $subject === $item->node_name ) { $formatting_element = $item; break; } } if ( null === $formatting_element ) { $this->bail( 'Cannot run adoption agency when "any other end tag" is required.' ); } if ( ! $this->state->stack_of_open_elements->contains_node( $formatting_element ) ) { $this->state->active_formatting_elements->remove_node( $formatting_element ); return; } if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $formatting_element->node_name ) ) { return; } $is_above_formatting_element = true; $furthest_block = null; foreach ( $this->state->stack_of_open_elements->walk_down() as $item ) { if ( $is_above_formatting_element && $formatting_element->bookmark_name !== $item->bookmark_name ) { continue; } if ( $is_above_formatting_element ) { $is_above_formatting_element = false; continue; } if ( self::is_special( $item ) ) { $furthest_block = $item; break; } } if ( null === $furthest_block ) { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $formatting_element->bookmark_name === $item->bookmark_name ) { $this->state->active_formatting_elements->remove_node( $formatting_element ); return; } } } $this->bail( 'Cannot extract common ancestor in adoption agency algorithm.' ); } $this->bail( 'Cannot run adoption agency when looping required.' ); } private function close_cell(): void { $this->generate_implied_end_tags(); foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) { $this->state->stack_of_open_elements->pop(); if ( 'TD' === $element->node_name || 'TH' === $element->node_name ) { break; } } $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; } private function insert_html_element( WP_HTML_Token $token ): void { $this->state->stack_of_open_elements->push( $token ); } private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to_element_stack ): void { $adjusted_current_node = $this->get_adjusted_current_node(); $token->namespace = $adjusted_current_node ? $adjusted_current_node->namespace : 'html'; if ( $this->is_mathml_integration_point() ) { $token->integration_node_type = 'math'; } elseif ( $this->is_html_integration_point() ) { $token->integration_node_type = 'html'; } if ( false === $only_add_to_element_stack ) { } $this->insert_html_element( $token ); } private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_HTML_Token { $here = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $name = $bookmark_name ?? $this->bookmark_token(); $this->bookmarks[ $name ] = new WP_HTML_Span( $here->start, 0 ); $token = new WP_HTML_Token( $name, $token_name, false ); $this->insert_html_element( $token ); return $token; } private function is_mathml_integration_point(): bool { $current_token = $this->state->current_token; if ( ! isset( $current_token ) ) { return false; } if ( 'math' !== $current_token->namespace || 'M' !== $current_token->node_name[0] ) { return false; } $tag_name = $current_token->node_name; return ( 'MI' === $tag_name || 'MO' === $tag_name || 'MN' === $tag_name || 'MS' === $tag_name || 'MTEXT' === $tag_name ); } private function is_html_integration_point(): bool { $current_token = $this->state->current_token; if ( ! isset( $current_token ) ) { return false; } if ( 'html' === $current_token->namespace ) { return false; } $tag_name = $current_token->node_name; if ( 'svg' === $current_token->namespace ) { return ( 'DESC' === $tag_name || 'FOREIGNOBJECT' === $tag_name || 'TITLE' === $tag_name ); } if ( 'math' === $current_token->namespace ) { if ( 'ANNOTATION-XML' !== $tag_name ) { return false; } $encoding = $this->get_attribute( 'encoding' ); return ( is_string( $encoding ) && ( 0 === strcasecmp( $encoding, 'application/xhtml+xml' ) || 0 === strcasecmp( $encoding, 'text/html' ) ) ); } $this->bail( 'Should not have reached end of HTML Integration Point detection: check HTML API code.' ); return false; } public static function is_special( $tag_name ): bool { if ( is_string( $tag_name ) ) { $tag_name = strtoupper( $tag_name ); } else { $tag_name = 'html' === $tag_name->namespace ? strtoupper( $tag_name->node_name ) : "{$tag_name->namespace} {$tag_name->node_name}"; } return ( 'ADDRESS' === $tag_name || 'APPLET' === $tag_name || 'AREA' === $tag_name || 'ARTICLE' === $tag_name || 'ASIDE' === $tag_name || 'BASE' === $tag_name || 'BASEFONT' === $tag_name || 'BGSOUND' === $tag_name || 'BLOCKQUOTE' === $tag_name || 'BODY' === $tag_name || 'BR' === $tag_name || 'BUTTON' === $tag_name || 'CAPTION' === $tag_name || 'CENTER' === $tag_name || 'COL' === $tag_name || 'COLGROUP' === $tag_name || 'DD' === $tag_name || 'DETAILS' === $tag_name || 'DIR' === $tag_name || 'DIV' === $tag_name || 'DL' === $tag_name || 'DT' === $tag_name || 'EMBED' === $tag_name || 'FIELDSET' === $tag_name || 'FIGCAPTION' === $tag_name || 'FIGURE' === $tag_name || 'FOOTER' === $tag_name || 'FORM' === $tag_name || 'FRAME' === $tag_name || 'FRAMESET' === $tag_name || 'H1' === $tag_name || 'H2' === $tag_name || 'H3' === $tag_name || 'H4' === $tag_name || 'H5' === $tag_name || 'H6' === $tag_name || 'HEAD' === $tag_name || 'HEADER' === $tag_name || 'HGROUP' === $tag_name || 'HR' === $tag_name || 'HTML' === $tag_name || 'IFRAME' === $tag_name || 'IMG' === $tag_name || 'INPUT' === $tag_name || 'KEYGEN' === $tag_name || 'LI' === $tag_name || 'LINK' === $tag_name || 'LISTING' === $tag_name || 'MAIN' === $tag_name || 'MARQUEE' === $tag_name || 'MENU' === $tag_name || 'META' === $tag_name || 'NAV' === $tag_name || 'NOEMBED' === $tag_name || 'NOFRAMES' === $tag_name || 'NOSCRIPT' === $tag_name || 'OBJECT' === $tag_name || 'OL' === $tag_name || 'P' === $tag_name || 'PARAM' === $tag_name || 'PLAINTEXT' === $tag_name || 'PRE' === $tag_name || 'SCRIPT' === $tag_name || 'SEARCH' === $tag_name || 'SECTION' === $tag_name || 'SELECT' === $tag_name || 'SOURCE' === $tag_name || 'STYLE' === $tag_name || 'SUMMARY' === $tag_name || 'TABLE' === $tag_name || 'TBODY' === $tag_name || 'TD' === $tag_name || 'TEMPLATE' === $tag_name || 'TEXTAREA' === $tag_name || 'TFOOT' === $tag_name || 'TH' === $tag_name || 'THEAD' === $tag_name || 'TITLE' === $tag_name || 'TR' === $tag_name || 'TRACK' === $tag_name || 'UL' === $tag_name || 'WBR' === $tag_name || 'XMP' === $tag_name || 'math MI' === $tag_name || 'math MO' === $tag_name || 'math MN' === $tag_name || 'math MS' === $tag_name || 'math MTEXT' === $tag_name || 'math ANNOTATION-XML' === $tag_name || 'svg DESC' === $tag_name || 'svg FOREIGNOBJECT' === $tag_name || 'svg TITLE' === $tag_name ); } public static function is_void( $tag_name ): bool { $tag_name = strtoupper( $tag_name ); return ( 'AREA' === $tag_name || 'BASE' === $tag_name || 'BASEFONT' === $tag_name || 'BGSOUND' === $tag_name || 'BR' === $tag_name || 'COL' === $tag_name || 'EMBED' === $tag_name || 'FRAME' === $tag_name || 'HR' === $tag_name || 'IMG' === $tag_name || 'INPUT' === $tag_name || 'KEYGEN' === $tag_name || 'LINK' === $tag_name || 'META' === $tag_name || 'PARAM' === $tag_name || 'SOURCE' === $tag_name || 'TRACK' === $tag_name || 'WBR' === $tag_name ); } protected static function get_encoding( string $label ): ?string { $label = trim( $label, " \t\f\r\n" ); switch ( strtolower( $label ) ) { case 'unicode-1-1-utf-8': case 'unicode11utf8': case 'unicode20utf8': case 'utf-8': case 'utf8': case 'x-unicode20utf8': return 'UTF-8'; default: return null; } } const PROCESS_NEXT_NODE = 'process-next-node'; const REPROCESS_CURRENT_NODE = 'reprocess-current-node'; const PROCESS_CURRENT_NODE = 'process-current-node'; const ERROR_UNSUPPORTED = 'unsupported'; const ERROR_EXCEEDED_MAX_BOOKMARKS = 'exceeded-max-bookmarks'; const CONSTRUCTOR_UNLOCK_CODE = 'Use WP_HTML_Processor::create_fragment() instead of calling the class constructor directly.'; }
###require ABSPATH . WPINC . '/class-wp-block-processor.php';
class WP_Block_Processor { private $last_error = null; private $last_json_error = JSON_ERROR_NONE; protected $source_text; private $matched_delimiter_at = 0; private $matched_delimiter_length = 0; private $after_previous_delimiter = 0; private $namespace_at = 0; private $name_at = 0; private $name_length = 0; private $has_closing_flag = false; private $json_at; private $json_length = 0; protected $state = self::READY; private $type; private $was_void = false; private $open_blocks_at = array(); private $open_blocks_length = array(); private $next_stack_op = null; public function __construct( string $source_text ) { $this->source_text = $source_text; } public function next_block( ?string $block_type = null ): bool { while ( $this->next_delimiter( $block_type ) ) { if ( self::CLOSER !== $this->get_delimiter_type() ) { return true; } } return false; } public function next_delimiter( ?string $block_name = null ): bool { if ( ! isset( $block_name ) ) { while ( $this->next_token() ) { if ( ! $this->is_html() ) { return true; } } return false; } while ( $this->next_token() ) { if ( $this->is_block_type( $block_name ) ) { return true; } } return false; } public function next_token(): bool { if ( $this->last_error || self::COMPLETE === $this->state || self::INCOMPLETE_INPUT === $this->state ) { return false; } if ( $this->was_void ) { array_pop( $this->open_blocks_at ); array_pop( $this->open_blocks_length ); $this->was_void = false; } $text = $this->source_text; $end = strlen( $text ); if ( self::HTML_SPAN === $this->state ) { if ( $this->matched_delimiter_at >= $end ) { $this->state = self::COMPLETE; return false; } switch ( $this->next_stack_op ) { case 'void': $this->was_void = true; $this->open_blocks_at[] = $this->namespace_at; $this->open_blocks_length[] = $this->name_at + $this->name_length - $this->namespace_at; break; case 'push': $this->open_blocks_at[] = $this->namespace_at; $this->open_blocks_length[] = $this->name_at + $this->name_length - $this->namespace_at; break; case 'pop': array_pop( $this->open_blocks_at ); array_pop( $this->open_blocks_length ); break; } $this->next_stack_op = null; $this->state = self::MATCHED; return true; } $this->state = self::READY; $after_prev_delimiter = $this->matched_delimiter_at + $this->matched_delimiter_length; $at = $after_prev_delimiter; while ( $at < $end ) { $comment_opening_at = strpos( $text, '<!--', $at ); if ( false === $comment_opening_at ) { if ( str_ends_with( $text, '<!-' ) ) { $backup = 3; } elseif ( str_ends_with( $text, '<!' ) ) { $backup = 2; } elseif ( str_ends_with( $text, '<' ) ) { $backup = 1; } else { $backup = 0; } if ( $after_prev_delimiter < ( $end - $backup ) ) { $this->state = self::HTML_SPAN; $this->after_previous_delimiter = $after_prev_delimiter; $this->matched_delimiter_at = $end - $backup; $this->matched_delimiter_length = $backup; $this->open_blocks_at[] = $after_prev_delimiter; $this->open_blocks_length[] = 0; $this->was_void = true; return true; } if ( $backup > 0 ) { goto incomplete; } $this->state = self::COMPLETE; return false; } $opening_whitespace_at = $comment_opening_at + 4; if ( $opening_whitespace_at >= $end ) { goto incomplete; } $opening_whitespace_length = strspn( $text, " \t\f\r\n", $opening_whitespace_at ); $wp_prefix_at = $opening_whitespace_at + $opening_whitespace_length; if ( $wp_prefix_at >= $end ) { goto incomplete; } if ( 0 === $opening_whitespace_length ) { $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $has_closer = false; if ( '/' === $text[ $wp_prefix_at ] ) { $has_closer = true; ++$wp_prefix_at; } if ( $wp_prefix_at < $end && 0 !== substr_compare( $text, 'wp:', $wp_prefix_at, 3 ) ) { if ( ( $wp_prefix_at + 2 >= $end && str_ends_with( $text, 'wp' ) ) || ( $wp_prefix_at + 1 >= $end && str_ends_with( $text, 'w' ) ) ) { goto incomplete; } $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $namespace_at = $wp_prefix_at + 3; if ( $namespace_at >= $end ) { goto incomplete; } $start_of_namespace = $text[ $namespace_at ]; if ( 'a' > $start_of_namespace || 'z' < $start_of_namespace ) { $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $namespace_length = 1 + strspn( $text, 'abcdefghijklmnopqrstuvwxyz0123456789-_', $namespace_at + 1 ); $separator_at = $namespace_at + $namespace_length; if ( $separator_at >= $end ) { goto incomplete; } $has_separator = '/' === $text[ $separator_at ]; if ( $has_separator ) { $name_at = $separator_at + 1; if ( $name_at >= $end ) { goto incomplete; } $start_of_name = $text[ $name_at ]; if ( 'a' > $start_of_name || 'z' < $start_of_name ) { $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $name_length = 1 + strspn( $text, 'abcdefghijklmnopqrstuvwxyz0123456789-_', $name_at + 1 ); } else { $name_at = $namespace_at; $name_length = $namespace_length; } if ( $name_at + $name_length >= $end ) { goto incomplete; } $after_name_whitespace_at = $name_at + $name_length; $after_name_whitespace_length = strspn( $text, " \t\f\r\n", $after_name_whitespace_at ); $json_at = $after_name_whitespace_at + $after_name_whitespace_length; if ( $json_at >= $end ) { goto incomplete; } if ( 0 === $after_name_whitespace_length ) { $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $has_json = '{' === $text[ $json_at ]; $json_length = 0; $comment_closing_at = strpos( $text, '-->', $json_at ); if ( false === $comment_closing_at ) { goto incomplete; } if ( '/' === $text[ $comment_closing_at - 1 ] ) { $has_void_flag = true; $void_flag_length = 1; } else { $has_void_flag = false; $void_flag_length = 0; } if ( ! $has_json ) { if ( $after_name_whitespace_at + $after_name_whitespace_length === $comment_closing_at - $void_flag_length ) { $this->state = self::MATCHED; break; } $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $after_json_whitespace_length = 0; for ( $char_at = $comment_closing_at - $void_flag_length - 1; $char_at > $json_at; $char_at-- ) { $char = $text[ $char_at ]; switch ( $char ) { case ' ': case "\t": case "\f": case "\r": case "\n": ++$after_json_whitespace_length; continue 2; case '}': $json_length = $char_at - $json_at + 1; break 2; default: ++$at; continue 3; } } if ( 0 === $json_length || 0 === $after_json_whitespace_length ) { $at = $this->find_html_comment_end( $comment_opening_at, $end ); continue; } $this->state = self::MATCHED; break; } if ( self::MATCHED !== $this->state ) { $this->state = self::COMPLETE; return false; } $this->after_previous_delimiter = $after_prev_delimiter; $this->matched_delimiter_at = $comment_opening_at; $this->matched_delimiter_length = $comment_closing_at + 3 - $comment_opening_at; $this->namespace_at = $namespace_at; $this->name_at = $name_at; $this->name_length = $name_length; $this->json_at = $json_at; $this->json_length = $json_length; if ( $has_void_flag ) { $this->type = self::VOID; $this->next_stack_op = 'void'; } elseif ( $has_closer ) { $this->type = self::CLOSER; $this->next_stack_op = 'pop'; } else { $this->type = self::OPENER; $this->next_stack_op = 'push'; } $this->has_closing_flag = $has_closer; if ( $comment_opening_at > $after_prev_delimiter ) { $this->state = self::HTML_SPAN; $this->open_blocks_at[] = $after_prev_delimiter; $this->open_blocks_length[] = 0; $this->was_void = true; return true; } switch ( $this->next_stack_op ) { case 'void': $this->was_void = true; $this->open_blocks_at[] = $namespace_at; $this->open_blocks_length[] = $name_at + $name_length - $namespace_at; break; case 'push': $this->open_blocks_at[] = $namespace_at; $this->open_blocks_length[] = $name_at + $name_length - $namespace_at; break; case 'pop': array_pop( $this->open_blocks_at ); array_pop( $this->open_blocks_length ); break; } $this->next_stack_op = null; return true; incomplete: $this->state = self::COMPLETE; $this->last_error = self::INCOMPLETE_INPUT; return false; } public function get_breadcrumbs(): array { $breadcrumbs = array_fill( 0, count( $this->open_blocks_at ), null ); foreach ( $this->open_blocks_at as $i => $at ) { $block_type = substr( $this->source_text, $at, $this->open_blocks_length[ $i ] ); $breadcrumbs[ $i ] = self::normalize_block_type( $block_type ); } if ( isset( $i ) && 0 === $this->open_blocks_length[ $i ] ) { $breadcrumbs[ $i ] = '#html'; } return $breadcrumbs; } public function get_depth(): int { return count( $this->open_blocks_at ); } public function extract_full_block_and_advance(): ?array { if ( $this->is_html() ) { $chunk = $this->get_html_content(); return array( 'blockName' => null, 'attrs' => array(), 'innerBlocks' => array(), 'innerHTML' => $chunk, 'innerContent' => array( $chunk ), ); } $block = array( 'blockName' => $this->get_block_type(), 'attrs' => $this->allocate_and_return_parsed_attributes() ?? array(), 'innerBlocks' => array(), 'innerHTML' => '', 'innerContent' => array(), ); $depth = $this->get_depth(); while ( $this->next_token() && $this->get_depth() > $depth ) { if ( $this->is_html() ) { $chunk = $this->get_html_content(); $block['innerHTML'] .= $chunk; $block['innerContent'][] = $chunk; continue; } if ( $this->opens_block() ) { $inner_block = $this->extract_full_block_and_advance(); $block['innerBlocks'][] = $inner_block; $block['innerContent'][] = null; } if ( $this->is_html() ) { $chunk = $this->get_html_content(); $block['innerHTML'] .= $chunk; $block['innerContent'][] = $chunk; } } return $block; } private function find_html_comment_end( int $comment_starting_at, int $search_end ): int { $text = $this->source_text; $span_of_dashes = strspn( $text, '-', $comment_starting_at + 2 ); if ( $comment_starting_at + 2 + $span_of_dashes < $search_end && '>' === $text[ $comment_starting_at + 2 + $span_of_dashes ] ) { return $comment_starting_at + $span_of_dashes + 1; } $now_at = $comment_starting_at + 4; while ( $now_at < $search_end ) { $dashes_at = strpos( $text, '--', $now_at ); if ( false === $dashes_at ) { return $search_end; } $closer_must_be_at = $dashes_at + 2 + strspn( $text, '-', $dashes_at + 2 ); if ( $closer_must_be_at < $search_end && '!' === $text[ $closer_must_be_at ] ) { ++$closer_must_be_at; } if ( $closer_must_be_at < $search_end && '>' === $text[ $closer_must_be_at ] ) { return $closer_must_be_at + 1; } ++$now_at; } return $search_end; } public function get_last_error(): ?string { return $this->last_error; } public function get_last_json_error(): int { return $this->last_json_error; } public function get_delimiter_type(): ?string { switch ( $this->state ) { case self::HTML_SPAN: return self::VOID; case self::MATCHED: return $this->type; default: return null; } } public function has_closing_flag(): bool { return $this->has_closing_flag; } public function is_block_type( string $block_type ): bool { if ( '*' === $block_type ) { return true; } if ( $this->is_html() ) { if ( 0 === ( $this->open_blocks_length[0] ?? null ) ) { return ( 'core/freeform' === $block_type || 'freeform' === $block_type ); } return false; } return $this->are_equal_block_types( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length, $block_type, 0, strlen( $block_type ) ); } public static function are_equal_block_types( string $a_text, int $a_at, int $a_length, string $b_text, int $b_at, int $b_length ): bool { $a_ns_length = strcspn( $a_text, '/', $a_at, $a_length ); $b_ns_length = strcspn( $b_text, '/', $b_at, $b_length ); $a_has_ns = $a_ns_length !== $a_length; $b_has_ns = $b_ns_length !== $b_length; if ( $a_has_ns && $b_has_ns ) { if ( $a_length !== $b_length ) { return false; } $a_block_type = substr( $a_text, $a_at, $a_length ); return 0 === substr_compare( $b_text, $a_block_type, $b_at, $b_length ); } if ( $a_has_ns ) { $b_block_type = 'core/' . substr( $b_text, $b_at, $b_length ); return ( strlen( $b_block_type ) === $a_length && 0 === substr_compare( $a_text, $b_block_type, $a_at, $a_length ) ); } if ( $b_has_ns ) { $a_block_type = 'core/' . substr( $a_text, $a_at, $a_length ); return ( strlen( $a_block_type ) === $b_length && 0 === substr_compare( $b_text, $a_block_type, $b_at, $b_length ) ); } if ( $a_length !== $b_length ) { return false; } $a_name = substr( $a_text, $a_at, $a_length ); return 0 === substr_compare( $b_text, $a_name, $b_at, $b_length ); } public function opens_block( string ...$block_type ): bool { if ( self::HTML_SPAN === $this->state && 1 !== count( $this->open_blocks_at ) ) { return false; } if ( self::CLOSER === $this->type && ! $this->is_html() ) { return false; } if ( count( $block_type ) === 0 ) { return true; } foreach ( $block_type as $block ) { if ( $this->is_block_type( $block ) ) { return true; } } return false; } public function is_html(): bool { return self::HTML_SPAN === $this->state; } public function is_non_whitespace_html(): bool { if ( ! $this->is_html() ) { return false; } $length = $this->matched_delimiter_at - $this->after_previous_delimiter; $whitespace_length = strspn( $this->source_text, " \t\f\r\n", $this->after_previous_delimiter, $length ); return $whitespace_length !== $length; } public function get_html_content(): ?string { if ( ! $this->is_html() ) { return null; } return substr( $this->source_text, $this->after_previous_delimiter, $this->matched_delimiter_at - $this->after_previous_delimiter ); } public function get_block_type(): ?string { if ( self::READY === $this->state || self::COMPLETE === $this->state || self::INCOMPLETE_INPUT === $this->state ) { return null; } if ( $this->is_html() ) { return null; } $block_type = substr( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length ); return self::normalize_block_type( $block_type ); } public function get_printable_block_type(): ?string { if ( self::READY === $this->state || self::COMPLETE === $this->state || self::INCOMPLETE_INPUT === $this->state ) { return null; } if ( $this->is_html() ) { return 1 === count( $this->open_blocks_at ) ? 'core/freeform' : '#innerHTML'; } $block_type = substr( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length ); return self::normalize_block_type( $block_type ); } public static function normalize_block_type( string $block_type ): string { return false === strpos( $block_type, '/' ) ? "core/{$block_type}" : $block_type; } public function get_attributes() { throw new Exception( 'Lazy attribute parsing not yet supported' ); } public function allocate_and_return_parsed_attributes(): ?array { $this->last_json_error = JSON_ERROR_NONE; if ( self::CLOSER === $this->type || $this->is_html() || 0 === $this->json_length ) { return null; } $json_span = substr( $this->source_text, $this->json_at, $this->json_length ); $parsed = json_decode( $json_span, null, 512, JSON_OBJECT_AS_ARRAY | JSON_INVALID_UTF8_SUBSTITUTE ); $last_error = json_last_error(); $this->last_json_error = $last_error; return ( JSON_ERROR_NONE === $last_error && is_array( $parsed ) ) ? $parsed : null; } public function get_span(): ?WP_HTML_Span { switch ( $this->state ) { case self::HTML_SPAN: return new WP_HTML_Span( $this->after_previous_delimiter, $this->matched_delimiter_at - $this->after_previous_delimiter ); case self::MATCHED: return new WP_HTML_Span( $this->matched_delimiter_at, $this->matched_delimiter_length ); default: return null; } } const CLOSER = 'closer'; const OPENER = 'opener'; const VOID = 'void'; const READY = 'processor-ready'; const MATCHED = 'processor-matched'; const HTML_SPAN = 'processor-html-span'; const INCOMPLETE_INPUT = 'incomplete-input'; const COMPLETE = 'processor-complete'; }
###require ABSPATH . WPINC . '/class-wp-http.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } if ( ! class_exists( 'WpOrg\Requests\Autoload' ) ) { require ABSPATH . WPINC . '/Requests/src/Autoload.php'; WpOrg\Requests\Autoload::register(); WpOrg\Requests\Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' ); } class WP_Http { const HTTP_CONTINUE = 100; const SWITCHING_PROTOCOLS = 101; const PROCESSING = 102; const EARLY_HINTS = 103; const OK = 200; const CREATED = 201; const ACCEPTED = 202; const NON_AUTHORITATIVE_INFORMATION = 203; const NO_CONTENT = 204; const RESET_CONTENT = 205; const PARTIAL_CONTENT = 206; const MULTI_STATUS = 207; const IM_USED = 226; const MULTIPLE_CHOICES = 300; const MOVED_PERMANENTLY = 301; const FOUND = 302; const SEE_OTHER = 303; const NOT_MODIFIED = 304; const USE_PROXY = 305; const RESERVED = 306; const TEMPORARY_REDIRECT = 307; const PERMANENT_REDIRECT = 308; const BAD_REQUEST = 400; const UNAUTHORIZED = 401; const PAYMENT_REQUIRED = 402; const FORBIDDEN = 403; const NOT_FOUND = 404; const METHOD_NOT_ALLOWED = 405; const NOT_ACCEPTABLE = 406; const PROXY_AUTHENTICATION_REQUIRED = 407; const REQUEST_TIMEOUT = 408; const CONFLICT = 409; const GONE = 410; const LENGTH_REQUIRED = 411; const PRECONDITION_FAILED = 412; const REQUEST_ENTITY_TOO_LARGE = 413; const REQUEST_URI_TOO_LONG = 414; const UNSUPPORTED_MEDIA_TYPE = 415; const REQUESTED_RANGE_NOT_SATISFIABLE = 416; const EXPECTATION_FAILED = 417; const IM_A_TEAPOT = 418; const MISDIRECTED_REQUEST = 421; const UNPROCESSABLE_ENTITY = 422; const LOCKED = 423; const FAILED_DEPENDENCY = 424; const TOO_EARLY = 425; const UPGRADE_REQUIRED = 426; const PRECONDITION_REQUIRED = 428; const TOO_MANY_REQUESTS = 429; const REQUEST_HEADER_FIELDS_TOO_LARGE = 431; const UNAVAILABLE_FOR_LEGAL_REASONS = 451; const INTERNAL_SERVER_ERROR = 500; const NOT_IMPLEMENTED = 501; const BAD_GATEWAY = 502; const SERVICE_UNAVAILABLE = 503; const GATEWAY_TIMEOUT = 504; const HTTP_VERSION_NOT_SUPPORTED = 505; const VARIANT_ALSO_NEGOTIATES = 506; const INSUFFICIENT_STORAGE = 507; const NOT_EXTENDED = 510; const NETWORK_AUTHENTICATION_REQUIRED = 511; public function request( $url, $args = array() ) { $defaults = array( 'method' => 'GET', 'timeout' => apply_filters( 'http_request_timeout', 5, $url ), 'redirection' => apply_filters( 'http_request_redirection_count', 5, $url ), 'httpversion' => apply_filters( 'http_request_version', '1.0', $url ), 'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ), $url ), 'reject_unsafe_urls' => apply_filters( 'http_request_reject_unsafe_urls', false, $url ), 'blocking' => true, 'headers' => array(), 'cookies' => array(), 'body' => null, 'compress' => false, 'decompress' => true, 'sslverify' => true, 'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt', 'stream' => false, 'filename' => null, 'limit_response_size' => null, ); $args = wp_parse_args( $args ); if ( isset( $args['method'] ) && 'HEAD' === $args['method'] ) { $defaults['redirection'] = 0; } $parsed_args = wp_parse_args( $args, $defaults ); $parsed_args = apply_filters( 'http_request_args', $parsed_args, $url ); if ( ! isset( $parsed_args['_redirection'] ) ) { $parsed_args['_redirection'] = $parsed_args['redirection']; } $pre = apply_filters( 'pre_http_request', false, $parsed_args, $url ); if ( false !== $pre ) { return $pre; } if ( function_exists( 'wp_kses_bad_protocol' ) ) { if ( $parsed_args['reject_unsafe_urls'] ) { $url = wp_http_validate_url( $url ); } if ( $url ) { $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) ); } } $parsed_url = parse_url( $url ); if ( empty( $url ) || empty( $parsed_url['scheme'] ) ) { $response = new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) ); do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url ); return $response; } if ( $this->block_request( $url ) ) { $response = new WP_Error( 'http_request_not_executed', __( 'User has blocked requests through HTTP.' ) ); do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url ); return $response; } if ( $parsed_args['stream'] ) { if ( empty( $parsed_args['filename'] ) ) { $parsed_args['filename'] = get_temp_dir() . basename( $url ); } $parsed_args['blocking'] = true; if ( ! wp_is_writable( dirname( $parsed_args['filename'] ) ) ) { $response = new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) ); do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url ); return $response; } } if ( is_null( $parsed_args['headers'] ) ) { $parsed_args['headers'] = array(); } if ( ! is_array( $parsed_args['headers'] ) ) { $processed_headers = self::processHeaders( $parsed_args['headers'] ); $parsed_args['headers'] = $processed_headers['headers']; } $headers = $parsed_args['headers']; $data = $parsed_args['body']; $type = $parsed_args['method']; $options = array( 'timeout' => $parsed_args['timeout'], 'useragent' => $parsed_args['user-agent'], 'blocking' => $parsed_args['blocking'], 'hooks' => new WP_HTTP_Requests_Hooks( $url, $parsed_args ), ); $options['hooks']->register( 'requests.before_redirect', array( static::class, 'browser_redirect_compatibility' ) ); if ( function_exists( 'wp_kses_bad_protocol' ) && $parsed_args['reject_unsafe_urls'] ) { $options['hooks']->register( 'requests.before_redirect', array( static::class, 'validate_redirects' ) ); } if ( $parsed_args['stream'] ) { $options['filename'] = $parsed_args['filename']; } if ( empty( $parsed_args['redirection'] ) ) { $options['follow_redirects'] = false; } else { $options['redirects'] = $parsed_args['redirection']; } if ( isset( $parsed_args['limit_response_size'] ) ) { $options['max_bytes'] = $parsed_args['limit_response_size']; } if ( ! empty( $parsed_args['cookies'] ) ) { $options['cookies'] = self::normalize_cookies( $parsed_args['cookies'] ); } if ( ! $parsed_args['sslverify'] ) { $options['verify'] = false; $options['verifyname'] = false; } else { $options['verify'] = $parsed_args['sslcertificates']; } if ( 'HEAD' !== $type && 'GET' !== $type ) { $options['data_format'] = 'body'; } $options['verify'] = apply_filters( 'https_ssl_verify', $options['verify'], $url ); $proxy = new WP_HTTP_Proxy(); if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { $options['proxy'] = new WpOrg\Requests\Proxy\Http( $proxy->host() . ':' . $proxy->port() ); if ( $proxy->use_authentication() ) { $options['proxy']->use_authentication = true; $options['proxy']->user = $proxy->username(); $options['proxy']->pass = $proxy->password(); } } mbstring_binary_safe_encoding(); try { $requests_response = WpOrg\Requests\Requests::request( $url, $headers, $data, $type, $options ); $http_response = new WP_HTTP_Requests_Response( $requests_response, $parsed_args['filename'] ); $response = $http_response->to_array(); $response['http_response'] = $http_response; } catch ( WpOrg\Requests\Exception $e ) { $response = new WP_Error( 'http_request_failed', $e->getMessage() ); } reset_mbstring_encoding(); do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url ); if ( is_wp_error( $response ) ) { return $response; } if ( ! $parsed_args['blocking'] ) { return array( 'headers' => array(), 'body' => '', 'response' => array( 'code' => false, 'message' => false, ), 'cookies' => array(), 'http_response' => null, ); } return apply_filters( 'http_response', $response, $parsed_args, $url ); } public static function normalize_cookies( $cookies ) { $cookie_jar = new WpOrg\Requests\Cookie\Jar(); foreach ( $cookies as $name => $value ) { if ( $value instanceof WP_Http_Cookie ) { $attributes = array_filter( $value->get_attributes(), static function ( $attr ) { return null !== $attr; } ); $cookie_jar[ $value->name ] = new WpOrg\Requests\Cookie( (string) $value->name, $value->value, $attributes, array( 'host-only' => $value->host_only ) ); } elseif ( is_scalar( $value ) ) { $cookie_jar[ $name ] = new WpOrg\Requests\Cookie( (string) $name, (string) $value ); } } return $cookie_jar; } public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) { if ( 302 === $original->status_code ) { $options['type'] = WpOrg\Requests\Requests::GET; } } public static function validate_redirects( $location ) { if ( ! wp_http_validate_url( $location ) ) { throw new WpOrg\Requests\Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' ); } } public function _get_first_available_transport( $args, $url = null ) { $transports = array( 'curl', 'streams' ); $request_order = apply_filters_deprecated( 'http_api_transports', array( $transports, $args, $url ), '6.4.0' ); foreach ( $request_order as $transport ) { if ( in_array( $transport, $transports, true ) ) { $transport = ucfirst( $transport ); } $class = 'WP_Http_' . $transport; if ( ! call_user_func( array( $class, 'test' ), $args, $url ) ) { continue; } return $class; } return false; } private function _dispatch_request( $url, $args ) { static $transports = array(); $class = $this->_get_first_available_transport( $args, $url ); if ( ! $class ) { return new WP_Error( 'http_failure', __( 'There are no HTTP transports available which can complete the requested request.' ) ); } if ( empty( $transports[ $class ] ) ) { $transports[ $class ] = new $class(); } $response = $transports[ $class ]->request( $url, $args ); do_action( 'http_api_debug', $response, 'response', $class, $args, $url ); if ( is_wp_error( $response ) ) { return $response; } return apply_filters( 'http_response', $response, $args, $url ); } public function post( $url, $args = array() ) { $defaults = array( 'method' => 'POST' ); $parsed_args = wp_parse_args( $args, $defaults ); return $this->request( $url, $parsed_args ); } public function get( $url, $args = array() ) { $defaults = array( 'method' => 'GET' ); $parsed_args = wp_parse_args( $args, $defaults ); return $this->request( $url, $parsed_args ); } public function head( $url, $args = array() ) { $defaults = array( 'method' => 'HEAD' ); $parsed_args = wp_parse_args( $args, $defaults ); return $this->request( $url, $parsed_args ); } public static function processResponse( $response ) { $response = explode( "\r\n\r\n", $response, 2 ); return array( 'headers' => $response[0], 'body' => isset( $response[1] ) ? $response[1] : '', ); } public static function processHeaders( $headers, $url = '' ) { if ( is_string( $headers ) ) { $headers = str_replace( "\r\n", "\n", $headers ); $headers = preg_replace( '/\n[ \t]/', ' ', $headers ); $headers = explode( "\n", $headers ); } $response = array( 'code' => 0, 'message' => '', ); for ( $i = count( $headers ) - 1; $i >= 0; $i-- ) { if ( ! empty( $headers[ $i ] ) && ! str_contains( $headers[ $i ], ':' ) ) { $headers = array_splice( $headers, $i ); break; } } $cookies = array(); $newheaders = array(); foreach ( (array) $headers as $tempheader ) { if ( empty( $tempheader ) ) { continue; } if ( ! str_contains( $tempheader, ':' ) ) { $stack = explode( ' ', $tempheader, 3 ); $stack[] = ''; list( , $response['code'], $response['message']) = $stack; continue; } list($key, $value) = explode( ':', $tempheader, 2 ); $key = strtolower( $key ); $value = trim( $value ); if ( isset( $newheaders[ $key ] ) ) { if ( ! is_array( $newheaders[ $key ] ) ) { $newheaders[ $key ] = array( $newheaders[ $key ] ); } $newheaders[ $key ][] = $value; } else { $newheaders[ $key ] = $value; } if ( 'set-cookie' === $key ) { $cookies[] = new WP_Http_Cookie( $value, $url ); } } $response['code'] = (int) $response['code']; return array( 'response' => $response, 'headers' => $newheaders, 'cookies' => $cookies, ); } public static function buildCookieHeader( &$r ) { if ( ! empty( $r['cookies'] ) ) { foreach ( $r['cookies'] as $name => $value ) { if ( ! is_object( $value ) ) { $r['cookies'][ $name ] = new WP_Http_Cookie( array( 'name' => $name, 'value' => $value, ) ); } } $cookies_header = ''; foreach ( (array) $r['cookies'] as $cookie ) { $cookies_header .= $cookie->getHeaderValue() . '; '; } $cookies_header = substr( $cookies_header, 0, -2 ); $r['headers']['cookie'] = $cookies_header; } } public static function chunkTransferDecode( $body ) { if ( ! preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', trim( $body ) ) ) { return $body; } $parsed_body = ''; $body_original = $body; while ( true ) { $has_chunk = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $body, $match ); if ( ! $has_chunk || empty( $match[1] ) ) { return $body_original; } $length = hexdec( $match[1] ); $chunk_length = strlen( $match[0] ); $parsed_body .= substr( $body, $chunk_length, $length ); $body = substr( $body, $length + $chunk_length ); if ( '0' === trim( $body ) ) { return $parsed_body; } } } public function block_request( $uri ) { if ( ! defined( 'WP_HTTP_BLOCK_EXTERNAL' ) || ! WP_HTTP_BLOCK_EXTERNAL ) { return false; } $check = parse_url( $uri ); if ( ! $check ) { return true; } $home = parse_url( get_option( 'siteurl' ) ); if ( 'localhost' === $check['host'] || ( isset( $home['host'] ) && $home['host'] === $check['host'] ) ) { return apply_filters( 'block_local_requests', false ); } if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) ) { return true; } static $accessible_hosts = null; static $wildcard_regex = array(); if ( null === $accessible_hosts ) { $accessible_hosts = preg_split( '|,\s*|', WP_ACCESSIBLE_HOSTS ); if ( str_contains( WP_ACCESSIBLE_HOSTS, '*' ) ) { $wildcard_regex = array(); foreach ( $accessible_hosts as $host ) { $wildcard_regex[] = str_replace( '\*', '.+', preg_quote( $host, '/' ) ); } $wildcard_regex = '/^(' . implode( '|', $wildcard_regex ) . ')$/i'; } } if ( ! empty( $wildcard_regex ) ) { return ! preg_match( $wildcard_regex, $check['host'] ); } else { return ! in_array( $check['host'], $accessible_hosts, true ); } } protected static function parse_url( $url ) { _deprecated_function( __METHOD__, '4.4.0', 'wp_parse_url()' ); return wp_parse_url( $url ); } public static function make_absolute_url( $maybe_relative_path, $url ) { if ( empty( $url ) ) { return $maybe_relative_path; } $url_parts = wp_parse_url( $url ); if ( ! $url_parts ) { return $maybe_relative_path; } $relative_url_parts = wp_parse_url( $maybe_relative_path ); if ( ! $relative_url_parts ) { return $maybe_relative_path; } if ( ! empty( $relative_url_parts['scheme'] ) ) { return $maybe_relative_path; } $absolute_path = $url_parts['scheme'] . '://'; if ( isset( $relative_url_parts['host'] ) ) { $absolute_path .= $relative_url_parts['host']; if ( isset( $relative_url_parts['port'] ) ) { $absolute_path .= ':' . $relative_url_parts['port']; } } else { $absolute_path .= $url_parts['host']; if ( isset( $url_parts['port'] ) ) { $absolute_path .= ':' . $url_parts['port']; } } $path = ! empty( $url_parts['path'] ) ? $url_parts['path'] : '/'; if ( ! empty( $relative_url_parts['path'] ) && '/' === $relative_url_parts['path'][0] ) { $path = $relative_url_parts['path']; } elseif ( ! empty( $relative_url_parts['path'] ) ) { $path = substr( $path, 0, strrpos( $path, '/' ) + 1 ); $path .= $relative_url_parts['path']; while ( strpos( $path, '../' ) > 1 ) { $path = preg_replace( '![^/]+/\.\./!', '', $path ); } $path = preg_replace( '!^/(\.\./)+!', '', $path ); } if ( ! empty( $relative_url_parts['query'] ) ) { $path .= '?' . $relative_url_parts['query']; } if ( ! empty( $relative_url_parts['fragment'] ) ) { $path .= '#' . $relative_url_parts['fragment']; } return $absolute_path . '/' . ltrim( $path, '/' ); } public static function handle_redirects( $url, $args, $response ) { if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] ) { return false; } if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 ) { return false; } if ( $args['redirection']-- <= 0 ) { return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); } $redirect_location = $response['headers']['location']; if ( is_array( $redirect_location ) ) { $redirect_location = array_pop( $redirect_location ); } $redirect_location = self::make_absolute_url( $redirect_location, $url ); if ( 'POST' === $args['method'] ) { if ( in_array( $response['response']['code'], array( 302, 303 ), true ) ) { $args['method'] = 'GET'; } } if ( ! empty( $response['cookies'] ) ) { foreach ( $response['cookies'] as $cookie ) { if ( $cookie->test( $redirect_location ) ) { $args['cookies'][] = $cookie; } } } return wp_remote_request( $redirect_location, $args ); } public static function is_ip_address( $maybe_ip ) { if ( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $maybe_ip ) ) { return 4; } if ( str_contains( $maybe_ip, ':' ) && preg_match( '/^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i', trim( $maybe_ip, ' []' ) ) ) { return 6; } return false; } }
###require ABSPATH . WPINC . '/class-wp-http-streams.php';
class WP_Http_Streams { public function request( $url, $args = array() ) { $defaults = array( 'method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array(), 'decompress' => false, 'stream' => false, 'filename' => null, ); $parsed_args = wp_parse_args( $args, $defaults ); if ( isset( $parsed_args['headers']['User-Agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['User-Agent']; unset( $parsed_args['headers']['User-Agent'] ); } elseif ( isset( $parsed_args['headers']['user-agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['user-agent']; unset( $parsed_args['headers']['user-agent'] ); } WP_Http::buildCookieHeader( $parsed_args ); $parsed_url = parse_url( $url ); $connect_host = $parsed_url['host']; $secure_transport = ( 'ssl' === $parsed_url['scheme'] || 'https' === $parsed_url['scheme'] ); if ( ! isset( $parsed_url['port'] ) ) { if ( 'ssl' === $parsed_url['scheme'] || 'https' === $parsed_url['scheme'] ) { $parsed_url['port'] = 443; $secure_transport = true; } else { $parsed_url['port'] = 80; } } if ( ! isset( $parsed_url['path'] ) ) { $parsed_url['path'] = '/'; } if ( isset( $parsed_args['headers']['Host'] ) || isset( $parsed_args['headers']['host'] ) ) { if ( isset( $parsed_args['headers']['Host'] ) ) { $parsed_url['host'] = $parsed_args['headers']['Host']; } else { $parsed_url['host'] = $parsed_args['headers']['host']; } unset( $parsed_args['headers']['Host'], $parsed_args['headers']['host'] ); } if ( 'localhost' === strtolower( $connect_host ) ) { $connect_host = '127.0.0.1'; } $connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host; $is_local = isset( $parsed_args['local'] ) && $parsed_args['local']; $ssl_verify = isset( $parsed_args['sslverify'] ) && $parsed_args['sslverify']; if ( $is_local ) { $ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify, $url ); } elseif ( ! $is_local ) { $ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify, $url ); } $proxy = new WP_HTTP_Proxy(); $context = stream_context_create( array( 'ssl' => array( 'verify_peer' => $ssl_verify, 'capture_peer_cert' => $ssl_verify, 'SNI_enabled' => true, 'cafile' => $parsed_args['sslcertificates'], 'allow_self_signed' => ! $ssl_verify, ), ) ); $timeout = (int) floor( $parsed_args['timeout'] ); $utimeout = 0; if ( $timeout !== (int) $parsed_args['timeout'] ) { $utimeout = 1000000 * $parsed_args['timeout'] % 1000000; } $connect_timeout = max( $timeout, 1 ); $connection_error = null; $connection_error_str = null; if ( ! WP_DEBUG ) { if ( $secure_transport ) { $error_reporting = error_reporting( 0 ); } if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { $handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } else { $handle = @stream_socket_client( $connect_host . ':' . $parsed_url['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } if ( $secure_transport ) { error_reporting( $error_reporting ); } } else { if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { $handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } else { $handle = stream_socket_client( $connect_host . ':' . $parsed_url['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } } if ( false === $handle ) { if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) { return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); } return new WP_Error( 'http_request_failed', $connection_error . ': ' . $connection_error_str ); } if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) { if ( ! self::verify_ssl_certificate( $handle, $parsed_url['host'] ) ) { return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); } } stream_set_timeout( $handle, $timeout, $utimeout ); if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { $request_path = $url; } else { $request_path = $parsed_url['path'] . ( isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '' ); } $headers = strtoupper( $parsed_args['method'] ) . ' ' . $request_path . ' HTTP/' . $parsed_args['httpversion'] . "\r\n"; $include_port_in_host_header = ( ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) || ( 'http' === $parsed_url['scheme'] && 80 !== $parsed_url['port'] ) || ( 'https' === $parsed_url['scheme'] && 443 !== $parsed_url['port'] ) ); if ( $include_port_in_host_header ) { $headers .= 'Host: ' . $parsed_url['host'] . ':' . $parsed_url['port'] . "\r\n"; } else { $headers .= 'Host: ' . $parsed_url['host'] . "\r\n"; } if ( isset( $parsed_args['user-agent'] ) ) { $headers .= 'User-agent: ' . $parsed_args['user-agent'] . "\r\n"; } if ( is_array( $parsed_args['headers'] ) ) { foreach ( (array) $parsed_args['headers'] as $header => $header_value ) { $headers .= $header . ': ' . $header_value . "\r\n"; } } else { $headers .= $parsed_args['headers']; } if ( $proxy->use_authentication() ) { $headers .= $proxy->authentication_header() . "\r\n"; } $headers .= "\r\n"; if ( ! is_null( $parsed_args['body'] ) ) { $headers .= $parsed_args['body']; } fwrite( $handle, $headers ); if ( ! $parsed_args['blocking'] ) { stream_set_blocking( $handle, 0 ); fclose( $handle ); return array( 'headers' => array(), 'body' => '', 'response' => array( 'code' => false, 'message' => false, ), 'cookies' => array(), ); } $response = ''; $body_started = false; $keep_reading = true; $block_size = 4096; if ( isset( $parsed_args['limit_response_size'] ) ) { $block_size = min( $block_size, $parsed_args['limit_response_size'] ); } if ( $parsed_args['stream'] ) { if ( ! WP_DEBUG ) { $stream_handle = @fopen( $parsed_args['filename'], 'w+' ); } else { $stream_handle = fopen( $parsed_args['filename'], 'w+' ); } if ( ! $stream_handle ) { return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for %1$s to %2$s.' ), 'fopen()', $parsed_args['filename'] ) ); } $bytes_written = 0; while ( ! feof( $handle ) && $keep_reading ) { $block = fread( $handle, $block_size ); if ( ! $body_started ) { $response .= $block; if ( strpos( $response, "\r\n\r\n" ) ) { $processed_response = WP_Http::processResponse( $response ); $body_started = true; $block = $processed_response['body']; unset( $response ); $processed_response['body'] = ''; } } $this_block_size = strlen( $block ); if ( isset( $parsed_args['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $parsed_args['limit_response_size'] ) { $this_block_size = ( $parsed_args['limit_response_size'] - $bytes_written ); $block = substr( $block, 0, $this_block_size ); } $bytes_written_to_file = fwrite( $stream_handle, $block ); if ( $bytes_written_to_file !== $this_block_size ) { fclose( $handle ); fclose( $stream_handle ); return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) ); } $bytes_written += $bytes_written_to_file; $keep_reading = ( ! isset( $parsed_args['limit_response_size'] ) || $bytes_written < $parsed_args['limit_response_size'] ); } fclose( $stream_handle ); } else { $header_length = 0; while ( ! feof( $handle ) && $keep_reading ) { $block = fread( $handle, $block_size ); $response .= $block; if ( ! $body_started && strpos( $response, "\r\n\r\n" ) ) { $header_length = strpos( $response, "\r\n\r\n" ) + 4; $body_started = true; } $keep_reading = ( ! $body_started || ! isset( $parsed_args['limit_response_size'] ) || strlen( $response ) < ( $header_length + $parsed_args['limit_response_size'] ) ); } $processed_response = WP_Http::processResponse( $response ); unset( $response ); } fclose( $handle ); $processed_headers = WP_Http::processHeaders( $processed_response['headers'], $url ); $response = array( 'headers' => $processed_headers['headers'], 'body' => null, 'response' => $processed_headers['response'], 'cookies' => $processed_headers['cookies'], 'filename' => $parsed_args['filename'], ); $redirect_response = WP_Http::handle_redirects( $url, $parsed_args, $response ); if ( false !== $redirect_response ) { return $redirect_response; } if ( ! empty( $processed_response['body'] ) && isset( $processed_headers['headers']['transfer-encoding'] ) && 'chunked' === $processed_headers['headers']['transfer-encoding'] ) { $processed_response['body'] = WP_Http::chunkTransferDecode( $processed_response['body'] ); } if ( true === $parsed_args['decompress'] && true === WP_Http_Encoding::should_decode( $processed_headers['headers'] ) ) { $processed_response['body'] = WP_Http_Encoding::decompress( $processed_response['body'] ); } if ( isset( $parsed_args['limit_response_size'] ) && strlen( $processed_response['body'] ) > $parsed_args['limit_response_size'] ) { $processed_response['body'] = substr( $processed_response['body'], 0, $parsed_args['limit_response_size'] ); } $response['body'] = $processed_response['body']; return $response; } public static function verify_ssl_certificate( $stream, $host ) { $context_options = stream_context_get_options( $stream ); if ( empty( $context_options['ssl']['peer_certificate'] ) ) { return false; } $cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] ); if ( ! $cert ) { return false; } $host_type = ( WP_Http::is_ip_address( $host ) ? 'ip' : 'dns' ); $certificate_hostnames = array(); if ( ! empty( $cert['extensions']['subjectAltName'] ) ) { $match_against = preg_split( '/,\s*/', $cert['extensions']['subjectAltName'] ); foreach ( $match_against as $match ) { list( $match_type, $match_host ) = explode( ':', $match ); if ( strtolower( trim( $match_type ) ) === $host_type ) { $certificate_hostnames[] = strtolower( trim( $match_host ) ); } } } elseif ( ! empty( $cert['subject']['CN'] ) ) { $certificate_hostnames[] = strtolower( $cert['subject']['CN'] ); } if ( in_array( strtolower( $host ), $certificate_hostnames, true ) ) { return true; } if ( 'ip' === $host_type ) { return false; } if ( substr_count( $host, '.' ) < 2 ) { return false; } $wildcard_host = preg_replace( '/^[^.]+\./', '*.', $host ); return in_array( strtolower( $wildcard_host ), $certificate_hostnames, true ); } public static function test( $args = array() ) { if ( ! function_exists( 'stream_socket_client' ) ) { return false; } $is_ssl = isset( $args['ssl'] ) && $args['ssl']; if ( $is_ssl ) { if ( ! extension_loaded( 'openssl' ) ) { return false; } if ( ! function_exists( 'openssl_x509_parse' ) ) { return false; } } return apply_filters( 'use_streams_transport', true, $args ); } } class WP_HTTP_Fsockopen extends WP_Http_Streams { }
###require ABSPATH . WPINC . '/class-wp-http-curl.php';
class WP_Http_Curl { private $headers = ''; private $body = ''; private $max_body_length = false; private $stream_handle = false; private $bytes_written_total = 0; public function request( $url, $args = array() ) { $defaults = array( 'method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array(), 'decompress' => false, 'stream' => false, 'filename' => null, ); $parsed_args = wp_parse_args( $args, $defaults ); if ( isset( $parsed_args['headers']['User-Agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['User-Agent']; unset( $parsed_args['headers']['User-Agent'] ); } elseif ( isset( $parsed_args['headers']['user-agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['user-agent']; unset( $parsed_args['headers']['user-agent'] ); } WP_Http::buildCookieHeader( $parsed_args ); $handle = curl_init(); $proxy = new WP_HTTP_Proxy(); if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { curl_setopt( $handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); curl_setopt( $handle, CURLOPT_PROXY, $proxy->host() ); curl_setopt( $handle, CURLOPT_PROXYPORT, $proxy->port() ); if ( $proxy->use_authentication() ) { curl_setopt( $handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); curl_setopt( $handle, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); } } $is_local = isset( $parsed_args['local'] ) && $parsed_args['local']; $ssl_verify = isset( $parsed_args['sslverify'] ) && $parsed_args['sslverify']; if ( $is_local ) { $ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify, $url ); } elseif ( ! $is_local ) { $ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify, $url ); } $timeout = (int) ceil( $parsed_args['timeout'] ); curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, $timeout ); curl_setopt( $handle, CURLOPT_TIMEOUT, $timeout ); curl_setopt( $handle, CURLOPT_URL, $url ); curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, ( true === $ssl_verify ) ? 2 : false ); curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, $ssl_verify ); if ( $ssl_verify ) { curl_setopt( $handle, CURLOPT_CAINFO, $parsed_args['sslcertificates'] ); } curl_setopt( $handle, CURLOPT_USERAGENT, $parsed_args['user-agent'] ); curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, false ); curl_setopt( $handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS ); switch ( $parsed_args['method'] ) { case 'HEAD': curl_setopt( $handle, CURLOPT_NOBODY, true ); break; case 'POST': curl_setopt( $handle, CURLOPT_POST, true ); curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] ); break; case 'PUT': curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, 'PUT' ); curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] ); break; default: curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, $parsed_args['method'] ); if ( ! is_null( $parsed_args['body'] ) ) { curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] ); } break; } if ( true === $parsed_args['blocking'] ) { curl_setopt( $handle, CURLOPT_HEADERFUNCTION, array( $this, 'stream_headers' ) ); curl_setopt( $handle, CURLOPT_WRITEFUNCTION, array( $this, 'stream_body' ) ); } curl_setopt( $handle, CURLOPT_HEADER, false ); if ( isset( $parsed_args['limit_response_size'] ) ) { $this->max_body_length = (int) $parsed_args['limit_response_size']; } else { $this->max_body_length = false; } if ( $parsed_args['stream'] ) { if ( ! WP_DEBUG ) { $this->stream_handle = @fopen( $parsed_args['filename'], 'w+' ); } else { $this->stream_handle = fopen( $parsed_args['filename'], 'w+' ); } if ( ! $this->stream_handle ) { return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for %1$s to %2$s.' ), 'fopen()', $parsed_args['filename'] ) ); } } else { $this->stream_handle = false; } if ( ! empty( $parsed_args['headers'] ) ) { $headers = array(); foreach ( $parsed_args['headers'] as $name => $value ) { $headers[] = "{$name}: $value"; } curl_setopt( $handle, CURLOPT_HTTPHEADER, $headers ); } if ( '1.0' === $parsed_args['httpversion'] ) { curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); } else { curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 ); } do_action_ref_array( 'http_api_curl', array( &$handle, $parsed_args, $url ) ); if ( ! $parsed_args['blocking'] ) { curl_exec( $handle ); $curl_error = curl_error( $handle ); if ( $curl_error ) { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return new WP_Error( 'http_request_failed', $curl_error ); } if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ), true ) ) { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); } if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return array( 'headers' => array(), 'body' => '', 'response' => array( 'code' => false, 'message' => false, ), 'cookies' => array(), ); } curl_exec( $handle ); $processed_headers = WP_Http::processHeaders( $this->headers, $url ); $body = $this->body; $bytes_written_total = $this->bytes_written_total; $this->headers = ''; $this->body = ''; $this->bytes_written_total = 0; $curl_error = curl_errno( $handle ); if ( $curl_error || ( 0 === strlen( $body ) && empty( $processed_headers['headers'] ) ) ) { if ( CURLE_WRITE_ERROR === $curl_error ) { if ( ! $this->max_body_length || $this->max_body_length !== $bytes_written_total ) { if ( $parsed_args['stream'] ) { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } fclose( $this->stream_handle ); return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) ); } else { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return new WP_Error( 'http_request_failed', curl_error( $handle ) ); } } } else { $curl_error = curl_error( $handle ); if ( $curl_error ) { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return new WP_Error( 'http_request_failed', $curl_error ); } } if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ), true ) ) { if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); } } if ( PHP_VERSION_ID < 80000 ) { curl_close( $handle ); } if ( $parsed_args['stream'] ) { fclose( $this->stream_handle ); } $response = array( 'headers' => $processed_headers['headers'], 'body' => null, 'response' => $processed_headers['response'], 'cookies' => $processed_headers['cookies'], 'filename' => $parsed_args['filename'], ); $redirect_response = WP_Http::handle_redirects( $url, $parsed_args, $response ); if ( false !== $redirect_response ) { return $redirect_response; } if ( true === $parsed_args['decompress'] && true === WP_Http_Encoding::should_decode( $processed_headers['headers'] ) ) { $body = WP_Http_Encoding::decompress( $body ); } $response['body'] = $body; return $response; } private function stream_headers( $handle, $headers ) { $this->headers .= $headers; return strlen( $headers ); } private function stream_body( $handle, $data ) { $data_length = strlen( $data ); if ( $this->max_body_length && ( $this->bytes_written_total + $data_length ) > $this->max_body_length ) { $data_length = ( $this->max_body_length - $this->bytes_written_total ); $data = substr( $data, 0, $data_length ); } if ( $this->stream_handle ) { $bytes_written = fwrite( $this->stream_handle, $data ); } else { $this->body .= $data; $bytes_written = $data_length; } $this->bytes_written_total += $bytes_written; return $bytes_written; } public static function test( $args = array() ) { if ( ! function_exists( 'curl_init' ) || ! function_exists( 'curl_exec' ) ) { return false; } $is_ssl = isset( $args['ssl'] ) && $args['ssl']; if ( $is_ssl ) { $curl_version = curl_version(); if ( ! ( CURL_VERSION_SSL & $curl_version['features'] ) ) { return false; } } return apply_filters( 'use_curl_transport', true, $args ); } }
###require ABSPATH . WPINC . '/class-wp-http-proxy.php';
class WP_HTTP_Proxy { public function is_enabled() { return defined( 'WP_PROXY_HOST' ) && defined( 'WP_PROXY_PORT' ); } public function use_authentication() { return defined( 'WP_PROXY_USERNAME' ) && defined( 'WP_PROXY_PASSWORD' ); } public function host() { if ( defined( 'WP_PROXY_HOST' ) ) { return WP_PROXY_HOST; } return ''; } public function port() { if ( defined( 'WP_PROXY_PORT' ) ) { return WP_PROXY_PORT; } return ''; } public function username() { if ( defined( 'WP_PROXY_USERNAME' ) ) { return WP_PROXY_USERNAME; } return ''; } public function password() { if ( defined( 'WP_PROXY_PASSWORD' ) ) { return WP_PROXY_PASSWORD; } return ''; } public function authentication() { return $this->username() . ':' . $this->password(); } public function authentication_header() { return 'Proxy-Authorization: Basic ' . base64_encode( $this->authentication() ); } public function send_through_proxy( $uri ) { $check = parse_url( $uri ); if ( false === $check ) { return true; } $home = parse_url( get_option( 'siteurl' ) ); $result = apply_filters( 'pre_http_send_through_proxy', null, $uri, $check, $home ); if ( ! is_null( $result ) ) { return $result; } if ( 'localhost' === $check['host'] || ( isset( $home['host'] ) && $home['host'] === $check['host'] ) ) { return false; } if ( ! defined( 'WP_PROXY_BYPASS_HOSTS' ) ) { return true; } static $bypass_hosts = null; static $wildcard_regex = array(); if ( null === $bypass_hosts ) { $bypass_hosts = preg_split( '|,\s*|', WP_PROXY_BYPASS_HOSTS ); if ( str_contains( WP_PROXY_BYPASS_HOSTS, '*' ) ) { $wildcard_regex = array(); foreach ( $bypass_hosts as $host ) { $wildcard_regex[] = str_replace( '\*', '.+', preg_quote( $host, '/' ) ); } $wildcard_regex = '/^(' . implode( '|', $wildcard_regex ) . ')$/i'; } } if ( ! empty( $wildcard_regex ) ) { return ! preg_match( $wildcard_regex, $check['host'] ); } else { return ! in_array( $check['host'], $bypass_hosts, true ); } } }
###require ABSPATH . WPINC . '/class-wp-http-cookie.php';
class WP_Http_Cookie { public $name; public $value; public $expires; public $path; public $domain; public $port; public $host_only; public function __construct( $data, $requested_url = '' ) { if ( $requested_url ) { $parsed_url = parse_url( $requested_url ); } if ( isset( $parsed_url['host'] ) ) { $this->domain = $parsed_url['host']; } $this->path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '/'; if ( ! str_ends_with( $this->path, '/' ) ) { $this->path = dirname( $this->path ) . '/'; } if ( is_string( $data ) ) { $pairs = explode( ';', $data ); $name = trim( substr( $pairs[0], 0, strpos( $pairs[0], '=' ) ) ); $value = substr( $pairs[0], strpos( $pairs[0], '=' ) + 1 ); $this->name = $name; $this->value = urldecode( $value ); array_shift( $pairs ); foreach ( $pairs as $pair ) { $pair = rtrim( $pair ); if ( empty( $pair ) ) { continue; } list( $key, $val ) = strpos( $pair, '=' ) ? explode( '=', $pair ) : array( $pair, '' ); $key = strtolower( trim( $key ) ); if ( 'expires' === $key ) { $val = strtotime( $val ); } $this->$key = $val; } } else { if ( ! isset( $data['name'] ) ) { return; } foreach ( array( 'name', 'value', 'path', 'domain', 'port', 'host_only' ) as $field ) { if ( isset( $data[ $field ] ) ) { $this->$field = $data[ $field ]; } } if ( isset( $data['expires'] ) ) { $this->expires = is_int( $data['expires'] ) ? $data['expires'] : strtotime( $data['expires'] ); } else { $this->expires = null; } } } public function test( $url ) { if ( is_null( $this->name ) ) { return false; } if ( isset( $this->expires ) && time() > $this->expires ) { return false; } $url = parse_url( $url ); $url['port'] = isset( $url['port'] ) ? $url['port'] : ( 'https' === $url['scheme'] ? 443 : 80 ); $url['path'] = isset( $url['path'] ) ? $url['path'] : '/'; $path = isset( $this->path ) ? $this->path : '/'; $port = isset( $this->port ) ? $this->port : null; $domain = isset( $this->domain ) ? strtolower( $this->domain ) : strtolower( $url['host'] ); if ( false === stripos( $domain, '.' ) ) { $domain .= '.local'; } $domain = ( str_starts_with( $domain, '.' ) ) ? substr( $domain, 1 ) : $domain; if ( ! str_ends_with( $url['host'], $domain ) ) { return false; } if ( ! empty( $port ) && ! in_array( $url['port'], array_map( 'intval', explode( ',', $port ) ), true ) ) { return false; } if ( ! str_starts_with( $url['path'], $path ) ) { return false; } return true; } public function getHeaderValue() { if ( ! isset( $this->name ) || ! isset( $this->value ) ) { return ''; } return $this->name . '=' . apply_filters( 'wp_http_cookie_value', $this->value, $this->name ); } public function getFullHeader() { return 'Cookie: ' . $this->getHeaderValue(); } public function get_attributes() { return array( 'expires' => $this->expires, 'path' => $this->path, 'domain' => $this->domain, ); } }
###require ABSPATH . WPINC . '/class-wp-http-encoding.php';
class WP_Http_Encoding { public static function compress( $raw, $level = 9, $supports = null ) { return gzdeflate( $raw, $level ); } public static function decompress( $compressed, $length = null ) { if ( empty( $compressed ) ) { return $compressed; } $decompressed = @gzinflate( $compressed ); if ( false !== $decompressed ) { return $decompressed; } $decompressed = self::compatible_gzinflate( $compressed ); if ( false !== $decompressed ) { return $decompressed; } $decompressed = @gzuncompress( $compressed ); if ( false !== $decompressed ) { return $decompressed; } if ( function_exists( 'gzdecode' ) ) { $decompressed = @gzdecode( $compressed ); if ( false !== $decompressed ) { return $decompressed; } } return $compressed; } public static function compatible_gzinflate( $gz_data ) { if ( str_starts_with( $gz_data, "\x1f\x8b\x08" ) ) { $i = 10; $flg = ord( substr( $gz_data, 3, 1 ) ); if ( $flg > 0 ) { if ( $flg & 4 ) { list($xlen) = unpack( 'v', substr( $gz_data, $i, 2 ) ); $i = $i + 2 + $xlen; } if ( $flg & 8 ) { $i = strpos( $gz_data, "\0", $i ) + 1; } if ( $flg & 16 ) { $i = strpos( $gz_data, "\0", $i ) + 1; } if ( $flg & 2 ) { $i = $i + 2; } } $decompressed = @gzinflate( substr( $gz_data, $i, -8 ) ); if ( false !== $decompressed ) { return $decompressed; } } $decompressed = @gzinflate( substr( $gz_data, 2 ) ); if ( false !== $decompressed ) { return $decompressed; } return false; } public static function accept_encoding( $url, $args ) { $type = array(); $compression_enabled = self::is_available(); if ( ! $args['decompress'] ) { $compression_enabled = false; } elseif ( $args['stream'] ) { $compression_enabled = false; } elseif ( isset( $args['limit_response_size'] ) ) { $compression_enabled = false; } if ( $compression_enabled ) { if ( function_exists( 'gzinflate' ) ) { $type[] = 'deflate;q=1.0'; } if ( function_exists( 'gzuncompress' ) ) { $type[] = 'compress;q=0.5'; } if ( function_exists( 'gzdecode' ) ) { $type[] = 'gzip;q=0.5'; } } $type = apply_filters( 'wp_http_accept_encoding', $type, $url, $args ); return implode( ', ', $type ); } public static function content_encoding() { return 'deflate'; } public static function should_decode( $headers ) { if ( is_array( $headers ) ) { if ( array_key_exists( 'content-encoding', $headers ) && ! empty( $headers['content-encoding'] ) ) { return true; } } elseif ( is_string( $headers ) ) { return ( stripos( $headers, 'content-encoding:' ) !== false ); } return false; } public static function is_available() { return ( function_exists( 'gzuncompress' ) || function_exists( 'gzdeflate' ) || function_exists( 'gzinflate' ) ); } }
###require ABSPATH . WPINC . '/class-wp-http-response.php';
class WP_HTTP_Response { public $data; public $headers; public $status; public function __construct( $data = null, $status = 200, $headers = array() ) { $this->set_data( $data ); $this->set_status( $status ); $this->set_headers( $headers ); } public function get_headers() { return $this->headers; } public function set_headers( $headers ) { $this->headers = $headers; } public function header( $key, $value, $replace = true ) { if ( $replace || ! isset( $this->headers[ $key ] ) ) { $this->headers[ $key ] = $value; } else { $this->headers[ $key ] .= ', ' . $value; } } public function get_status() { return $this->status; } public function set_status( $code ) { $this->status = absint( $code ); } public function get_data() { return $this->data; } public function set_data( $data ) { $this->data = $data; } public function jsonSerialize() { return $this->get_data(); } }
###require ABSPATH . WPINC . '/class-wp-http-requests-response.php';
class WP_HTTP_Requests_Response extends WP_HTTP_Response { protected $response; protected $filename; public function __construct( WpOrg\Requests\Response $response, $filename = '' ) { $this->response = $response; $this->filename = $filename; } public function get_response_object() { return $this->response; } public function get_headers() { $converted = new WpOrg\Requests\Utility\CaseInsensitiveDictionary(); foreach ( $this->response->headers->getAll() as $key => $value ) { if ( count( $value ) === 1 ) { $converted[ $key ] = $value[0]; } else { $converted[ $key ] = $value; } } return $converted; } public function set_headers( $headers ) { $this->response->headers = new WpOrg\Requests\Response\Headers( $headers ); } public function header( $key, $value, $replace = true ) { if ( $replace ) { unset( $this->response->headers[ $key ] ); } $this->response->headers[ $key ] = $value; } public function get_status() { return $this->response->status_code; } public function set_status( $code ) { $this->response->status_code = absint( $code ); } public function get_data() { return $this->response->body; } public function set_data( $data ) { $this->response->body = $data; } public function get_cookies() { $cookies = array(); foreach ( $this->response->cookies as $cookie ) { $cookies[] = new WP_Http_Cookie( array( 'name' => $cookie->name, 'value' => urldecode( $cookie->value ), 'expires' => isset( $cookie->attributes['expires'] ) ? $cookie->attributes['expires'] : null, 'path' => isset( $cookie->attributes['path'] ) ? $cookie->attributes['path'] : null, 'domain' => isset( $cookie->attributes['domain'] ) ? $cookie->attributes['domain'] : null, 'host_only' => isset( $cookie->flags['host-only'] ) ? $cookie->flags['host-only'] : null, ) ); } return $cookies; } public function to_array() { return array( 'headers' => $this->get_headers(), 'body' => $this->get_data(), 'response' => array( 'code' => $this->get_status(), 'message' => get_status_header_desc( $this->get_status() ), ), 'cookies' => $this->get_cookies(), 'filename' => $this->filename, ); } }
###require ABSPATH . WPINC . '/class-wp-http-requests-hooks.php';
class WP_HTTP_Requests_Hooks extends WpOrg\Requests\Hooks { protected $url; protected $request = array(); public function __construct( $url, $request ) { $this->url = $url; $this->request = $request; } public function dispatch( $hook, $parameters = array() ) { $result = parent::dispatch( $hook, $parameters ); switch ( $hook ) { case 'curl.before_send': do_action_ref_array( 'http_api_curl', array( &$parameters[0], $this->request, $this->url ) ); break; } do_action_ref_array( "requests-{$hook}", $parameters, $this->request, $this->url ); return $result; } }
###require ABSPATH . WPINC . '/widgets.php';
global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; $wp_registered_sidebars = array(); $wp_registered_widgets = array(); $wp_registered_widget_controls = array(); $wp_registered_widget_updates = array(); $_wp_sidebars_widgets = array(); $GLOBALS['_wp_deprecated_widgets_callbacks'] = array( 'wp_widget_pages', 'wp_widget_pages_control', 'wp_widget_calendar', 'wp_widget_calendar_control', 'wp_widget_archives', 'wp_widget_archives_control', 'wp_widget_links', 'wp_widget_meta', 'wp_widget_meta_control', 'wp_widget_search', 'wp_widget_recent_entries', 'wp_widget_recent_entries_control', 'wp_widget_tag_cloud', 'wp_widget_tag_cloud_control', 'wp_widget_categories', 'wp_widget_categories_control', 'wp_widget_text', 'wp_widget_text_control', 'wp_widget_rss', 'wp_widget_rss_control', 'wp_widget_recent_comments', 'wp_widget_recent_comments_control', ); function register_widget( $widget ) { global $wp_widget_factory; $wp_widget_factory->register( $widget ); } function unregister_widget( $widget ) { global $wp_widget_factory; $wp_widget_factory->unregister( $widget ); } function register_sidebars( $number = 1, $args = array() ) { global $wp_registered_sidebars; $number = (int) $number; if ( is_string( $args ) ) { parse_str( $args, $args ); } for ( $i = 1; $i <= $number; $i++ ) { $_args = $args; if ( $number > 1 ) { if ( isset( $args['name'] ) ) { $_args['name'] = sprintf( $args['name'], $i ); } else { $_args['name'] = sprintf( __( 'Sidebar %d' ), $i ); } } else { $_args['name'] = isset( $args['name'] ) ? $args['name'] : __( 'Sidebar' ); } if ( isset( $args['id'] ) ) { $_args['id'] = $args['id']; $n = 2; while ( is_registered_sidebar( $_args['id'] ) ) { $_args['id'] = $args['id'] . '-' . $n++; } } else { $n = count( $wp_registered_sidebars ); do { $_args['id'] = 'sidebar-' . ++$n; } while ( is_registered_sidebar( $_args['id'] ) ); } register_sidebar( $_args ); } } function register_sidebar( $args = array() ) { global $wp_registered_sidebars; $i = count( $wp_registered_sidebars ) + 1; $id_is_empty = empty( $args['id'] ); $defaults = array( 'name' => sprintf( __( 'Sidebar %d' ), $i ), 'id' => "sidebar-$i", 'description' => '', 'class' => '', 'before_widget' => '<li id="%1$s" class="widget %2$s">', 'after_widget' => "</li>\n", 'before_title' => '<h2 class="widgettitle">', 'after_title' => "</h2>\n", 'before_sidebar' => '', 'after_sidebar' => '', 'show_in_rest' => false, ); $sidebar = wp_parse_args( $args, apply_filters( 'register_sidebar_defaults', $defaults ) ); if ( $id_is_empty ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'No %1$s was set in the arguments array for the "%2$s" sidebar. Defaulting to "%3$s". Manually set the %1$s to "%3$s" to silence this notice and keep existing sidebar content.' ), '<code>id</code>', $sidebar['name'], $sidebar['id'] ), '4.2.0' ); } $wp_registered_sidebars[ $sidebar['id'] ] = $sidebar; add_theme_support( 'widgets' ); do_action( 'register_sidebar', $sidebar ); return $sidebar['id']; } function unregister_sidebar( $sidebar_id ) { global $wp_registered_sidebars; unset( $wp_registered_sidebars[ $sidebar_id ] ); } function is_registered_sidebar( $sidebar_id ) { global $wp_registered_sidebars; return isset( $wp_registered_sidebars[ $sidebar_id ] ); } function wp_register_sidebar_widget( $id, $name, $output_callback, $options = array(), ...$params ) { global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks; $id = strtolower( $id ); if ( empty( $output_callback ) ) { unset( $wp_registered_widgets[ $id ] ); return; } $id_base = _get_widget_id_base( $id ); if ( in_array( $output_callback, $_wp_deprecated_widgets_callbacks, true ) && ! is_callable( $output_callback ) ) { unset( $wp_registered_widget_controls[ $id ] ); unset( $wp_registered_widget_updates[ $id_base ] ); return; } $defaults = array( 'classname' => $output_callback ); $options = wp_parse_args( $options, $defaults ); $widget = array( 'name' => $name, 'id' => $id, 'callback' => $output_callback, 'params' => $params, ); $widget = array_merge( $widget, $options ); if ( is_callable( $output_callback ) && ( ! isset( $wp_registered_widgets[ $id ] ) || did_action( 'widgets_init' ) ) ) { do_action( 'wp_register_sidebar_widget', $widget ); $wp_registered_widgets[ $id ] = $widget; } } function wp_widget_description( $id ) { if ( ! is_scalar( $id ) ) { return; } global $wp_registered_widgets; if ( isset( $wp_registered_widgets[ $id ]['description'] ) ) { return esc_html( $wp_registered_widgets[ $id ]['description'] ); } } function wp_sidebar_description( $id ) { if ( ! is_scalar( $id ) ) { return; } global $wp_registered_sidebars; if ( isset( $wp_registered_sidebars[ $id ]['description'] ) ) { return wp_kses( $wp_registered_sidebars[ $id ]['description'], 'sidebar_description' ); } } function wp_unregister_sidebar_widget( $id ) { do_action( 'wp_unregister_sidebar_widget', $id ); wp_register_sidebar_widget( $id, '', '' ); wp_unregister_widget_control( $id ); } function wp_register_widget_control( $id, $name, $control_callback, $options = array(), ...$params ) { global $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks; $id = strtolower( $id ); $id_base = _get_widget_id_base( $id ); if ( empty( $control_callback ) ) { unset( $wp_registered_widget_controls[ $id ] ); unset( $wp_registered_widget_updates[ $id_base ] ); return; } if ( in_array( $control_callback, $_wp_deprecated_widgets_callbacks, true ) && ! is_callable( $control_callback ) ) { unset( $wp_registered_widgets[ $id ] ); return; } if ( isset( $wp_registered_widget_controls[ $id ] ) && ! did_action( 'widgets_init' ) ) { return; } $defaults = array( 'width' => 250, 'height' => 200, ); $options = wp_parse_args( $options, $defaults ); $options['width'] = (int) $options['width']; $options['height'] = (int) $options['height']; $widget = array( 'name' => $name, 'id' => $id, 'callback' => $control_callback, 'params' => $params, ); $widget = array_merge( $widget, $options ); $wp_registered_widget_controls[ $id ] = $widget; if ( isset( $wp_registered_widget_updates[ $id_base ] ) ) { return; } if ( isset( $widget['params'][0]['number'] ) ) { $widget['params'][0]['number'] = -1; } unset( $widget['width'], $widget['height'], $widget['name'], $widget['id'] ); $wp_registered_widget_updates[ $id_base ] = $widget; } function _register_widget_update_callback( $id_base, $update_callback, $options = array(), ...$params ) { global $wp_registered_widget_updates; if ( isset( $wp_registered_widget_updates[ $id_base ] ) ) { if ( empty( $update_callback ) ) { unset( $wp_registered_widget_updates[ $id_base ] ); } return; } $widget = array( 'callback' => $update_callback, 'params' => $params, ); $widget = array_merge( $widget, $options ); $wp_registered_widget_updates[ $id_base ] = $widget; } function _register_widget_form_callback( $id, $name, $form_callback, $options = array(), ...$params ) { global $wp_registered_widget_controls; $id = strtolower( $id ); if ( empty( $form_callback ) ) { unset( $wp_registered_widget_controls[ $id ] ); return; } if ( isset( $wp_registered_widget_controls[ $id ] ) && ! did_action( 'widgets_init' ) ) { return; } $defaults = array( 'width' => 250, 'height' => 200, ); $options = wp_parse_args( $options, $defaults ); $options['width'] = (int) $options['width']; $options['height'] = (int) $options['height']; $widget = array( 'name' => $name, 'id' => $id, 'callback' => $form_callback, 'params' => $params, ); $widget = array_merge( $widget, $options ); $wp_registered_widget_controls[ $id ] = $widget; } function wp_unregister_widget_control( $id ) { wp_register_widget_control( $id, '', '' ); } function dynamic_sidebar( $index = 1 ) { global $wp_registered_sidebars, $wp_registered_widgets; if ( is_int( $index ) ) { $index = "sidebar-$index"; } else { $index = sanitize_title( $index ); foreach ( (array) $wp_registered_sidebars as $key => $value ) { if ( sanitize_title( $value['name'] ) === $index ) { $index = $key; break; } } } $sidebars_widgets = wp_get_sidebars_widgets(); if ( empty( $wp_registered_sidebars[ $index ] ) || empty( $sidebars_widgets[ $index ] ) || ! is_array( $sidebars_widgets[ $index ] ) ) { do_action( 'dynamic_sidebar_before', $index, false ); do_action( 'dynamic_sidebar_after', $index, false ); return apply_filters( 'dynamic_sidebar_has_widgets', false, $index ); } $sidebar = $wp_registered_sidebars[ $index ]; $sidebar['before_sidebar'] = sprintf( $sidebar['before_sidebar'], $sidebar['id'], $sidebar['class'] ); do_action( 'dynamic_sidebar_before', $index, true ); if ( ! is_admin() && ! empty( $sidebar['before_sidebar'] ) ) { echo $sidebar['before_sidebar']; } $did_one = false; foreach ( (array) $sidebars_widgets[ $index ] as $id ) { if ( ! isset( $wp_registered_widgets[ $id ] ) ) { continue; } $params = array_merge( array( array_merge( $sidebar, array( 'widget_id' => $id, 'widget_name' => $wp_registered_widgets[ $id ]['name'], ) ), ), (array) $wp_registered_widgets[ $id ]['params'] ); $classname_ = ''; foreach ( (array) $wp_registered_widgets[ $id ]['classname'] as $cn ) { if ( is_string( $cn ) ) { $classname_ .= '_' . $cn; } elseif ( is_object( $cn ) ) { $classname_ .= '_' . get_class( $cn ); } } $classname_ = ltrim( $classname_, '_' ); $params[0]['before_widget'] = sprintf( $params[0]['before_widget'], str_replace( '\\', '_', $id ), $classname_ ); $params = apply_filters( 'dynamic_sidebar_params', $params ); $callback = $wp_registered_widgets[ $id ]['callback']; do_action( 'dynamic_sidebar', $wp_registered_widgets[ $id ] ); if ( is_callable( $callback ) ) { call_user_func_array( $callback, $params ); $did_one = true; } } if ( ! is_admin() && ! empty( $sidebar['after_sidebar'] ) ) { echo $sidebar['after_sidebar']; } do_action( 'dynamic_sidebar_after', $index, true ); return apply_filters( 'dynamic_sidebar_has_widgets', $did_one, $index ); } function is_active_widget( $callback = false, $widget_id = false, $id_base = false, $skip_inactive = true ) { global $wp_registered_widgets; $sidebars_widgets = wp_get_sidebars_widgets(); if ( is_array( $sidebars_widgets ) ) { foreach ( $sidebars_widgets as $sidebar => $widgets ) { if ( $skip_inactive && ( 'wp_inactive_widgets' === $sidebar || str_starts_with( $sidebar, 'orphaned_widgets' ) ) ) { continue; } if ( is_array( $widgets ) ) { foreach ( $widgets as $widget ) { if ( ( $callback && isset( $wp_registered_widgets[ $widget ]['callback'] ) && $wp_registered_widgets[ $widget ]['callback'] === $callback ) || ( $id_base && _get_widget_id_base( $widget ) === $id_base ) ) { if ( ! $widget_id || $widget_id === $wp_registered_widgets[ $widget ]['id'] ) { return $sidebar; } } } } } } return false; } function is_dynamic_sidebar() { global $wp_registered_widgets, $wp_registered_sidebars; $sidebars_widgets = get_option( 'sidebars_widgets' ); foreach ( (array) $wp_registered_sidebars as $index => $sidebar ) { if ( ! empty( $sidebars_widgets[ $index ] ) ) { foreach ( (array) $sidebars_widgets[ $index ] as $widget ) { if ( array_key_exists( $widget, $wp_registered_widgets ) ) { return true; } } } } return false; } function is_active_sidebar( $index ) { $index = ( is_int( $index ) ) ? "sidebar-$index" : sanitize_title( $index ); $sidebars_widgets = wp_get_sidebars_widgets(); $is_active_sidebar = ! empty( $sidebars_widgets[ $index ] ); return apply_filters( 'is_active_sidebar', $is_active_sidebar, $index ); } function wp_get_sidebars_widgets( $deprecated = true ) { if ( true !== $deprecated ) { _deprecated_argument( __FUNCTION__, '2.8.1' ); } global $_wp_sidebars_widgets, $sidebars_widgets; if ( ! is_admin() ) { if ( empty( $_wp_sidebars_widgets ) ) { $_wp_sidebars_widgets = get_option( 'sidebars_widgets', array() ); } $sidebars_widgets = $_wp_sidebars_widgets; } else { $sidebars_widgets = get_option( 'sidebars_widgets', array() ); } if ( is_array( $sidebars_widgets ) && isset( $sidebars_widgets['array_version'] ) ) { unset( $sidebars_widgets['array_version'] ); } return apply_filters( 'sidebars_widgets', $sidebars_widgets ); } function wp_get_sidebar( $id ) { global $wp_registered_sidebars; foreach ( (array) $wp_registered_sidebars as $sidebar ) { if ( $sidebar['id'] === $id ) { return $sidebar; } } if ( 'wp_inactive_widgets' === $id ) { return array( 'id' => 'wp_inactive_widgets', 'name' => __( 'Inactive widgets' ), ); } return null; } function wp_set_sidebars_widgets( $sidebars_widgets ) { global $_wp_sidebars_widgets; $_wp_sidebars_widgets = null; if ( ! isset( $sidebars_widgets['array_version'] ) ) { $sidebars_widgets['array_version'] = 3; } update_option( 'sidebars_widgets', $sidebars_widgets ); } function wp_get_widget_defaults() { global $wp_registered_sidebars; $defaults = array(); foreach ( (array) $wp_registered_sidebars as $index => $sidebar ) { $defaults[ $index ] = array(); } return $defaults; } function wp_convert_widget_settings( $base_name, $option_name, $settings ) { $single = false; $changed = false; if ( empty( $settings ) ) { $single = true; } else { foreach ( array_keys( $settings ) as $number ) { if ( 'number' === $number ) { continue; } if ( ! is_numeric( $number ) ) { $single = true; break; } } } if ( $single ) { $settings = array( 2 => $settings ); if ( is_admin() ) { $sidebars_widgets = get_option( 'sidebars_widgets' ); } else { if ( empty( $GLOBALS['_wp_sidebars_widgets'] ) ) { $GLOBALS['_wp_sidebars_widgets'] = get_option( 'sidebars_widgets', array() ); } $sidebars_widgets = &$GLOBALS['_wp_sidebars_widgets']; } foreach ( (array) $sidebars_widgets as $index => $sidebar ) { if ( is_array( $sidebar ) ) { foreach ( $sidebar as $i => $name ) { if ( $base_name === $name ) { $sidebars_widgets[ $index ][ $i ] = "$name-2"; $changed = true; break 2; } } } } if ( is_admin() && $changed ) { update_option( 'sidebars_widgets', $sidebars_widgets ); } } $settings['_multiwidget'] = 1; if ( is_admin() ) { update_option( $option_name, $settings ); } return $settings; } function the_widget( $widget, $instance = array(), $args = array() ) { global $wp_widget_factory; if ( ! isset( $wp_widget_factory->widgets[ $widget ] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Widgets need to be registered using %s, before they can be displayed.' ), '<code>register_widget()</code>' ), '4.9.0' ); return; } $widget_obj = $wp_widget_factory->widgets[ $widget ]; if ( ! ( $widget_obj instanceof WP_Widget ) ) { return; } $default_args = array( 'before_widget' => '<div class="widget %s">', 'after_widget' => '</div>', 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>', ); $args = wp_parse_args( $args, $default_args ); $args['before_widget'] = sprintf( $args['before_widget'], $widget_obj->widget_options['classname'] ); $instance = wp_parse_args( $instance ); $instance = apply_filters( 'widget_display_callback', $instance, $widget_obj, $args ); if ( false === $instance ) { return; } do_action( 'the_widget', $widget, $instance, $args ); $widget_obj->_set( -1 ); $widget_obj->widget( $args, $instance ); } function _get_widget_id_base( $id ) { return preg_replace( '/-[0-9]+$/', '', $id ); } function _wp_sidebars_changed() { global $sidebars_widgets; if ( ! is_array( $sidebars_widgets ) ) { $sidebars_widgets = wp_get_sidebars_widgets(); } retrieve_widgets( true ); } function retrieve_widgets( $theme_changed = false ) { global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets; $registered_sidebars_keys = array_keys( $wp_registered_sidebars ); $registered_widgets_ids = array_keys( $wp_registered_widgets ); if ( ! is_array( get_theme_mod( 'sidebars_widgets' ) ) ) { if ( empty( $sidebars_widgets ) ) { return array(); } unset( $sidebars_widgets['array_version'] ); $sidebars_widgets_keys = array_keys( $sidebars_widgets ); sort( $sidebars_widgets_keys ); sort( $registered_sidebars_keys ); if ( $sidebars_widgets_keys === $registered_sidebars_keys ) { $sidebars_widgets = _wp_remove_unregistered_widgets( $sidebars_widgets, $registered_widgets_ids ); return $sidebars_widgets; } } $sidebars_widgets = _wp_remove_unregistered_widgets( $sidebars_widgets, $registered_widgets_ids ); $sidebars_widgets = wp_map_sidebars_widgets( $sidebars_widgets ); foreach ( $sidebars_widgets as $key => $value ) { if ( ! is_array( $value ) ) { $sidebars_widgets[ $key ] = array(); } } $shown_widgets = array_merge( ...array_values( $sidebars_widgets ) ); $lost_widgets = array_diff( $registered_widgets_ids, $shown_widgets ); foreach ( $lost_widgets as $key => $widget_id ) { $number = preg_replace( '/.+?-([0-9]+)$/', '$1', $widget_id ); if ( is_numeric( $number ) && (int) $number < 2 ) { unset( $lost_widgets[ $key ] ); } } $sidebars_widgets['wp_inactive_widgets'] = array_merge( $lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets'] ); if ( 'customize' !== $theme_changed ) { wp_set_sidebars_widgets( $sidebars_widgets ); } return $sidebars_widgets; } function wp_map_sidebars_widgets( $existing_sidebars_widgets ) { global $wp_registered_sidebars; $new_sidebars_widgets = array( 'wp_inactive_widgets' => array(), ); if ( ! is_array( $existing_sidebars_widgets ) || empty( $existing_sidebars_widgets ) ) { return $new_sidebars_widgets; } foreach ( $existing_sidebars_widgets as $sidebar => $widgets ) { if ( 'wp_inactive_widgets' === $sidebar || str_starts_with( $sidebar, 'orphaned_widgets' ) ) { $new_sidebars_widgets['wp_inactive_widgets'] = array_merge( $new_sidebars_widgets['wp_inactive_widgets'], (array) $widgets ); unset( $existing_sidebars_widgets[ $sidebar ] ); } } if ( 1 === count( $existing_sidebars_widgets ) && 1 === count( $wp_registered_sidebars ) ) { $new_sidebars_widgets[ key( $wp_registered_sidebars ) ] = array_pop( $existing_sidebars_widgets ); return $new_sidebars_widgets; } $existing_sidebars = array_keys( $existing_sidebars_widgets ); foreach ( $wp_registered_sidebars as $sidebar => $name ) { if ( in_array( $sidebar, $existing_sidebars, true ) ) { $new_sidebars_widgets[ $sidebar ] = $existing_sidebars_widgets[ $sidebar ]; unset( $existing_sidebars_widgets[ $sidebar ] ); } elseif ( ! array_key_exists( $sidebar, $new_sidebars_widgets ) ) { $new_sidebars_widgets[ $sidebar ] = array(); } } if ( ! empty( $existing_sidebars_widgets ) ) { $common_slug_groups = array( array( 'sidebar', 'primary', 'main', 'right' ), array( 'second', 'left' ), array( 'sidebar-2', 'footer', 'bottom' ), array( 'header', 'top' ), ); foreach ( $common_slug_groups as $slug_group ) { foreach ( $slug_group as $slug ) { foreach ( $wp_registered_sidebars as $new_sidebar => $args ) { if ( false === stripos( $new_sidebar, $slug ) && false === stripos( $slug, $new_sidebar ) ) { continue; } foreach ( $existing_sidebars_widgets as $sidebar => $widgets ) { foreach ( $slug_group as $slug ) { if ( false === stripos( $sidebar, $slug ) && false === stripos( $slug, $sidebar ) ) { continue; } if ( ! empty( $existing_sidebars_widgets[ $sidebar ] ) ) { $new_sidebars_widgets[ $new_sidebar ] = array_merge( $new_sidebars_widgets[ $new_sidebar ], $existing_sidebars_widgets[ $sidebar ] ); unset( $existing_sidebars_widgets[ $sidebar ] ); continue 3; } } } } } } } foreach ( $existing_sidebars_widgets as $widgets ) { if ( is_array( $widgets ) && ! empty( $widgets ) ) { $new_sidebars_widgets['wp_inactive_widgets'] = array_merge( $new_sidebars_widgets['wp_inactive_widgets'], $widgets ); } } $old_sidebars_widgets = get_theme_mod( 'sidebars_widgets' ); $old_sidebars_widgets = isset( $old_sidebars_widgets['data'] ) ? $old_sidebars_widgets['data'] : false; if ( is_array( $old_sidebars_widgets ) ) { $old_sidebars_widgets = array_filter( $old_sidebars_widgets ); foreach ( $new_sidebars_widgets as $new_sidebar => $new_widgets ) { if ( array_key_exists( $new_sidebar, $old_sidebars_widgets ) && ! empty( $new_widgets ) ) { unset( $old_sidebars_widgets[ $new_sidebar ] ); } } foreach ( $old_sidebars_widgets as $sidebar => $widgets ) { if ( str_starts_with( $sidebar, 'orphaned_widgets' ) ) { unset( $old_sidebars_widgets[ $sidebar ] ); } } $old_sidebars_widgets = _wp_remove_unregistered_widgets( $old_sidebars_widgets ); foreach ( $new_sidebars_widgets as $key => $value ) { if ( ! is_array( $value ) ) { $new_sidebars_widgets[ $key ] = array(); } } if ( ! empty( $old_sidebars_widgets ) ) { foreach ( $old_sidebars_widgets as $old_sidebar => $old_widgets ) { foreach ( $new_sidebars_widgets as $new_sidebar => $new_widgets ) { foreach ( $old_widgets as $key => $widget_id ) { $active_key = array_search( $widget_id, $new_widgets, true ); if ( false !== $active_key ) { if ( 'wp_inactive_widgets' === $new_sidebar ) { unset( $new_sidebars_widgets['wp_inactive_widgets'][ $active_key ] ); } else { unset( $old_sidebars_widgets[ $old_sidebar ][ $key ] ); } } } } } } $new_sidebars_widgets = array_merge( $new_sidebars_widgets, $old_sidebars_widgets ); } return $new_sidebars_widgets; } function _wp_remove_unregistered_widgets( $sidebars_widgets, $allowed_widget_ids = array() ) { if ( empty( $allowed_widget_ids ) ) { $allowed_widget_ids = array_keys( $GLOBALS['wp_registered_widgets'] ); } foreach ( $sidebars_widgets as $sidebar => $widgets ) { if ( is_array( $widgets ) ) { $sidebars_widgets[ $sidebar ] = array_intersect( $widgets, $allowed_widget_ids ); } } return $sidebars_widgets; } function wp_widget_rss_output( $rss, $args = array() ) { if ( is_string( $rss ) ) { $rss = fetch_feed( $rss ); } elseif ( is_array( $rss ) && isset( $rss['url'] ) ) { $args = $rss; $rss = fetch_feed( $rss['url'] ); } elseif ( ! is_object( $rss ) ) { return; } if ( is_wp_error( $rss ) ) { if ( is_admin() || current_user_can( 'manage_options' ) ) { echo '<p><strong>' . __( 'RSS Error:' ) . '</strong> ' . esc_html( $rss->get_error_message() ) . '</p>'; } return; } $default_args = array( 'show_author' => 0, 'show_date' => 0, 'show_summary' => 0, 'items' => 0, ); $args = wp_parse_args( $args, $default_args ); $items = (int) $args['items']; if ( $items < 1 || 20 < $items ) { $items = 10; } $show_summary = (int) $args['show_summary']; $show_author = (int) $args['show_author']; $show_date = (int) $args['show_date']; if ( ! $rss->get_item_quantity() ) { echo '<ul><li>' . __( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '</li></ul>'; $rss->__destruct(); unset( $rss ); return; } echo '<ul>'; foreach ( $rss->get_items( 0, $items ) as $item ) { $link = $item->get_link(); while ( ! empty( $link ) && stristr( $link, 'http' ) !== $link ) { $link = substr( $link, 1 ); } $link = esc_url( strip_tags( $link ) ); $title = esc_html( trim( strip_tags( $item->get_title() ) ) ); if ( empty( $title ) ) { $title = __( 'Untitled' ); } $desc = html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) ); $desc = esc_attr( wp_trim_words( $desc, 55, ' […]' ) ); $summary = ''; if ( $show_summary ) { $summary = $desc; if ( str_ends_with( $summary, '[...]' ) ) { $summary = substr( $summary, 0, -5 ) . '[…]'; } $summary = '<div class="rssSummary">' . esc_html( $summary ) . '</div>'; } $date = ''; if ( $show_date ) { $date = $item->get_date( 'U' ); if ( $date ) { $date = ' <span class="rss-date">' . date_i18n( get_option( 'date_format' ), $date ) . '</span>'; } } $author = ''; if ( $show_author ) { $author = $item->get_author(); if ( is_object( $author ) ) { $author = $author->get_name(); $author = ' <cite>' . esc_html( strip_tags( $author ) ) . '</cite>'; } } if ( '' === $link ) { echo "<li>$title{$date}{$summary}{$author}</li>"; } elseif ( $show_summary ) { echo "<li><a class='rsswidget' href='$link'>$title</a>{$date}{$summary}{$author}</li>"; } else { echo "<li><a class='rsswidget' href='$link'>$title</a>{$date}{$author}</li>"; } } echo '</ul>'; $rss->__destruct(); unset( $rss ); } function wp_widget_rss_form( $args, $inputs = null ) { $default_inputs = array( 'url' => true, 'title' => true, 'items' => true, 'show_summary' => true, 'show_author' => true, 'show_date' => true, ); $inputs = wp_parse_args( $inputs, $default_inputs ); $args['title'] = isset( $args['title'] ) ? $args['title'] : ''; $args['url'] = isset( $args['url'] ) ? $args['url'] : ''; $args['items'] = isset( $args['items'] ) ? (int) $args['items'] : 0; if ( $args['items'] < 1 || 20 < $args['items'] ) { $args['items'] = 10; } $args['show_summary'] = isset( $args['show_summary'] ) ? (int) $args['show_summary'] : (int) $inputs['show_summary']; $args['show_author'] = isset( $args['show_author'] ) ? (int) $args['show_author'] : (int) $inputs['show_author']; $args['show_date'] = isset( $args['show_date'] ) ? (int) $args['show_date'] : (int) $inputs['show_date']; if ( ! empty( $args['error'] ) ) { echo '<p class="widget-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . esc_html( $args['error'] ) . '</p>'; } $esc_number = esc_attr( $args['number'] ); if ( $inputs['url'] ) : ?>
<p><label for="rss-url-<?php echo $esc_number; ?>"><?php _e( 'Enter the RSS feed URL here:' ); ?></label>
<input class="widefat" id="rss-url-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][url]" type="text" value="<?php echo esc_url( $args['url'] ); ?>" /></p>
<?php endif; if ( $inputs['title'] ) : ?>
<p><label for="rss-title-<?php echo $esc_number; ?>"><?php _e( 'Give the feed a title (optional):' ); ?></label>
<input class="widefat" id="rss-title-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][title]" type="text" value="<?php echo esc_attr( $args['title'] ); ?>" /></p>
<?php endif; if ( $inputs['items'] ) : ?>
<p><label for="rss-items-<?php echo $esc_number; ?>"><?php _e( 'How many items would you like to display?' ); ?></label>
<select id="rss-items-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][items]">
<?php
for ( $i = 1; $i <= 20; ++$i ) { echo "<option value='$i' " . selected( $args['items'], $i, false ) . ">$i</option>"; } ?>
</select></p>
<?php endif; if ( $inputs['show_summary'] || $inputs['show_author'] || $inputs['show_date'] ) : ?>
<p>
<?php if ( $inputs['show_summary'] ) : ?>
<input id="rss-show-summary-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_summary]" type="checkbox" value="1" <?php checked( $args['show_summary'] ); ?> />
<label for="rss-show-summary-<?php echo $esc_number; ?>"><?php _e( 'Display item content?' ); ?></label><br />
<?php endif; if ( $inputs['show_author'] ) : ?>
<input id="rss-show-author-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_author]" type="checkbox" value="1" <?php checked( $args['show_author'] ); ?> />
<label for="rss-show-author-<?php echo $esc_number; ?>"><?php _e( 'Display item author if available?' ); ?></label><br />
<?php endif; if ( $inputs['show_date'] ) : ?>
<input id="rss-show-date-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][show_date]" type="checkbox" value="1" <?php checked( $args['show_date'] ); ?> />
<label for="rss-show-date-<?php echo $esc_number; ?>"><?php _e( 'Display item date?' ); ?></label><br />
<?php endif; ?>
</p>
<?php
endif; foreach ( array_keys( $default_inputs ) as $input ) : if ( 'hidden' === $inputs[ $input ] ) : $id = str_replace( '_', '-', $input ); ?>
<input type="hidden" id="rss-<?php echo esc_attr( $id ); ?>-<?php echo $esc_number; ?>" name="widget-rss[<?php echo $esc_number; ?>][<?php echo esc_attr( $input ); ?>]" value="<?php echo esc_attr( $args[ $input ] ); ?>" />
<?php
endif; endforeach; } function wp_widget_rss_process( $widget_rss, $check_feed = true ) { $items = (int) $widget_rss['items']; if ( $items < 1 || 20 < $items ) { $items = 10; } $url = sanitize_url( strip_tags( $widget_rss['url'] ) ); $title = isset( $widget_rss['title'] ) ? trim( strip_tags( $widget_rss['title'] ) ) : ''; $show_summary = isset( $widget_rss['show_summary'] ) ? (int) $widget_rss['show_summary'] : 0; $show_author = isset( $widget_rss['show_author'] ) ? (int) $widget_rss['show_author'] : 0; $show_date = isset( $widget_rss['show_date'] ) ? (int) $widget_rss['show_date'] : 0; $error = false; $link = ''; if ( $check_feed ) { $rss = fetch_feed( $url ); if ( is_wp_error( $rss ) ) { $error = $rss->get_error_message(); } else { $link = esc_url( strip_tags( $rss->get_permalink() ) ); while ( stristr( $link, 'http' ) !== $link ) { $link = substr( $link, 1 ); } $rss->__destruct(); unset( $rss ); } } return compact( 'title', 'url', 'link', 'items', 'error', 'show_summary', 'show_author', 'show_date' ); } function wp_widgets_init() { if ( ! is_blog_installed() ) { return; } register_widget( 'WP_Widget_Pages' ); register_widget( 'WP_Widget_Calendar' ); register_widget( 'WP_Widget_Archives' ); if ( get_option( 'link_manager_enabled' ) ) { register_widget( 'WP_Widget_Links' ); } register_widget( 'WP_Widget_Media_Audio' ); register_widget( 'WP_Widget_Media_Image' ); register_widget( 'WP_Widget_Media_Gallery' ); register_widget( 'WP_Widget_Media_Video' ); register_widget( 'WP_Widget_Meta' ); register_widget( 'WP_Widget_Search' ); register_widget( 'WP_Widget_Text' ); register_widget( 'WP_Widget_Categories' ); register_widget( 'WP_Widget_Recent_Posts' ); register_widget( 'WP_Widget_Recent_Comments' ); register_widget( 'WP_Widget_RSS' ); register_widget( 'WP_Widget_Tag_Cloud' ); register_widget( 'WP_Nav_Menu_Widget' ); register_widget( 'WP_Widget_Custom_HTML' ); register_widget( 'WP_Widget_Block' ); do_action( 'widgets_init' ); } function wp_setup_widgets_block_editor() { add_theme_support( 'widgets-block-editor' ); } function wp_use_widgets_block_editor() { return apply_filters( 'use_widgets_block_editor', get_theme_support( 'widgets-block-editor' ) ); } function wp_parse_widget_id( $id ) { $parsed = array(); if ( preg_match( '/^(.+)-(\d+)$/', $id, $matches ) ) { $parsed['id_base'] = $matches[1]; $parsed['number'] = (int) $matches[2]; } else { $parsed['id_base'] = $id; } return $parsed; } function wp_find_widgets_sidebar( $widget_id ) { foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { foreach ( $widget_ids as $maybe_widget_id ) { if ( $maybe_widget_id === $widget_id ) { return (string) $sidebar_id; } } } return null; } function wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ) { $sidebars = wp_get_sidebars_widgets(); foreach ( $sidebars as $maybe_sidebar_id => $widgets ) { foreach ( $widgets as $i => $maybe_widget_id ) { if ( $widget_id === $maybe_widget_id && $sidebar_id !== $maybe_sidebar_id ) { unset( $sidebars[ $maybe_sidebar_id ][ $i ] ); continue 2; } } } if ( $sidebar_id ) { $sidebars[ $sidebar_id ][] = $widget_id; } wp_set_sidebars_widgets( $sidebars ); } function wp_render_widget( $widget_id, $sidebar_id ) { global $wp_registered_widgets, $wp_registered_sidebars; if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { return ''; } if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) { $sidebar = $wp_registered_sidebars[ $sidebar_id ]; } elseif ( 'wp_inactive_widgets' === $sidebar_id ) { $sidebar = array(); } else { return ''; } $params = array_merge( array( array_merge( $sidebar, array( 'widget_id' => $widget_id, 'widget_name' => $wp_registered_widgets[ $widget_id ]['name'], ) ), ), (array) $wp_registered_widgets[ $widget_id ]['params'] ); $classname_ = ''; foreach ( (array) $wp_registered_widgets[ $widget_id ]['classname'] as $cn ) { if ( is_string( $cn ) ) { $classname_ .= '_' . $cn; } elseif ( is_object( $cn ) ) { $classname_ .= '_' . get_class( $cn ); } } $classname_ = ltrim( $classname_, '_' ); $params[0]['before_widget'] = sprintf( $params[0]['before_widget'], $widget_id, $classname_ ); $params = apply_filters( 'dynamic_sidebar_params', $params ); $callback = $wp_registered_widgets[ $widget_id ]['callback']; ob_start(); do_action( 'dynamic_sidebar', $wp_registered_widgets[ $widget_id ] ); if ( is_callable( $callback ) ) { call_user_func_array( $callback, $params ); } return ob_get_clean(); } function wp_render_widget_control( $id ) { global $wp_registered_widget_controls; if ( ! isset( $wp_registered_widget_controls[ $id ]['callback'] ) ) { return null; } $callback = $wp_registered_widget_controls[ $id ]['callback']; $params = $wp_registered_widget_controls[ $id ]['params']; ob_start(); if ( is_callable( $callback ) ) { call_user_func_array( $callback, $params ); } return ob_get_clean(); } function wp_check_widget_editor_deps() { global $wp_scripts, $wp_styles; if ( $wp_scripts->query( 'wp-edit-widgets', 'enqueued' ) || $wp_scripts->query( 'wp-customize-widgets', 'enqueued' ) ) { if ( $wp_scripts->query( 'wp-editor', 'enqueued' ) ) { _doing_it_wrong( 'wp_enqueue_script()', sprintf( __( '"%1$s" script should not be enqueued together with the new widgets editor (%2$s or %3$s).' ), 'wp-editor', 'wp-edit-widgets', 'wp-customize-widgets' ), '5.8.0' ); } if ( $wp_styles->query( 'wp-edit-post', 'enqueued' ) ) { _doing_it_wrong( 'wp_enqueue_style()', sprintf( __( '"%1$s" style should not be enqueued together with the new widgets editor (%2$s or %3$s).' ), 'wp-edit-post', 'wp-edit-widgets', 'wp-customize-widgets' ), '5.8.0' ); } } } function _wp_block_theme_register_classic_sidebars() { global $wp_registered_sidebars; if ( ! wp_is_block_theme() ) { return; } $classic_sidebars = get_theme_mod( 'wp_classic_sidebars' ); if ( empty( $classic_sidebars ) ) { return; } foreach ( $classic_sidebars as $sidebar ) { $wp_registered_sidebars[ $sidebar['id'] ] = $sidebar; } }
###require ABSPATH . WPINC . '/class-wp-widget.php';
class WP_Widget { public $id_base; public $name; public $option_name; public $alt_option_name; public $widget_options; public $control_options; public $number = false; public $id = false; public $updated = false; public function widget( $args, $instance ) { die( 'function WP_Widget::widget() must be overridden in a subclass.' ); } public function update( $new_instance, $old_instance ) { return $new_instance; } public function form( $instance ) { echo '<p class="no-options-widget">' . __( 'There are no options for this widget.' ) . '</p>'; return 'noform'; } public function __construct( $id_base, $name, $widget_options = array(), $control_options = array() ) { if ( ! empty( $id_base ) ) { $id_base = strtolower( $id_base ); } else { $id_base = preg_replace( '/(wp_)?widget_/', '', strtolower( get_class( $this ) ) ); } $this->id_base = $id_base; $this->name = $name; $this->option_name = 'widget_' . $this->id_base; $this->widget_options = wp_parse_args( $widget_options, array( 'classname' => str_replace( '\\', '_', $this->option_name ), 'customize_selective_refresh' => false, ) ); $this->control_options = wp_parse_args( $control_options, array( 'id_base' => $this->id_base ) ); } public function WP_Widget( $id_base, $name, $widget_options = array(), $control_options = array() ) { _deprecated_constructor( 'WP_Widget', '4.3.0', get_class( $this ) ); WP_Widget::__construct( $id_base, $name, $widget_options, $control_options ); } public function get_field_name( $field_name ) { $pos = strpos( $field_name, '[' ); if ( false !== $pos ) { $field_name = '[' . substr_replace( $field_name, '][', $pos, strlen( '[' ) ); } else { $field_name = '[' . $field_name . ']'; } return 'widget-' . $this->id_base . '[' . $this->number . ']' . $field_name; } public function get_field_id( $field_name ) { $field_name = str_replace( array( '[]', '[', ']' ), array( '', '-', '' ), $field_name ); $field_name = trim( $field_name, '-' ); return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name; } public function _register() { $settings = $this->get_settings(); $empty = true; if ( $settings instanceof ArrayObject || $settings instanceof ArrayIterator ) { $settings = $settings->getArrayCopy(); } if ( is_array( $settings ) ) { foreach ( array_keys( $settings ) as $number ) { if ( is_numeric( $number ) ) { $this->_set( $number ); $this->_register_one( $number ); $empty = false; } } } if ( $empty ) { $this->_set( 1 ); $this->_register_one(); } } public function _set( $number ) { $this->number = $number; $this->id = $this->id_base . '-' . $number; } public function _get_display_callback() { return array( $this, 'display_callback' ); } public function _get_update_callback() { return array( $this, 'update_callback' ); } public function _get_form_callback() { return array( $this, 'form_callback' ); } public function is_preview() { global $wp_customize; return ( isset( $wp_customize ) && $wp_customize->is_preview() ); } public function display_callback( $args, $widget_args = 1 ) { if ( is_numeric( $widget_args ) ) { $widget_args = array( 'number' => $widget_args ); } $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); $this->_set( $widget_args['number'] ); $instances = $this->get_settings(); if ( isset( $instances[ $this->number ] ) ) { $instance = $instances[ $this->number ]; $instance = apply_filters( 'widget_display_callback', $instance, $this, $args ); if ( false === $instance ) { return; } $was_cache_addition_suspended = wp_suspend_cache_addition(); if ( $this->is_preview() && ! $was_cache_addition_suspended ) { wp_suspend_cache_addition( true ); } $this->widget( $args, $instance ); if ( $this->is_preview() ) { wp_suspend_cache_addition( $was_cache_addition_suspended ); } } } public function update_callback( $deprecated = 1 ) { global $wp_registered_widgets; $all_instances = $this->get_settings(); if ( $this->updated ) { return; } if ( isset( $_POST['delete_widget'] ) && $_POST['delete_widget'] ) { if ( isset( $_POST['the-widget-id'] ) ) { $del_id = $_POST['the-widget-id']; } else { return; } if ( isset( $wp_registered_widgets[ $del_id ]['params'][0]['number'] ) ) { $number = $wp_registered_widgets[ $del_id ]['params'][0]['number']; if ( $this->id_base . '-' . $number === $del_id ) { unset( $all_instances[ $number ] ); } } } else { if ( isset( $_POST[ 'widget-' . $this->id_base ] ) && is_array( $_POST[ 'widget-' . $this->id_base ] ) ) { $settings = $_POST[ 'widget-' . $this->id_base ]; } elseif ( isset( $_POST['id_base'] ) && $_POST['id_base'] === $this->id_base ) { $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number']; $settings = array( $num => array() ); } else { return; } foreach ( $settings as $number => $new_instance ) { $new_instance = stripslashes_deep( $new_instance ); $this->_set( $number ); $old_instance = isset( $all_instances[ $number ] ) ? $all_instances[ $number ] : array(); $was_cache_addition_suspended = wp_suspend_cache_addition(); if ( $this->is_preview() && ! $was_cache_addition_suspended ) { wp_suspend_cache_addition( true ); } $instance = $this->update( $new_instance, $old_instance ); if ( $this->is_preview() ) { wp_suspend_cache_addition( $was_cache_addition_suspended ); } $instance = apply_filters( 'widget_update_callback', $instance, $new_instance, $old_instance, $this ); if ( false !== $instance ) { $all_instances[ $number ] = $instance; } break; } } $this->save_settings( $all_instances ); $this->updated = true; } public function form_callback( $widget_args = 1 ) { if ( is_numeric( $widget_args ) ) { $widget_args = array( 'number' => $widget_args ); } $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); $all_instances = $this->get_settings(); if ( -1 === $widget_args['number'] ) { $this->_set( '__i__' ); $instance = array(); } else { $this->_set( $widget_args['number'] ); $instance = $all_instances[ $widget_args['number'] ]; } $instance = apply_filters( 'widget_form_callback', $instance, $this ); $return = null; if ( false !== $instance ) { $return = $this->form( $instance ); do_action_ref_array( 'in_widget_form', array( &$this, &$return, $instance ) ); } return $return; } public function _register_one( $number = -1 ) { wp_register_sidebar_widget( $this->id, $this->name, $this->_get_display_callback(), $this->widget_options, array( 'number' => $number ) ); _register_widget_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) ); _register_widget_form_callback( $this->id, $this->name, $this->_get_form_callback(), $this->control_options, array( 'number' => $number ) ); } public function save_settings( $settings ) { $settings['_multiwidget'] = 1; update_option( $this->option_name, $settings ); } public function get_settings() { $settings = get_option( $this->option_name ); if ( false === $settings ) { $settings = array(); if ( isset( $this->alt_option_name ) ) { $settings = get_option( $this->alt_option_name, array() ); delete_option( $this->alt_option_name ); } $this->save_settings( $settings ); } if ( ! is_array( $settings ) && ! ( $settings instanceof ArrayObject || $settings instanceof ArrayIterator ) ) { $settings = array(); } if ( ! empty( $settings ) && ! isset( $settings['_multiwidget'] ) ) { $settings = wp_convert_widget_settings( $this->id_base, $this->option_name, $settings ); } unset( $settings['_multiwidget'], $settings['__i__'] ); return $settings; } }
###require ABSPATH . WPINC . '/class-wp-widget-factory.php';
class WP_Widget_Factory { public $widgets = array(); public function __construct() { add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 ); } public function WP_Widget_Factory() { _deprecated_constructor( 'WP_Widget_Factory', '4.3.0' ); self::__construct(); } public function register( $widget ) { if ( $widget instanceof WP_Widget ) { $this->widgets[ spl_object_hash( $widget ) ] = $widget; } else { $this->widgets[ $widget ] = new $widget(); } } public function unregister( $widget ) { if ( $widget instanceof WP_Widget ) { unset( $this->widgets[ spl_object_hash( $widget ) ] ); } else { unset( $this->widgets[ $widget ] ); } } public function _register_widgets() { global $wp_registered_widgets; $keys = array_keys( $this->widgets ); $registered = array_keys( $wp_registered_widgets ); $registered = array_map( '_get_widget_id_base', $registered ); foreach ( $keys as $key ) { if ( in_array( $this->widgets[ $key ]->id_base, $registered, true ) ) { unset( $this->widgets[ $key ] ); continue; } $this->widgets[ $key ]->_register(); } } public function get_widget_object( $id_base ) { $key = $this->get_widget_key( $id_base ); if ( '' === $key ) { return null; } return $this->widgets[ $key ]; } public function get_widget_key( $id_base ) { foreach ( $this->widgets as $key => $widget_object ) { if ( $widget_object->id_base === $id_base ) { return $key; } } return ''; } }
###require ABSPATH . WPINC . '/nav-menu-template.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } require_once ABSPATH . WPINC . '/class-walker-nav-menu.php'; function wp_nav_menu( $args = array() ) { static $menu_id_slugs = array(); $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'container_aria_label' => '', 'menu_class' => 'menu', 'menu_id' => '', 'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'item_spacing' => 'preserve', 'depth' => 0, 'walker' => '', 'theme_location' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ), true ) ) { $args['item_spacing'] = $defaults['item_spacing']; } $args = apply_filters( 'wp_nav_menu_args', $args ); $args = (object) $args; $nav_menu = apply_filters( 'pre_wp_nav_menu', null, $args ); if ( null !== $nav_menu ) { if ( $args->echo ) { echo $nav_menu; return; } return $nav_menu; } $menu = wp_get_nav_menu_object( $args->menu ); $locations = get_nav_menu_locations(); if ( ! $menu && $args->theme_location && $locations && isset( $locations[ $args->theme_location ] ) ) { $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] ); } if ( ! $menu && ! $args->theme_location ) { $menus = wp_get_nav_menus(); foreach ( $menus as $menu_maybe ) { $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ); if ( $menu_items ) { $menu = $menu_maybe; break; } } } if ( empty( $args->menu ) ) { $args->menu = $menu; } if ( $menu && ! is_wp_error( $menu ) && ! isset( $menu_items ) ) { $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); } if ( ( ! $menu || is_wp_error( $menu ) || ( isset( $menu_items ) && empty( $menu_items ) && ! $args->theme_location ) ) && isset( $args->fallback_cb ) && $args->fallback_cb && is_callable( $args->fallback_cb ) ) { return call_user_func( $args->fallback_cb, (array) $args ); } if ( ! $menu || is_wp_error( $menu ) ) { return false; } $nav_menu = ''; $items = ''; $show_container = false; if ( $args->container ) { $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) ); if ( is_string( $args->container ) && in_array( $args->container, $allowed_tags, true ) ) { $show_container = true; $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-' . $menu->slug . '-container"'; $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : ''; $aria_label = ( 'nav' === $args->container && $args->container_aria_label ) ? ' aria-label="' . esc_attr( $args->container_aria_label ) . '"' : ''; $nav_menu .= '<' . $args->container . $id . $class . $aria_label . '>'; } } _wp_menu_item_classes_by_context( $menu_items ); $sorted_menu_items = array(); $menu_items_with_children = array(); foreach ( (array) $menu_items as $menu_item ) { if ( (string) $menu_item->ID === (string) $menu_item->menu_item_parent ) { $menu_item->menu_item_parent = 0; } $sorted_menu_items[ $menu_item->menu_order ] = $menu_item; if ( $menu_item->menu_item_parent ) { $menu_items_with_children[ $menu_item->menu_item_parent ] = true; } } if ( $menu_items_with_children ) { foreach ( $sorted_menu_items as &$menu_item ) { if ( isset( $menu_items_with_children[ $menu_item->ID ] ) ) { $menu_item->classes[] = 'menu-item-has-children'; } } } unset( $menu_items, $menu_item ); $sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args ); $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args ); unset( $sorted_menu_items ); if ( ! empty( $args->menu_id ) ) { $wrap_id = $args->menu_id; } else { $wrap_id = 'menu-' . $menu->slug; while ( in_array( $wrap_id, $menu_id_slugs, true ) ) { if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) { $wrap_id = preg_replace( '#-(\d+)$#', '-' . ++$matches[1], $wrap_id ); } else { $wrap_id = $wrap_id . '-1'; } } } $menu_id_slugs[] = $wrap_id; $wrap_class = $args->menu_class ? $args->menu_class : ''; $items = apply_filters( 'wp_nav_menu_items', $items, $args ); $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args ); if ( empty( $items ) ) { return false; } $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items ); unset( $items ); if ( $show_container ) { $nav_menu .= '</' . $args->container . '>'; } $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args ); if ( $args->echo ) { echo $nav_menu; } else { return $nav_menu; } } function _wp_menu_item_classes_by_context( &$menu_items ) { global $wp_query, $wp_rewrite; $queried_object = $wp_query->get_queried_object(); $queried_object_id = (int) $wp_query->queried_object_id; $active_object = ''; $active_ancestor_item_ids = array(); $active_parent_item_ids = array(); $active_parent_object_ids = array(); $possible_taxonomy_ancestors = array(); $possible_object_parents = array(); $home_page_id = (int) get_option( 'page_for_posts' ); if ( $wp_query->is_singular && ! empty( $queried_object->post_type ) && ! is_post_type_hierarchical( $queried_object->post_type ) ) { foreach ( (array) get_object_taxonomies( $queried_object->post_type ) as $taxonomy ) { if ( is_taxonomy_hierarchical( $taxonomy ) ) { $term_hierarchy = _get_term_hierarchy( $taxonomy ); $terms = wp_get_object_terms( $queried_object_id, $taxonomy, array( 'fields' => 'ids' ) ); if ( is_array( $terms ) ) { $possible_object_parents = array_merge( $possible_object_parents, $terms ); $term_to_ancestor = array(); foreach ( (array) $term_hierarchy as $ancestor => $descendents ) { foreach ( (array) $descendents as $desc ) { $term_to_ancestor[ $desc ] = $ancestor; } } foreach ( $terms as $desc ) { do { $possible_taxonomy_ancestors[ $taxonomy ][] = $desc; if ( isset( $term_to_ancestor[ $desc ] ) ) { $_desc = $term_to_ancestor[ $desc ]; unset( $term_to_ancestor[ $desc ] ); $desc = $_desc; } else { $desc = 0; } } while ( ! empty( $desc ) ); } } } } } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) { $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy ); $term_to_ancestor = array(); foreach ( (array) $term_hierarchy as $ancestor => $descendents ) { foreach ( (array) $descendents as $desc ) { $term_to_ancestor[ $desc ] = $ancestor; } } $desc = $queried_object->term_id; do { $possible_taxonomy_ancestors[ $queried_object->taxonomy ][] = $desc; if ( isset( $term_to_ancestor[ $desc ] ) ) { $_desc = $term_to_ancestor[ $desc ]; unset( $term_to_ancestor[ $desc ] ); $desc = $_desc; } else { $desc = 0; } } while ( ! empty( $desc ) ); } $possible_object_parents = array_filter( $possible_object_parents ); $front_page_url = home_url(); $front_page_id = (int) get_option( 'page_on_front' ); $privacy_policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); foreach ( (array) $menu_items as $key => $menu_item ) { $menu_items[ $key ]->current = false; $classes = (array) $menu_item->classes; $classes[] = 'menu-item'; $classes[] = 'menu-item-type-' . $menu_item->type; $classes[] = 'menu-item-object-' . $menu_item->object; if ( 'post_type' === $menu_item->type && $front_page_id === (int) $menu_item->object_id ) { $classes[] = 'menu-item-home'; } if ( 'post_type' === $menu_item->type && $privacy_policy_page_id === (int) $menu_item->object_id ) { $classes[] = 'menu-item-privacy-policy'; } if ( $wp_query->is_singular && 'taxonomy' === $menu_item->type && in_array( (int) $menu_item->object_id, $possible_object_parents, true ) ) { $active_parent_object_ids[] = (int) $menu_item->object_id; $active_parent_item_ids[] = (int) $menu_item->db_id; $active_object = $queried_object->post_type; } elseif ( (int) $menu_item->object_id === $queried_object_id && ( ( ! empty( $home_page_id ) && 'post_type' === $menu_item->type && $wp_query->is_home && $home_page_id === (int) $menu_item->object_id ) || ( 'post_type' === $menu_item->type && $wp_query->is_singular ) || ( 'taxonomy' === $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) && $queried_object->taxonomy === $menu_item->object ) ) ) { $classes[] = 'current-menu-item'; $menu_items[ $key ]->current = true; $ancestor_id = (int) $menu_item->db_id; while ( ( $ancestor_id = (int) get_post_meta( $ancestor_id, '_menu_item_menu_item_parent', true ) ) && ! in_array( $ancestor_id, $active_ancestor_item_ids, true ) ) { $active_ancestor_item_ids[] = $ancestor_id; } if ( 'post_type' === $menu_item->type && 'page' === $menu_item->object ) { $classes[] = 'page_item'; $classes[] = 'page-item-' . $menu_item->object_id; $classes[] = 'current_page_item'; } $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; $active_parent_object_ids[] = (int) $menu_item->post_parent; $active_object = $menu_item->object; } elseif ( 'post_type_archive' === $menu_item->type && is_post_type_archive( array( $menu_item->object ) ) ) { $classes[] = 'current-menu-item'; $menu_items[ $key ]->current = true; $ancestor_id = (int) $menu_item->db_id; while ( ( $ancestor_id = (int) get_post_meta( $ancestor_id, '_menu_item_menu_item_parent', true ) ) && ! in_array( $ancestor_id, $active_ancestor_item_ids, true ) ) { $active_ancestor_item_ids[] = $ancestor_id; } $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; } elseif ( 'custom' === $menu_item->object && isset( $_SERVER['HTTP_HOST'] ) ) { $_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] ); if ( is_customize_preview() ) { $_root_relative_current = strtok( untrailingslashit( $_SERVER['REQUEST_URI'] ), '?' ); } $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current ); $raw_item_url = strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url; $item_url = set_url_scheme( untrailingslashit( $raw_item_url ) ); $_indexless_current = untrailingslashit( preg_replace( '/' . preg_quote( $wp_rewrite->index, '/' ) . '$/', '', $current_url ) ); $matches = array( $current_url, urldecode( $current_url ), $_indexless_current, urldecode( $_indexless_current ), $_root_relative_current, urldecode( $_root_relative_current ), ); if ( $raw_item_url && in_array( $item_url, $matches, true ) ) { $classes[] = 'current-menu-item'; $menu_items[ $key ]->current = true; $ancestor_id = (int) $menu_item->db_id; while ( ( $ancestor_id = (int) get_post_meta( $ancestor_id, '_menu_item_menu_item_parent', true ) ) && ! in_array( $ancestor_id, $active_ancestor_item_ids, true ) ) { $active_ancestor_item_ids[] = $ancestor_id; } if ( in_array( home_url(), array( untrailingslashit( $current_url ), untrailingslashit( $_indexless_current ) ), true ) ) { $classes[] = 'current_page_item'; } $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; $active_parent_object_ids[] = (int) $menu_item->post_parent; $active_object = $menu_item->object; } elseif ( $item_url === $front_page_url && is_front_page() ) { $classes[] = 'current-menu-item'; } if ( untrailingslashit( $item_url ) === home_url() ) { $classes[] = 'menu-item-home'; } } if ( ! empty( $home_page_id ) && 'post_type' === $menu_item->type && empty( $wp_query->is_page ) && $home_page_id === (int) $menu_item->object_id ) { $classes[] = 'current_page_parent'; } $menu_items[ $key ]->classes = array_unique( $classes ); } $active_ancestor_item_ids = array_filter( array_unique( $active_ancestor_item_ids ) ); $active_parent_item_ids = array_filter( array_unique( $active_parent_item_ids ) ); $active_parent_object_ids = array_filter( array_unique( $active_parent_object_ids ) ); foreach ( (array) $menu_items as $key => $parent_item ) { $classes = (array) $parent_item->classes; $menu_items[ $key ]->current_item_ancestor = false; $menu_items[ $key ]->current_item_parent = false; if ( isset( $parent_item->type ) && ( ( 'post_type' === $parent_item->type && ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) && in_array( (int) $parent_item->object_id, $queried_object->ancestors, true ) && (int) $parent_item->object_id !== $queried_object->ID ) || ( 'taxonomy' === $parent_item->type && isset( $possible_taxonomy_ancestors[ $parent_item->object ] ) && in_array( (int) $parent_item->object_id, $possible_taxonomy_ancestors[ $parent_item->object ], true ) && ( ! isset( $queried_object->term_id ) || (int) $parent_item->object_id !== $queried_object->term_id ) ) ) ) { if ( ! empty( $queried_object->taxonomy ) ) { $classes[] = 'current-' . $queried_object->taxonomy . '-ancestor'; } else { $classes[] = 'current-' . $queried_object->post_type . '-ancestor'; } } if ( in_array( (int) $parent_item->db_id, $active_ancestor_item_ids, true ) ) { $classes[] = 'current-menu-ancestor'; $menu_items[ $key ]->current_item_ancestor = true; } if ( in_array( (int) $parent_item->db_id, $active_parent_item_ids, true ) ) { $classes[] = 'current-menu-parent'; $menu_items[ $key ]->current_item_parent = true; } if ( in_array( (int) $parent_item->object_id, $active_parent_object_ids, true ) ) { $classes[] = 'current-' . $active_object . '-parent'; } if ( 'post_type' === $parent_item->type && 'page' === $parent_item->object ) { if ( in_array( 'current-menu-parent', $classes, true ) ) { $classes[] = 'current_page_parent'; } if ( in_array( 'current-menu-ancestor', $classes, true ) ) { $classes[] = 'current_page_ancestor'; } } $menu_items[ $key ]->classes = array_unique( $classes ); } } function walk_nav_menu_tree( $items, $depth, $args ) { $walker = ( empty( $args->walker ) ) ? new Walker_Nav_Menu() : $args->walker; return $walker->walk( $items, $depth, $args ); } function _nav_menu_item_id_use_once( $id, $item ) { static $_used_ids = array(); if ( in_array( $item->ID, $_used_ids, true ) ) { return ''; } $_used_ids[] = $item->ID; return $id; } function wp_nav_menu_remove_menu_item_has_children_class( $classes, $menu_item, $args = false, $depth = false ) { if ( false === $depth || false === $args ) { return $classes; } $max_depth = isset( $args->depth ) ? (int) $args->depth : 0; $depth = $depth + 1; if ( 0 === $max_depth ) { return $classes; } if ( -1 === $max_depth || $depth >= $max_depth ) { $classes = array_diff( $classes, array( 'menu-item-has-children' ) ); } return $classes; }
###require ABSPATH . WPINC . '/nav-menu.php';
function wp_get_nav_menu_object( $menu ) { $menu_obj = false; if ( is_object( $menu ) ) { $menu_obj = $menu; } if ( $menu && ! $menu_obj ) { $menu_obj = get_term( $menu, 'nav_menu' ); if ( ! $menu_obj ) { $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' ); } if ( ! $menu_obj ) { $menu_obj = get_term_by( 'name', $menu, 'nav_menu' ); } } if ( ! $menu_obj || is_wp_error( $menu_obj ) ) { $menu_obj = false; } return apply_filters( 'wp_get_nav_menu_object', $menu_obj, $menu ); } function is_nav_menu( $menu ) { if ( ! $menu ) { return false; } $menu_obj = wp_get_nav_menu_object( $menu ); if ( $menu_obj && ! is_wp_error( $menu_obj ) && ! empty( $menu_obj->taxonomy ) && 'nav_menu' === $menu_obj->taxonomy ) { return true; } return false; } function register_nav_menus( $locations = array() ) { global $_wp_registered_nav_menus; add_theme_support( 'menus' ); foreach ( $locations as $key => $value ) { if ( is_int( $key ) ) { _doing_it_wrong( __FUNCTION__, __( 'Nav menu locations must be strings.' ), '5.3.0' ); break; } } $_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations ); } function unregister_nav_menu( $location ) { global $_wp_registered_nav_menus; if ( is_array( $_wp_registered_nav_menus ) && isset( $_wp_registered_nav_menus[ $location ] ) ) { unset( $_wp_registered_nav_menus[ $location ] ); if ( empty( $_wp_registered_nav_menus ) ) { _remove_theme_support( 'menus' ); } return true; } return false; } function register_nav_menu( $location, $description ) { register_nav_menus( array( $location => $description ) ); } function get_registered_nav_menus() { global $_wp_registered_nav_menus; if ( isset( $_wp_registered_nav_menus ) ) { return $_wp_registered_nav_menus; } return array(); } function get_nav_menu_locations() { $locations = get_theme_mod( 'nav_menu_locations' ); return ( is_array( $locations ) ) ? $locations : array(); } function has_nav_menu( $location ) { $has_nav_menu = false; $registered_nav_menus = get_registered_nav_menus(); if ( isset( $registered_nav_menus[ $location ] ) ) { $locations = get_nav_menu_locations(); $has_nav_menu = ! empty( $locations[ $location ] ); } return apply_filters( 'has_nav_menu', $has_nav_menu, $location ); } function wp_get_nav_menu_name( $location ) { $menu_name = ''; $locations = get_nav_menu_locations(); if ( isset( $locations[ $location ] ) ) { $menu = wp_get_nav_menu_object( $locations[ $location ] ); if ( $menu && $menu->name ) { $menu_name = $menu->name; } } return apply_filters( 'wp_get_nav_menu_name', $menu_name, $location ); } function is_nav_menu_item( $menu_item_id = 0 ) { return ( ! is_wp_error( $menu_item_id ) && ( 'nav_menu_item' === get_post_type( $menu_item_id ) ) ); } function wp_create_nav_menu( $menu_name ) { return wp_update_nav_menu_object( 0, array( 'menu-name' => $menu_name ) ); } function wp_delete_nav_menu( $menu ) { $menu = wp_get_nav_menu_object( $menu ); if ( ! $menu ) { return false; } $menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' ); if ( ! empty( $menu_objects ) ) { foreach ( $menu_objects as $item ) { wp_delete_post( $item ); } } $result = wp_delete_term( $menu->term_id, 'nav_menu' ); $locations = get_nav_menu_locations(); foreach ( $locations as $location => $menu_id ) { if ( $menu_id === $menu->term_id ) { $locations[ $location ] = 0; } } set_theme_mod( 'nav_menu_locations', $locations ); if ( $result && ! is_wp_error( $result ) ) { do_action( 'wp_delete_nav_menu', $menu->term_id ); } return $result; } function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) { $menu_id = (int) $menu_id; $_menu = wp_get_nav_menu_object( $menu_id ); $args = array( 'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ), 'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ), 'parent' => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ), 'slug' => null, ); $_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' ); if ( $_possible_existing && ! is_wp_error( $_possible_existing ) && isset( $_possible_existing->term_id ) && $_possible_existing->term_id !== $menu_id ) { return new WP_Error( 'menu_exists', sprintf( __( 'The menu name %s conflicts with another menu name. Please try another.' ), '<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>' ) ); } if ( ! $_menu || is_wp_error( $_menu ) ) { $menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' ); if ( $menu_exists ) { return new WP_Error( 'menu_exists', sprintf( __( 'The menu name %s conflicts with another menu name. Please try another.' ), '<strong>' . esc_html( $menu_data['menu-name'] ) . '</strong>' ) ); } $_menu = wp_insert_term( $menu_data['menu-name'], 'nav_menu', $args ); if ( is_wp_error( $_menu ) ) { return $_menu; } do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data ); return (int) $_menu['term_id']; } if ( ! $_menu || ! isset( $_menu->term_id ) ) { return 0; } $menu_id = (int) $_menu->term_id; $update_response = wp_update_term( $menu_id, 'nav_menu', $args ); if ( is_wp_error( $update_response ) ) { return $update_response; } $menu_id = (int) $update_response['term_id']; do_action( 'wp_update_nav_menu', $menu_id, $menu_data ); return $menu_id; } function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true ) { $menu_id = (int) $menu_id; $menu_item_db_id = (int) $menu_item_db_id; if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) { return new WP_Error( 'update_nav_menu_item_failed', __( 'The given object ID is not that of a menu item.' ) ); } $menu = wp_get_nav_menu_object( $menu_id ); if ( ! $menu && 0 !== $menu_id ) { return new WP_Error( 'invalid_menu_id', __( 'Invalid menu ID.' ) ); } if ( is_wp_error( $menu ) ) { return $menu; } $defaults = array( 'menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '', ); $args = wp_parse_args( $menu_item_data, $defaults ); if ( 0 === $menu_id ) { $args['menu-item-position'] = 1; } elseif ( 0 === (int) $args['menu-item-position'] ) { $menu_items = array(); if ( 0 !== $menu_id ) { $menu_items = (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); } $last_item = array_pop( $menu_items ); if ( $last_item && isset( $last_item->menu_order ) ) { $args['menu-item-position'] = 1 + $last_item->menu_order; } else { $args['menu-item-position'] = count( $menu_items ); } } $original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0; if ( 'custom' === $args['menu-item-type'] ) { $args['menu-item-url'] = trim( $args['menu-item-url'] ); } else { $args['menu-item-url'] = ''; $original_title = ''; if ( 'taxonomy' === $args['menu-item-type'] ) { $original_object = get_term( $args['menu-item-object-id'], $args['menu-item-object'] ); if ( $original_object instanceof WP_Term ) { $original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' ); $original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' ); } } elseif ( 'post_type' === $args['menu-item-type'] ) { $original_object = get_post( $args['menu-item-object-id'] ); if ( $original_object instanceof WP_Post ) { $original_parent = (int) $original_object->post_parent; $original_title = $original_object->post_title; } } elseif ( 'post_type_archive' === $args['menu-item-type'] ) { $original_object = get_post_type_object( $args['menu-item-object'] ); if ( $original_object instanceof WP_Post_Type ) { $original_title = $original_object->labels->archives; } } if ( wp_unslash( $args['menu-item-title'] ) === $original_title ) { $args['menu-item-title'] = ''; } if ( '' === $args['menu-item-title'] && '' === $args['menu-item-description'] ) { $args['menu-item-description'] = ' '; } } $post = array( 'menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item', ); $post_date = wp_resolve_post_date( $args['menu-item-post-date'], $args['menu-item-post-date-gmt'] ); if ( $post_date ) { $post['post_date'] = $post_date; } $update = 0 !== $menu_item_db_id; if ( ! $update ) { $post['ID'] = 0; $post['post_status'] = 'publish' === $args['menu-item-status'] ? 'publish' : 'draft'; $menu_item_db_id = wp_insert_post( $post, true, $fire_after_hooks ); if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) { return $menu_item_db_id; } do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args ); } if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) { $update_terms = wp_set_object_terms( $menu_item_db_id, array( $menu->term_id ), 'nav_menu' ); if ( is_wp_error( $update_terms ) ) { return $update_terms; } } if ( 'custom' === $args['menu-item-type'] ) { $args['menu-item-object-id'] = $menu_item_db_id; $args['menu-item-object'] = 'custom'; } $menu_item_db_id = (int) $menu_item_db_id; if ( (int) $args['menu-item-parent-id'] === $menu_item_db_id ) { $args['menu-item-parent-id'] = 0; } update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key( $args['menu-item-type'] ) ); update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', (string) ( (int) $args['menu-item-parent-id'] ) ); update_post_meta( $menu_item_db_id, '_menu_item_object_id', (string) ( (int) $args['menu-item-object-id'] ) ); update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key( $args['menu-item-object'] ) ); update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key( $args['menu-item-target'] ) ); $args['menu-item-classes'] = array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-classes'] ) ); $args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) ); update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] ); update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] ); update_post_meta( $menu_item_db_id, '_menu_item_url', sanitize_url( $args['menu-item-url'] ) ); if ( 0 === $menu_id ) { update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() ); } elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) ) { delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' ); } if ( $update ) { $post['ID'] = $menu_item_db_id; $post['post_status'] = ( 'draft' === $args['menu-item-status'] ) ? 'draft' : 'publish'; $update_post = wp_update_post( $post, true ); if ( is_wp_error( $update_post ) ) { return $update_post; } } do_action( 'wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args ); return $menu_item_db_id; } function wp_get_nav_menus( $args = array() ) { $defaults = array( 'taxonomy' => 'nav_menu', 'hide_empty' => false, 'orderby' => 'name', ); $args = wp_parse_args( $args, $defaults ); return apply_filters( 'wp_get_nav_menus', get_terms( $args ), $args ); } function _is_valid_nav_menu_item( $item ) { return empty( $item->_invalid ); } function wp_get_nav_menu_items( $menu, $args = array() ) { $menu = wp_get_nav_menu_object( $menu ); if ( ! $menu ) { return false; } if ( ! taxonomy_exists( 'nav_menu' ) ) { return false; } $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true, 'update_menu_item_cache' => true, 'tax_query' => array( array( 'taxonomy' => 'nav_menu', 'field' => 'term_taxonomy_id', 'terms' => $menu->term_taxonomy_id, ), ), ); $args = wp_parse_args( $args, $defaults ); if ( $menu->count > 0 ) { $items = get_posts( $args ); } else { $items = array(); } $items = array_map( 'wp_setup_nav_menu_item', $items ); if ( ! is_admin() ) { $items = array_filter( $items, '_is_valid_nav_menu_item' ); } if ( ARRAY_A === $args['output'] ) { $items = wp_list_sort( $items, array( $args['output_key'] => 'ASC', ) ); $i = 1; foreach ( $items as $k => $item ) { $items[ $k ]->{$args['output_key']} = $i++; } } return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args ); } function update_menu_item_cache( $menu_items ) { $post_ids = array(); $term_ids = array(); foreach ( $menu_items as $menu_item ) { if ( 'nav_menu_item' !== $menu_item->post_type ) { continue; } $object_id = get_post_meta( $menu_item->ID, '_menu_item_object_id', true ); $type = get_post_meta( $menu_item->ID, '_menu_item_type', true ); if ( 'post_type' === $type ) { $post_ids[] = (int) $object_id; } elseif ( 'taxonomy' === $type ) { $term_ids[] = (int) $object_id; } } if ( ! empty( $post_ids ) ) { _prime_post_caches( $post_ids, false ); } if ( ! empty( $term_ids ) ) { _prime_term_caches( $term_ids ); } } function wp_setup_nav_menu_item( $menu_item ) { $pre_menu_item = apply_filters( 'pre_wp_setup_nav_menu_item', null, $menu_item ); if ( null !== $pre_menu_item ) { return $pre_menu_item; } if ( isset( $menu_item->post_type ) ) { if ( 'nav_menu_item' === $menu_item->post_type ) { $menu_item->db_id = (int) $menu_item->ID; $menu_item->menu_item_parent = ! isset( $menu_item->menu_item_parent ) ? get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true ) : $menu_item->menu_item_parent; $menu_item->object_id = ! isset( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id; $menu_item->object = ! isset( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object; $menu_item->type = ! isset( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type; if ( 'post_type' === $menu_item->type ) { $object = get_post_type_object( $menu_item->object ); if ( $object ) { $menu_item->type_label = $object->labels->singular_name; if ( function_exists( 'get_post_states' ) ) { $menu_post = get_post( $menu_item->object_id ); $post_states = get_post_states( $menu_post ); if ( $post_states ) { $menu_item->type_label = wp_strip_all_tags( implode( ', ', $post_states ) ); } } } else { $menu_item->type_label = $menu_item->object; $menu_item->_invalid = true; } if ( 'trash' === get_post_status( $menu_item->object_id ) ) { $menu_item->_invalid = true; } $original_object = get_post( $menu_item->object_id ); if ( $original_object ) { $menu_item->url = get_permalink( $original_object->ID ); $original_title = apply_filters( 'the_title', $original_object->post_title, $original_object->ID ); } else { $menu_item->url = ''; $original_title = ''; $menu_item->_invalid = true; } if ( '' === $original_title ) { $original_title = sprintf( __( '#%d (no title)' ), $menu_item->object_id ); } $menu_item->title = ( '' === $menu_item->post_title ) ? $original_title : $menu_item->post_title; } elseif ( 'post_type_archive' === $menu_item->type ) { $object = get_post_type_object( $menu_item->object ); if ( $object ) { $menu_item->title = ( '' === $menu_item->post_title ) ? $object->labels->archives : $menu_item->post_title; $post_type_description = $object->description; } else { $post_type_description = ''; $menu_item->_invalid = true; } $menu_item->type_label = __( 'Post Type Archive' ); $post_content = wp_trim_words( $menu_item->post_content, 200 ); $post_type_description = ( '' === $post_content ) ? $post_type_description : $post_content; $menu_item->url = get_post_type_archive_link( $menu_item->object ); } elseif ( 'taxonomy' === $menu_item->type ) { $object = get_taxonomy( $menu_item->object ); if ( $object ) { $menu_item->type_label = $object->labels->singular_name; } else { $menu_item->type_label = $menu_item->object; $menu_item->_invalid = true; } $original_object = get_term( (int) $menu_item->object_id, $menu_item->object ); if ( $original_object && ! is_wp_error( $original_object ) ) { $menu_item->url = get_term_link( (int) $menu_item->object_id, $menu_item->object ); $original_title = $original_object->name; } else { $menu_item->url = ''; $original_title = ''; $menu_item->_invalid = true; } if ( '' === $original_title ) { $original_title = sprintf( __( '#%d (no title)' ), $menu_item->object_id ); } $menu_item->title = ( '' === $menu_item->post_title ) ? $original_title : $menu_item->post_title; } else { $menu_item->type_label = __( 'Custom Link' ); $menu_item->title = $menu_item->post_title; $menu_item->url = ! isset( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url; } $menu_item->target = ! isset( $menu_item->target ) ? get_post_meta( $menu_item->ID, '_menu_item_target', true ) : $menu_item->target; $menu_item->attr_title = ! isset( $menu_item->attr_title ) ? apply_filters( 'nav_menu_attr_title', $menu_item->post_excerpt ) : $menu_item->attr_title; if ( ! isset( $menu_item->description ) ) { $menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) ); } $menu_item->classes = ! isset( $menu_item->classes ) ? (array) get_post_meta( $menu_item->ID, '_menu_item_classes', true ) : $menu_item->classes; $menu_item->xfn = ! isset( $menu_item->xfn ) ? get_post_meta( $menu_item->ID, '_menu_item_xfn', true ) : $menu_item->xfn; } else { $menu_item->db_id = 0; $menu_item->menu_item_parent = 0; $menu_item->object_id = (int) $menu_item->ID; $menu_item->type = 'post_type'; $object = get_post_type_object( $menu_item->post_type ); $menu_item->object = $object->name; $menu_item->type_label = $object->labels->singular_name; if ( '' === $menu_item->post_title ) { $menu_item->post_title = sprintf( __( '#%d (no title)' ), $menu_item->ID ); } $menu_item->title = $menu_item->post_title; $menu_item->url = get_permalink( $menu_item->ID ); $menu_item->target = ''; $menu_item->attr_title = apply_filters( 'nav_menu_attr_title', '' ); $menu_item->description = apply_filters( 'nav_menu_description', '' ); $menu_item->classes = array(); $menu_item->xfn = ''; } } elseif ( isset( $menu_item->taxonomy ) ) { $menu_item->ID = $menu_item->term_id; $menu_item->db_id = 0; $menu_item->menu_item_parent = 0; $menu_item->object_id = (int) $menu_item->term_id; $menu_item->post_parent = (int) $menu_item->parent; $menu_item->type = 'taxonomy'; $object = get_taxonomy( $menu_item->taxonomy ); $menu_item->object = $object->name; $menu_item->type_label = $object->labels->singular_name; $menu_item->title = $menu_item->name; $menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy ); $menu_item->target = ''; $menu_item->attr_title = ''; $menu_item->description = get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy ); $menu_item->classes = array(); $menu_item->xfn = ''; } return apply_filters( 'wp_setup_nav_menu_item', $menu_item ); } function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type', $taxonomy = '' ) { $object_id = (int) $object_id; $menu_item_ids = array(); $query = new WP_Query(); $menu_items = $query->query( array( 'meta_key' => '_menu_item_object_id', 'meta_value' => $object_id, 'post_status' => 'any', 'post_type' => 'nav_menu_item', 'posts_per_page' => -1, ) ); foreach ( (array) $menu_items as $menu_item ) { if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) { $menu_item_type = get_post_meta( $menu_item->ID, '_menu_item_type', true ); if ( 'post_type' === $object_type && 'post_type' === $menu_item_type ) { $menu_item_ids[] = (int) $menu_item->ID; } elseif ( 'taxonomy' === $object_type && 'taxonomy' === $menu_item_type && get_post_meta( $menu_item->ID, '_menu_item_object', true ) === $taxonomy ) { $menu_item_ids[] = (int) $menu_item->ID; } } } return array_unique( $menu_item_ids ); } function _wp_delete_post_menu_item( $object_id ) { $object_id = (int) $object_id; $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'post_type' ); foreach ( (array) $menu_item_ids as $menu_item_id ) { wp_delete_post( $menu_item_id, true ); } } function _wp_delete_tax_menu_item( $object_id, $tt_id, $taxonomy ) { $object_id = (int) $object_id; $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'taxonomy', $taxonomy ); foreach ( (array) $menu_item_ids as $menu_item_id ) { wp_delete_post( $menu_item_id, true ); } } function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) { if ( 'publish' !== $new_status || 'publish' === $old_status || 'page' !== $post->post_type ) { return; } if ( ! empty( $post->post_parent ) ) { return; } $auto_add = get_option( 'nav_menu_options' ); if ( empty( $auto_add ) || ! is_array( $auto_add ) || ! isset( $auto_add['auto_add'] ) ) { return; } $auto_add = $auto_add['auto_add']; if ( empty( $auto_add ) || ! is_array( $auto_add ) ) { return; } $args = array( 'menu-item-object-id' => $post->ID, 'menu-item-object' => $post->post_type, 'menu-item-type' => 'post_type', 'menu-item-status' => 'publish', ); foreach ( $auto_add as $menu_id ) { $items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); if ( ! is_array( $items ) ) { continue; } foreach ( $items as $item ) { if ( $post->ID === (int) $item->object_id ) { continue 2; } } wp_update_nav_menu_item( $menu_id, 0, $args ); } } function _wp_delete_customize_changeset_dependent_auto_drafts( $post_id ) { $post = get_post( $post_id ); if ( ! $post || 'customize_changeset' !== $post->post_type ) { return; } $data = json_decode( $post->post_content, true ); if ( empty( $data['nav_menus_created_posts']['value'] ) ) { return; } remove_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); foreach ( $data['nav_menus_created_posts']['value'] as $stub_post_id ) { if ( empty( $stub_post_id ) ) { continue; } if ( 'auto-draft' === get_post_status( $stub_post_id ) ) { wp_delete_post( $stub_post_id, true ); } elseif ( 'draft' === get_post_status( $stub_post_id ) ) { wp_trash_post( $stub_post_id ); delete_post_meta( $stub_post_id, '_customize_changeset_uuid' ); } } add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); } function _wp_menus_changed() { $old_nav_menu_locations = get_option( 'theme_switch_menu_locations', array() ); $new_nav_menu_locations = get_nav_menu_locations(); $mapped_nav_menu_locations = wp_map_nav_menu_locations( $new_nav_menu_locations, $old_nav_menu_locations ); set_theme_mod( 'nav_menu_locations', $mapped_nav_menu_locations ); delete_option( 'theme_switch_menu_locations' ); } function wp_map_nav_menu_locations( $new_nav_menu_locations, $old_nav_menu_locations ) { $registered_nav_menus = get_registered_nav_menus(); $new_nav_menu_locations = array_intersect_key( $new_nav_menu_locations, $registered_nav_menus ); if ( empty( $old_nav_menu_locations ) ) { return $new_nav_menu_locations; } if ( 1 === count( $old_nav_menu_locations ) && 1 === count( $registered_nav_menus ) ) { $new_nav_menu_locations[ key( $registered_nav_menus ) ] = array_pop( $old_nav_menu_locations ); return $new_nav_menu_locations; } $old_locations = array_keys( $old_nav_menu_locations ); foreach ( $registered_nav_menus as $location => $name ) { if ( in_array( $location, $old_locations, true ) ) { $new_nav_menu_locations[ $location ] = $old_nav_menu_locations[ $location ]; unset( $old_nav_menu_locations[ $location ] ); } } if ( empty( $old_nav_menu_locations ) ) { return $new_nav_menu_locations; } $common_slug_groups = array( array( 'primary', 'menu-1', 'main', 'header', 'navigation', 'top' ), array( 'secondary', 'menu-2', 'footer', 'subsidiary', 'bottom' ), array( 'social' ), ); foreach ( $common_slug_groups as $slug_group ) { foreach ( $slug_group as $slug ) { foreach ( $registered_nav_menus as $new_location => $name ) { if ( is_string( $new_location ) && false === stripos( $new_location, $slug ) && false === stripos( $slug, $new_location ) ) { continue; } elseif ( is_numeric( $new_location ) && $new_location !== $slug ) { continue; } foreach ( $old_nav_menu_locations as $location => $menu_id ) { foreach ( $slug_group as $slug ) { if ( is_string( $location ) && false === stripos( $location, $slug ) && false === stripos( $slug, $location ) ) { continue; } elseif ( is_numeric( $location ) && $location !== $slug ) { continue; } if ( ! empty( $old_nav_menu_locations[ $location ] ) ) { $new_nav_menu_locations[ $new_location ] = $old_nav_menu_locations[ $location ]; unset( $old_nav_menu_locations[ $location ] ); continue 3; } } } } } } return $new_nav_menu_locations; } function _wp_reset_invalid_menu_item_parent( $menu_item_data ) { if ( ! is_array( $menu_item_data ) ) { return $menu_item_data; } if ( ! empty( $menu_item_data['ID'] ) && ! empty( $menu_item_data['menu_item_parent'] ) && (int) $menu_item_data['ID'] === (int) $menu_item_data['menu_item_parent'] ) { $menu_item_data['menu_item_parent'] = 0; } return $menu_item_data; }
###require ABSPATH . WPINC . '/admin-bar.php';
function _wp_admin_bar_init() { global $wp_admin_bar; if ( ! is_admin_bar_showing() ) { return false; } require_once ABSPATH . WPINC . '/class-wp-admin-bar.php'; $admin_bar_class = apply_filters( 'wp_admin_bar_class', 'WP_Admin_Bar' ); if ( class_exists( $admin_bar_class ) ) { $wp_admin_bar = new $admin_bar_class(); } else { return false; } $wp_admin_bar->initialize(); $wp_admin_bar->add_menus(); return true; } function wp_admin_bar_render() { global $wp_admin_bar; static $rendered = false; if ( $rendered ) { return; } if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) ) { return; } do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) ); do_action( 'wp_before_admin_bar_render' ); $wp_admin_bar->render(); do_action( 'wp_after_admin_bar_render' ); $rendered = true; } function wp_admin_bar_wp_menu( $wp_admin_bar ) { if ( current_user_can( 'read' ) ) { $about_url = self_admin_url( 'about.php' ); $contribute_url = self_admin_url( 'contribute.php' ); } elseif ( is_multisite() ) { $about_url = get_dashboard_url( get_current_user_id(), 'about.php' ); $contribute_url = get_dashboard_url( get_current_user_id(), 'contribute.php' ); } else { $about_url = false; $contribute_url = false; } $wp_logo_menu_args = array( 'id' => 'wp-logo', 'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' . __( 'About WordPress' ) . '</span>', 'href' => $about_url, 'meta' => array( 'menu_title' => __( 'About WordPress' ), ), ); if ( ! $about_url ) { $wp_logo_menu_args['meta'] = array( 'tabindex' => 0, ); } $wp_admin_bar->add_node( $wp_logo_menu_args ); if ( $about_url ) { $wp_admin_bar->add_node( array( 'parent' => 'wp-logo', 'id' => 'about', 'title' => __( 'About WordPress' ), 'href' => $about_url, ) ); } if ( $contribute_url ) { $wp_admin_bar->add_node( array( 'parent' => 'wp-logo', 'id' => 'contribute', 'title' => __( 'Get Involved' ), 'href' => $contribute_url, ) ); } $wp_admin_bar->add_node( array( 'parent' => 'wp-logo-external', 'id' => 'wporg', 'title' => __( 'WordPress.org' ), 'href' => __( 'https://wordpress.org/' ), ) ); $wp_admin_bar->add_node( array( 'parent' => 'wp-logo-external', 'id' => 'documentation', 'title' => __( 'Documentation' ), 'href' => __( 'https://wordpress.org/documentation/' ), ) ); $wp_admin_bar->add_node( array( 'parent' => 'wp-logo-external', 'id' => 'learn', 'title' => __( 'Learn WordPress' ), 'href' => __( 'https://learn.wordpress.org/' ), ) ); $wp_admin_bar->add_node( array( 'parent' => 'wp-logo-external', 'id' => 'support-forums', 'title' => __( 'Support' ), 'href' => __( 'https://wordpress.org/support/forums/' ), ) ); $wp_admin_bar->add_node( array( 'parent' => 'wp-logo-external', 'id' => 'feedback', 'title' => __( 'Feedback' ), 'href' => __( 'https://wordpress.org/support/forum/requests-and-feedback' ), ) ); } function wp_admin_bar_sidebar_toggle( $wp_admin_bar ) { if ( is_admin() ) { $wp_admin_bar->add_node( array( 'id' => 'menu-toggle', 'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' . __( 'Menu' ) . '</span>', 'href' => '#', ) ); } } function wp_admin_bar_my_account_item( $wp_admin_bar ) { $user_id = get_current_user_id(); if ( ! $user_id ) { return; } if ( current_user_can( 'read' ) ) { $profile_url = get_edit_profile_url( $user_id ); } elseif ( is_multisite() ) { $profile_url = get_dashboard_url( $user_id, 'profile.php' ); } else { $profile_url = false; } $howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . wp_get_current_user()->display_name . '</span>' ); $avatar = get_avatar( $user_id, 26 ); $wp_admin_bar->add_node( array( 'id' => 'my-account', 'parent' => 'top-secondary', 'title' => $howdy . $avatar, 'href' => $profile_url, 'meta' => array( 'class' => empty( $avatar ) ? '' : 'with-avatar', 'menu_title' => wp_strip_all_tags( $howdy ), 'tabindex' => ( false !== $profile_url ) ? '' : 0, ), ) ); } function wp_admin_bar_my_account_menu( $wp_admin_bar ) { $user_id = get_current_user_id(); $current_user = wp_get_current_user(); if ( ! $user_id ) { return; } if ( current_user_can( 'read' ) ) { $profile_url = get_edit_profile_url( $user_id ); } elseif ( is_multisite() ) { $profile_url = get_dashboard_url( $user_id, 'profile.php' ); } else { $profile_url = false; } $wp_admin_bar->add_group( array( 'parent' => 'my-account', 'id' => 'user-actions', ) ); $user_info = get_avatar( $user_id, 64 ); $user_info .= "<span class='display-name'>{$current_user->display_name}</span>"; if ( $current_user->display_name !== $current_user->user_login ) { $user_info .= "<span class='username'>{$current_user->user_login}</span>"; } if ( false !== $profile_url ) { $user_info .= "<span class='display-name edit-profile'>" . __( 'Edit Profile' ) . '</span>'; } $wp_admin_bar->add_node( array( 'parent' => 'user-actions', 'id' => 'user-info', 'title' => $user_info, 'href' => $profile_url, ) ); $wp_admin_bar->add_node( array( 'parent' => 'user-actions', 'id' => 'logout', 'title' => __( 'Log Out' ), 'href' => wp_logout_url(), ) ); } function wp_admin_bar_site_menu( $wp_admin_bar ) { if ( ! is_user_logged_in() ) { return; } if ( ! is_user_member_of_blog() && ! current_user_can( 'manage_network' ) ) { return; } $blogname = get_bloginfo( 'name' ); if ( ! $blogname ) { $blogname = preg_replace( '#^(https?://)?(www\.)?#', '', get_home_url() ); } if ( is_network_admin() ) { $blogname = sprintf( __( 'Network Admin: %s' ), esc_html( get_network()->site_name ) ); } elseif ( is_user_admin() ) { $blogname = sprintf( __( 'User Dashboard: %s' ), esc_html( get_network()->site_name ) ); } $title = wp_html_excerpt( $blogname, 40, '…' ); $wp_admin_bar->add_node( array( 'id' => 'site-name', 'title' => $title, 'href' => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(), 'meta' => array( 'menu_title' => $title, ), ) ); if ( is_admin() ) { $wp_admin_bar->add_node( array( 'parent' => 'site-name', 'id' => 'view-site', 'title' => __( 'Visit Site' ), 'href' => home_url( '/' ), ) ); if ( is_blog_admin() && is_multisite() && current_user_can( 'manage_sites' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'site-name', 'id' => 'edit-site', 'title' => __( 'Manage Site' ), 'href' => network_admin_url( 'site-info.php?id=' . get_current_blog_id() ), ) ); } } elseif ( current_user_can( 'read' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'site-name', 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => admin_url(), ) ); wp_admin_bar_appearance_menu( $wp_admin_bar ); if ( current_user_can( 'activate_plugins' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'site-name', 'id' => 'plugins', 'title' => __( 'Plugins' ), 'href' => admin_url( 'plugins.php' ), ) ); } } } function wp_admin_bar_edit_site_menu( $wp_admin_bar ) { global $_wp_current_template_id; if ( ! wp_is_block_theme() ) { return; } if ( ! current_user_can( 'edit_theme_options' ) || is_admin() ) { return; } $wp_admin_bar->add_node( array( 'id' => 'site-editor', 'title' => __( 'Edit Site' ), 'href' => add_query_arg( array( 'postType' => 'wp_template', 'postId' => $_wp_current_template_id, 'canvas' => 'edit', ), admin_url( 'site-editor.php' ) ), ) ); } function wp_admin_bar_customize_menu( $wp_admin_bar ) { global $wp_customize; if ( wp_is_block_theme() && ! has_action( 'customize_register' ) ) { return; } if ( ! current_user_can( 'customize' ) || is_admin() ) { return; } if ( is_customize_preview() && $wp_customize->changeset_post_id() && ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->edit_post, $wp_customize->changeset_post_id() ) ) { return; } $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; if ( is_customize_preview() && $wp_customize->changeset_uuid() ) { $current_url = remove_query_arg( 'customize_changeset_uuid', $current_url ); } $customize_url = add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() ); if ( is_customize_preview() ) { $customize_url = add_query_arg( array( 'changeset_uuid' => $wp_customize->changeset_uuid() ), $customize_url ); } $wp_admin_bar->add_node( array( 'id' => 'customize', 'title' => __( 'Customize' ), 'href' => $customize_url, 'meta' => array( 'class' => 'hide-if-no-customize', ), ) ); add_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); } function wp_admin_bar_my_sites_menu( $wp_admin_bar ) { if ( ! is_user_logged_in() || ! is_multisite() ) { return; } if ( count( $wp_admin_bar->user->blogs ) < 1 && ! current_user_can( 'manage_network' ) ) { return; } if ( $wp_admin_bar->user->active_blog ) { $my_sites_url = get_admin_url( $wp_admin_bar->user->active_blog->blog_id, 'my-sites.php' ); } else { $my_sites_url = admin_url( 'my-sites.php' ); } $wp_admin_bar->add_node( array( 'id' => 'my-sites', 'title' => __( 'My Sites' ), 'href' => $my_sites_url, ) ); if ( current_user_can( 'manage_network' ) ) { $wp_admin_bar->add_group( array( 'parent' => 'my-sites', 'id' => 'my-sites-super-admin', ) ); $wp_admin_bar->add_node( array( 'parent' => 'my-sites-super-admin', 'id' => 'network-admin', 'title' => __( 'Network Admin' ), 'href' => network_admin_url(), ) ); $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-d', 'title' => __( 'Dashboard' ), 'href' => network_admin_url(), ) ); if ( current_user_can( 'manage_sites' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-s', 'title' => __( 'Sites' ), 'href' => network_admin_url( 'sites.php' ), ) ); } if ( current_user_can( 'manage_network_users' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-u', 'title' => __( 'Users' ), 'href' => network_admin_url( 'users.php' ), ) ); } if ( current_user_can( 'manage_network_themes' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-t', 'title' => __( 'Themes' ), 'href' => network_admin_url( 'themes.php' ), ) ); } if ( current_user_can( 'manage_network_plugins' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-p', 'title' => __( 'Plugins' ), 'href' => network_admin_url( 'plugins.php' ), ) ); } if ( current_user_can( 'manage_network_options' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'network-admin', 'id' => 'network-admin-o', 'title' => __( 'Settings' ), 'href' => network_admin_url( 'settings.php' ), ) ); } } $wp_admin_bar->add_group( array( 'parent' => 'my-sites', 'id' => 'my-sites-list', 'meta' => array( 'class' => current_user_can( 'manage_network' ) ? 'ab-sub-secondary' : '', ), ) ); $show_site_icons = apply_filters( 'wp_admin_bar_show_site_icons', true ); foreach ( (array) $wp_admin_bar->user->blogs as $blog ) { switch_to_blog( $blog->userblog_id ); if ( true === $show_site_icons && has_site_icon() ) { $blavatar = sprintf( '<img class="blavatar" src="%s" srcset="%s 2x" alt="" width="16" height="16"%s />', esc_url( get_site_icon_url( 16 ) ), esc_url( get_site_icon_url( 32 ) ), ( wp_lazy_loading_enabled( 'img', 'site_icon_in_toolbar' ) ? ' loading="lazy"' : '' ) ); } else { $blavatar = '<div class="blavatar"></div>'; } $blogname = $blog->blogname; if ( ! $blogname ) { $blogname = preg_replace( '#^(https?://)?(www\.)?#', '', get_home_url() ); } $menu_id = 'blog-' . $blog->userblog_id; if ( current_user_can( 'read' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'my-sites-list', 'id' => $menu_id, 'title' => $blavatar . $blogname, 'href' => admin_url(), ) ); $wp_admin_bar->add_node( array( 'parent' => $menu_id, 'id' => $menu_id . '-d', 'title' => __( 'Dashboard' ), 'href' => admin_url(), ) ); } else { $wp_admin_bar->add_node( array( 'parent' => 'my-sites-list', 'id' => $menu_id, 'title' => $blavatar . $blogname, 'href' => home_url(), ) ); } if ( current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) { $wp_admin_bar->add_node( array( 'parent' => $menu_id, 'id' => $menu_id . '-n', 'title' => get_post_type_object( 'post' )->labels->new_item, 'href' => admin_url( 'post-new.php' ), ) ); } if ( current_user_can( 'edit_posts' ) ) { $wp_admin_bar->add_node( array( 'parent' => $menu_id, 'id' => $menu_id . '-c', 'title' => __( 'Manage Comments' ), 'href' => admin_url( 'edit-comments.php' ), ) ); } $wp_admin_bar->add_node( array( 'parent' => $menu_id, 'id' => $menu_id . '-v', 'title' => __( 'Visit Site' ), 'href' => home_url( '/' ), ) ); restore_current_blog(); } } function wp_admin_bar_shortlink_menu( $wp_admin_bar ) { $short = wp_get_shortlink( 0, 'query' ); $id = 'get-shortlink'; if ( empty( $short ) ) { return; } $html = '<input class="shortlink-input" type="text" readonly="readonly" value="' . esc_attr( $short ) . '" aria-label="' . __( 'Shortlink' ) . '" />'; $wp_admin_bar->add_node( array( 'id' => $id, 'title' => __( 'Shortlink' ), 'href' => $short, 'meta' => array( 'html' => $html ), ) ); } function wp_admin_bar_edit_menu( $wp_admin_bar ) { global $tag, $wp_the_query, $user_id, $post_id; if ( is_admin() ) { $current_screen = get_current_screen(); $post = get_post(); $post_type_object = null; if ( 'post' === $current_screen->base ) { $post_type_object = get_post_type_object( $post->post_type ); } elseif ( 'edit' === $current_screen->base ) { $post_type_object = get_post_type_object( $current_screen->post_type ); } elseif ( 'edit-comments' === $current_screen->base && $post_id ) { $post = get_post( $post_id ); if ( $post ) { $post_type_object = get_post_type_object( $post->post_type ); } } if ( ( 'post' === $current_screen->base || 'edit-comments' === $current_screen->base ) && 'add' !== $current_screen->action && ( $post_type_object ) && current_user_can( 'read_post', $post->ID ) && ( $post_type_object->public ) && ( $post_type_object->show_in_admin_bar ) ) { if ( 'draft' === $post->post_status ) { $preview_link = get_preview_post_link( $post ); $wp_admin_bar->add_node( array( 'id' => 'preview', 'title' => $post_type_object->labels->view_item, 'href' => esc_url( $preview_link ), 'meta' => array( 'target' => 'wp-preview-' . $post->ID ), ) ); } else { $wp_admin_bar->add_node( array( 'id' => 'view', 'title' => $post_type_object->labels->view_item, 'href' => get_permalink( $post->ID ), ) ); } } elseif ( 'edit' === $current_screen->base && ( $post_type_object ) && ( $post_type_object->public ) && ( $post_type_object->show_in_admin_bar ) && ( get_post_type_archive_link( $post_type_object->name ) ) && ! ( 'post' === $post_type_object->name && 'posts' === get_option( 'show_on_front' ) ) ) { $wp_admin_bar->add_node( array( 'id' => 'archive', 'title' => $post_type_object->labels->view_items, 'href' => get_post_type_archive_link( $current_screen->post_type ), ) ); } elseif ( 'term' === $current_screen->base && isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag ) ) { $tax = get_taxonomy( $tag->taxonomy ); if ( is_term_publicly_viewable( $tag ) ) { $wp_admin_bar->add_node( array( 'id' => 'view', 'title' => $tax->labels->view_item, 'href' => get_term_link( $tag ), ) ); } } elseif ( 'user-edit' === $current_screen->base && isset( $user_id ) ) { $user_object = get_userdata( $user_id ); $view_link = get_author_posts_url( $user_object->ID ); if ( $user_object->exists() && $view_link ) { $wp_admin_bar->add_node( array( 'id' => 'view', 'title' => __( 'View User' ), 'href' => $view_link, ) ); } } } else { $current_object = $wp_the_query->get_queried_object(); if ( empty( $current_object ) ) { return; } if ( ! empty( $current_object->post_type ) ) { $post_type_object = get_post_type_object( $current_object->post_type ); $edit_post_link = get_edit_post_link( $current_object->ID ); if ( $post_type_object && $edit_post_link && current_user_can( 'edit_post', $current_object->ID ) && $post_type_object->show_in_admin_bar ) { $wp_admin_bar->add_node( array( 'id' => 'edit', 'title' => $post_type_object->labels->edit_item, 'href' => $edit_post_link, ) ); } } elseif ( ! empty( $current_object->taxonomy ) ) { $tax = get_taxonomy( $current_object->taxonomy ); $edit_term_link = get_edit_term_link( $current_object->term_id, $current_object->taxonomy ); if ( $tax && $edit_term_link && current_user_can( 'edit_term', $current_object->term_id ) ) { $wp_admin_bar->add_node( array( 'id' => 'edit', 'title' => $tax->labels->edit_item, 'href' => $edit_term_link, ) ); } } elseif ( $current_object instanceof WP_User && current_user_can( 'edit_user', $current_object->ID ) ) { $edit_user_link = get_edit_user_link( $current_object->ID ); if ( $edit_user_link ) { $wp_admin_bar->add_node( array( 'id' => 'edit', 'title' => __( 'Edit User' ), 'href' => $edit_user_link, ) ); } } } } function wp_admin_bar_new_content_menu( $wp_admin_bar ) { $actions = array(); $cpts = (array) get_post_types( array( 'show_in_admin_bar' => true ), 'objects' ); if ( isset( $cpts['post'] ) && current_user_can( $cpts['post']->cap->create_posts ) ) { $actions['post-new.php'] = array( $cpts['post']->labels->name_admin_bar, 'new-post' ); } if ( isset( $cpts['attachment'] ) && current_user_can( 'upload_files' ) ) { $actions['media-new.php'] = array( $cpts['attachment']->labels->name_admin_bar, 'new-media' ); } if ( current_user_can( 'manage_links' ) ) { $actions['link-add.php'] = array( _x( 'Link', 'add new from admin bar' ), 'new-link' ); } if ( isset( $cpts['page'] ) && current_user_can( $cpts['page']->cap->create_posts ) ) { $actions['post-new.php?post_type=page'] = array( $cpts['page']->labels->name_admin_bar, 'new-page' ); } unset( $cpts['post'], $cpts['page'], $cpts['attachment'] ); foreach ( $cpts as $cpt ) { if ( ! current_user_can( $cpt->cap->create_posts ) ) { continue; } $key = 'post-new.php?post_type=' . $cpt->name; $actions[ $key ] = array( $cpt->labels->name_admin_bar, 'new-' . $cpt->name ); } if ( isset( $actions['post-new.php?post_type=content'] ) ) { $actions['post-new.php?post_type=content'][1] = 'add-new-content'; } if ( current_user_can( 'create_users' ) || ( is_multisite() && current_user_can( 'promote_users' ) ) ) { $actions['user-new.php'] = array( _x( 'User', 'add new from admin bar' ), 'new-user' ); } if ( ! $actions ) { return; } $title = '<span class="ab-icon" aria-hidden="true"></span><span class="ab-label">' . _x( 'New', 'admin bar menu group label' ) . '</span>'; $wp_admin_bar->add_node( array( 'id' => 'new-content', 'title' => $title, 'href' => admin_url( current( array_keys( $actions ) ) ), 'meta' => array( 'menu_title' => _x( 'New', 'admin bar menu group label' ), ), ) ); foreach ( $actions as $link => $action ) { list( $title, $id ) = $action; $wp_admin_bar->add_node( array( 'parent' => 'new-content', 'id' => $id, 'title' => $title, 'href' => admin_url( $link ), ) ); } if ( is_multisite() && current_user_can( 'create_sites' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'new-content', 'id' => 'add-new-site', 'title' => _x( 'Site', 'add new from admin bar' ), 'href' => network_admin_url( 'site-new.php' ), ) ); } } function wp_admin_bar_comments_menu( $wp_admin_bar ) { if ( ! current_user_can( 'edit_posts' ) ) { return; } $awaiting_mod = wp_count_comments(); $awaiting_mod = $awaiting_mod->moderated; $awaiting_text = sprintf( _n( '%s Comment in moderation', '%s Comments in moderation', $awaiting_mod ), number_format_i18n( $awaiting_mod ) ); $icon = '<span class="ab-icon" aria-hidden="true"></span>'; $title = '<span class="ab-label awaiting-mod pending-count count-' . $awaiting_mod . '" aria-hidden="true">' . number_format_i18n( $awaiting_mod ) . '</span>'; $title .= '<span class="screen-reader-text comments-in-moderation-text">' . $awaiting_text . '</span>'; $wp_admin_bar->add_node( array( 'id' => 'comments', 'title' => $icon . $title, 'href' => admin_url( 'edit-comments.php' ), ) ); } function wp_admin_bar_appearance_menu( $wp_admin_bar ) { $wp_admin_bar->add_group( array( 'parent' => 'site-name', 'id' => 'appearance', ) ); if ( current_user_can( 'switch_themes' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'appearance', 'id' => 'themes', 'title' => __( 'Themes' ), 'href' => admin_url( 'themes.php' ), ) ); } if ( ! current_user_can( 'edit_theme_options' ) ) { return; } if ( current_theme_supports( 'widgets' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'appearance', 'id' => 'widgets', 'title' => __( 'Widgets' ), 'href' => admin_url( 'widgets.php' ), ) ); } if ( current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'appearance', 'id' => 'menus', 'title' => __( 'Menus' ), 'href' => admin_url( 'nav-menus.php' ), ) ); } if ( current_theme_supports( 'custom-background' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'appearance', 'id' => 'background', 'title' => _x( 'Background', 'custom background' ), 'href' => admin_url( 'themes.php?page=custom-background' ), 'meta' => array( 'class' => 'hide-if-customize', ), ) ); } if ( current_theme_supports( 'custom-header' ) ) { $wp_admin_bar->add_node( array( 'parent' => 'appearance', 'id' => 'header', 'title' => _x( 'Header', 'custom image header' ), 'href' => admin_url( 'themes.php?page=custom-header' ), 'meta' => array( 'class' => 'hide-if-customize', ), ) ); } } function wp_admin_bar_updates_menu( $wp_admin_bar ) { $update_data = wp_get_update_data(); if ( ! $update_data['counts']['total'] ) { return; } $updates_text = sprintf( _n( '%s update available', '%s updates available', $update_data['counts']['total'] ), number_format_i18n( $update_data['counts']['total'] ) ); $icon = '<span class="ab-icon" aria-hidden="true"></span>'; $title = '<span class="ab-label" aria-hidden="true">' . number_format_i18n( $update_data['counts']['total'] ) . '</span>'; $title .= '<span class="screen-reader-text updates-available-text">' . $updates_text . '</span>'; $wp_admin_bar->add_node( array( 'id' => 'updates', 'title' => $icon . $title, 'href' => network_admin_url( 'update-core.php' ), ) ); } function wp_admin_bar_search_menu( $wp_admin_bar ) { if ( is_admin() ) { return; } $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">'; $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />'; $form .= '<label for="adminbar-search" class="screen-reader-text">' . __( 'Search' ) . '</label>'; $form .= '<input type="submit" class="adminbar-button" value="' . __( 'Search' ) . '" />'; $form .= '</form>'; $wp_admin_bar->add_node( array( 'parent' => 'top-secondary', 'id' => 'search', 'title' => $form, 'meta' => array( 'class' => 'admin-bar-search', 'tabindex' => -1, ), ) ); } function wp_admin_bar_recovery_mode_menu( $wp_admin_bar ) { if ( ! wp_is_recovery_mode() ) { return; } $url = wp_login_url(); $url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url ); $url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION ); $wp_admin_bar->add_node( array( 'parent' => 'top-secondary', 'id' => 'recovery-mode', 'title' => __( 'Exit Recovery Mode' ), 'href' => $url, ) ); } function wp_admin_bar_add_secondary_groups( $wp_admin_bar ) { $wp_admin_bar->add_group( array( 'id' => 'top-secondary', 'meta' => array( 'class' => 'ab-top-secondary', ), ) ); $wp_admin_bar->add_group( array( 'parent' => 'wp-logo', 'id' => 'wp-logo-external', 'meta' => array( 'class' => 'ab-sub-secondary', ), ) ); } function wp_enqueue_admin_bar_header_styles() { $action = is_admin() ? 'admin_head' : 'wp_head'; if ( ! has_action( $action, 'wp_admin_bar_header' ) ) { return; } remove_action( $action, 'wp_admin_bar_header' ); wp_add_inline_style( 'admin-bar', '@media print { #wpadminbar { display:none; } }' ); } function wp_enqueue_admin_bar_bump_styles() { if ( current_theme_supports( 'admin-bar' ) ) { $admin_bar_args = get_theme_support( 'admin-bar' ); $header_callback = $admin_bar_args[0]['callback']; } if ( empty( $header_callback ) ) { $header_callback = '_admin_bar_bump_cb'; } if ( '_admin_bar_bump_cb' !== $header_callback ) { return; } if ( ! has_action( 'wp_head', $header_callback ) ) { return; } remove_action( 'wp_head', $header_callback ); $css = '
@media screen { html { margin-top: 32px !important; } }
@media screen and ( max-width: 782px ) { html { margin-top: 46px !important; } }
'; wp_add_inline_style( 'admin-bar', $css ); } function show_admin_bar( $show ) { global $show_admin_bar; $show_admin_bar = (bool) $show; } function is_admin_bar_showing() { global $show_admin_bar, $pagenow; if ( defined( 'XMLRPC_REQUEST' ) || defined( 'DOING_AJAX' ) || defined( 'IFRAME_REQUEST' ) || wp_is_json_request() ) { return false; } if ( is_embed() ) { return false; } if ( is_admin() ) { return true; } if ( ! isset( $show_admin_bar ) ) { if ( ! is_user_logged_in() || 'wp-login.php' === $pagenow ) { $show_admin_bar = false; } else { $show_admin_bar = _get_admin_bar_pref(); } } $show_admin_bar = apply_filters( 'show_admin_bar', $show_admin_bar ); return $show_admin_bar; } function _get_admin_bar_pref( $context = 'front', $user = 0 ) { $pref = get_user_option( "show_admin_bar_{$context}", $user ); if ( false === $pref ) { return true; } return 'true' === $pref; }
###require ABSPATH . WPINC . '/class-wp-application-passwords.php';
class WP_Application_Passwords { const USERMETA_KEY_APPLICATION_PASSWORDS = '_application_passwords'; const OPTION_KEY_IN_USE = 'using_application_passwords'; const PW_LENGTH = 24; public static function is_in_use() { $network_id = get_main_network_id(); return (bool) get_network_option( $network_id, self::OPTION_KEY_IN_USE ); } public static function create_new_application_password( $user_id, $args = array() ) { if ( ! empty( $args['name'] ) ) { $args['name'] = sanitize_text_field( $args['name'] ); } if ( empty( $args['name'] ) ) { return new WP_Error( 'application_password_empty_name', __( 'An application name is required to create an application password.' ), array( 'status' => 400 ) ); } $new_password = wp_generate_password( static::PW_LENGTH, false ); $hashed_password = self::hash_password( $new_password ); $new_item = array( 'uuid' => wp_generate_uuid4(), 'app_id' => empty( $args['app_id'] ) ? '' : $args['app_id'], 'name' => $args['name'], 'password' => $hashed_password, 'created' => time(), 'last_used' => null, 'last_ip' => null, ); $passwords = static::get_user_application_passwords( $user_id ); $passwords[] = $new_item; $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); } $network_id = get_main_network_id(); if ( ! get_network_option( $network_id, self::OPTION_KEY_IN_USE ) ) { update_network_option( $network_id, self::OPTION_KEY_IN_USE, true ); } do_action( 'wp_create_application_password', $user_id, $new_item, $new_password, $args ); return array( $new_password, $new_item ); } public static function get_user_application_passwords( $user_id ) { $passwords = get_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, true ); if ( ! is_array( $passwords ) ) { return array(); } $save = false; foreach ( $passwords as $i => $password ) { if ( ! isset( $password['uuid'] ) ) { $passwords[ $i ]['uuid'] = wp_generate_uuid4(); $save = true; } } if ( $save ) { static::set_user_application_passwords( $user_id, $passwords ); } return $passwords; } public static function get_user_application_password( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $password ) { if ( $password['uuid'] === $uuid ) { return $password; } } return null; } public static function application_name_exists_for_user( $user_id, $name ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $password ) { if ( strtolower( $password['name'] ) === strtolower( $name ) ) { return true; } } return false; } public static function update_application_password( $user_id, $uuid, $update = array() ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as &$item ) { if ( $item['uuid'] !== $uuid ) { continue; } if ( ! empty( $update['name'] ) ) { $update['name'] = sanitize_text_field( $update['name'] ); } $save = false; if ( ! empty( $update['name'] ) && $item['name'] !== $update['name'] ) { $item['name'] = $update['name']; $save = true; } if ( $save ) { $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); } } do_action( 'wp_update_application_password', $user_id, $item, $update ); return true; } return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } public static function record_application_password_usage( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as &$password ) { if ( $password['uuid'] !== $uuid ) { continue; } if ( $password['last_used'] + DAY_IN_SECONDS > time() ) { return true; } $password['last_used'] = time(); $password['last_ip'] = $_SERVER['REMOTE_ADDR']; $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); } return true; } return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } public static function delete_application_password( $user_id, $uuid ) { $passwords = static::get_user_application_passwords( $user_id ); foreach ( $passwords as $key => $item ) { if ( $item['uuid'] === $uuid ) { unset( $passwords[ $key ] ); $saved = static::set_user_application_passwords( $user_id, $passwords ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not delete application password.' ) ); } do_action( 'wp_delete_application_password', $user_id, $item ); return true; } } return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); } public static function delete_all_application_passwords( $user_id ) { $passwords = static::get_user_application_passwords( $user_id ); if ( $passwords ) { $saved = static::set_user_application_passwords( $user_id, array() ); if ( ! $saved ) { return new WP_Error( 'db_error', __( 'Could not delete application passwords.' ) ); } foreach ( $passwords as $item ) { do_action( 'wp_delete_application_password', $user_id, $item ); } return count( $passwords ); } return 0; } protected static function set_user_application_passwords( $user_id, $passwords ) { return update_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, $passwords ); } public static function chunk_password( $raw_password ) { $raw_password = preg_replace( '/[^a-z\d]/i', '', $raw_password ); return trim( chunk_split( $raw_password, 4, ' ' ) ); } public static function hash_password( string $password ): string { return wp_fast_hash( $password ); } public static function check_password( string $password, string $hash ): bool { if ( ! str_starts_with( $hash, '$generic$' ) ) { return wp_check_password( $password, $hash ); } return wp_verify_fast_hash( $password, $hash ); } }
###require ABSPATH . WPINC . '/abilities-api/class-wp-ability-category.php';
declare( strict_types = 1 ); final class WP_Ability_Category { protected $slug; protected $label; protected $description; protected $meta = array(); public function __construct( string $slug, array $args ) { if ( empty( $slug ) ) { throw new InvalidArgumentException( __( 'The ability category slug cannot be empty.' ) ); } $this->slug = $slug; $properties = $this->prepare_properties( $args ); foreach ( $properties as $property_name => $property_value ) { if ( ! property_exists( $this, $property_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Property "%1$s" is not a valid property for ability category "%2$s". Please check the %3$s class for allowed properties.' ), '<code>' . esc_html( $property_name ) . '</code>', '<code>' . esc_html( $this->slug ) . '</code>', '<code>' . __CLASS__ . '</code>' ), '6.9.0' ); continue; } $this->$property_name = $property_value; } } protected function prepare_properties( array $args ): array { if ( empty( $args['label'] ) || ! is_string( $args['label'] ) ) { throw new InvalidArgumentException( __( 'The ability category properties must contain a `label` string.' ) ); } if ( empty( $args['description'] ) || ! is_string( $args['description'] ) ) { throw new InvalidArgumentException( __( 'The ability category properties must contain a `description` string.' ) ); } if ( isset( $args['meta'] ) && ! is_array( $args['meta'] ) ) { throw new InvalidArgumentException( __( 'The ability category properties should provide a valid `meta` array.' ) ); } return $args; } public function get_slug(): string { return $this->slug; } public function get_label(): string { return $this->label; } public function get_description(): string { return $this->description; } public function get_meta(): array { return $this->meta; } public function __wakeup(): void { throw new LogicException( __CLASS__ . ' should never be unserialized.' ); } public function __sleep(): array { throw new LogicException( __CLASS__ . ' should never be serialized.' ); } }
###require ABSPATH . WPINC . '/abilities-api/class-wp-ability-categories-registry.php';
declare( strict_types = 1 ); final class WP_Ability_Categories_Registry { private static $instance = null; private $registered_categories = array(); public function register( string $slug, array $args ): ?WP_Ability_Category { if ( $this->is_registered( $slug ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability category "%s" is already registered.' ), esc_html( $slug ) ), '6.9.0' ); return null; } if ( ! preg_match( '/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $slug ) ) { _doing_it_wrong( __METHOD__, __( 'Ability category slug must contain only lowercase alphanumeric characters and dashes.' ), '6.9.0' ); return null; } $args = apply_filters( 'wp_register_ability_category_args', $args, $slug ); try { $category = new WP_Ability_Category( $slug, $args ); } catch ( InvalidArgumentException $e ) { _doing_it_wrong( __METHOD__, $e->getMessage(), '6.9.0' ); return null; } $this->registered_categories[ $slug ] = $category; return $category; } public function unregister( string $slug ): ?WP_Ability_Category { if ( ! $this->is_registered( $slug ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability category "%s" not found.' ), esc_html( $slug ) ), '6.9.0' ); return null; } $unregistered_category = $this->registered_categories[ $slug ]; unset( $this->registered_categories[ $slug ] ); return $unregistered_category; } public function get_all_registered(): array { return $this->registered_categories; } public function is_registered( string $slug ): bool { return isset( $this->registered_categories[ $slug ] ); } public function get_registered( string $slug ): ?WP_Ability_Category { if ( ! $this->is_registered( $slug ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability category "%s" not found.' ), esc_html( $slug ) ), '6.9.0' ); return null; } return $this->registered_categories[ $slug ]; } public static function get_instance(): ?self { if ( ! did_action( 'init' ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability API should not be initialized before the %s action has fired.' ), '<code>init</code>' ), '6.9.0' ); return null; } if ( null === self::$instance ) { self::$instance = new self(); do_action( 'wp_abilities_api_categories_init', self::$instance ); } return self::$instance; } public function __wakeup(): void { throw new LogicException( __CLASS__ . ' should never be unserialized.' ); } public function __sleep(): array { throw new LogicException( __CLASS__ . ' should never be serialized.' ); } }
###require ABSPATH . WPINC . '/abilities-api/class-wp-ability.php';
declare( strict_types = 1 ); class WP_Ability { protected const DEFAULT_SHOW_IN_REST = false; protected static $default_annotations = array( 'readonly' => null, 'destructive' => null, 'idempotent' => null, ); protected $name; protected $label; protected $description; protected $category; protected $input_schema = array(); protected $output_schema = array(); protected $execute_callback; protected $permission_callback; protected $meta; public function __construct( string $name, array $args ) { $this->name = $name; $properties = $this->prepare_properties( $args ); foreach ( $properties as $property_name => $property_value ) { if ( ! property_exists( $this, $property_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Property "%1$s" is not a valid property for ability "%2$s". Please check the %3$s class for allowed properties.' ), '<code>' . esc_html( $property_name ) . '</code>', '<code>' . esc_html( $this->name ) . '</code>', '<code>' . __CLASS__ . '</code>' ), '6.9.0' ); continue; } $this->$property_name = $property_value; } } protected function prepare_properties( array $args ): array { if ( empty( $args['label'] ) || ! is_string( $args['label'] ) ) { throw new InvalidArgumentException( __( 'The ability properties must contain a `label` string.' ) ); } if ( empty( $args['description'] ) || ! is_string( $args['description'] ) ) { throw new InvalidArgumentException( __( 'The ability properties must contain a `description` string.' ) ); } if ( empty( $args['category'] ) || ! is_string( $args['category'] ) ) { throw new InvalidArgumentException( __( 'The ability properties must contain a `category` string.' ) ); } if ( empty( $args['execute_callback'] ) || ! is_callable( $args['execute_callback'] ) ) { throw new InvalidArgumentException( __( 'The ability properties must contain a valid `execute_callback` function.' ) ); } if ( empty( $args['permission_callback'] ) || ! is_callable( $args['permission_callback'] ) ) { throw new InvalidArgumentException( __( 'The ability properties must provide a valid `permission_callback` function.' ) ); } if ( isset( $args['input_schema'] ) && ! is_array( $args['input_schema'] ) ) { throw new InvalidArgumentException( __( 'The ability properties should provide a valid `input_schema` definition.' ) ); } if ( isset( $args['output_schema'] ) && ! is_array( $args['output_schema'] ) ) { throw new InvalidArgumentException( __( 'The ability properties should provide a valid `output_schema` definition.' ) ); } if ( isset( $args['meta'] ) && ! is_array( $args['meta'] ) ) { throw new InvalidArgumentException( __( 'The ability properties should provide a valid `meta` array.' ) ); } if ( isset( $args['meta']['annotations'] ) && ! is_array( $args['meta']['annotations'] ) ) { throw new InvalidArgumentException( __( 'The ability meta should provide a valid `annotations` array.' ) ); } if ( isset( $args['meta']['show_in_rest'] ) && ! is_bool( $args['meta']['show_in_rest'] ) ) { throw new InvalidArgumentException( __( 'The ability meta should provide a valid `show_in_rest` boolean.' ) ); } $args['meta'] = wp_parse_args( $args['meta'] ?? array(), array( 'annotations' => static::$default_annotations, 'show_in_rest' => self::DEFAULT_SHOW_IN_REST, ) ); $args['meta']['annotations'] = wp_parse_args( $args['meta']['annotations'], static::$default_annotations ); return $args; } public function get_name(): string { return $this->name; } public function get_label(): string { return $this->label; } public function get_description(): string { return $this->description; } public function get_category(): string { return $this->category; } public function get_input_schema(): array { return $this->input_schema; } public function get_output_schema(): array { return $this->output_schema; } public function get_meta(): array { return $this->meta; } public function get_meta_item( string $key, $default_value = null ) { return array_key_exists( $key, $this->meta ) ? $this->meta[ $key ] : $default_value; } public function normalize_input( $input = null ) { if ( null !== $input ) { return $input; } $input_schema = $this->get_input_schema(); if ( ! empty( $input_schema ) && array_key_exists( 'default', $input_schema ) ) { return $input_schema['default']; } return null; } public function validate_input( $input = null ) { $input_schema = $this->get_input_schema(); if ( empty( $input_schema ) ) { if ( null === $input ) { return true; } return new WP_Error( 'ability_missing_input_schema', sprintf( __( 'Ability "%s" does not define an input schema required to validate the provided input.' ), esc_html( $this->name ) ) ); } $valid_input = rest_validate_value_from_schema( $input, $input_schema, 'input' ); if ( is_wp_error( $valid_input ) ) { return new WP_Error( 'ability_invalid_input', sprintf( __( 'Ability "%1$s" has invalid input. Reason: %2$s' ), esc_html( $this->name ), $valid_input->get_error_message() ) ); } return true; } protected function invoke_callback( callable $callback, $input = null ) { $args = array(); if ( ! empty( $this->get_input_schema() ) ) { $args[] = $input; } return $callback( ...$args ); } public function check_permissions( $input = null ) { if ( ! is_callable( $this->permission_callback ) ) { return new WP_Error( 'ability_invalid_permission_callback', sprintf( __( 'Ability "%s" does not have a valid permission callback.' ), esc_html( $this->name ) ) ); } return $this->invoke_callback( $this->permission_callback, $input ); } protected function do_execute( $input = null ) { if ( ! is_callable( $this->execute_callback ) ) { return new WP_Error( 'ability_invalid_execute_callback', sprintf( __( 'Ability "%s" does not have a valid execute callback.' ), esc_html( $this->name ) ) ); } return $this->invoke_callback( $this->execute_callback, $input ); } protected function validate_output( $output ) { $output_schema = $this->get_output_schema(); if ( empty( $output_schema ) ) { return true; } $valid_output = rest_validate_value_from_schema( $output, $output_schema, 'output' ); if ( is_wp_error( $valid_output ) ) { return new WP_Error( 'ability_invalid_output', sprintf( __( 'Ability "%1$s" has invalid output. Reason: %2$s' ), esc_html( $this->name ), $valid_output->get_error_message() ) ); } return true; } public function execute( $input = null ) { $input = $this->normalize_input( $input ); $is_valid = $this->validate_input( $input ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } $has_permissions = $this->check_permissions( $input ); if ( true !== $has_permissions ) { if ( is_wp_error( $has_permissions ) ) { _doing_it_wrong( __METHOD__, esc_html( $has_permissions->get_error_message() ), '6.9.0' ); } return new WP_Error( 'ability_invalid_permissions', sprintf( __( 'Ability "%s" does not have necessary permission.' ), esc_html( $this->name ) ) ); } do_action( 'wp_before_execute_ability', $this->name, $input ); $result = $this->do_execute( $input ); if ( is_wp_error( $result ) ) { return $result; } $is_valid = $this->validate_output( $result ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } do_action( 'wp_after_execute_ability', $this->name, $input, $result ); return $result; } public function __wakeup(): void { throw new LogicException( __CLASS__ . ' should never be unserialized.' ); } public function __sleep(): array { throw new LogicException( __CLASS__ . ' should never be serialized.' ); } }
###require ABSPATH . WPINC . '/abilities-api/class-wp-abilities-registry.php';
declare( strict_types = 1 ); final class WP_Abilities_Registry { private static $instance = null; private $registered_abilities = array(); public function register( string $name, array $args ): ?WP_Ability { if ( ! preg_match( '/^[a-z0-9-]+\/[a-z0-9-]+$/', $name ) ) { _doing_it_wrong( __METHOD__, __( 'Ability name must be a string containing a namespace prefix, i.e. "my-plugin/my-ability". It can only contain lowercase alphanumeric characters, dashes and the forward slash.' ), '6.9.0' ); return null; } if ( $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability "%s" is already registered.' ), esc_html( $name ) ), '6.9.0' ); return null; } $args = apply_filters( 'wp_register_ability_args', $args, $name ); if ( isset( $args['category'] ) ) { if ( ! wp_has_ability_category( $args['category'] ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability category "%1$s" is not registered. Please register the ability category before assigning it to ability "%2$s".' ), esc_html( $args['category'] ), esc_html( $name ) ), '6.9.0' ); return null; } } if ( isset( $args['ability_class'] ) && ! is_a( $args['ability_class'], WP_Ability::class, true ) ) { _doing_it_wrong( __METHOD__, __( 'The ability args should provide a valid `ability_class` that extends WP_Ability.' ), '6.9.0' ); return null; } $ability_class = $args['ability_class'] ?? WP_Ability::class; unset( $args['ability_class'] ); try { $ability = new $ability_class( $name, $args ); } catch ( InvalidArgumentException $e ) { _doing_it_wrong( __METHOD__, $e->getMessage(), '6.9.0' ); return null; } $this->registered_abilities[ $name ] = $ability; return $ability; } public function unregister( string $name ): ?WP_Ability { if ( ! $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability "%s" not found.' ), esc_html( $name ) ), '6.9.0' ); return null; } $unregistered_ability = $this->registered_abilities[ $name ]; unset( $this->registered_abilities[ $name ] ); return $unregistered_ability; } public function get_all_registered(): array { return $this->registered_abilities; } public function is_registered( string $name ): bool { return isset( $this->registered_abilities[ $name ] ); } public function get_registered( string $name ): ?WP_Ability { if ( ! $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability "%s" not found.' ), esc_html( $name ) ), '6.9.0' ); return null; } return $this->registered_abilities[ $name ]; } public static function get_instance(): ?self { if ( ! did_action( 'init' ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Ability API should not be initialized before the %s action has fired.' ), '<code>init</code>' ), '6.9.0' ); return null; } if ( null === self::$instance ) { self::$instance = new self(); WP_Ability_Categories_Registry::get_instance(); do_action( 'wp_abilities_api_init', self::$instance ); } return self::$instance; } public function __wakeup(): void { throw new LogicException( __CLASS__ . ' should never be unserialized.' ); } public function __sleep(): array { throw new LogicException( __CLASS__ . ' should never be serialized.' ); } }
###require ABSPATH . WPINC . '/abilities-api.php';
declare( strict_types = 1 ); function wp_register_ability( string $name, array $args ): ?WP_Ability { if ( ! doing_action( 'wp_abilities_api_init' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Abilities must be registered on the %1$s action. The ability %2$s was not registered.' ), '<code>wp_abilities_api_init</code>', '<code>' . esc_html( $name ) . '</code>' ), '6.9.0' ); return null; } $registry = WP_Abilities_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->register( $name, $args ); } function wp_unregister_ability( string $name ): ?WP_Ability { $registry = WP_Abilities_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->unregister( $name ); } function wp_has_ability( string $name ): bool { $registry = WP_Abilities_Registry::get_instance(); if ( null === $registry ) { return false; } return $registry->is_registered( $name ); } function wp_get_ability( string $name ): ?WP_Ability { $registry = WP_Abilities_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->get_registered( $name ); } function wp_get_abilities(): array { $registry = WP_Abilities_Registry::get_instance(); if ( null === $registry ) { return array(); } return $registry->get_all_registered(); } function wp_register_ability_category( string $slug, array $args ): ?WP_Ability_Category { if ( ! doing_action( 'wp_abilities_api_categories_init' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Ability categories must be registered on the %1$s action. The ability category %2$s was not registered.' ), '<code>wp_abilities_api_categories_init</code>', '<code>' . esc_html( $slug ) . '</code>' ), '6.9.0' ); return null; } $registry = WP_Ability_Categories_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->register( $slug, $args ); } function wp_unregister_ability_category( string $slug ): ?WP_Ability_Category { $registry = WP_Ability_Categories_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->unregister( $slug ); } function wp_has_ability_category( string $slug ): bool { $registry = WP_Ability_Categories_Registry::get_instance(); if ( null === $registry ) { return false; } return $registry->is_registered( $slug ); } function wp_get_ability_category( string $slug ): ?WP_Ability_Category { $registry = WP_Ability_Categories_Registry::get_instance(); if ( null === $registry ) { return null; } return $registry->get_registered( $slug ); } function wp_get_ability_categories(): array { $registry = WP_Ability_Categories_Registry::get_instance(); if ( null === $registry ) { return array(); } return $registry->get_all_registered(); }
###require ABSPATH . WPINC . '/abilities.php';
declare( strict_types = 1 ); function wp_register_core_ability_categories(): void { wp_register_ability_category( 'site', array( 'label' => __( 'Site' ), 'description' => __( 'Abilities that retrieve or modify site information and settings.' ), ) ); wp_register_ability_category( 'user', array( 'label' => __( 'User' ), 'description' => __( 'Abilities that retrieve or modify user information and settings.' ), ) ); } function wp_register_core_abilities(): void { $category_site = 'site'; $category_user = 'user'; $site_info_properties = array( 'name' => array( 'type' => 'string', 'description' => __( 'The site title.' ), ), 'description' => array( 'type' => 'string', 'description' => __( 'The site tagline.' ), ), 'url' => array( 'type' => 'string', 'description' => __( 'The site home URL.' ), ), 'wpurl' => array( 'type' => 'string', 'description' => __( 'The WordPress installation URL.' ), ), 'admin_email' => array( 'type' => 'string', 'description' => __( 'The site administrator email address.' ), ), 'charset' => array( 'type' => 'string', 'description' => __( 'The site character encoding.' ), ), 'language' => array( 'type' => 'string', 'description' => __( 'The site language locale code.' ), ), 'version' => array( 'type' => 'string', 'description' => __( 'The WordPress version.' ), ), ); $site_info_fields = array_keys( $site_info_properties ); wp_register_ability( 'core/get-site-info', array( 'label' => __( 'Get Site Information' ), 'description' => __( 'Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.' ), 'category' => $category_site, 'input_schema' => array( 'type' => 'object', 'properties' => array( 'fields' => array( 'type' => 'array', 'items' => array( 'type' => 'string', 'enum' => $site_info_fields, ), 'description' => __( 'Optional: Limit response to specific fields. If omitted, all fields are returned.' ), ), ), 'additionalProperties' => false, 'default' => array(), ), 'output_schema' => array( 'type' => 'object', 'properties' => $site_info_properties, 'additionalProperties' => false, ), 'execute_callback' => static function ( $input = array() ) use ( $site_info_fields ): array { $input = is_array( $input ) ? $input : array(); $requested_fields = ! empty( $input['fields'] ) ? $input['fields'] : $site_info_fields; $result = array(); foreach ( $requested_fields as $field ) { $result[ $field ] = get_bloginfo( $field ); } return $result; }, 'permission_callback' => static function (): bool { return current_user_can( 'manage_options' ); }, 'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => true, ), ) ); wp_register_ability( 'core/get-user-info', array( 'label' => __( 'Get User Information' ), 'description' => __( 'Returns basic profile details for the current authenticated user to support personalization, auditing, and access-aware behavior.' ), 'category' => $category_user, 'output_schema' => array( 'type' => 'object', 'required' => array( 'id', 'display_name', 'user_nicename', 'user_login', 'roles', 'locale' ), 'properties' => array( 'id' => array( 'type' => 'integer', 'description' => __( 'The user ID.' ), ), 'display_name' => array( 'type' => 'string', 'description' => __( 'The display name of the user.' ), ), 'user_nicename' => array( 'type' => 'string', 'description' => __( 'The URL-friendly name for the user.' ), ), 'user_login' => array( 'type' => 'string', 'description' => __( 'The login username for the user.' ), ), 'roles' => array( 'type' => 'array', 'description' => __( 'The roles assigned to the user.' ), 'items' => array( 'type' => 'string', ), ), 'locale' => array( 'type' => 'string', 'description' => __( 'The locale string for the user, such as en_US.' ), ), ), 'additionalProperties' => false, ), 'execute_callback' => static function (): array { $current_user = wp_get_current_user(); return array( 'id' => $current_user->ID, 'display_name' => $current_user->display_name, 'user_nicename' => $current_user->user_nicename, 'user_login' => $current_user->user_login, 'roles' => $current_user->roles, 'locale' => get_user_locale( $current_user ), ); }, 'permission_callback' => static function (): bool { return is_user_logged_in(); }, 'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => false, ), ) ); wp_register_ability( 'core/get-environment-info', array( 'label' => __( 'Get Environment Info' ), 'description' => __( 'Returns core details about the site\'s runtime context for diagnostics and compatibility (environment, PHP runtime, database server info, WordPress version).' ), 'category' => $category_site, 'output_schema' => array( 'type' => 'object', 'required' => array( 'environment', 'php_version', 'db_server_info', 'wp_version' ), 'properties' => array( 'environment' => array( 'type' => 'string', 'description' => __( 'The site\'s runtime environment classification (can be one of these: production, staging, development, local).' ), 'enum' => array( 'production', 'staging', 'development', 'local' ), ), 'php_version' => array( 'type' => 'string', 'description' => __( 'The PHP runtime version executing WordPress.' ), ), 'db_server_info' => array( 'type' => 'string', 'description' => __( 'The database server vendor and version string reported by the driver.' ), ), 'wp_version' => array( 'type' => 'string', 'description' => __( 'The WordPress core version running on this site.' ), ), ), 'additionalProperties' => false, ), 'execute_callback' => static function (): array { global $wpdb; $env = wp_get_environment_type(); $php_version = phpversion(); $db_server_info = ''; if ( method_exists( $wpdb, 'db_server_info' ) ) { $db_server_info = $wpdb->db_server_info() ?? ''; } $wp_version = get_bloginfo( 'version' ); return array( 'environment' => $env, 'php_version' => $php_version, 'db_server_info' => $db_server_info, 'wp_version' => $wp_version, ); }, 'permission_callback' => static function (): bool { return current_user_can( 'manage_options' ); }, 'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => true, ), ) ); }
###require ABSPATH . WPINC . '/rest-api.php';
define( 'REST_API_VERSION', '2.0' ); function register_rest_route( $route_namespace, $route, $args = array(), $override = false ) { if ( empty( $route_namespace ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Routes must be namespaced with plugin or theme name and version. Instead there seems to be an empty namespace \'%1$s\' for route \'%2$s\'.' ), '<code>' . $route_namespace . '</code>', '<code>' . $route . '</code>' ), '4.4.0' ); return false; } elseif ( empty( $route ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Route must be specified. Instead within the namespace \'%1$s\', there seems to be an empty route \'%2$s\'.' ), '<code>' . $route_namespace . '</code>', '<code>' . $route . '</code>' ), '4.4.0' ); return false; } $clean_namespace = trim( $route_namespace, '/' ); if ( $clean_namespace !== $route_namespace ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'Namespace must not start or end with a slash. Instead namespace \'%1$s\' for route \'%2$s\' seems to contain a slash.' ), '<code>' . $route_namespace . '</code>', '<code>' . $route . '</code>' ), '5.4.2' ); } if ( ! did_action( 'rest_api_init' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'REST API routes must be registered on the %1$s action. Instead route \'%2$s\' with namespace \'%3$s\' was not registered on this action.' ), '<code>rest_api_init</code>', '<code>' . $route . '</code>', '<code>' . $route_namespace . '</code>' ), '5.1.0' ); } if ( isset( $args['args'] ) ) { $common_args = $args['args']; unset( $args['args'] ); } else { $common_args = array(); } if ( isset( $args['callback'] ) ) { $args = array( $args ); } $defaults = array( 'methods' => 'GET', 'callback' => null, 'args' => array(), ); foreach ( $args as $key => &$arg_group ) { if ( ! is_numeric( $key ) ) { continue; } $arg_group = array_merge( $defaults, $arg_group ); $arg_group['args'] = array_merge( $common_args, $arg_group['args'] ); if ( ! isset( $arg_group['permission_callback'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'The REST API route definition for %1$s is missing the required %2$s argument. For REST API routes that are intended to be public, use %3$s as the permission callback.' ), '<code>' . $clean_namespace . '/' . trim( $route, '/' ) . '</code>', '<code>permission_callback</code>', '<code>__return_true</code>' ), '5.5.0' ); } foreach ( $arg_group['args'] as $arg ) { if ( ! is_array( $arg ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'REST API %1$s should be an array of arrays. Non-array value detected for %2$s.' ), '<code>$args</code>', '<code>' . $clean_namespace . '/' . trim( $route, '/' ) . '</code>' ), '6.1.0' ); break; } } } $full_route = '/' . $clean_namespace . '/' . trim( $route, '/' ); rest_get_server()->register_route( $clean_namespace, $full_route, $args, $override ); return true; } function register_rest_field( $object_type, $attribute, $args = array() ) { global $wp_rest_additional_fields; $defaults = array( 'get_callback' => null, 'update_callback' => null, 'schema' => null, ); $args = wp_parse_args( $args, $defaults ); $object_types = (array) $object_type; foreach ( $object_types as $object_type ) { $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; } } function rest_api_init() { rest_api_register_rewrites(); global $wp; $wp->add_query_var( 'rest_route' ); } function rest_api_register_rewrites() { global $wp_rewrite; add_rewrite_rule( '^' . rest_get_url_prefix() . '/?$', 'index.php?rest_route=/', 'top' ); add_rewrite_rule( '^' . rest_get_url_prefix() . '/(.*)?', 'index.php?rest_route=/$matches[1]', 'top' ); add_rewrite_rule( '^' . $wp_rewrite->index . '/' . rest_get_url_prefix() . '/?$', 'index.php?rest_route=/', 'top' ); add_rewrite_rule( '^' . $wp_rewrite->index . '/' . rest_get_url_prefix() . '/(.*)?', 'index.php?rest_route=/$matches[1]', 'top' ); } function rest_api_default_filters() { if ( wp_is_serving_rest_request() ) { add_action( 'deprecated_function_run', 'rest_handle_deprecated_function', 10, 3 ); add_filter( 'deprecated_function_trigger_error', '__return_false' ); add_action( 'deprecated_argument_run', 'rest_handle_deprecated_argument', 10, 3 ); add_filter( 'deprecated_argument_trigger_error', '__return_false' ); add_action( 'doing_it_wrong_run', 'rest_handle_doing_it_wrong', 10, 3 ); add_filter( 'doing_it_wrong_trigger_error', '__return_false' ); } add_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' ); add_filter( 'rest_post_dispatch', 'rest_send_allow_header', 10, 3 ); add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 ); add_filter( 'rest_index', 'rest_add_application_passwords_to_index' ); } function create_initial_rest_routes() { foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { $controller = $post_type->get_rest_controller(); if ( ! $controller ) { continue; } if ( ! $post_type->late_route_registration ) { $controller->register_routes(); } $revisions_controller = $post_type->get_revisions_rest_controller(); if ( $revisions_controller ) { $revisions_controller->register_routes(); } $autosaves_controller = $post_type->get_autosave_rest_controller(); if ( $autosaves_controller ) { $autosaves_controller->register_routes(); } if ( $post_type->late_route_registration ) { $controller->register_routes(); } } $controller = new WP_REST_Post_Types_Controller(); $controller->register_routes(); $controller = new WP_REST_Post_Statuses_Controller(); $controller->register_routes(); $controller = new WP_REST_Taxonomies_Controller(); $controller->register_routes(); foreach ( get_taxonomies( array( 'show_in_rest' => true ), 'object' ) as $taxonomy ) { $controller = $taxonomy->get_rest_controller(); if ( ! $controller ) { continue; } $controller->register_routes(); } $controller = new WP_REST_Users_Controller(); $controller->register_routes(); $controller = new WP_REST_Application_Passwords_Controller(); $controller->register_routes(); $controller = new WP_REST_Comments_Controller(); $controller->register_routes(); $search_handlers = array( new WP_REST_Post_Search_Handler(), new WP_REST_Term_Search_Handler(), new WP_REST_Post_Format_Search_Handler(), ); $search_handlers = apply_filters( 'wp_rest_search_handlers', $search_handlers ); $controller = new WP_REST_Search_Controller( $search_handlers ); $controller->register_routes(); $controller = new WP_REST_Block_Renderer_Controller(); $controller->register_routes(); $controller = new WP_REST_Block_Types_Controller(); $controller->register_routes(); $controller = new WP_REST_Settings_Controller(); $controller->register_routes(); $controller = new WP_REST_Themes_Controller(); $controller->register_routes(); $controller = new WP_REST_Plugins_Controller(); $controller->register_routes(); $controller = new WP_REST_Sidebars_Controller(); $controller->register_routes(); $controller = new WP_REST_Widget_Types_Controller(); $controller->register_routes(); $controller = new WP_REST_Widgets_Controller(); $controller->register_routes(); $controller = new WP_REST_Block_Directory_Controller(); $controller->register_routes(); $controller = new WP_REST_Pattern_Directory_Controller(); $controller->register_routes(); $controller = new WP_REST_Block_Patterns_Controller(); $controller->register_routes(); $controller = new WP_REST_Block_Pattern_Categories_Controller(); $controller->register_routes(); $site_health = WP_Site_Health::get_instance(); $controller = new WP_REST_Site_Health_Controller( $site_health ); $controller->register_routes(); $controller = new WP_REST_URL_Details_Controller(); $controller->register_routes(); $controller = new WP_REST_Menu_Locations_Controller(); $controller->register_routes(); $controller = new WP_REST_Edit_Site_Export_Controller(); $controller->register_routes(); $controller = new WP_REST_Navigation_Fallback_Controller(); $controller->register_routes(); $font_collections_controller = new WP_REST_Font_Collections_Controller(); $font_collections_controller->register_routes(); $abilities_categories_controller = new WP_REST_Abilities_V1_Categories_Controller(); $abilities_categories_controller->register_routes(); $abilities_run_controller = new WP_REST_Abilities_V1_Run_Controller(); $abilities_run_controller->register_routes(); $abilities_list_controller = new WP_REST_Abilities_V1_List_Controller(); $abilities_list_controller->register_routes(); } function rest_api_loaded() { if ( empty( $GLOBALS['wp']->query_vars['rest_route'] ) ) { return; } if ( ! is_string( $GLOBALS['wp']->query_vars['rest_route'] ) ) { $rest_type_error = new WP_Error( 'rest_path_invalid_type', __( 'The REST route parameter must be a string.' ), array( 'status' => 400 ) ); wp_die( $rest_type_error ); } define( 'REST_REQUEST', true ); $server = rest_get_server(); $route = untrailingslashit( $GLOBALS['wp']->query_vars['rest_route'] ); if ( empty( $route ) ) { $route = '/'; } $server->serve_request( $route ); die(); } function rest_get_url_prefix() { return apply_filters( 'rest_url_prefix', 'wp-json' ); } function get_rest_url( $blog_id = null, $path = '/', $scheme = 'rest' ) { if ( empty( $path ) ) { $path = '/'; } $path = '/' . ltrim( $path, '/' ); if ( is_multisite() && get_blog_option( $blog_id, 'permalink_structure' ) || get_option( 'permalink_structure' ) ) { global $wp_rewrite; if ( $wp_rewrite->using_index_permalinks() ) { $url = get_home_url( $blog_id, $wp_rewrite->index . '/' . rest_get_url_prefix(), $scheme ); } else { $url = get_home_url( $blog_id, rest_get_url_prefix(), $scheme ); } $url .= $path; } else { $url = trailingslashit( get_home_url( $blog_id, '', $scheme ) ); if ( ! str_ends_with( $url, 'index.php' ) ) { $url .= 'index.php'; } $url = add_query_arg( 'rest_route', $path, $url ); } if ( is_ssl() && isset( $_SERVER['SERVER_NAME'] ) ) { if ( parse_url( get_home_url( $blog_id ), PHP_URL_HOST ) === $_SERVER['SERVER_NAME'] ) { $url = set_url_scheme( $url, 'https' ); } } if ( is_admin() && force_ssl_admin() ) { $url = set_url_scheme( $url, 'https' ); } return apply_filters( 'rest_url', $url, $path, $blog_id, $scheme ); } function rest_url( $path = '', $scheme = 'rest' ) { return get_rest_url( null, $path, $scheme ); } function rest_do_request( $request ) { $request = rest_ensure_request( $request ); return rest_get_server()->dispatch( $request ); } function rest_get_server() { global $wp_rest_server; if ( empty( $wp_rest_server ) ) { $wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' ); $wp_rest_server = new $wp_rest_server_class(); do_action( 'rest_api_init', $wp_rest_server ); } return $wp_rest_server; } function rest_ensure_request( $request ) { if ( $request instanceof WP_REST_Request ) { return $request; } if ( is_string( $request ) ) { return new WP_REST_Request( 'GET', $request ); } return new WP_REST_Request( 'GET', '', $request ); } function rest_ensure_response( $response ) { if ( is_wp_error( $response ) ) { return $response; } if ( $response instanceof WP_REST_Response ) { return $response; } if ( $response instanceof WP_HTTP_Response ) { return new WP_REST_Response( $response->get_data(), $response->get_status(), $response->get_headers() ); } return new WP_REST_Response( $response ); } function rest_handle_deprecated_function( $function_name, $replacement, $version ) { if ( ! WP_DEBUG || headers_sent() ) { return; } if ( ! empty( $replacement ) ) { $string = sprintf( __( '%1$s (since %2$s; use %3$s instead)' ), $function_name, $version, $replacement ); } else { $string = sprintf( __( '%1$s (since %2$s; no alternative available)' ), $function_name, $version ); } header( sprintf( 'X-WP-DeprecatedFunction: %s', $string ) ); } function rest_handle_deprecated_argument( $function_name, $message, $version ) { if ( ! WP_DEBUG || headers_sent() ) { return; } if ( $message ) { $string = sprintf( __( '%1$s (since %2$s; %3$s)' ), $function_name, $version, $message ); } else { $string = sprintf( __( '%1$s (since %2$s; no alternative available)' ), $function_name, $version ); } header( sprintf( 'X-WP-DeprecatedParam: %s', $string ) ); } function rest_handle_doing_it_wrong( $function_name, $message, $version ) { if ( ! WP_DEBUG || headers_sent() ) { return; } if ( $version ) { $string = __( '%1$s (since %2$s; %3$s)' ); $string = sprintf( $string, $function_name, $version, $message ); } else { $string = __( '%1$s (%2$s)' ); $string = sprintf( $string, $function_name, $message ); } header( sprintf( 'X-WP-DoingItWrong: %s', $string ) ); } function rest_send_cors_headers( $value ) { $origin = get_http_origin(); if ( $origin ) { if ( 'null' !== $origin ) { $origin = sanitize_url( $origin ); } header( 'Access-Control-Allow-Origin: ' . $origin ); header( 'Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE' ); header( 'Access-Control-Allow-Credentials: true' ); header( 'Vary: Origin', false ); } elseif ( ! headers_sent() && 'GET' === $_SERVER['REQUEST_METHOD'] && ! is_user_logged_in() ) { header( 'Vary: Origin', false ); } return $value; } function rest_handle_options_request( $response, $handler, $request ) { if ( ! empty( $response ) || $request->get_method() !== 'OPTIONS' ) { return $response; } $response = new WP_REST_Response(); $data = array(); foreach ( $handler->get_routes() as $route => $endpoints ) { $match = preg_match( '@^' . $route . '$@i', $request->get_route(), $matches ); if ( ! $match ) { continue; } $args = array(); foreach ( $matches as $param => $value ) { if ( ! is_int( $param ) ) { $args[ $param ] = $value; } } foreach ( $endpoints as $endpoint ) { $request->set_url_params( $args ); $request->set_attributes( $endpoint ); } $data = $handler->get_data_for_route( $route, $endpoints, 'help' ); $response->set_matched_route( $route ); break; } $response->set_data( $data ); return $response; } function rest_send_allow_header( $response, $server, $request ) { $matched_route = $response->get_matched_route(); if ( ! $matched_route ) { return $response; } $routes = $server->get_routes(); $allowed_methods = array(); foreach ( $routes[ $matched_route ] as $_handler ) { foreach ( $_handler['methods'] as $handler_method => $value ) { if ( ! empty( $_handler['permission_callback'] ) ) { $permission = call_user_func( $_handler['permission_callback'], $request ); $allowed_methods[ $handler_method ] = true === $permission; } else { $allowed_methods[ $handler_method ] = true; } } } $allowed_methods = array_filter( $allowed_methods ); if ( $allowed_methods ) { $response->header( 'Allow', implode( ', ', array_map( 'strtoupper', array_keys( $allowed_methods ) ) ) ); } return $response; } function _rest_array_intersect_key_recursive( $array1, $array2 ) { $array1 = array_intersect_key( $array1, $array2 ); foreach ( $array1 as $key => $value ) { if ( is_array( $value ) && is_array( $array2[ $key ] ) ) { $array1[ $key ] = _rest_array_intersect_key_recursive( $value, $array2[ $key ] ); } } return $array1; } function rest_filter_response_fields( $response, $server, $request ) { if ( ! isset( $request['_fields'] ) || $response->is_error() ) { return $response; } $data = $response->get_data(); $fields = wp_parse_list( $request['_fields'] ); if ( 0 === count( $fields ) ) { return $response; } $fields = array_map( 'trim', $fields ); $fields_as_keyed = array(); foreach ( $fields as $field ) { $parts = explode( '.', $field ); $ref = &$fields_as_keyed; while ( count( $parts ) > 1 ) { $next = array_shift( $parts ); if ( isset( $ref[ $next ] ) && true === $ref[ $next ] ) { break 2; } $ref[ $next ] = isset( $ref[ $next ] ) ? $ref[ $next ] : array(); $ref = &$ref[ $next ]; } $last = array_shift( $parts ); $ref[ $last ] = true; } if ( wp_is_numeric_array( $data ) ) { $new_data = array(); foreach ( $data as $item ) { $new_data[] = _rest_array_intersect_key_recursive( $item, $fields_as_keyed ); } } else { $new_data = _rest_array_intersect_key_recursive( $data, $fields_as_keyed ); } $response->set_data( $new_data ); return $response; } function rest_is_field_included( $field, $fields ) { if ( in_array( $field, $fields, true ) ) { return true; } foreach ( $fields as $accepted_field ) { if ( str_starts_with( $accepted_field, "$field." ) ) { return true; } if ( str_starts_with( $field, "$accepted_field." ) ) { return true; } } return false; } function rest_output_rsd() { $api_root = get_rest_url(); if ( empty( $api_root ) ) { return; } ?>
<api name="WP-API" blogID="1" preferred="false" apiLink="<?php echo esc_url( $api_root ); ?>" />
<?php
} function rest_output_link_wp_head() { $api_root = get_rest_url(); if ( empty( $api_root ) ) { return; } printf( '<link rel="https://api.w.org/" href="%s" />', esc_url( $api_root ) ); $resource = rest_get_queried_resource_route(); if ( $resource ) { printf( '<link rel="alternate" title="%1$s" type="application/json" href="%2$s" />', _x( 'JSON', 'REST API resource link name' ), esc_url( rest_url( $resource ) ) ); } } function rest_output_link_header() { if ( headers_sent() ) { return; } $api_root = get_rest_url(); if ( empty( $api_root ) ) { return; } header( sprintf( 'Link: <%s>; rel="https://api.w.org/"', sanitize_url( $api_root ) ), false ); $resource = rest_get_queried_resource_route(); if ( $resource ) { header( sprintf( 'Link: <%1$s>; rel="alternate"; title="%2$s"; type="application/json"', sanitize_url( rest_url( $resource ) ), _x( 'JSON', 'REST API resource link name' ) ), false ); } } function rest_cookie_check_errors( $result ) { if ( ! empty( $result ) ) { return $result; } global $wp_rest_auth_cookie; if ( true !== $wp_rest_auth_cookie && is_user_logged_in() ) { return $result; } $nonce = null; if ( isset( $_REQUEST['_wpnonce'] ) ) { $nonce = $_REQUEST['_wpnonce']; } elseif ( isset( $_SERVER['HTTP_X_WP_NONCE'] ) ) { $nonce = $_SERVER['HTTP_X_WP_NONCE']; } if ( null === $nonce ) { wp_set_current_user( 0 ); return true; } $result = wp_verify_nonce( $nonce, 'wp_rest' ); if ( ! $result ) { add_filter( 'rest_send_nocache_headers', '__return_true', 20 ); return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie check failed' ), array( 'status' => 403 ) ); } rest_get_server()->send_header( 'X-WP-Nonce', wp_create_nonce( 'wp_rest' ) ); return true; } function rest_cookie_collect_status() { global $wp_rest_auth_cookie; $status_type = current_action(); if ( 'auth_cookie_valid' !== $status_type ) { $wp_rest_auth_cookie = substr( $status_type, 12 ); return; } $wp_rest_auth_cookie = true; } function rest_application_password_collect_status( $user_or_error, $app_password = array() ) { global $wp_rest_application_password_status, $wp_rest_application_password_uuid; $wp_rest_application_password_status = $user_or_error; if ( empty( $app_password['uuid'] ) ) { $wp_rest_application_password_uuid = null; } else { $wp_rest_application_password_uuid = $app_password['uuid']; } } function rest_get_authenticated_app_password() { global $wp_rest_application_password_uuid; return $wp_rest_application_password_uuid; } function rest_application_password_check_errors( $result ) { global $wp_rest_application_password_status; if ( ! empty( $result ) ) { return $result; } if ( is_wp_error( $wp_rest_application_password_status ) ) { $data = $wp_rest_application_password_status->get_error_data(); if ( ! isset( $data['status'] ) ) { $data['status'] = 401; } $wp_rest_application_password_status->add_data( $data ); return $wp_rest_application_password_status; } if ( $wp_rest_application_password_status instanceof WP_User ) { return true; } return $result; } function rest_add_application_passwords_to_index( $response ) { if ( ! wp_is_application_passwords_available() ) { return $response; } $response->data['authentication']['application-passwords'] = array( 'endpoints' => array( 'authorization' => admin_url( 'authorize-application.php' ), ), ); return $response; } function rest_get_avatar_urls( $id_or_email ) { $avatar_sizes = rest_get_avatar_sizes(); $urls = array(); foreach ( $avatar_sizes as $size ) { $urls[ $size ] = get_avatar_url( $id_or_email, array( 'size' => $size ) ); } return $urls; } function rest_get_avatar_sizes() { return apply_filters( 'rest_avatar_sizes', array( 24, 48, 96 ) ); } function rest_parse_date( $date, $force_utc = false ) { if ( $force_utc ) { $date = preg_replace( '/[+-]\d+:?\d+$/', '+00:00', $date ); } $regex = '#^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}(?::\d{2})?)?$#'; if ( ! preg_match( $regex, $date, $matches ) ) { return false; } return strtotime( $date ); } function rest_parse_hex_color( $color ) { $regex = '|^#([A-Fa-f0-9]{3}){1,2}$|'; if ( ! preg_match( $regex, $color, $matches ) ) { return false; } return $color; } function rest_get_date_with_gmt( $date, $is_utc = false ) { $has_timezone = preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date ); $date = rest_parse_date( $date ); if ( false === $date ) { return null; } if ( ! $is_utc && ! $has_timezone ) { $local = gmdate( 'Y-m-d H:i:s', $date ); $utc = get_gmt_from_date( $local ); } else { $utc = gmdate( 'Y-m-d H:i:s', $date ); $local = get_date_from_gmt( $utc ); } return array( $local, $utc ); } function rest_authorization_required_code() { return is_user_logged_in() ? 403 : 401; } function rest_validate_request_arg( $value, $request, $param ) { $attributes = $request->get_attributes(); if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { return true; } $args = $attributes['args'][ $param ]; return rest_validate_value_from_schema( $value, $args, $param ); } function rest_sanitize_request_arg( $value, $request, $param ) { $attributes = $request->get_attributes(); if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { return $value; } $args = $attributes['args'][ $param ]; return rest_sanitize_value_from_schema( $value, $args, $param ); } function rest_parse_request_arg( $value, $request, $param ) { $is_valid = rest_validate_request_arg( $value, $request, $param ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } $value = rest_sanitize_request_arg( $value, $request, $param ); return $value; } function rest_is_ip_address( $ip ) { $ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/'; if ( ! preg_match( $ipv4_pattern, $ip ) && ! WpOrg\Requests\Ipv6::check_ipv6( $ip ) ) { return false; } return $ip; } function rest_sanitize_boolean( $value ) { if ( is_string( $value ) ) { $value = strtolower( $value ); if ( in_array( $value, array( 'false', '0' ), true ) ) { $value = false; } } return (bool) $value; } function rest_is_boolean( $maybe_bool ) { if ( is_bool( $maybe_bool ) ) { return true; } if ( is_string( $maybe_bool ) ) { $maybe_bool = strtolower( $maybe_bool ); $valid_boolean_values = array( 'false', 'true', '0', '1', ); return in_array( $maybe_bool, $valid_boolean_values, true ); } if ( is_int( $maybe_bool ) ) { return in_array( $maybe_bool, array( 0, 1 ), true ); } return false; } function rest_is_integer( $maybe_integer ) { return is_numeric( $maybe_integer ) && round( (float) $maybe_integer ) === (float) $maybe_integer; } function rest_is_array( $maybe_array ) { if ( is_scalar( $maybe_array ) ) { $maybe_array = wp_parse_list( $maybe_array ); } return wp_is_numeric_array( $maybe_array ); } function rest_sanitize_array( $maybe_array ) { if ( is_scalar( $maybe_array ) ) { return wp_parse_list( $maybe_array ); } if ( ! is_array( $maybe_array ) ) { return array(); } return array_values( $maybe_array ); } function rest_is_object( $maybe_object ) { if ( '' === $maybe_object ) { return true; } if ( $maybe_object instanceof stdClass ) { return true; } if ( $maybe_object instanceof JsonSerializable ) { $maybe_object = $maybe_object->jsonSerialize(); } return is_array( $maybe_object ); } function rest_sanitize_object( $maybe_object ) { if ( '' === $maybe_object ) { return array(); } if ( $maybe_object instanceof stdClass ) { return (array) $maybe_object; } if ( $maybe_object instanceof JsonSerializable ) { $maybe_object = $maybe_object->jsonSerialize(); } if ( ! is_array( $maybe_object ) ) { return array(); } return $maybe_object; } function rest_get_best_type_for_value( $value, $types ) { static $checks = array( 'array' => 'rest_is_array', 'object' => 'rest_is_object', 'integer' => 'rest_is_integer', 'number' => 'is_numeric', 'boolean' => 'rest_is_boolean', 'string' => 'is_string', 'null' => 'is_null', ); if ( '' === $value && in_array( 'string', $types, true ) ) { return 'string'; } foreach ( $types as $type ) { if ( isset( $checks[ $type ] ) && $checks[ $type ]( $value ) ) { return $type; } } return ''; } function rest_handle_multi_type_schema( $value, $args, $param = '' ) { $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); $invalid_types = array_diff( $args['type'], $allowed_types ); if ( $invalid_types ) { _doing_it_wrong( __FUNCTION__, wp_sprintf( __( 'The "type" schema keyword for %1$s can only contain the built-in types: %2$l.' ), $param, $allowed_types ), '5.5.0' ); } $best_type = rest_get_best_type_for_value( $value, $args['type'] ); if ( ! $best_type ) { if ( ! $invalid_types ) { return ''; } $best_type = reset( $invalid_types ); } return $best_type; } function rest_validate_array_contains_unique_items( $input_array ) { $seen = array(); foreach ( $input_array as $item ) { $stabilized = rest_stabilize_value( $item ); $key = serialize( $stabilized ); if ( ! isset( $seen[ $key ] ) ) { $seen[ $key ] = true; continue; } return false; } return true; } function rest_stabilize_value( $value ) { if ( is_scalar( $value ) || is_null( $value ) ) { return $value; } if ( is_object( $value ) ) { _doing_it_wrong( __FUNCTION__, __( 'Cannot stabilize objects. Convert the object to an array first.' ), '5.5.0' ); return $value; } ksort( $value ); foreach ( $value as $k => $v ) { $value[ $k ] = rest_stabilize_value( $v ); } return $value; } function rest_validate_json_schema_pattern( $pattern, $value ) { $escaped_pattern = str_replace( '#', '\\#', $pattern ); return 1 === preg_match( '#' . $escaped_pattern . '#u', $value ); } function rest_find_matching_pattern_property_schema( $property, $args ) { if ( isset( $args['patternProperties'] ) ) { foreach ( $args['patternProperties'] as $pattern => $child_schema ) { if ( rest_validate_json_schema_pattern( $pattern, $property ) ) { return $child_schema; } } } return null; } function rest_format_combining_operation_error( $param, $error ) { $position = $error['index']; $reason = $error['error_object']->get_error_message(); if ( isset( $error['schema']['title'] ) ) { $title = $error['schema']['title']; return new WP_Error( 'rest_no_matching_schema', sprintf( __( '%1$s is not a valid %2$s. Reason: %3$s' ), $param, $title, $reason ), array( 'position' => $position ) ); } return new WP_Error( 'rest_no_matching_schema', sprintf( __( '%1$s does not match the expected format. Reason: %2$s' ), $param, $reason ), array( 'position' => $position ) ); } function rest_get_combining_operation_error( $value, $param, $errors ) { if ( 1 === count( $errors ) ) { return rest_format_combining_operation_error( $param, $errors[0] ); } $filtered_errors = array(); foreach ( $errors as $error ) { $error_code = $error['error_object']->get_error_code(); $error_data = $error['error_object']->get_error_data(); if ( 'rest_invalid_type' !== $error_code || ( isset( $error_data['param'] ) && $param !== $error_data['param'] ) ) { $filtered_errors[] = $error; } } if ( 1 === count( $filtered_errors ) ) { return rest_format_combining_operation_error( $param, $filtered_errors[0] ); } if ( count( $filtered_errors ) > 1 && 'object' === $filtered_errors[0]['schema']['type'] ) { $result = null; $number = 0; foreach ( $filtered_errors as $error ) { if ( isset( $error['schema']['properties'] ) ) { $n = count( array_intersect_key( $error['schema']['properties'], $value ) ); if ( $n > $number ) { $result = $error; $number = $n; } } } if ( null !== $result ) { return rest_format_combining_operation_error( $param, $result ); } } $schema_titles = array(); foreach ( $errors as $error ) { if ( isset( $error['schema']['title'] ) ) { $schema_titles[] = $error['schema']['title']; } } if ( count( $schema_titles ) === count( $errors ) ) { return new WP_Error( 'rest_no_matching_schema', wp_sprintf( __( '%1$s is not a valid %2$l.' ), $param, $schema_titles ) ); } return new WP_Error( 'rest_no_matching_schema', sprintf( __( '%s does not match any of the expected formats.' ), $param ) ); } function rest_find_any_matching_schema( $value, $args, $param ) { $errors = array(); foreach ( $args['anyOf'] as $index => $schema ) { if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) { $schema['type'] = $args['type']; } $is_valid = rest_validate_value_from_schema( $value, $schema, $param ); if ( ! is_wp_error( $is_valid ) ) { return $schema; } $errors[] = array( 'error_object' => $is_valid, 'schema' => $schema, 'index' => $index, ); } return rest_get_combining_operation_error( $value, $param, $errors ); } function rest_find_one_matching_schema( $value, $args, $param, $stop_after_first_match = false ) { $matching_schemas = array(); $errors = array(); foreach ( $args['oneOf'] as $index => $schema ) { if ( ! isset( $schema['type'] ) && isset( $args['type'] ) ) { $schema['type'] = $args['type']; } $is_valid = rest_validate_value_from_schema( $value, $schema, $param ); if ( ! is_wp_error( $is_valid ) ) { if ( $stop_after_first_match ) { return $schema; } $matching_schemas[] = array( 'schema_object' => $schema, 'index' => $index, ); } else { $errors[] = array( 'error_object' => $is_valid, 'schema' => $schema, 'index' => $index, ); } } if ( ! $matching_schemas ) { return rest_get_combining_operation_error( $value, $param, $errors ); } if ( count( $matching_schemas ) > 1 ) { $schema_positions = array(); $schema_titles = array(); foreach ( $matching_schemas as $schema ) { $schema_positions[] = $schema['index']; if ( isset( $schema['schema_object']['title'] ) ) { $schema_titles[] = $schema['schema_object']['title']; } } if ( count( $schema_titles ) === count( $matching_schemas ) ) { return new WP_Error( 'rest_one_of_multiple_matches', wp_sprintf( __( '%1$s matches %2$l, but should match only one.' ), $param, $schema_titles ), array( 'positions' => $schema_positions ) ); } return new WP_Error( 'rest_one_of_multiple_matches', sprintf( __( '%s matches more than one of the expected formats.' ), $param ), array( 'positions' => $schema_positions ) ); } return $matching_schemas[0]['schema_object']; } function rest_are_values_equal( $value1, $value2 ) { if ( is_array( $value1 ) && is_array( $value2 ) ) { if ( count( $value1 ) !== count( $value2 ) ) { return false; } foreach ( $value1 as $index => $value ) { if ( ! array_key_exists( $index, $value2 ) || ! rest_are_values_equal( $value, $value2[ $index ] ) ) { return false; } } return true; } if ( is_int( $value1 ) && is_float( $value2 ) || is_float( $value1 ) && is_int( $value2 ) ) { return (float) $value1 === (float) $value2; } return $value1 === $value2; } function rest_validate_enum( $value, $args, $param ) { $sanitized_value = rest_sanitize_value_from_schema( $value, $args, $param ); if ( is_wp_error( $sanitized_value ) ) { return $sanitized_value; } foreach ( $args['enum'] as $enum_value ) { if ( rest_are_values_equal( $sanitized_value, $enum_value ) ) { return true; } } $encoded_enum_values = array(); foreach ( $args['enum'] as $enum_value ) { $encoded_enum_values[] = is_scalar( $enum_value ) ? $enum_value : wp_json_encode( $enum_value ); } if ( count( $encoded_enum_values ) === 1 ) { return new WP_Error( 'rest_not_in_enum', wp_sprintf( __( '%1$s is not %2$s.' ), $param, $encoded_enum_values[0] ) ); } return new WP_Error( 'rest_not_in_enum', wp_sprintf( __( '%1$s is not one of %2$l.' ), $param, $encoded_enum_values ) ); } function rest_get_allowed_schema_keywords() { return array( 'title', 'description', 'default', 'type', 'format', 'enum', 'items', 'properties', 'additionalProperties', 'patternProperties', 'minProperties', 'maxProperties', 'minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'minLength', 'maxLength', 'pattern', 'minItems', 'maxItems', 'uniqueItems', 'anyOf', 'oneOf', ); } function rest_validate_value_from_schema( $value, $args, $param = '' ) { if ( isset( $args['anyOf'] ) ) { $matching_schema = rest_find_any_matching_schema( $value, $args, $param ); if ( is_wp_error( $matching_schema ) ) { return $matching_schema; } if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) { $args['type'] = $matching_schema['type']; } } if ( isset( $args['oneOf'] ) ) { $matching_schema = rest_find_one_matching_schema( $value, $args, $param ); if ( is_wp_error( $matching_schema ) ) { return $matching_schema; } if ( ! isset( $args['type'] ) && isset( $matching_schema['type'] ) ) { $args['type'] = $matching_schema['type']; } } $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); if ( ! isset( $args['type'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' ); } if ( is_array( $args['type'] ) ) { $best_type = rest_handle_multi_type_schema( $value, $args, $param ); if ( ! $best_type ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, implode( ',', $args['type'] ) ), array( 'param' => $param ) ); } $args['type'] = $best_type; } if ( ! in_array( $args['type'], $allowed_types, true ) ) { _doing_it_wrong( __FUNCTION__, wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ), '5.5.0' ); } switch ( $args['type'] ) { case 'null': $is_valid = rest_validate_null_value_from_schema( $value, $param ); break; case 'boolean': $is_valid = rest_validate_boolean_value_from_schema( $value, $param ); break; case 'object': $is_valid = rest_validate_object_value_from_schema( $value, $args, $param ); break; case 'array': $is_valid = rest_validate_array_value_from_schema( $value, $args, $param ); break; case 'number': $is_valid = rest_validate_number_value_from_schema( $value, $args, $param ); break; case 'string': $is_valid = rest_validate_string_value_from_schema( $value, $args, $param ); break; case 'integer': $is_valid = rest_validate_integer_value_from_schema( $value, $args, $param ); break; default: $is_valid = true; break; } if ( is_wp_error( $is_valid ) ) { return $is_valid; } if ( ! empty( $args['enum'] ) ) { $enum_contains_value = rest_validate_enum( $value, $args, $param ); if ( is_wp_error( $enum_contains_value ) ) { return $enum_contains_value; } } if ( isset( $args['format'] ) && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) ) ) { switch ( $args['format'] ) { case 'hex-color': if ( ! rest_parse_hex_color( $value ) ) { return new WP_Error( 'rest_invalid_hex_color', __( 'Invalid hex color.' ) ); } break; case 'date-time': if ( false === rest_parse_date( $value ) ) { return new WP_Error( 'rest_invalid_date', __( 'Invalid date.' ) ); } break; case 'email': if ( ! is_email( $value ) ) { return new WP_Error( 'rest_invalid_email', __( 'Invalid email address.' ) ); } break; case 'ip': if ( ! rest_is_ip_address( $value ) ) { return new WP_Error( 'rest_invalid_ip', sprintf( __( '%s is not a valid IP address.' ), $param ) ); } break; case 'uuid': if ( ! wp_is_uuid( $value ) ) { return new WP_Error( 'rest_invalid_uuid', sprintf( __( '%s is not a valid UUID.' ), $param ) ); } break; } } return true; } function rest_validate_null_value_from_schema( $value, $param ) { if ( null !== $value ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'null' ), array( 'param' => $param ) ); } return true; } function rest_validate_boolean_value_from_schema( $value, $param ) { if ( ! rest_is_boolean( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ), array( 'param' => $param ) ); } return true; } function rest_validate_object_value_from_schema( $value, $args, $param ) { if ( ! rest_is_object( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'object' ), array( 'param' => $param ) ); } $value = rest_sanitize_object( $value ); if ( isset( $args['required'] ) && is_array( $args['required'] ) ) { foreach ( $args['required'] as $name ) { if ( ! array_key_exists( $name, $value ) ) { return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) ); } } } elseif ( isset( $args['properties'] ) ) { foreach ( $args['properties'] as $name => $property ) { if ( isset( $property['required'] ) && true === $property['required'] && ! array_key_exists( $name, $value ) ) { return new WP_Error( 'rest_property_required', sprintf( __( '%1$s is a required property of %2$s.' ), $name, $param ) ); } } } foreach ( $value as $property => $v ) { if ( isset( $args['properties'][ $property ] ) ) { $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } continue; } $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args ); if ( null !== $pattern_property_schema ) { $is_valid = rest_validate_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } continue; } if ( isset( $args['additionalProperties'] ) ) { if ( false === $args['additionalProperties'] ) { return new WP_Error( 'rest_additional_properties_forbidden', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) ); } if ( is_array( $args['additionalProperties'] ) ) { $is_valid = rest_validate_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } } } } if ( isset( $args['minProperties'] ) && count( $value ) < $args['minProperties'] ) { return new WP_Error( 'rest_too_few_properties', sprintf( _n( '%1$s must contain at least %2$s property.', '%1$s must contain at least %2$s properties.', $args['minProperties'] ), $param, number_format_i18n( $args['minProperties'] ) ) ); } if ( isset( $args['maxProperties'] ) && count( $value ) > $args['maxProperties'] ) { return new WP_Error( 'rest_too_many_properties', sprintf( _n( '%1$s must contain at most %2$s property.', '%1$s must contain at most %2$s properties.', $args['maxProperties'] ), $param, number_format_i18n( $args['maxProperties'] ) ) ); } return true; } function rest_validate_array_value_from_schema( $value, $args, $param ) { if ( ! rest_is_array( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'array' ), array( 'param' => $param ) ); } $value = rest_sanitize_array( $value ); if ( isset( $args['items'] ) ) { foreach ( $value as $index => $v ) { $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } } } if ( isset( $args['minItems'] ) && count( $value ) < $args['minItems'] ) { return new WP_Error( 'rest_too_few_items', sprintf( _n( '%1$s must contain at least %2$s item.', '%1$s must contain at least %2$s items.', $args['minItems'] ), $param, number_format_i18n( $args['minItems'] ) ) ); } if ( isset( $args['maxItems'] ) && count( $value ) > $args['maxItems'] ) { return new WP_Error( 'rest_too_many_items', sprintf( _n( '%1$s must contain at most %2$s item.', '%1$s must contain at most %2$s items.', $args['maxItems'] ), $param, number_format_i18n( $args['maxItems'] ) ) ); } if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) { return new WP_Error( 'rest_duplicate_items', sprintf( __( '%s has duplicate items.' ), $param ) ); } return true; } function rest_validate_number_value_from_schema( $value, $args, $param ) { if ( ! is_numeric( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, $args['type'] ), array( 'param' => $param ) ); } if ( isset( $args['multipleOf'] ) && fmod( $value, $args['multipleOf'] ) !== 0.0 ) { return new WP_Error( 'rest_invalid_multiple', sprintf( __( '%1$s must be a multiple of %2$s.' ), $param, $args['multipleOf'] ) ); } if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be greater than %2$d' ), $param, $args['minimum'] ) ); } if ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be greater than or equal to %2$d' ), $param, $args['minimum'] ) ); } } if ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be less than %2$d' ), $param, $args['maximum'] ) ); } if ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be less than or equal to %2$d' ), $param, $args['maximum'] ) ); } } if ( isset( $args['minimum'], $args['maximum'] ) ) { if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); } } if ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be between %2$d (exclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); } } if ( ! empty( $args['exclusiveMaximum'] ) && empty( $args['exclusiveMinimum'] ) ) { if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); } } if ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { if ( $value > $args['maximum'] || $value < $args['minimum'] ) { return new WP_Error( 'rest_out_of_bounds', sprintf( __( '%1$s must be between %2$d (inclusive) and %3$d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); } } } return true; } function rest_validate_string_value_from_schema( $value, $args, $param ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ), array( 'param' => $param ) ); } if ( isset( $args['minLength'] ) && mb_strlen( $value ) < $args['minLength'] ) { return new WP_Error( 'rest_too_short', sprintf( _n( '%1$s must be at least %2$s character long.', '%1$s must be at least %2$s characters long.', $args['minLength'] ), $param, number_format_i18n( $args['minLength'] ) ) ); } if ( isset( $args['maxLength'] ) && mb_strlen( $value ) > $args['maxLength'] ) { return new WP_Error( 'rest_too_long', sprintf( _n( '%1$s must be at most %2$s character long.', '%1$s must be at most %2$s characters long.', $args['maxLength'] ), $param, number_format_i18n( $args['maxLength'] ) ) ); } if ( isset( $args['pattern'] ) && ! rest_validate_json_schema_pattern( $args['pattern'], $value ) ) { return new WP_Error( 'rest_invalid_pattern', sprintf( __( '%1$s does not match pattern %2$s.' ), $param, $args['pattern'] ) ); } return true; } function rest_validate_integer_value_from_schema( $value, $args, $param ) { $is_valid_number = rest_validate_number_value_from_schema( $value, $args, $param ); if ( is_wp_error( $is_valid_number ) ) { return $is_valid_number; } if ( ! rest_is_integer( $value ) ) { return new WP_Error( 'rest_invalid_type', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'integer' ), array( 'param' => $param ) ); } return true; } function rest_sanitize_value_from_schema( $value, $args, $param = '' ) { if ( isset( $args['anyOf'] ) ) { $matching_schema = rest_find_any_matching_schema( $value, $args, $param ); if ( is_wp_error( $matching_schema ) ) { return $matching_schema; } if ( ! isset( $args['type'] ) ) { $args['type'] = $matching_schema['type']; } $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param ); } if ( isset( $args['oneOf'] ) ) { $matching_schema = rest_find_one_matching_schema( $value, $args, $param ); if ( is_wp_error( $matching_schema ) ) { return $matching_schema; } if ( ! isset( $args['type'] ) ) { $args['type'] = $matching_schema['type']; } $value = rest_sanitize_value_from_schema( $value, $matching_schema, $param ); } $allowed_types = array( 'array', 'object', 'string', 'number', 'integer', 'boolean', 'null' ); if ( ! isset( $args['type'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( 'The "type" schema keyword for %s is required.' ), $param ), '5.5.0' ); } if ( is_array( $args['type'] ) ) { $best_type = rest_handle_multi_type_schema( $value, $args, $param ); if ( ! $best_type ) { return null; } $args['type'] = $best_type; } if ( ! in_array( $args['type'], $allowed_types, true ) ) { _doing_it_wrong( __FUNCTION__, wp_sprintf( __( 'The "type" schema keyword for %1$s can only be one of the built-in types: %2$l.' ), $param, $allowed_types ), '5.5.0' ); } if ( 'array' === $args['type'] ) { $value = rest_sanitize_array( $value ); if ( ! empty( $args['items'] ) ) { foreach ( $value as $index => $v ) { $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' ); } } if ( ! empty( $args['uniqueItems'] ) && ! rest_validate_array_contains_unique_items( $value ) ) { return new WP_Error( 'rest_duplicate_items', sprintf( __( '%s has duplicate items.' ), $param ) ); } return $value; } if ( 'object' === $args['type'] ) { $value = rest_sanitize_object( $value ); foreach ( $value as $property => $v ) { if ( isset( $args['properties'][ $property ] ) ) { $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' ); continue; } $pattern_property_schema = rest_find_matching_pattern_property_schema( $property, $args ); if ( null !== $pattern_property_schema ) { $value[ $property ] = rest_sanitize_value_from_schema( $v, $pattern_property_schema, $param . '[' . $property . ']' ); continue; } if ( isset( $args['additionalProperties'] ) ) { if ( false === $args['additionalProperties'] ) { unset( $value[ $property ] ); } elseif ( is_array( $args['additionalProperties'] ) ) { $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' ); } } } return $value; } if ( 'null' === $args['type'] ) { return null; } if ( 'integer' === $args['type'] ) { return (int) $value; } if ( 'number' === $args['type'] ) { return (float) $value; } if ( 'boolean' === $args['type'] ) { return rest_sanitize_boolean( $value ); } if ( isset( $args['format'] ) && ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) ) ) { switch ( $args['format'] ) { case 'hex-color': return (string) sanitize_hex_color( $value ); case 'date-time': return sanitize_text_field( $value ); case 'email': return sanitize_text_field( $value ); case 'uri': return sanitize_url( $value ); case 'ip': return sanitize_text_field( $value ); case 'uuid': return sanitize_text_field( $value ); case 'text-field': return sanitize_text_field( $value ); case 'textarea-field': return sanitize_textarea_field( $value ); } } if ( 'string' === $args['type'] ) { return (string) $value; } return $value; } function rest_preload_api_request( $memo, $path ) { if ( ! is_array( $memo ) ) { $memo = array(); } if ( empty( $path ) ) { return $memo; } $method = 'GET'; if ( is_array( $path ) && 2 === count( $path ) ) { $method = end( $path ); $path = reset( $path ); if ( ! in_array( $method, array( 'GET', 'OPTIONS' ), true ) ) { $method = 'GET'; } } $path = untrailingslashit( $path ); if ( empty( $path ) ) { $path = '/'; } $path_parts = parse_url( $path ); if ( false === $path_parts ) { return $memo; } if ( isset( $path_parts['path'] ) && '/' !== $path_parts['path'] ) { $path_parts['path'] = untrailingslashit( $path_parts['path'] ); $path = str_contains( $path, '?' ) ? $path_parts['path'] . '?' . ( $path_parts['query'] ?? '' ) : $path_parts['path']; } $request = new WP_REST_Request( $method, $path_parts['path'] ); if ( ! empty( $path_parts['query'] ) ) { parse_str( $path_parts['query'], $query_params ); $request->set_query_params( $query_params ); } $response = rest_do_request( $request ); if ( 200 === $response->status ) { $server = rest_get_server(); $response = apply_filters( 'rest_post_dispatch', rest_ensure_response( $response ), $server, $request ); $embed = $request->has_param( '_embed' ) ? rest_parse_embed_param( $request['_embed'] ) : false; $data = (array) $server->response_to_data( $response, $embed ); if ( 'OPTIONS' === $method ) { $memo[ $method ][ $path ] = array( 'body' => $data, 'headers' => $response->headers, ); } else { $memo[ $path ] = array( 'body' => $data, 'headers' => $response->headers, ); } } return $memo; } function rest_parse_embed_param( $embed ) { if ( ! $embed || 'true' === $embed || '1' === $embed ) { return true; } $rels = wp_parse_list( $embed ); if ( ! $rels ) { return true; } return $rels; } function rest_filter_response_by_context( $response_data, $schema, $context ) { if ( isset( $schema['anyOf'] ) ) { $matching_schema = rest_find_any_matching_schema( $response_data, $schema, '' ); if ( ! is_wp_error( $matching_schema ) ) { if ( ! isset( $schema['type'] ) ) { $schema['type'] = $matching_schema['type']; } $response_data = rest_filter_response_by_context( $response_data, $matching_schema, $context ); } } if ( isset( $schema['oneOf'] ) ) { $matching_schema = rest_find_one_matching_schema( $response_data, $schema, '', true ); if ( ! is_wp_error( $matching_schema ) ) { if ( ! isset( $schema['type'] ) ) { $schema['type'] = $matching_schema['type']; } $response_data = rest_filter_response_by_context( $response_data, $matching_schema, $context ); } } if ( ! is_array( $response_data ) && ! is_object( $response_data ) ) { return $response_data; } if ( isset( $schema['type'] ) ) { $type = $schema['type']; } elseif ( isset( $schema['properties'] ) ) { $type = 'object'; } else { return $response_data; } $is_array_type = 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) ); $is_object_type = 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) ); if ( $is_array_type && $is_object_type ) { if ( rest_is_array( $response_data ) ) { $is_object_type = false; } else { $is_array_type = false; } } $has_additional_properties = $is_object_type && isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] ); foreach ( $response_data as $key => $value ) { $check = array(); if ( $is_array_type ) { $check = isset( $schema['items'] ) ? $schema['items'] : array(); } elseif ( $is_object_type ) { if ( isset( $schema['properties'][ $key ] ) ) { $check = $schema['properties'][ $key ]; } else { $pattern_property_schema = rest_find_matching_pattern_property_schema( $key, $schema ); if ( null !== $pattern_property_schema ) { $check = $pattern_property_schema; } elseif ( $has_additional_properties ) { $check = $schema['additionalProperties']; } } } if ( ! isset( $check['context'] ) ) { continue; } if ( ! in_array( $context, $check['context'], true ) ) { if ( $is_array_type ) { $response_data = array(); break; } if ( is_object( $response_data ) ) { unset( $response_data->$key ); } else { unset( $response_data[ $key ] ); } } elseif ( is_array( $value ) || is_object( $value ) ) { $new_value = rest_filter_response_by_context( $value, $check, $context ); if ( is_object( $response_data ) ) { $response_data->$key = $new_value; } else { $response_data[ $key ] = $new_value; } } } return $response_data; } function rest_default_additional_properties_to_false( $schema ) { $type = (array) $schema['type']; if ( in_array( 'object', $type, true ) ) { if ( isset( $schema['properties'] ) ) { foreach ( $schema['properties'] as $key => $child_schema ) { $schema['properties'][ $key ] = rest_default_additional_properties_to_false( $child_schema ); } } if ( isset( $schema['patternProperties'] ) ) { foreach ( $schema['patternProperties'] as $key => $child_schema ) { $schema['patternProperties'][ $key ] = rest_default_additional_properties_to_false( $child_schema ); } } if ( ! isset( $schema['additionalProperties'] ) ) { $schema['additionalProperties'] = false; } } if ( in_array( 'array', $type, true ) ) { if ( isset( $schema['items'] ) ) { $schema['items'] = rest_default_additional_properties_to_false( $schema['items'] ); } } return $schema; } function rest_get_route_for_post( $post ) { $post = get_post( $post ); if ( ! $post instanceof WP_Post ) { return ''; } $post_type_route = rest_get_route_for_post_type_items( $post->post_type ); if ( ! $post_type_route ) { return ''; } $route = sprintf( '%s/%d', $post_type_route, $post->ID ); return apply_filters( 'rest_route_for_post', $route, $post ); } function rest_get_route_for_post_type_items( $post_type ) { $post_type = get_post_type_object( $post_type ); if ( ! $post_type ) { return ''; } if ( ! $post_type->show_in_rest ) { return ''; } $namespace = ! empty( $post_type->rest_namespace ) ? $post_type->rest_namespace : 'wp/v2'; $rest_base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name; $route = sprintf( '/%s/%s', $namespace, $rest_base ); return apply_filters( 'rest_route_for_post_type_items', $route, $post_type ); } function rest_get_route_for_term( $term ) { $term = get_term( $term ); if ( ! $term instanceof WP_Term ) { return ''; } $taxonomy_route = rest_get_route_for_taxonomy_items( $term->taxonomy ); if ( ! $taxonomy_route ) { return ''; } $route = sprintf( '%s/%d', $taxonomy_route, $term->term_id ); return apply_filters( 'rest_route_for_term', $route, $term ); } function rest_get_route_for_taxonomy_items( $taxonomy ) { $taxonomy = get_taxonomy( $taxonomy ); if ( ! $taxonomy ) { return ''; } if ( ! $taxonomy->show_in_rest ) { return ''; } $namespace = ! empty( $taxonomy->rest_namespace ) ? $taxonomy->rest_namespace : 'wp/v2'; $rest_base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $route = sprintf( '/%s/%s', $namespace, $rest_base ); return apply_filters( 'rest_route_for_taxonomy_items', $route, $taxonomy ); } function rest_get_queried_resource_route() { if ( is_singular() ) { $route = rest_get_route_for_post( get_queried_object() ); } elseif ( is_category() || is_tag() || is_tax() ) { $route = rest_get_route_for_term( get_queried_object() ); } elseif ( is_author() ) { $route = '/wp/v2/users/' . get_queried_object_id(); } else { $route = ''; } return apply_filters( 'rest_queried_resource_route', $route ); } function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::CREATABLE ) { $schema_properties = ! empty( $schema['properties'] ) ? $schema['properties'] : array(); $endpoint_args = array(); $valid_schema_properties = rest_get_allowed_schema_keywords(); $valid_schema_properties = array_diff( $valid_schema_properties, array( 'default', 'required' ) ); foreach ( $schema_properties as $field_id => $params ) { if ( ! empty( $params['readonly'] ) ) { continue; } $endpoint_args[ $field_id ] = array( 'validate_callback' => 'rest_validate_request_arg', 'sanitize_callback' => 'rest_sanitize_request_arg', ); if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) { $endpoint_args[ $field_id ]['default'] = $params['default']; } if ( WP_REST_Server::CREATABLE === $method && ! empty( $params['required'] ) ) { $endpoint_args[ $field_id ]['required'] = true; } foreach ( $valid_schema_properties as $schema_prop ) { if ( isset( $params[ $schema_prop ] ) ) { $endpoint_args[ $field_id ][ $schema_prop ] = $params[ $schema_prop ]; } } if ( isset( $params['arg_options'] ) ) { if ( WP_REST_Server::CREATABLE !== $method ) { $params['arg_options'] = array_diff_key( $params['arg_options'], array( 'required' => '', 'default' => '', ) ); } $endpoint_args[ $field_id ] = array_merge( $endpoint_args[ $field_id ], $params['arg_options'] ); } } return $endpoint_args; } function rest_convert_error_to_response( $error ) { $status = array_reduce( $error->get_all_error_data(), static function ( $status, $error_data ) { return is_array( $error_data ) && isset( $error_data['status'] ) ? $error_data['status'] : $status; }, 500 ); $errors = array(); foreach ( (array) $error->errors as $code => $messages ) { $all_data = $error->get_all_error_data( $code ); $last_data = array_pop( $all_data ); foreach ( (array) $messages as $message ) { $formatted = array( 'code' => $code, 'message' => $message, 'data' => $last_data, ); if ( $all_data ) { $formatted['additional_data'] = $all_data; } $errors[] = $formatted; } } $data = $errors[0]; if ( count( $errors ) > 1 ) { array_shift( $errors ); $data['additional_errors'] = $errors; } return new WP_REST_Response( $data, $status ); } function wp_is_rest_endpoint() { global $wp_rest_server; $is_rest_endpoint = wp_is_serving_rest_request(); if ( ! $is_rest_endpoint ) { $is_rest_endpoint = isset( $wp_rest_server ) && $wp_rest_server->is_dispatching(); } return (bool) apply_filters( 'wp_is_rest_endpoint', $is_rest_endpoint ); }
###require ABSPATH . WPINC . '/rest-api/class-wp-rest-server.php';
class WP_REST_Server { const READABLE = 'GET'; const CREATABLE = 'POST'; const EDITABLE = 'POST, PUT, PATCH'; const DELETABLE = 'DELETE'; const ALLMETHODS = 'GET, POST, PUT, PATCH, DELETE'; protected $namespaces = array(); protected $endpoints = array(); protected $route_options = array(); protected $embed_cache = array(); protected $dispatching_requests = array(); public function __construct() { $this->endpoints = array( '/' => array( 'callback' => array( $this, 'get_index' ), 'methods' => 'GET', 'args' => array( 'context' => array( 'default' => 'view', ), ), ), '/batch/v1' => array( 'callback' => array( $this, 'serve_batch_request_v1' ), 'methods' => 'POST', 'args' => array( 'validation' => array( 'type' => 'string', 'enum' => array( 'require-all-validate', 'normal' ), 'default' => 'normal', ), 'requests' => array( 'required' => true, 'type' => 'array', 'maxItems' => $this->get_max_batch_size(), 'items' => array( 'type' => 'object', 'properties' => array( 'method' => array( 'type' => 'string', 'enum' => array( 'POST', 'PUT', 'PATCH', 'DELETE' ), 'default' => 'POST', ), 'path' => array( 'type' => 'string', 'required' => true, ), 'body' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => true, ), 'headers' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => array( 'type' => array( 'string', 'array' ), 'items' => array( 'type' => 'string', ), ), ), ), ), ), ), ), ); } public function check_authentication() { return apply_filters( 'rest_authentication_errors', null ); } protected function error_to_response( $error ) { return rest_convert_error_to_response( $error ); } protected function json_error( $code, $message, $status = null ) { if ( $status ) { $this->set_status( $status ); } $error = compact( 'code', 'message' ); return wp_json_encode( $error ); } protected function get_json_encode_options( WP_REST_Request $request ) { $options = 0; if ( $request->has_param( '_pretty' ) ) { $options |= JSON_PRETTY_PRINT; } return apply_filters( 'rest_json_encode_options', $options, $request ); } public function serve_request( $path = null ) { global $current_user; if ( $current_user instanceof WP_User && ! $current_user->exists() ) { $current_user = null; } $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true ); $jsonp_callback = false; if ( isset( $_GET['_jsonp'] ) ) { $jsonp_callback = $_GET['_jsonp']; } $content_type = ( $jsonp_callback && $jsonp_enabled ) ? 'application/javascript' : 'application/json'; $this->send_header( 'Content-Type', $content_type . '; charset=' . get_option( 'blog_charset' ) ); $this->send_header( 'X-Robots-Tag', 'noindex' ); $api_root = get_rest_url(); if ( ! empty( $api_root ) ) { $this->send_header( 'Link', '<' . sanitize_url( $api_root ) . '>; rel="https://api.w.org/"' ); } $this->send_header( 'X-Content-Type-Options', 'nosniff' ); apply_filters_deprecated( 'rest_enabled', array( true ), '4.7.0', 'rest_authentication_errors', sprintf( __( 'The REST API can no longer be completely disabled, the %s filter can be used to restrict access to the API, instead.' ), 'rest_authentication_errors' ) ); if ( $jsonp_callback ) { if ( ! $jsonp_enabled ) { echo $this->json_error( 'rest_callback_disabled', __( 'JSONP support is disabled on this site.' ), 400 ); return false; } if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { echo $this->json_error( 'rest_callback_invalid', __( 'Invalid JSONP callback function.' ), 400 ); return false; } } if ( empty( $path ) ) { if ( isset( $_SERVER['PATH_INFO'] ) ) { $path = $_SERVER['PATH_INFO']; } else { $path = '/'; } } $request = new WP_REST_Request( $_SERVER['REQUEST_METHOD'], $path ); $request->set_query_params( wp_unslash( $_GET ) ); $request->set_body_params( wp_unslash( $_POST ) ); $request->set_file_params( $_FILES ); $request->set_headers( $this->get_headers( wp_unslash( $_SERVER ) ) ); $request->set_body( self::get_raw_data() ); $method_overridden = false; if ( isset( $_GET['_method'] ) ) { $request->set_method( $_GET['_method'] ); } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ); $method_overridden = true; } $expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' ); $expose_headers = apply_filters( 'rest_exposed_cors_headers', $expose_headers, $request ); $this->send_header( 'Access-Control-Expose-Headers', implode( ', ', $expose_headers ) ); $allow_headers = array( 'Authorization', 'X-WP-Nonce', 'Content-Disposition', 'Content-MD5', 'Content-Type', ); $allow_headers = apply_filters( 'rest_allowed_cors_headers', $allow_headers, $request ); $this->send_header( 'Access-Control-Allow-Headers', implode( ', ', $allow_headers ) ); $result = $this->check_authentication(); if ( ! is_wp_error( $result ) ) { $result = $this->dispatch( $request ); } $result = rest_ensure_response( $result ); if ( is_wp_error( $result ) ) { $result = $this->error_to_response( $result ); } $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); if ( isset( $_GET['_envelope'] ) ) { $embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false; $result = $this->envelope_response( $result, $embed ); } $headers = $result->get_headers(); $this->send_headers( $headers ); $code = $result->get_status(); $this->set_status( $code ); $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); if ( $send_no_cache_headers || ( true === $method_overridden && str_starts_with( $code, '4' ) ) ) { foreach ( wp_get_nocache_headers() as $header => $header_value ) { if ( empty( $header_value ) ) { $this->remove_header( $header ); } else { $this->send_header( $header, $header_value ); } } } $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this ); if ( ! $served ) { if ( 'HEAD' === $request->get_method() ) { return null; } $embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false; $result = $this->response_to_data( $result, $embed ); $result = apply_filters( 'rest_pre_echo_response', $result, $this, $request ); if ( 204 === $code || null === $result ) { return null; } $result = wp_json_encode( $result, $this->get_json_encode_options( $request ) ); $json_error_message = $this->get_json_last_error(); if ( $json_error_message ) { $this->set_status( 500 ); $json_error_obj = new WP_Error( 'rest_encode_error', $json_error_message, array( 'status' => 500 ) ); $result = $this->error_to_response( $json_error_obj ); $result = wp_json_encode( $result->data, $this->get_json_encode_options( $request ) ); } if ( $jsonp_callback ) { echo '/**/' . $jsonp_callback . '(' . $result . ')'; } else { echo $result; } } return null; } public function response_to_data( $response, $embed ) { $data = $response->get_data(); $links = self::get_compact_response_links( $response ); if ( ! empty( $links ) ) { $data['_links'] = $links; } if ( $embed ) { $this->embed_cache = array(); if ( wp_is_numeric_array( $data ) ) { foreach ( $data as $key => $item ) { $data[ $key ] = $this->embed_links( $item, $embed ); } } else { $data = $this->embed_links( $data, $embed ); } $this->embed_cache = array(); } return $data; } public static function get_response_links( $response ) { $links = $response->get_links(); if ( empty( $links ) ) { return array(); } $data = array(); foreach ( $links as $rel => $items ) { $data[ $rel ] = array(); foreach ( $items as $item ) { $attributes = $item['attributes']; $attributes['href'] = $item['href']; if ( 'self' !== $rel ) { $data[ $rel ][] = $attributes; continue; } $target_hints = self::get_target_hints_for_link( $attributes ); if ( $target_hints ) { $attributes['targetHints'] = $target_hints; } $data[ $rel ][] = $attributes; } } return $data; } protected static function get_target_hints_for_link( $link ) { if ( isset( $link['targetHints']['allow'] ) ) { return null; } $request = WP_REST_Request::from_url( $link['href'] ); if ( ! $request ) { return null; } $server = rest_get_server(); $match = $server->match_request_to_handler( $request ); if ( is_wp_error( $match ) ) { return null; } if ( is_wp_error( $request->has_valid_params() ) ) { return null; } if ( is_wp_error( $request->sanitize_params() ) ) { return null; } $target_hints = array(); $response = new WP_REST_Response(); $response->set_matched_route( $match[0] ); $response->set_matched_handler( $match[1] ); $headers = rest_send_allow_header( $response, $server, $request )->get_headers(); foreach ( $headers as $name => $value ) { $name = WP_REST_Request::canonicalize_header_name( $name ); $target_hints[ $name ] = array_map( 'trim', explode( ',', $value ) ); } return $target_hints; } public static function get_compact_response_links( $response ) { $links = self::get_response_links( $response ); if ( empty( $links ) ) { return array(); } $curies = $response->get_curies(); $used_curies = array(); foreach ( $links as $rel => $items ) { foreach ( $curies as $curie ) { $href_prefix = substr( $curie['href'], 0, strpos( $curie['href'], '{rel}' ) ); if ( ! str_starts_with( $rel, $href_prefix ) ) { continue; } $rel_regex = str_replace( '\{rel\}', '(.+)', preg_quote( $curie['href'], '!' ) ); preg_match( '!' . $rel_regex . '!', $rel, $matches ); if ( $matches ) { $new_rel = $curie['name'] . ':' . $matches[1]; $used_curies[ $curie['name'] ] = $curie; $links[ $new_rel ] = $items; unset( $links[ $rel ] ); break; } } } if ( $used_curies ) { $links['curies'] = array_values( $used_curies ); } return $links; } protected function embed_links( $data, $embed = true ) { if ( empty( $data['_links'] ) ) { return $data; } $embedded = array(); foreach ( $data['_links'] as $rel => $links ) { if ( is_array( $embed ) && ! in_array( $rel, $embed, true ) ) { continue; } $embeds = array(); foreach ( $links as $item ) { if ( empty( $item['embeddable'] ) ) { $embeds[] = array(); continue; } if ( ! array_key_exists( $item['href'], $this->embed_cache ) ) { $request = WP_REST_Request::from_url( $item['href'] ); if ( ! $request ) { $embeds[] = array(); continue; } if ( empty( $request['context'] ) ) { $request['context'] = 'embed'; } if ( empty( $request['per_page'] ) ) { $matched = $this->match_request_to_handler( $request ); if ( ! is_wp_error( $matched ) && isset( $matched[1]['args']['per_page']['maximum'] ) ) { $request['per_page'] = (int) $matched[1]['args']['per_page']['maximum']; } } $response = $this->dispatch( $request ); $response = apply_filters( 'rest_post_dispatch', rest_ensure_response( $response ), $this, $request ); $this->embed_cache[ $item['href'] ] = $this->response_to_data( $response, false ); } $embeds[] = $this->embed_cache[ $item['href'] ]; } $has_links = count( array_filter( $embeds ) ); if ( $has_links ) { $embedded[ $rel ] = $embeds; } } if ( ! empty( $embedded ) ) { $data['_embedded'] = $embedded; } return $data; } public function envelope_response( $response, $embed ) { $envelope = array( 'body' => $this->response_to_data( $response, $embed ), 'status' => $response->get_status(), 'headers' => $response->get_headers(), ); $envelope = apply_filters( 'rest_envelope_response', $envelope, $response ); return rest_ensure_response( $envelope ); } public function register_route( $route_namespace, $route, $route_args, $override = false ) { if ( ! isset( $this->namespaces[ $route_namespace ] ) ) { $this->namespaces[ $route_namespace ] = array(); $this->register_route( $route_namespace, '/' . $route_namespace, array( array( 'methods' => self::READABLE, 'callback' => array( $this, 'get_namespace_index' ), 'args' => array( 'namespace' => array( 'default' => $route_namespace, ), 'context' => array( 'default' => 'view', ), ), ), ) ); } $this->namespaces[ $route_namespace ][ $route ] = true; $route_args['namespace'] = $route_namespace; if ( $override || empty( $this->endpoints[ $route ] ) ) { $this->endpoints[ $route ] = $route_args; } else { $this->endpoints[ $route ] = array_merge( $this->endpoints[ $route ], $route_args ); } } public function get_routes( $route_namespace = '' ) { $endpoints = $this->endpoints; if ( $route_namespace ) { $endpoints = wp_list_filter( $endpoints, array( 'namespace' => $route_namespace ) ); } $endpoints = apply_filters( 'rest_endpoints', $endpoints ); $defaults = array( 'methods' => '', 'accept_json' => false, 'accept_raw' => false, 'show_in_index' => true, 'args' => array(), ); foreach ( $endpoints as $route => &$handlers ) { if ( isset( $handlers['callback'] ) ) { $handlers = array( $handlers ); } if ( ! isset( $this->route_options[ $route ] ) ) { $this->route_options[ $route ] = array(); } foreach ( $handlers as $key => &$handler ) { if ( ! is_numeric( $key ) ) { $this->route_options[ $route ][ $key ] = $handler; unset( $handlers[ $key ] ); continue; } $handler = wp_parse_args( $handler, $defaults ); if ( is_string( $handler['methods'] ) ) { $methods = explode( ',', $handler['methods'] ); } elseif ( is_array( $handler['methods'] ) ) { $methods = $handler['methods']; } else { $methods = array(); } $handler['methods'] = array(); foreach ( $methods as $method ) { $method = strtoupper( trim( $method ) ); $handler['methods'][ $method ] = true; } } } return $endpoints; } public function get_namespaces() { return array_keys( $this->namespaces ); } public function get_route_options( $route ) { if ( ! isset( $this->route_options[ $route ] ) ) { return null; } return $this->route_options[ $route ]; } public function dispatch( $request ) { $this->dispatching_requests[] = $request; $result = apply_filters( 'rest_pre_dispatch', null, $this, $request ); if ( ! empty( $result ) ) { $result = rest_ensure_response( $result ); if ( is_wp_error( $result ) ) { $result = $this->error_to_response( $result ); } array_pop( $this->dispatching_requests ); return $result; } $error = null; $matched = $this->match_request_to_handler( $request ); if ( is_wp_error( $matched ) ) { $response = $this->error_to_response( $matched ); array_pop( $this->dispatching_requests ); return $response; } list( $route, $handler ) = $matched; if ( ! is_callable( $handler['callback'] ) ) { $error = new WP_Error( 'rest_invalid_handler', __( 'The handler for the route is invalid.' ), array( 'status' => 500 ) ); } if ( ! is_wp_error( $error ) ) { $check_required = $request->has_valid_params(); if ( is_wp_error( $check_required ) ) { $error = $check_required; } else { $check_sanitized = $request->sanitize_params(); if ( is_wp_error( $check_sanitized ) ) { $error = $check_sanitized; } } } $response = $this->respond_to_request( $request, $route, $handler, $error ); array_pop( $this->dispatching_requests ); return $response; } public function is_dispatching() { return (bool) $this->dispatching_requests; } protected function match_request_to_handler( $request ) { $method = $request->get_method(); $path = $request->get_route(); $with_namespace = array(); foreach ( $this->get_namespaces() as $namespace ) { if ( str_starts_with( trailingslashit( ltrim( $path, '/' ) ), $namespace ) ) { $with_namespace[] = $this->get_routes( $namespace ); } } if ( $with_namespace ) { $routes = array_merge( ...$with_namespace ); } else { $routes = $this->get_routes(); } foreach ( $routes as $route => $handlers ) { $match = preg_match( '@^' . $route . '$@i', $path, $matches ); if ( ! $match ) { continue; } $args = array(); foreach ( $matches as $param => $value ) { if ( ! is_int( $param ) ) { $args[ $param ] = $value; } } foreach ( $handlers as $handler ) { $callback = $handler['callback']; $checked_method = $method; if ( 'HEAD' === $method && empty( $handler['methods']['HEAD'] ) ) { $checked_method = 'GET'; } if ( empty( $handler['methods'][ $checked_method ] ) ) { continue; } if ( ! is_callable( $callback ) ) { return array( $route, $handler ); } $request->set_url_params( $args ); $request->set_attributes( $handler ); $defaults = array(); foreach ( $handler['args'] as $arg => $options ) { if ( isset( $options['default'] ) ) { $defaults[ $arg ] = $options['default']; } } $request->set_default_params( $defaults ); return array( $route, $handler ); } } return new WP_Error( 'rest_no_route', __( 'No route was found matching the URL and request method.' ), array( 'status' => 404 ) ); } protected function respond_to_request( $request, $route, $handler, $response ) { $response = apply_filters( 'rest_request_before_callbacks', $response, $handler, $request ); if ( ! is_wp_error( $response ) && ! empty( $handler['permission_callback'] ) ) { $permission = call_user_func( $handler['permission_callback'], $request ); if ( is_wp_error( $permission ) ) { $response = $permission; } elseif ( false === $permission || null === $permission ) { $response = new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( 'status' => rest_authorization_required_code() ) ); } } if ( ! is_wp_error( $response ) ) { $dispatch_result = apply_filters( 'rest_dispatch_request', null, $request, $route, $handler ); if ( null !== $dispatch_result ) { $response = $dispatch_result; } else { $response = call_user_func( $handler['callback'], $request ); } } $response = apply_filters( 'rest_request_after_callbacks', $response, $handler, $request ); if ( is_wp_error( $response ) ) { $response = $this->error_to_response( $response ); } else { $response = rest_ensure_response( $response ); } $response->set_matched_route( $route ); $response->set_matched_handler( $handler ); return $response; } protected function get_json_last_error() { if ( JSON_ERROR_NONE === json_last_error() ) { return false; } return json_last_error_msg(); } public function get_index( $request ) { $available = array( 'name' => get_option( 'blogname' ), 'description' => get_option( 'blogdescription' ), 'url' => get_option( 'siteurl' ), 'home' => home_url(), 'gmt_offset' => get_option( 'gmt_offset' ), 'timezone_string' => get_option( 'timezone_string' ), 'page_for_posts' => (int) get_option( 'page_for_posts' ), 'page_on_front' => (int) get_option( 'page_on_front' ), 'show_on_front' => get_option( 'show_on_front' ), 'namespaces' => array_keys( $this->namespaces ), 'authentication' => array(), 'routes' => $this->get_data_for_routes( $this->get_routes(), $request['context'] ), ); $response = new WP_REST_Response( $available ); $fields = isset( $request['_fields'] ) ? $request['_fields'] : ''; $fields = wp_parse_list( $fields ); if ( empty( $fields ) ) { $fields[] = '_links'; } if ( $request->has_param( '_embed' ) ) { $fields[] = '_embedded'; } if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_link( 'help', 'https://developer.wordpress.org/rest-api/' ); $this->add_active_theme_link_to_index( $response ); $this->add_site_logo_to_index( $response ); $this->add_site_icon_to_index( $response ); } else { if ( rest_is_field_included( 'site_logo', $fields ) ) { $this->add_site_logo_to_index( $response ); } if ( rest_is_field_included( 'site_icon', $fields ) || rest_is_field_included( 'site_icon_url', $fields ) ) { $this->add_site_icon_to_index( $response ); } } return apply_filters( 'rest_index', $response, $request ); } protected function add_active_theme_link_to_index( WP_REST_Response $response ) { $should_add = current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ); if ( ! $should_add && current_user_can( 'edit_posts' ) ) { $should_add = true; } if ( ! $should_add ) { foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { $should_add = true; break; } } } if ( $should_add ) { $theme = wp_get_theme(); $response->add_link( 'https://api.w.org/active-theme', rest_url( 'wp/v2/themes/' . $theme->get_stylesheet() ) ); } } protected function add_site_logo_to_index( WP_REST_Response $response ) { $site_logo_id = get_theme_mod( 'custom_logo', 0 ); $this->add_image_to_index( $response, $site_logo_id, 'site_logo' ); } protected function add_site_icon_to_index( WP_REST_Response $response ) { $site_icon_id = get_option( 'site_icon', 0 ); $this->add_image_to_index( $response, $site_icon_id, 'site_icon' ); $response->data['site_icon_url'] = get_site_icon_url(); } protected function add_image_to_index( WP_REST_Response $response, $image_id, $type ) { $response->data[ $type ] = (int) $image_id; if ( $image_id ) { $response->add_link( 'https://api.w.org/featuredmedia', rest_url( rest_get_route_for_post( $image_id ) ), array( 'embeddable' => true, 'type' => $type, ) ); } } public function get_namespace_index( $request ) { $namespace = $request['namespace']; if ( ! isset( $this->namespaces[ $namespace ] ) ) { return new WP_Error( 'rest_invalid_namespace', __( 'The specified namespace could not be found.' ), array( 'status' => 404 ) ); } $routes = $this->namespaces[ $namespace ]; $endpoints = array_intersect_key( $this->get_routes(), $routes ); $data = array( 'namespace' => $namespace, 'routes' => $this->get_data_for_routes( $endpoints, $request['context'] ), ); $response = rest_ensure_response( $data ); $response->add_link( 'up', rest_url( '/' ) ); return apply_filters( 'rest_namespace_index', $response, $request ); } public function get_data_for_routes( $routes, $context = 'view' ) { $available = array(); foreach ( $routes as $route => $callbacks ) { $data = $this->get_data_for_route( $route, $callbacks, $context ); if ( empty( $data ) ) { continue; } $available[ $route ] = apply_filters( 'rest_endpoints_description', $data ); } return apply_filters( 'rest_route_data', $available, $routes ); } public function get_data_for_route( $route, $callbacks, $context = 'view' ) { $data = array( 'namespace' => '', 'methods' => array(), 'endpoints' => array(), ); $allow_batch = false; if ( isset( $this->route_options[ $route ] ) ) { $options = $this->route_options[ $route ]; if ( isset( $options['namespace'] ) ) { $data['namespace'] = $options['namespace']; } $allow_batch = isset( $options['allow_batch'] ) ? $options['allow_batch'] : false; if ( isset( $options['schema'] ) && 'help' === $context ) { $data['schema'] = call_user_func( $options['schema'] ); } } $allowed_schema_keywords = array_flip( rest_get_allowed_schema_keywords() ); $route = preg_replace( '#\(\?P<(\w+?)>.*?\)#', '{$1}', $route ); foreach ( $callbacks as $callback ) { if ( empty( $callback['show_in_index'] ) ) { continue; } $data['methods'] = array_merge( $data['methods'], array_keys( $callback['methods'] ) ); $endpoint_data = array( 'methods' => array_keys( $callback['methods'] ), ); $callback_batch = isset( $callback['allow_batch'] ) ? $callback['allow_batch'] : $allow_batch; if ( $callback_batch ) { $endpoint_data['allow_batch'] = $callback_batch; } if ( isset( $callback['args'] ) ) { $endpoint_data['args'] = array(); foreach ( $callback['args'] as $key => $opts ) { if ( is_string( $opts ) ) { $opts = array( $opts => 0 ); } elseif ( ! is_array( $opts ) ) { $opts = array(); } $arg_data = array_intersect_key( $opts, $allowed_schema_keywords ); $arg_data['required'] = ! empty( $opts['required'] ); $endpoint_data['args'][ $key ] = $arg_data; } } $data['endpoints'][] = $endpoint_data; if ( ! str_contains( $route, '{' ) ) { $data['_links'] = array( 'self' => array( array( 'href' => rest_url( $route ), ), ), ); } } if ( empty( $data['methods'] ) ) { return null; } return $data; } protected function get_max_batch_size() { return apply_filters( 'rest_get_max_batch_size', 25 ); } public function serve_batch_request_v1( WP_REST_Request $batch_request ) { $requests = array(); foreach ( $batch_request['requests'] as $args ) { $parsed_url = wp_parse_url( $args['path'] ); if ( false === $parsed_url ) { $requests[] = new WP_Error( 'parse_path_failed', __( 'Could not parse the path.' ), array( 'status' => 400 ) ); continue; } $single_request = new WP_REST_Request( isset( $args['method'] ) ? $args['method'] : 'POST', $parsed_url['path'] ); if ( ! empty( $parsed_url['query'] ) ) { $query_args = array(); wp_parse_str( $parsed_url['query'], $query_args ); $single_request->set_query_params( $query_args ); } if ( ! empty( $args['body'] ) ) { $single_request->set_body_params( $args['body'] ); } if ( ! empty( $args['headers'] ) ) { $single_request->set_headers( $args['headers'] ); } $requests[] = $single_request; } $matches = array(); $validation = array(); $has_error = false; foreach ( $requests as $single_request ) { if ( is_wp_error( $single_request ) ) { $has_error = true; $validation[] = $single_request; continue; } $match = $this->match_request_to_handler( $single_request ); $matches[] = $match; $error = null; if ( is_wp_error( $match ) ) { $error = $match; } if ( ! $error ) { list( $route, $handler ) = $match; if ( isset( $handler['allow_batch'] ) ) { $allow_batch = $handler['allow_batch']; } else { $route_options = $this->get_route_options( $route ); $allow_batch = isset( $route_options['allow_batch'] ) ? $route_options['allow_batch'] : false; } if ( ! is_array( $allow_batch ) || empty( $allow_batch['v1'] ) ) { $error = new WP_Error( 'rest_batch_not_allowed', __( 'The requested route does not support batch requests.' ), array( 'status' => 400 ) ); } } if ( ! $error ) { $check_required = $single_request->has_valid_params(); if ( is_wp_error( $check_required ) ) { $error = $check_required; } } if ( ! $error ) { $check_sanitized = $single_request->sanitize_params(); if ( is_wp_error( $check_sanitized ) ) { $error = $check_sanitized; } } if ( $error ) { $has_error = true; $validation[] = $error; } else { $validation[] = true; } } $responses = array(); if ( $has_error && 'require-all-validate' === $batch_request['validation'] ) { foreach ( $validation as $valid ) { if ( is_wp_error( $valid ) ) { $responses[] = $this->envelope_response( $this->error_to_response( $valid ), false )->get_data(); } else { $responses[] = null; } } return new WP_REST_Response( array( 'failed' => 'validation', 'responses' => $responses, ), WP_Http::MULTI_STATUS ); } foreach ( $requests as $i => $single_request ) { if ( is_wp_error( $single_request ) ) { $result = $this->error_to_response( $single_request ); $responses[] = $this->envelope_response( $result, false )->get_data(); continue; } $clean_request = clone $single_request; $clean_request->set_url_params( array() ); $clean_request->set_attributes( array() ); $clean_request->set_default_params( array() ); $result = apply_filters( 'rest_pre_dispatch', null, $this, $clean_request ); if ( empty( $result ) ) { $match = $matches[ $i ]; $error = null; if ( is_wp_error( $validation[ $i ] ) ) { $error = $validation[ $i ]; } if ( is_wp_error( $match ) ) { $result = $this->error_to_response( $match ); } else { list( $route, $handler ) = $match; if ( ! $error && ! is_callable( $handler['callback'] ) ) { $error = new WP_Error( 'rest_invalid_handler', __( 'The handler for the route is invalid' ), array( 'status' => 500 ) ); } $result = $this->respond_to_request( $single_request, $route, $handler, $error ); } } $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $single_request ); $responses[] = $this->envelope_response( $result, false )->get_data(); } return new WP_REST_Response( array( 'responses' => $responses ), WP_Http::MULTI_STATUS ); } protected function set_status( $code ) { status_header( $code ); } public function send_header( $key, $value ) { $value = preg_replace( '/\s+/', ' ', $value ); header( sprintf( '%s: %s', $key, $value ) ); } public function send_headers( $headers ) { foreach ( $headers as $key => $value ) { $this->send_header( $key, $value ); } } public function remove_header( $key ) { header_remove( $key ); } public static function get_raw_data() { global $HTTP_RAW_POST_DATA; if ( ! isset( $HTTP_RAW_POST_DATA ) ) { $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } return $HTTP_RAW_POST_DATA; } public function get_headers( $server ) { $headers = array(); $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true, ); foreach ( $server as $key => $value ) { if ( str_starts_with( $key, 'HTTP_' ) ) { $headers[ substr( $key, 5 ) ] = $value; } elseif ( 'REDIRECT_HTTP_AUTHORIZATION' === $key && empty( $server['HTTP_AUTHORIZATION'] ) ) { $headers['AUTHORIZATION'] = $value; } elseif ( isset( $additional[ $key ] ) ) { $headers[ $key ] = $value; } } return $headers; } }
###require ABSPATH . WPINC . '/rest-api/class-wp-rest-response.php';
class WP_REST_Response extends WP_HTTP_Response { protected $links = array(); protected $matched_route = ''; protected $matched_handler = null; public function add_link( $rel, $href, $attributes = array() ) { if ( empty( $this->links[ $rel ] ) ) { $this->links[ $rel ] = array(); } if ( isset( $attributes['href'] ) ) { unset( $attributes['href'] ); } $this->links[ $rel ][] = array( 'href' => $href, 'attributes' => $attributes, ); } public function remove_link( $rel, $href = null ) { if ( ! isset( $this->links[ $rel ] ) ) { return; } if ( $href ) { $this->links[ $rel ] = wp_list_filter( $this->links[ $rel ], array( 'href' => $href ), 'NOT' ); } else { $this->links[ $rel ] = array(); } if ( ! $this->links[ $rel ] ) { unset( $this->links[ $rel ] ); } } public function add_links( $links ) { foreach ( $links as $rel => $set ) { if ( isset( $set['href'] ) ) { $set = array( $set ); } foreach ( $set as $attributes ) { $this->add_link( $rel, $attributes['href'], $attributes ); } } } public function get_links() { return $this->links; } public function link_header( $rel, $link, $other = array() ) { $header = '<' . $link . '>; rel="' . $rel . '"'; foreach ( $other as $key => $value ) { if ( 'title' === $key ) { $value = '"' . $value . '"'; } $header .= '; ' . $key . '=' . $value; } $this->header( 'Link', $header, false ); } public function get_matched_route() { return $this->matched_route; } public function set_matched_route( $route ) { $this->matched_route = $route; } public function get_matched_handler() { return $this->matched_handler; } public function set_matched_handler( $handler ) { $this->matched_handler = $handler; } public function is_error() { return $this->get_status() >= 400; } public function as_error() { if ( ! $this->is_error() ) { return null; } $error = new WP_Error(); if ( is_array( $this->get_data() ) ) { $data = $this->get_data(); $error->add( $data['code'], $data['message'], $data['data'] ); if ( ! empty( $data['additional_errors'] ) ) { foreach ( $data['additional_errors'] as $err ) { $error->add( $err['code'], $err['message'], $err['data'] ); } } } else { $error->add( $this->get_status(), '', array( 'status' => $this->get_status() ) ); } return $error; } public function get_curies() { $curies = array( array( 'name' => 'wp', 'href' => 'https://api.w.org/{rel}', 'templated' => true, ), ); $additional = apply_filters( 'rest_response_link_curies', array() ); return array_merge( $curies, $additional ); } }
###require ABSPATH . WPINC . '/rest-api/class-wp-rest-request.php';
class WP_REST_Request implements ArrayAccess { protected $method = ''; protected $params; protected $headers = array(); protected $body = null; protected $route; protected $attributes = array(); protected $parsed_json = false; protected $parsed_body = false; public function __construct( $method = '', $route = '', $attributes = array() ) { $this->params = array( 'URL' => array(), 'GET' => array(), 'POST' => array(), 'FILES' => array(), 'JSON' => null, 'defaults' => array(), ); $this->set_method( $method ); $this->set_route( $route ); $this->set_attributes( $attributes ); } public function get_method() { return $this->method; } public function set_method( $method ) { $this->method = strtoupper( $method ); } public function get_headers() { return $this->headers; } public function is_method( $method ) { return $this->get_method() === strtoupper( $method ); } public static function canonicalize_header_name( $key ) { $key = strtolower( $key ); $key = str_replace( '-', '_', $key ); return $key; } public function get_header( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return implode( ',', $this->headers[ $key ] ); } public function get_header_as_array( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return $this->headers[ $key ]; } public function set_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; $this->headers[ $key ] = $value; } public function add_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; if ( ! isset( $this->headers[ $key ] ) ) { $this->headers[ $key ] = array(); } $this->headers[ $key ] = array_merge( $this->headers[ $key ], $value ); } public function remove_header( $key ) { $key = $this->canonicalize_header_name( $key ); unset( $this->headers[ $key ] ); } public function set_headers( $headers, $override = true ) { if ( true === $override ) { $this->headers = array(); } foreach ( $headers as $key => $value ) { $this->set_header( $key, $value ); } } public function get_content_type() { $value = $this->get_header( 'Content-Type' ); if ( empty( $value ) ) { return null; } $parameters = ''; if ( strpos( $value, ';' ) ) { list( $value, $parameters ) = explode( ';', $value, 2 ); } $value = strtolower( $value ); if ( ! str_contains( $value, '/' ) ) { return null; } list( $type, $subtype ) = explode( '/', $value, 2 ); $data = compact( 'value', 'type', 'subtype', 'parameters' ); $data = array_map( 'trim', $data ); return $data; } public function is_json_content_type() { $content_type = $this->get_content_type(); return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] ); } protected function get_parameter_order() { $order = array(); if ( $this->is_json_content_type() ) { $order[] = 'JSON'; } $this->parse_json_params(); $body = $this->get_body(); if ( 'POST' !== $this->method && ! empty( $body ) ) { $this->parse_body_params(); } $accepts_body_data = array( 'POST', 'PUT', 'PATCH', 'DELETE' ); if ( in_array( $this->method, $accepts_body_data, true ) ) { $order[] = 'POST'; } $order[] = 'GET'; $order[] = 'URL'; $order[] = 'defaults'; return apply_filters( 'rest_request_parameter_order', $order, $this ); } public function get_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( isset( $this->params[ $type ][ $key ] ) ) { return $this->params[ $type ][ $key ]; } } return null; } public function has_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { return true; } } return false; } public function set_param( $key, $value ) { $order = $this->get_parameter_order(); $found_key = false; foreach ( $order as $type ) { if ( 'defaults' !== $type && is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { $this->params[ $type ][ $key ] = $value; $found_key = true; } } if ( ! $found_key ) { $this->params[ $order[0] ][ $key ] = $value; } } public function get_params() { $order = $this->get_parameter_order(); $order = array_reverse( $order, true ); $params = array(); foreach ( $order as $type ) { foreach ( (array) $this->params[ $type ] as $key => $value ) { $params[ $key ] = $value; } } if ( ! get_option( 'permalink_structure' ) ) { unset( $params['rest_route'] ); } return $params; } public function get_url_params() { return $this->params['URL']; } public function set_url_params( $params ) { $this->params['URL'] = $params; } public function get_query_params() { return $this->params['GET']; } public function set_query_params( $params ) { $this->params['GET'] = $params; } public function get_body_params() { return $this->params['POST']; } public function set_body_params( $params ) { $this->params['POST'] = $params; } public function get_file_params() { return $this->params['FILES']; } public function set_file_params( $params ) { $this->params['FILES'] = $params; } public function get_default_params() { return $this->params['defaults']; } public function set_default_params( $params ) { $this->params['defaults'] = $params; } public function get_body() { return $this->body; } public function set_body( $data ) { $this->body = $data; $this->parsed_json = false; $this->parsed_body = false; $this->params['JSON'] = null; } public function get_json_params() { $this->parse_json_params(); return $this->params['JSON']; } protected function parse_json_params() { if ( $this->parsed_json ) { return true; } $this->parsed_json = true; if ( ! $this->is_json_content_type() ) { return true; } $body = $this->get_body(); if ( empty( $body ) ) { return true; } $params = json_decode( $body, true ); if ( null === $params && JSON_ERROR_NONE !== json_last_error() ) { $this->parsed_json = false; $error_data = array( 'status' => WP_Http::BAD_REQUEST, 'json_error_code' => json_last_error(), 'json_error_message' => json_last_error_msg(), ); return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data ); } $this->params['JSON'] = $params; return true; } protected function parse_body_params() { if ( $this->parsed_body ) { return; } $this->parsed_body = true; $content_type = $this->get_content_type(); if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) { return; } parse_str( $this->get_body(), $params ); $this->params['POST'] = array_merge( $params, $this->params['POST'] ); } public function get_route() { return $this->route; } public function set_route( $route ) { $this->route = $route; } public function get_attributes() { return $this->attributes; } public function set_attributes( $attributes ) { $this->attributes = $attributes; } public function sanitize_params() { $attributes = $this->get_attributes(); if ( empty( $attributes['args'] ) ) { return true; } $order = $this->get_parameter_order(); $invalid_params = array(); $invalid_details = array(); foreach ( $order as $type ) { if ( empty( $this->params[ $type ] ) ) { continue; } foreach ( $this->params[ $type ] as $key => $value ) { if ( ! isset( $attributes['args'][ $key ] ) ) { continue; } $param_args = $attributes['args'][ $key ]; if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) { $param_args['sanitize_callback'] = 'rest_parse_request_arg'; } if ( empty( $param_args['sanitize_callback'] ) ) { continue; } $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); if ( is_wp_error( $sanitized_value ) ) { $invalid_params[ $key ] = implode( ' ', $sanitized_value->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $sanitized_value )->get_data(); } else { $this->params[ $type ][ $key ] = $sanitized_value; } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } return true; } public function has_valid_params() { $json_error = $this->parse_json_params(); if ( is_wp_error( $json_error ) ) { return $json_error; } $attributes = $this->get_attributes(); $required = array(); $args = empty( $attributes['args'] ) ? array() : $attributes['args']; foreach ( $args as $key => $arg ) { $param = $this->get_param( $key ); if ( isset( $arg['required'] ) && true === $arg['required'] && null === $param ) { $required[] = $key; } } if ( ! empty( $required ) ) { return new WP_Error( 'rest_missing_callback_param', sprintf( __( 'Missing parameter(s): %s' ), implode( ', ', $required ) ), array( 'status' => 400, 'params' => $required, ) ); } $invalid_params = array(); $invalid_details = array(); foreach ( $args as $key => $arg ) { $param = $this->get_param( $key ); if ( null !== $param && ! empty( $arg['validate_callback'] ) ) { $valid_check = call_user_func( $arg['validate_callback'], $param, $this, $key ); if ( false === $valid_check ) { $invalid_params[ $key ] = __( 'Invalid parameter.' ); } if ( is_wp_error( $valid_check ) ) { $invalid_params[ $key ] = implode( ' ', $valid_check->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $valid_check )->get_data(); } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } if ( isset( $attributes['validate_callback'] ) ) { $valid_check = call_user_func( $attributes['validate_callback'], $this ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } if ( false === $valid_check ) { return new WP_Error( 'rest_invalid_params', __( 'Invalid parameters.' ), array( 'status' => 400 ) ); } } return true; } public function offsetExists( $offset ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( isset( $this->params[ $type ][ $offset ] ) ) { return true; } } return false; } public function offsetGet( $offset ) { return $this->get_param( $offset ); } public function offsetSet( $offset, $value ) { $this->set_param( $offset, $value ); } public function offsetUnset( $offset ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { unset( $this->params[ $type ][ $offset ] ); } } public static function from_url( $url ) { $bits = parse_url( $url ); $query_params = array(); if ( ! empty( $bits['query'] ) ) { wp_parse_str( $bits['query'], $query_params ); } $api_root = rest_url(); if ( get_option( 'permalink_structure' ) && str_starts_with( $url, $api_root ) ) { $api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) ); $route = parse_url( $api_url_part, PHP_URL_PATH ); } elseif ( ! empty( $query_params['rest_route'] ) ) { $route = $query_params['rest_route']; unset( $query_params['rest_route'] ); } $request = false; if ( ! empty( $route ) ) { $request = new WP_REST_Request( 'GET', $route ); $request->set_query_params( $query_params ); } return apply_filters( 'rest_request_from_url', $request, $url ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-controller.php';
abstract class WP_REST_Controller { protected $namespace; protected $rest_base; protected $schema; public function register_routes() { _doing_it_wrong( 'WP_REST_Controller::register_routes', sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), '4.7.0' ); } public function get_items_permissions_check( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function get_items( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function get_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function get_item( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function create_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function create_item( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function update_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function update_item( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function delete_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function delete_item( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } protected function prepare_item_for_database( $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function prepare_item_for_response( $item, $request ) { return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } public function prepare_response_for_collection( $response ) { if ( ! ( $response instanceof WP_REST_Response ) ) { return $response; } $data = (array) $response->get_data(); $server = rest_get_server(); $links = $server::get_compact_response_links( $response ); if ( ! empty( $links ) ) { $data['_links'] = $links; } return $data; } public function filter_response_by_context( $response_data, $context ) { $schema = $this->get_item_schema(); return rest_filter_response_by_context( $response_data, $schema, $context ); } public function get_item_schema() { return $this->add_additional_fields_schema( array() ); } public function get_public_item_schema() { $schema = $this->get_item_schema(); if ( ! empty( $schema['properties'] ) ) { foreach ( $schema['properties'] as &$property ) { unset( $property['arg_options'] ); } } return $schema; } public function get_collection_params() { return array( 'context' => $this->get_context_param(), 'page' => array( 'description' => __( 'Current page of the collection.' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', 'minimum' => 1, ), 'per_page' => array( 'description' => __( 'Maximum number of items to be returned in result set.' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, 'maximum' => 100, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), 'search' => array( 'description' => __( 'Limit results to those matching a string.' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), ); } public function get_context_param( $args = array() ) { $param_details = array( 'description' => __( 'Scope under which the request is made; determines fields present in response.' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $schema = $this->get_item_schema(); if ( empty( $schema['properties'] ) ) { return array_merge( $param_details, $args ); } $contexts = array(); foreach ( $schema['properties'] as $attributes ) { if ( ! empty( $attributes['context'] ) ) { $contexts = array_merge( $contexts, $attributes['context'] ); } } if ( ! empty( $contexts ) ) { $param_details['enum'] = array_unique( $contexts ); rsort( $param_details['enum'] ); } return array_merge( $param_details, $args ); } protected function add_additional_fields_to_object( $response_data, $request ) { $additional_fields = $this->get_additional_fields(); $requested_fields = $this->get_fields_for_response( $request ); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['get_callback'] ) { continue; } if ( ! rest_is_field_included( $field_name, $requested_fields ) ) { continue; } $response_data[ $field_name ] = call_user_func( $field_options['get_callback'], $response_data, $field_name, $request, $this->get_object_type() ); } return $response_data; } protected function update_additional_fields_for_object( $data_object, $request ) { $additional_fields = $this->get_additional_fields(); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['update_callback'] ) { continue; } if ( ! isset( $request[ $field_name ] ) ) { continue; } $result = call_user_func( $field_options['update_callback'], $request[ $field_name ], $data_object, $field_name, $request, $this->get_object_type() ); if ( is_wp_error( $result ) ) { return $result; } } return true; } protected function add_additional_fields_schema( $schema ) { if ( empty( $schema['title'] ) ) { return $schema; } $object_type = $schema['title']; $additional_fields = $this->get_additional_fields( $object_type ); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['schema'] ) { continue; } $schema['properties'][ $field_name ] = $field_options['schema']; } return $schema; } protected function get_additional_fields( $object_type = null ) { global $wp_rest_additional_fields; if ( ! $object_type ) { $object_type = $this->get_object_type(); } if ( ! $object_type ) { return array(); } if ( ! $wp_rest_additional_fields || ! isset( $wp_rest_additional_fields[ $object_type ] ) ) { return array(); } return $wp_rest_additional_fields[ $object_type ]; } protected function get_object_type() { $schema = $this->get_item_schema(); if ( ! $schema || ! isset( $schema['title'] ) ) { return null; } return $schema['title']; } public function get_fields_for_response( $request ) { $schema = $this->get_item_schema(); $properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); $additional_fields = $this->get_additional_fields(); foreach ( $additional_fields as $field_name => $field_options ) { if ( is_null( $field_options['schema'] ) ) { $properties[ $field_name ] = $field_options; } } $context = $request['context']; if ( $context ) { foreach ( $properties as $name => $options ) { if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { unset( $properties[ $name ] ); } } } $fields = array_keys( $properties ); $fields[] = '_links'; if ( $request->has_param( '_embed' ) ) { $fields[] = '_embedded'; } $fields = array_unique( $fields ); if ( ! isset( $request['_fields'] ) ) { return $fields; } $requested_fields = wp_parse_list( $request['_fields'] ); if ( 0 === count( $requested_fields ) ) { return $fields; } $requested_fields = array_map( 'trim', $requested_fields ); if ( in_array( 'id', $fields, true ) ) { $requested_fields[] = 'id'; } return array_reduce( $requested_fields, static function ( $response_fields, $field ) use ( $fields ) { if ( in_array( $field, $fields, true ) ) { $response_fields[] = $field; return $response_fields; } $nested_fields = explode( '.', $field ); if ( in_array( $nested_fields[0], $fields, true ) ) { $response_fields[] = $field; } return $response_fields; }, array() ); } public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { return rest_get_endpoint_args_for_schema( $this->get_item_schema(), $method ); } public function sanitize_slug( $slug ) { return sanitize_title( $slug ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-posts-controller.php';
class WP_REST_Posts_Controller extends WP_REST_Controller { protected $post_type; protected $meta; protected $password_check_passed = array(); protected $allow_batch = array( 'v1' => true ); public function __construct( $post_type ) { $this->post_type = $post_type; $obj = get_post_type_object( $post_type ); $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Post_Meta_Fields( $this->post_type ); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); $schema = $this->get_item_schema(); $get_item_args = array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); if ( isset( $schema['properties']['excerpt'] ) ) { $get_item_args['excerpt_length'] = array( 'description' => __( 'Override the default excerpt length.' ), 'type' => 'integer', ); } if ( isset( $schema['properties']['password'] ) ) { $get_item_args['password'] = array( 'description' => __( 'The password for the post if it is password protected.' ), 'type' => 'string', ); } register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $get_item_args, ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function check_password_required( $required, $post ) { if ( ! $required ) { return $required; } $post = get_post( $post ); if ( ! $post ) { return $required; } if ( ! empty( $this->password_check_passed[ $post->ID ] ) ) { return false; } return ! current_user_can( 'edit_post', $post->ID ); } public function get_items( $request ) { if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) { return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['orderby'] ) && 'include' === $request['orderby'] && empty( $request['include'] ) ) { return new WP_Error( 'rest_orderby_include_missing_include', __( 'You need to define an include parameter to order by include.' ), array( 'status' => 400 ) ); } $registered = $this->get_collection_params(); $args = array(); $parameter_mappings = array( 'author' => 'author__in', 'author_exclude' => 'author__not_in', 'exclude' => 'post__not_in', 'include' => 'post__in', 'ignore_sticky' => 'ignore_sticky_posts', 'menu_order' => 'menu_order', 'offset' => 'offset', 'order' => 'order', 'orderby' => 'orderby', 'page' => 'paged', 'parent' => 'post_parent__in', 'parent_exclude' => 'post_parent__not_in', 'search' => 's', 'search_columns' => 'search_columns', 'slug' => 'post_name__in', 'status' => 'post_status', ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $args[ $wp_param ] = $request[ $api_param ]; } } $args['date_query'] = array(); if ( isset( $registered['before'], $request['before'] ) ) { $args['date_query'][] = array( 'before' => $request['before'], 'column' => 'post_date', ); } if ( isset( $registered['modified_before'], $request['modified_before'] ) ) { $args['date_query'][] = array( 'before' => $request['modified_before'], 'column' => 'post_modified', ); } if ( isset( $registered['after'], $request['after'] ) ) { $args['date_query'][] = array( 'after' => $request['after'], 'column' => 'post_date', ); } if ( isset( $registered['modified_after'], $request['modified_after'] ) ) { $args['date_query'][] = array( 'after' => $request['modified_after'], 'column' => 'post_modified', ); } if ( isset( $registered['per_page'] ) ) { $args['posts_per_page'] = $request['per_page']; } if ( isset( $registered['sticky'], $request['sticky'] ) ) { $sticky_posts = get_option( 'sticky_posts', array() ); if ( ! is_array( $sticky_posts ) ) { $sticky_posts = array(); } if ( $request['sticky'] ) { $args['post__in'] = $args['post__in'] ? array_intersect( $sticky_posts, $args['post__in'] ) : $sticky_posts; if ( ! $args['post__in'] ) { $args['post__in'] = array( 0 ); } } elseif ( $sticky_posts ) { $args['post__not_in'] = array_merge( $args['post__not_in'], $sticky_posts ); } } if ( ! empty( $args['post__in'] ) ) { unset( $args['ignore_sticky_posts'] ); } if ( isset( $registered['search_semantics'], $request['search_semantics'] ) && 'exact' === $request['search_semantics'] ) { $args['exact'] = true; } $args = $this->prepare_tax_query( $args, $request ); if ( isset( $registered['format'], $request['format'] ) ) { $formats = $request['format']; $formats_query = array( 'relation' => 'OR' ); if ( in_array( 'standard', $formats, true ) ) { $formats_query[] = array( 'taxonomy' => 'post_format', 'field' => 'slug', 'operator' => 'NOT EXISTS', ); unset( $formats[ array_search( 'standard', $formats, true ) ] ); } if ( ! empty( $formats ) ) { $terms = array_map( static function ( $format ) { return "post-format-$format"; }, $formats ); $formats_query[] = array( 'taxonomy' => 'post_format', 'field' => 'slug', 'terms' => $terms, 'operator' => 'IN', ); } if ( isset( $args['tax_query'] ) ) { $args['tax_query'][] = array( 'relation' => 'AND', $formats_query, ); } else { $args['tax_query'] = $formats_query; } } $args['post_type'] = $this->post_type; $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { $args['fields'] = 'ids'; $args['update_post_term_cache'] = false; $args['update_post_meta_cache'] = false; } $args = apply_filters( "rest_{$this->post_type}_query", $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); $posts_query = new WP_Query(); $query_result = $posts_query->query( $query_args ); if ( 'edit' === $request['context'] ) { add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } if ( ! $is_head_request ) { $posts = array(); update_post_author_caches( $query_result ); update_post_parent_caches( $query_result ); if ( post_type_supports( $this->post_type, 'thumbnail' ) ) { update_post_thumbnail_cache( $posts_query ); } foreach ( $query_result as $post ) { if ( 'edit' === $request['context'] ) { $permission = $this->check_update_permission( $post ); } else { $permission = $this->check_read_permission( $post ); } if ( ! $permission ) { continue; } $data = $this->prepare_item_for_response( $post, $request ); $posts[] = $this->prepare_response_for_collection( $data ); } } if ( 'edit' === $request['context'] ) { remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_posts = $posts_query->found_posts; if ( $total_posts < 1 && $page > 1 ) { unset( $query_args['paged'] ); $count_query = new WP_Query(); $query_args['fields'] = 'ids'; $query_args['posts_per_page'] = 1; $query_args['update_post_meta_cache'] = false; $query_args['update_post_term_cache'] = false; $count_query->query( $query_args ); $total_posts = $count_query->found_posts; } $max_pages = (int) ceil( $total_posts / (int) $posts_query->query_vars['posts_per_page'] ); if ( $page > $max_pages && $total_posts > 0 ) { return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $posts ); $response->header( 'X-WP-Total', (int) $total_posts ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( rest_get_route_for_post_type_items( $this->post_type ) ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } protected function get_post( $id ) { $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $post = get_post( (int) $id ); if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { return $error; } return $post; } public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( $post && ! empty( $request->get_query_params()['password'] ) ) { if ( ! hash_equals( $post->post_password, $request->get_query_params()['password'] ) ) { return new WP_Error( 'rest_post_incorrect_password', __( 'Incorrect post password.' ), array( 'status' => 403 ) ); } } if ( 'edit' === $request['context'] ) { add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } if ( $post ) { return $this->check_read_permission( $post ); } return true; } public function can_access_password_content( $post, $request ) { if ( empty( $post->post_password ) ) { return false; } if ( 'edit' === $request['context'] && current_user_can( 'edit_post', $post->ID ) ) { return true; } if ( empty( $request['password'] ) ) { return false; } return hash_equals( $post->post_password, $request['password'] ); } public function get_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $data = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $data ); if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) { $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) ); } return $response; } public function create_item_permissions_check( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $post_type = get_post_type_object( $this->post_type ); if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) { return new WP_Error( 'rest_cannot_edit_others', __( 'Sorry, you are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( $post_type->cap->create_posts ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_assign_terms_permission( $request ) ) { return new WP_Error( 'rest_cannot_assign_term', __( 'Sorry, you are not allowed to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $prepared_post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_post ) ) { return $prepared_post; } $prepared_post->post_type = $this->post_type; if ( ! empty( $prepared_post->post_name ) && ! empty( $prepared_post->post_status ) && in_array( $prepared_post->post_status, array( 'draft', 'pending' ), true ) ) { $prepared_post->post_name = wp_unique_post_slug( $prepared_post->post_name, $prepared_post->id, 'publish', $prepared_post->post_type, $prepared_post->post_parent ); } $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false ); if ( is_wp_error( $post_id ) ) { if ( 'db_insert_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $post = get_post( $post_id ); do_action( "rest_insert_{$this->post_type}", $post, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['sticky'] ) ) { if ( ! empty( $request['sticky'] ) ) { stick_post( $post_id ); } else { unstick_post( $post_id ); } } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $this->handle_featured_media( $request['featured_media'], $post_id ); } if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) { set_post_format( $post, $request['format'] ); } if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) { $this->handle_template( $request['template'], $post_id, true ); } $terms_update = $this->handle_terms( $post_id, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $post_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( "rest_after_insert_{$this->post_type}", $post, $request, true ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( rest_get_route_for_post( $post ) ) ); return $response; } public function update_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $post_type = get_post_type_object( $this->post_type ); if ( $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) { return new WP_Error( 'rest_cannot_edit_others', __( 'Sorry, you are not allowed to update posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_assign_terms_permission( $request ) ) { return new WP_Error( 'rest_cannot_assign_term', __( 'Sorry, you are not allowed to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function update_item( $request ) { $valid_check = $this->get_post( $request['id'] ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } $post_before = get_post( $request['id'] ); $post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $post ) ) { return $post; } if ( ! empty( $post->post_status ) ) { $post_status = $post->post_status; } else { $post_status = $post_before->post_status; } if ( ! empty( $post->post_name ) && in_array( $post_status, array( 'draft', 'pending' ), true ) ) { $post_parent = ! empty( $post->post_parent ) ? $post->post_parent : 0; $post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, 'publish', $post->post_type, $post_parent ); } $post_id = wp_update_post( wp_slash( (array) $post ), true, false ); if ( is_wp_error( $post_id ) ) { if ( 'db_update_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $post = get_post( $post_id ); do_action( "rest_insert_{$this->post_type}", $post, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) { set_post_format( $post, $request['format'] ); } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $this->handle_featured_media( $request['featured_media'], $post_id ); } if ( ! empty( $schema['properties']['sticky'] ) && isset( $request['sticky'] ) ) { if ( ! empty( $request['sticky'] ) ) { stick_post( $post_id ); } else { unstick_post( $post_id ); } } if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) { $this->handle_template( $request['template'], $post->ID ); } $terms_update = $this->handle_terms( $post->ID, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $post->ID ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); if ( 'attachment' === $this->post_type ) { $response = $this->prepare_item_for_response( $post, $request ); return rest_ensure_response( $response ); } do_action( "rest_after_insert_{$this->post_type}", $post, $request, false ); wp_after_insert_post( $post, true, $post_before ); $response = $this->prepare_item_for_response( $post, $request ); return rest_ensure_response( $response ); } public function delete_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( $post && ! $this->check_delete_permission( $post ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $id = $post->ID; $force = (bool) $request['force']; $supports_trash = ( EMPTY_TRASH_DAYS > 0 ); if ( 'attachment' === $post->post_type ) { $supports_trash = $supports_trash && MEDIA_TRASH; } $supports_trash = apply_filters( "rest_{$this->post_type}_trashable", $supports_trash, $post ); if ( ! $this->check_delete_permission( $post ) ) { return new WP_Error( 'rest_user_cannot_delete_post', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); if ( $force ) { $previous = $this->prepare_item_for_response( $post, $request ); $result = wp_delete_post( $id, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { if ( ! $supports_trash ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "The post does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $post->post_status ) { return new WP_Error( 'rest_already_trashed', __( 'The post has already been deleted.' ), array( 'status' => 410 ) ); } $result = wp_trash_post( $id ); $post = get_post( $id ); $response = $this->prepare_item_for_response( $post, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } do_action( "rest_delete_{$this->post_type}", $post, $response, $request ); return $response; } protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = array(); foreach ( $prepared_args as $key => $value ) { $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); } if ( 'post' !== $this->post_type || ! isset( $query_args['ignore_sticky_posts'] ) ) { $query_args['ignore_sticky_posts'] = true; } if ( isset( $query_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } return $query_args; } protected function prepare_date_response( $date_gmt, $date = null ) { if ( isset( $date ) ) { return mysql_to_rfc3339( $date ); } if ( '0000-00-00 00:00:00' === $date_gmt ) { return null; } return mysql_to_rfc3339( $date_gmt ); } protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); $current_status = ''; if ( isset( $request['id'] ) ) { $existing_post = $this->get_post( $request['id'] ); if ( is_wp_error( $existing_post ) ) { return $existing_post; } $prepared_post->ID = $existing_post->ID; $current_status = $existing_post->post_status; } $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $prepared_post->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $prepared_post->post_title = $request['title']['raw']; } } if ( ! empty( $schema['properties']['content'] ) && isset( $request['content'] ) ) { if ( is_string( $request['content'] ) ) { $prepared_post->post_content = $request['content']; } elseif ( isset( $request['content']['raw'] ) ) { $prepared_post->post_content = $request['content']['raw']; } } if ( ! empty( $schema['properties']['excerpt'] ) && isset( $request['excerpt'] ) ) { if ( is_string( $request['excerpt'] ) ) { $prepared_post->post_excerpt = $request['excerpt']; } elseif ( isset( $request['excerpt']['raw'] ) ) { $prepared_post->post_excerpt = $request['excerpt']['raw']; } } if ( empty( $request['id'] ) ) { $prepared_post->post_type = $this->post_type; } else { $prepared_post->post_type = get_post_type( $request['id'] ); } $post_type = get_post_type_object( $prepared_post->post_type ); if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) && ( ! $current_status || $current_status !== $request['status'] ) ) { $status = $this->handle_status_param( $request['status'], $post_type ); if ( is_wp_error( $status ) ) { return $status; } $prepared_post->post_status = $status; } if ( ! empty( $schema['properties']['date'] ) && ! empty( $request['date'] ) ) { $current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date : false; $date_data = rest_get_date_with_gmt( $request['date'] ); if ( ! empty( $date_data ) && $current_date !== $date_data[0] ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; $prepared_post->edit_date = true; } } elseif ( ! empty( $schema['properties']['date_gmt'] ) && ! empty( $request['date_gmt'] ) ) { $current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date_gmt : false; $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) && $current_date !== $date_data[1] ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; $prepared_post->edit_date = true; } } if ( ( ! empty( $schema['properties']['date_gmt'] ) && $request->has_param( 'date_gmt' ) && null === $request['date_gmt'] ) || ( ! empty( $schema['properties']['date'] ) && $request->has_param( 'date' ) && null === $request['date'] ) ) { $prepared_post->post_date_gmt = null; $prepared_post->post_date = null; } if ( ! empty( $schema['properties']['slug'] ) && isset( $request['slug'] ) ) { $prepared_post->post_name = $request['slug']; } if ( ! empty( $schema['properties']['author'] ) && ! empty( $request['author'] ) ) { $post_author = (int) $request['author']; if ( get_current_user_id() !== $post_author ) { $user_obj = get_userdata( $post_author ); if ( ! $user_obj ) { return new WP_Error( 'rest_invalid_author', __( 'Invalid author ID.' ), array( 'status' => 400 ) ); } } $prepared_post->post_author = $post_author; } if ( ! empty( $schema['properties']['password'] ) && isset( $request['password'] ) ) { $prepared_post->post_password = $request['password']; if ( '' !== $request['password'] ) { if ( ! empty( $schema['properties']['sticky'] ) && ! empty( $request['sticky'] ) ) { return new WP_Error( 'rest_invalid_field', __( 'A post can not be sticky and have a password.' ), array( 'status' => 400 ) ); } if ( ! empty( $prepared_post->ID ) && is_sticky( $prepared_post->ID ) ) { return new WP_Error( 'rest_invalid_field', __( 'A sticky post can not be password protected.' ), array( 'status' => 400 ) ); } } } if ( ! empty( $schema['properties']['sticky'] ) && ! empty( $request['sticky'] ) ) { if ( ! empty( $prepared_post->ID ) && post_password_required( $prepared_post->ID ) ) { return new WP_Error( 'rest_invalid_field', __( 'A password protected post can not be set to sticky.' ), array( 'status' => 400 ) ); } } if ( ! empty( $schema['properties']['parent'] ) && isset( $request['parent'] ) ) { if ( 0 === (int) $request['parent'] ) { $prepared_post->post_parent = 0; } else { $parent = get_post( (int) $request['parent'] ); if ( empty( $parent ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post parent ID.' ), array( 'status' => 400 ) ); } $prepared_post->post_parent = (int) $parent->ID; } } if ( ! empty( $schema['properties']['menu_order'] ) && isset( $request['menu_order'] ) ) { $prepared_post->menu_order = (int) $request['menu_order']; } if ( ! empty( $schema['properties']['comment_status'] ) && ! empty( $request['comment_status'] ) ) { $prepared_post->comment_status = $request['comment_status']; } if ( ! empty( $schema['properties']['ping_status'] ) && ! empty( $request['ping_status'] ) ) { $prepared_post->ping_status = $request['ping_status']; } if ( ! empty( $schema['properties']['template'] ) ) { $prepared_post->page_template = null; } return apply_filters( "rest_pre_insert_{$this->post_type}", $prepared_post, $request ); } public function check_status( $status, $request, $param ) { if ( $request['id'] ) { $post = $this->get_post( $request['id'] ); if ( ! is_wp_error( $post ) && $post->post_status === $status ) { return true; } } $args = $request->get_attributes()['args'][ $param ]; return rest_validate_value_from_schema( $status, $args, $param ); } protected function handle_status_param( $post_status, $post_type ) { switch ( $post_status ) { case 'draft': case 'pending': break; case 'private': if ( ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create private posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } break; case 'publish': case 'future': if ( ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to publish posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } break; default: if ( ! get_post_status_object( $post_status ) ) { $post_status = 'draft'; } break; } return $post_status; } protected function handle_featured_media( $featured_media, $post_id ) { $featured_media = (int) $featured_media; if ( $featured_media ) { $result = set_post_thumbnail( $post_id, $featured_media ); if ( $result ) { return true; } else { return new WP_Error( 'rest_invalid_featured_media', __( 'Invalid featured media ID.' ), array( 'status' => 400 ) ); } } else { return delete_post_thumbnail( $post_id ); } } public function check_template( $template, $request ) { if ( ! $template ) { return true; } if ( $request['id'] ) { $post = get_post( $request['id'] ); $current_template = get_page_template_slug( $request['id'] ); } else { $post = null; $current_template = ''; } if ( $template === $current_template ) { return true; } $allowed_templates = wp_get_theme()->get_page_templates( $post, $this->post_type ); if ( isset( $allowed_templates[ $template ] ) ) { return true; } return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), 'template', implode( ', ', array_keys( $allowed_templates ) ) ) ); } public function handle_template( $template, $post_id, $validate = false ) { if ( $validate && ! array_key_exists( $template, wp_get_theme()->get_page_templates( get_post( $post_id ) ) ) ) { $template = ''; } update_post_meta( $post_id, '_wp_page_template', $template ); } protected function handle_terms( $post_id, $request ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( ! isset( $request[ $base ] ) ) { continue; } $result = wp_set_object_terms( $post_id, $request[ $base ], $taxonomy->name ); if ( is_wp_error( $result ) ) { return $result; } } return null; } protected function check_assign_terms_permission( $request ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( ! isset( $request[ $base ] ) ) { continue; } foreach ( (array) $request[ $base ] as $term_id ) { if ( ! get_term( $term_id, $taxonomy->name ) ) { continue; } if ( ! current_user_can( 'assign_term', (int) $term_id ) ) { return false; } } } return true; } protected function check_is_post_type_allowed( $post_type ) { if ( ! is_object( $post_type ) ) { $post_type = get_post_type_object( $post_type ); } if ( ! empty( $post_type ) && ! empty( $post_type->show_in_rest ) ) { return true; } return false; } public function check_read_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } if ( 'publish' === $post->post_status || current_user_can( 'read_post', $post->ID ) ) { return true; } $post_status_obj = get_post_status_object( $post->post_status ); if ( $post_status_obj && $post_status_obj->public ) { return true; } if ( 'inherit' === $post->post_status && $post->post_parent > 0 ) { $parent = get_post( $post->post_parent ); if ( $parent ) { return $this->check_read_permission( $parent ); } } if ( 'inherit' === $post->post_status ) { return true; } return false; } protected function check_update_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( 'edit_post', $post->ID ); } protected function check_create_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( $post_type->cap->create_posts ); } protected function check_delete_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( 'delete_post', $post->ID ); } public function prepare_item_for_response( $item, $request ) { $post = $item; $GLOBALS['post'] = $post; setup_postdata( $post ); if ( $request->is_method( 'HEAD' ) ) { return apply_filters( "rest_prepare_{$this->post_type}", new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $post->ID; } if ( rest_is_field_included( 'date', $fields ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( rest_is_field_included( 'date_gmt', $fields ) ) { if ( '0000-00-00 00:00:00' === $post->post_date_gmt ) { $post_date_gmt = get_gmt_from_date( $post->post_date ); } else { $post_date_gmt = $post->post_date_gmt; } $data['date_gmt'] = $this->prepare_date_response( $post_date_gmt ); } if ( rest_is_field_included( 'guid', $fields ) ) { $data['guid'] = array( 'rendered' => apply_filters( 'get_the_guid', $post->guid, $post->ID ), 'raw' => $post->guid, ); } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( rest_is_field_included( 'modified_gmt', $fields ) ) { if ( '0000-00-00 00:00:00' === $post->post_modified_gmt ) { $post_modified_gmt = gmdate( 'Y-m-d H:i:s', strtotime( $post->post_modified ) - (int) ( (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ); } else { $post_modified_gmt = $post->post_modified_gmt; } $data['modified_gmt'] = $this->prepare_date_response( $post_modified_gmt ); } if ( rest_is_field_included( 'password', $fields ) ) { $data['password'] = $post->post_password; } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $post->post_name; } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $post->post_status; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $post->post_type; } if ( rest_is_field_included( 'link', $fields ) ) { $data['link'] = get_permalink( $post->ID ); } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $post->post_title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data['title']['rendered'] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } $has_password_filter = false; if ( $this->can_access_password_content( $post, $request ) ) { $this->password_check_passed[ $post->ID ] = true; add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); $has_password_filter = true; } if ( rest_is_field_included( 'content', $fields ) ) { $data['content'] = array(); } if ( rest_is_field_included( 'content.raw', $fields ) ) { $data['content']['raw'] = $post->post_content; } if ( rest_is_field_included( 'content.rendered', $fields ) ) { $data['content']['rendered'] = post_password_required( $post ) ? '' : apply_filters( 'the_content', $post->post_content ); } if ( rest_is_field_included( 'content.protected', $fields ) ) { $data['content']['protected'] = (bool) $post->post_password; } if ( rest_is_field_included( 'content.block_version', $fields ) ) { $data['content']['block_version'] = block_version( $post->post_content ); } if ( rest_is_field_included( 'excerpt', $fields ) ) { if ( isset( $request['excerpt_length'] ) ) { $excerpt_length = $request['excerpt_length']; $override_excerpt_length = static function () use ( $excerpt_length ) { return $excerpt_length; }; add_filter( 'excerpt_length', $override_excerpt_length, 20 ); } $excerpt = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); $excerpt = apply_filters( 'the_excerpt', $excerpt ); $data['excerpt'] = array( 'raw' => $post->post_excerpt, 'rendered' => post_password_required( $post ) ? '' : $excerpt, 'protected' => (bool) $post->post_password, ); if ( isset( $override_excerpt_length ) ) { remove_filter( 'excerpt_length', $override_excerpt_length, 20 ); } } if ( $has_password_filter ) { remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $post->post_author; } if ( rest_is_field_included( 'featured_media', $fields ) ) { $data['featured_media'] = (int) get_post_thumbnail_id( $post->ID ); } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = (int) $post->post_parent; } if ( rest_is_field_included( 'menu_order', $fields ) ) { $data['menu_order'] = (int) $post->menu_order; } if ( rest_is_field_included( 'comment_status', $fields ) ) { $data['comment_status'] = $post->comment_status; } if ( rest_is_field_included( 'ping_status', $fields ) ) { $data['ping_status'] = $post->ping_status; } if ( rest_is_field_included( 'sticky', $fields ) ) { $data['sticky'] = is_sticky( $post->ID ); } if ( rest_is_field_included( 'template', $fields ) ) { $template = get_page_template_slug( $post->ID ); if ( $template ) { $data['template'] = $template; } else { $data['template'] = ''; } } if ( rest_is_field_included( 'format', $fields ) ) { $data['format'] = get_post_format( $post->ID ); if ( empty( $data['format'] ) ) { $data['format'] = 'standard'; } } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $post->ID, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( rest_is_field_included( $base, $fields ) ) { $terms = get_the_terms( $post, $taxonomy->name ); $data[ $base ] = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); } } $post_type_obj = get_post_type_object( $post->post_type ); if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { $permalink_template_requested = rest_is_field_included( 'permalink_template', $fields ); $generated_slug_requested = rest_is_field_included( 'generated_slug', $fields ); if ( $permalink_template_requested || $generated_slug_requested ) { if ( ! function_exists( 'get_sample_permalink' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; } $sample_permalink = get_sample_permalink( $post->ID, $post->post_title, '' ); if ( $permalink_template_requested ) { $data['permalink_template'] = $sample_permalink[0]; } if ( $generated_slug_requested ) { $data['generated_slug'] = $sample_permalink[1]; } } if ( rest_is_field_included( 'class_list', $fields ) ) { $data['class_list'] = get_post_class( array(), $post->ID ); } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $post ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $post, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); } public function protected_title_format() { return '%s'; } protected function prepare_links( $post ) { $links = array( 'self' => array( 'href' => rest_url( rest_get_route_for_post( $post->ID ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $this->post_type ) ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'author' ) ) && ! empty( $post->post_author ) ) { $links['author'] = array( 'href' => rest_url( 'wp/v2/users/' . $post->post_author ), 'embeddable' => true, ); } if ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'comments' ) ) { $replies_url = rest_url( 'wp/v2/comments' ); $replies_url = add_query_arg( 'post', $post->ID, $replies_url ); $links['replies'] = array( 'href' => $replies_url, 'embeddable' => true, ); } if ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'revisions' ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $post->ID ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%s/%d/revisions', $this->namespace, $this->rest_base, $post->ID ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); if ( $revisions_count > 0 ) { $links['predecessor-version'] = array( 'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ), 'id' => $revisions['latest_id'], ); } } $post_type_obj = get_post_type_object( $post->post_type ); if ( $post_type_obj->hierarchical && ! empty( $post->post_parent ) ) { $links['up'] = array( 'href' => rest_url( rest_get_route_for_post( $post->post_parent ) ), 'embeddable' => true, ); } $featured_media = get_post_thumbnail_id( $post->ID ); if ( $featured_media ) { $image_url = rest_url( rest_get_route_for_post( $featured_media ) ); $links['https://api.w.org/featuredmedia'] = array( 'href' => $image_url, 'embeddable' => true, ); } if ( ! in_array( $post->post_type, array( 'attachment', 'nav_menu_item', 'revision' ), true ) ) { $attachments_url = rest_url( rest_get_route_for_post_type_items( 'attachment' ) ); $attachments_url = add_query_arg( 'parent', $post->ID, $attachments_url ); $links['https://api.w.org/attachment'] = array( 'href' => $attachments_url, ); } $taxonomies = get_object_taxonomies( $post->post_type ); if ( ! empty( $taxonomies ) ) { $links['https://api.w.org/term'] = array(); foreach ( $taxonomies as $tax ) { $taxonomy_route = rest_get_route_for_taxonomy_items( $tax ); if ( empty( $taxonomy_route ) ) { continue; } $terms_url = add_query_arg( 'post', $post->ID, rest_url( $taxonomy_route ) ); $links['https://api.w.org/term'][] = array( 'href' => $terms_url, 'taxonomy' => $tax, 'embeddable' => true, ); } } return $links; } protected function get_available_actions( $post, $request ) { if ( 'edit' !== $request['context'] ) { return array(); } $rels = array(); $post_type = get_post_type_object( $post->post_type ); if ( 'attachment' !== $this->post_type && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'unfiltered_html' ) ) { $rels[] = 'https://api.w.org/action-unfiltered-html'; } if ( 'post' === $post_type->name ) { if ( current_user_can( $post_type->cap->edit_others_posts ) && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-sticky'; } } if ( post_type_supports( $post_type->name, 'author' ) ) { if ( current_user_can( $post_type->cap->edit_others_posts ) ) { $rels[] = 'https://api.w.org/action-assign-author'; } } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $tax ) { $tax_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name; $create_cap = is_taxonomy_hierarchical( $tax->name ) ? $tax->cap->edit_terms : $tax->cap->assign_terms; if ( current_user_can( $create_cap ) ) { $rels[] = 'https://api.w.org/action-create-' . $tax_base; } if ( current_user_can( $tax->cap->assign_terms ) ) { $rels[] = 'https://api.w.org/action-assign-' . $tax_base; } } return $rels; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'date' => array( 'description' => __( "The date the post was published, in the site's timezone." ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the post was published, as GMT.' ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'guid' => array( 'description' => __( 'The globally unique identifier for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'GUID for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'rendered' => array( 'description' => __( 'GUID for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ), 'id' => array( 'description' => __( 'Unique identifier for the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'link' => array( 'description' => __( 'URL to the post.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'modified' => array( 'description' => __( "The date the post was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'modified_gmt' => array( 'description' => __( 'The date the post was last modified, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the post unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'status' => array( 'description' => __( 'A named status for the post.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => array( $this, 'check_status' ), ), ), 'type' => array( 'description' => __( 'Type of post.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'password' => array( 'description' => __( 'A password to protect access to the content and excerpt.' ), 'type' => 'string', 'context' => array( 'edit' ), ), ), ); $post_type_obj = get_post_type_object( $this->post_type ); if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { $schema['properties']['permalink_template'] = array( 'description' => __( 'Permalink template for the post.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ); $schema['properties']['generated_slug'] = array( 'description' => __( 'Slug automatically generated from the post title.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ); $schema['properties']['class_list'] = array( 'description' => __( 'An array of the class names for the post container element.' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'items' => array( 'type' => 'string', ), ); } if ( $post_type_obj->hierarchical ) { $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); } $post_type_attributes = array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'page-attributes', 'post-formats', 'custom-fields', ); $fixed_schemas = array( 'post' => array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'post-formats', 'custom-fields', ), 'page' => array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'page-attributes', 'custom-fields', ), 'attachment' => array( 'title', 'author', 'comments', 'revisions', 'custom-fields', 'thumbnail', ), ); foreach ( $post_type_attributes as $attribute ) { if ( isset( $fixed_schemas[ $this->post_type ] ) && ! in_array( $attribute, $fixed_schemas[ $this->post_type ], true ) ) { continue; } elseif ( ! isset( $fixed_schemas[ $this->post_type ] ) && ! post_type_supports( $this->post_type, $attribute ) ) { continue; } switch ( $attribute ) { case 'title': $schema['properties']['title'] = array( 'description' => __( 'The title for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML title for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'editor': $schema['properties']['content'] = array( 'description' => __( 'The content for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML content for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'block_version' => array( 'description' => __( 'Version of the content block format used by the post.' ), 'type' => 'integer', 'context' => array( 'edit' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether the content is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'author': $schema['properties']['author'] = array( 'description' => __( 'The ID for the author of the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); break; case 'excerpt': $schema['properties']['excerpt'] = array( 'description' => __( 'The excerpt for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Excerpt for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML excerpt for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether the excerpt is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'thumbnail': $schema['properties']['featured_media'] = array( 'description' => __( 'The ID of the featured media for the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); break; case 'comments': $schema['properties']['comment_status'] = array( 'description' => __( 'Whether or not comments are open on the post.' ), 'type' => 'string', 'enum' => array( 'open', 'closed' ), 'context' => array( 'view', 'edit' ), ); $schema['properties']['ping_status'] = array( 'description' => __( 'Whether or not the post can be pinged.' ), 'type' => 'string', 'enum' => array( 'open', 'closed' ), 'context' => array( 'view', 'edit' ), ); break; case 'page-attributes': $schema['properties']['menu_order'] = array( 'description' => __( 'The order of the post in relation to other posts.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); break; case 'post-formats': $formats = array_values( get_post_format_slugs() ); $schema['properties']['format'] = array( 'description' => __( 'The format for the post.' ), 'type' => 'string', 'enum' => $formats, 'context' => array( 'view', 'edit' ), ); break; case 'custom-fields': $schema['properties']['meta'] = $this->meta->get_field_schema(); break; } } if ( 'post' === $this->post_type ) { $schema['properties']['sticky'] = array( 'description' => __( 'Whether or not the post should be treated as sticky.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ); } $schema['properties']['template'] = array( 'description' => __( 'The theme file to use to display the post.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => array( $this, 'check_template' ), ), ); $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( array_key_exists( $base, $schema['properties'] ) ) { $taxonomy_field_name_with_conflict = ! empty( $taxonomy->rest_base ) ? 'rest_base' : 'name'; _doing_it_wrong( 'register_taxonomy', sprintf( __( 'The "%1$s" taxonomy "%2$s" property (%3$s) conflicts with an existing property on the REST API Posts Controller. Specify a custom "rest_base" when registering the taxonomy to avoid this error.' ), $taxonomy->name, $taxonomy_field_name_with_conflict, $base ), '5.4.0' ); } $schema['properties'][ $base ] = array( 'description' => sprintf( __( 'The terms assigned to the post in the %s taxonomy.' ), $taxonomy->name ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ); } $schema_links = $this->get_schema_links(); if ( $schema_links ) { $schema['links'] = $schema_links; } $schema_fields = array_keys( $schema['properties'] ); $schema = apply_filters( "rest_{$this->post_type}_item_schema", $schema ); $new_fields = array_diff( array_keys( $schema['properties'] ), $schema_fields ); if ( count( $new_fields ) > 0 ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Please use %s to add new schema properties.' ), 'register_rest_field' ), '5.4.0' ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } protected function get_schema_links() { $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" ); $links = array(); if ( 'attachment' !== $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-publish', 'title' => __( 'The current user can publish this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'status' => array( 'type' => 'string', 'enum' => array( 'publish', 'future' ), ), ), ), ); } $links[] = array( 'rel' => 'https://api.w.org/action-unfiltered-html', 'title' => __( 'The current user can post unfiltered HTML markup and JavaScript.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'content' => array( 'raw' => array( 'type' => 'string', ), ), ), ), ); if ( 'post' === $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-sticky', 'title' => __( 'The current user can sticky this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'sticky' => array( 'type' => 'boolean', ), ), ), ); } if ( post_type_supports( $this->post_type, 'author' ) ) { $links[] = array( 'rel' => 'https://api.w.org/action-assign-author', 'title' => __( 'The current user can change the author on this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'author' => array( 'type' => 'integer', ), ), ), ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $tax ) { $tax_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name; $assign_title = sprintf( __( 'The current user can assign terms in the %s taxonomy.' ), $tax->name ); $create_title = sprintf( __( 'The current user can create terms in the %s taxonomy.' ), $tax->name ); $links[] = array( 'rel' => 'https://api.w.org/action-assign-' . $tax_base, 'title' => $assign_title, 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( $tax_base => array( 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), ), ), ); $links[] = array( 'rel' => 'https://api.w.org/action-create-' . $tax_base, 'title' => $create_title, 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( $tax_base => array( 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), ), ), ); } return $links; } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['after'] = array( 'description' => __( 'Limit response to posts published after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['modified_after'] = array( 'description' => __( 'Limit response to posts modified after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); if ( post_type_supports( $this->post_type, 'author' ) ) { $query_params['author'] = array( 'description' => __( 'Limit result set to posts assigned to specific authors.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['author_exclude'] = array( 'description' => __( 'Ensure result set excludes posts assigned to specific authors.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); } $query_params['before'] = array( 'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['modified_before'] = array( 'description' => __( 'Limit response to posts modified before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) { $query_params['menu_order'] = array( 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), 'type' => 'integer', ); } $query_params['search_semantics'] = array( 'description' => __( 'How to interpret the search input.' ), 'type' => 'string', 'enum' => array( 'exact' ), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by post attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', ), ); if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) { $query_params['orderby']['enum'][] = 'menu_order'; } $post_type = get_post_type_object( $this->post_type ); if ( $post_type->hierarchical || 'attachment' === $this->post_type ) { $query_params['parent'] = array( 'description' => __( 'Limit result set to items with particular parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['parent_exclude'] = array( 'description' => __( 'Limit result set to all items except those of a particular parent ID.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); } $query_params['search_columns'] = array( 'default' => array(), 'description' => __( 'Array of column names to be searched.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'post_title', 'post_content', 'post_excerpt' ), 'type' => 'string', ), ); $query_params['slug'] = array( 'description' => __( 'Limit result set to posts with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['status'] = array( 'default' => 'publish', 'description' => __( 'Limit result set to posts assigned one or more statuses.' ), 'type' => 'array', 'items' => array( 'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ), 'type' => 'string', ), 'sanitize_callback' => array( $this, 'sanitize_post_statuses' ), ); $query_params = $this->prepare_taxonomy_limit_schema( $query_params ); if ( 'post' === $this->post_type ) { $query_params['sticky'] = array( 'description' => __( 'Limit result set to items that are sticky.' ), 'type' => 'boolean', ); $query_params['ignore_sticky'] = array( 'description' => __( 'Whether to ignore sticky posts or not.' ), 'type' => 'boolean', 'default' => true, ); } if ( post_type_supports( $this->post_type, 'post-formats' ) ) { $query_params['format'] = array( 'description' => __( 'Limit result set to items assigned one or more given formats.' ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'enum' => array_values( get_post_format_slugs() ), 'type' => 'string', ), ); } return apply_filters( "rest_{$this->post_type}_collection_params", $query_params, $post_type ); } public function sanitize_post_statuses( $statuses, $request, $parameter ) { $statuses = wp_parse_slug_list( $statuses ); $attributes = $request->get_attributes(); $default_status = $attributes['args']['status']['default']; foreach ( $statuses as $status ) { if ( $status === $default_status ) { continue; } $post_type_obj = get_post_type_object( $this->post_type ); if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { $result = rest_validate_request_arg( $status, $request, $parameter ); if ( is_wp_error( $result ) ) { return $result; } } else { return new WP_Error( 'rest_forbidden_status', __( 'Status is forbidden.' ), array( 'status' => rest_authorization_required_code() ) ); } } return $statuses; } private function prepare_tax_query( array $args, WP_REST_Request $request ) { $relation = $request['tax_relation']; if ( $relation ) { $args['tax_query'] = array( 'relation' => $relation ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $tax_include = $request[ $base ]; $tax_exclude = $request[ $base . '_exclude' ]; if ( $tax_include ) { $terms = array(); $include_children = false; $operator = 'IN'; if ( rest_is_array( $tax_include ) ) { $terms = $tax_include; } elseif ( rest_is_object( $tax_include ) ) { $terms = empty( $tax_include['terms'] ) ? array() : $tax_include['terms']; $include_children = ! empty( $tax_include['include_children'] ); if ( isset( $tax_include['operator'] ) && 'AND' === $tax_include['operator'] ) { $operator = 'AND'; } } if ( $terms ) { $args['tax_query'][] = array( 'taxonomy' => $taxonomy->name, 'field' => 'term_id', 'terms' => $terms, 'include_children' => $include_children, 'operator' => $operator, ); } } if ( $tax_exclude ) { $terms = array(); $include_children = false; if ( rest_is_array( $tax_exclude ) ) { $terms = $tax_exclude; } elseif ( rest_is_object( $tax_exclude ) ) { $terms = empty( $tax_exclude['terms'] ) ? array() : $tax_exclude['terms']; $include_children = ! empty( $tax_exclude['include_children'] ); } if ( $terms ) { $args['tax_query'][] = array( 'taxonomy' => $taxonomy->name, 'field' => 'term_id', 'terms' => $terms, 'include_children' => $include_children, 'operator' => 'NOT IN', ); } } } return $args; } private function prepare_taxonomy_limit_schema( array $query_params ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); if ( ! $taxonomies ) { return $query_params; } $query_params['tax_relation'] = array( 'description' => __( 'Limit result set based on relationship between multiple taxonomies.' ), 'type' => 'string', 'enum' => array( 'AND', 'OR' ), ); $limit_schema = array( 'type' => array( 'object', 'array' ), 'oneOf' => array( array( 'title' => __( 'Term ID List' ), 'description' => __( 'Match terms with the listed IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), array( 'title' => __( 'Term ID Taxonomy Query' ), 'description' => __( 'Perform an advanced term query.' ), 'type' => 'object', 'properties' => array( 'terms' => array( 'description' => __( 'Term IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ), 'include_children' => array( 'description' => __( 'Whether to include child terms in the terms limiting the result set.' ), 'type' => 'boolean', 'default' => false, ), ), 'additionalProperties' => false, ), ), ); $include_schema = array_merge( array( 'description' => __( 'Limit result set to items with specific terms assigned in the %s taxonomy.' ), ), $limit_schema ); $include_schema['oneOf'][1]['properties']['operator'] = array( 'description' => __( 'Whether items must be assigned all or any of the specified terms.' ), 'type' => 'string', 'enum' => array( 'AND', 'OR' ), 'default' => 'OR', ); $exclude_schema = array_merge( array( 'description' => __( 'Limit result set to items except those with specific terms assigned in the %s taxonomy.' ), ), $limit_schema ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $base_exclude = $base . '_exclude'; $query_params[ $base ] = $include_schema; $query_params[ $base ]['description'] = sprintf( $query_params[ $base ]['description'], $base ); $query_params[ $base_exclude ] = $exclude_schema; $query_params[ $base_exclude ]['description'] = sprintf( $query_params[ $base_exclude ]['description'], $base ); if ( ! $taxonomy->hierarchical ) { unset( $query_params[ $base ]['oneOf'][1]['properties']['include_children'] ); unset( $query_params[ $base_exclude ]['oneOf'][1]['properties']['include_children'] ); } } return $query_params; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-attachments-controller.php';
class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { protected $allow_batch = false; public function register_routes() { parent::register_routes(); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/post-process', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'post_process_item' ), 'permission_callback' => array( $this, 'post_process_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the attachment.' ), 'type' => 'integer', ), 'action' => array( 'type' => 'string', 'enum' => array( 'create-image-subsizes' ), 'required' => true, ), ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/edit', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'edit_media_item' ), 'permission_callback' => array( $this, 'edit_media_item_permissions_check' ), 'args' => $this->get_edit_media_item_args(), ) ); } protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = parent::prepare_items_query( $prepared_args, $request ); if ( empty( $query_args['post_status'] ) ) { $query_args['post_status'] = 'inherit'; } $all_mime_types = array(); $media_types = $this->get_media_types(); if ( ! empty( $request['media_type'] ) && is_array( $request['media_type'] ) ) { foreach ( $request['media_type'] as $type ) { if ( isset( $media_types[ $type ] ) ) { $all_mime_types = array_merge( $all_mime_types, $media_types[ $type ] ); } } } if ( ! empty( $request['mime_type'] ) && is_array( $request['mime_type'] ) ) { foreach ( $request['mime_type'] as $mime_type ) { $parts = explode( '/', $mime_type ); if ( isset( $media_types[ $parts[0] ] ) && in_array( $mime_type, $media_types[ $parts[0] ], true ) ) { $all_mime_types[] = $mime_type; } } } if ( ! empty( $all_mime_types ) ) { $query_args['post_mime_type'] = array_values( array_unique( $all_mime_types ) ); } if ( isset( $query_args['s'] ) ) { add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' ); } return $query_args; } public function create_item_permissions_check( $request ) { $ret = parent::create_item_permissions_check( $request ); if ( ! $ret || is_wp_error( $ret ) ) { return $ret; } if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['post'] ) && ! current_user_can( 'edit_post', (int) $request['post'] ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $files = $request->get_file_params(); $prevent_unsupported_uploads = apply_filters( 'wp_prevent_unsupported_mime_type_uploads', true, isset( $files['file']['type'] ) ? $files['file']['type'] : null ); if ( $prevent_unsupported_uploads && isset( $files['file']['type'] ) && str_starts_with( $files['file']['type'], 'image/' ) ) { $editor_non_resizable_formats = array( 'image/svg+xml', ); if ( ! in_array( $files['file']['type'], $editor_non_resizable_formats, true ) && ! wp_image_editor_supports( array( 'mime_type' => $files['file']['type'] ) ) ) { return new WP_Error( 'rest_upload_image_type_not_supported', __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), array( 'status' => 400 ) ); } } return true; } public function create_item( $request ) { if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) { return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) ); } $insert = $this->insert_attachment( $request ); if ( is_wp_error( $insert ) ) { return $insert; } $schema = $this->get_item_schema(); $attachment_id = $insert['attachment_id']; $file = $insert['file']; if ( isset( $request['alt_text'] ) ) { update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) ); } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $thumbnail_update = $this->handle_featured_media( $request['featured_media'], $attachment_id ); if ( is_wp_error( $thumbnail_update ) ) { return $thumbnail_update; } } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $attachment_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $attachment = get_post( $attachment_id ); $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $terms_update = $this->handle_terms( $attachment_id, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_attachment', $attachment, $request, true ); wp_after_insert_post( $attachment, false, null ); if ( wp_is_serving_rest_request() ) { header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id ); } require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); $response = $this->prepare_item_for_response( $attachment, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $attachment_id ) ) ); return $response; } protected function insert_attachment( $request ) { $files = $request->get_file_params(); $headers = $request->get_headers(); $time = null; if ( ! empty( $request['post'] ) ) { $post = get_post( $request['post'] ); if ( $post && 'page' !== $post->post_type && substr( $post->post_date, 0, 4 ) > 0 ) { $time = $post->post_date; } } if ( ! empty( $files ) ) { $file = $this->upload_from_file( $files, $headers, $time ); } else { $file = $this->upload_from_data( $request->get_body(), $headers, $time ); } if ( is_wp_error( $file ) ) { return $file; } $name = wp_basename( $file['file'] ); $name_parts = pathinfo( $name ); $name = trim( substr( $name, 0, -( 1 + strlen( $name_parts['extension'] ) ) ) ); $url = $file['url']; $type = $file['type']; $file = $file['file']; require_once ABSPATH . 'wp-admin/includes/image.php'; $image_meta = wp_read_image_metadata( $file ); if ( ! empty( $image_meta ) ) { if ( empty( $request['title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { $request['title'] = $image_meta['title']; } if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) { $request['caption'] = $image_meta['caption']; } } $attachment = $this->prepare_item_for_database( $request ); $attachment->post_mime_type = $type; $attachment->guid = $url; if ( empty( $attachment->post_title ) && ! empty( $files['file']['name'] ) ) { $tmp_title = substr( $files['file']['name'], 0, strrpos( $files['file']['name'], '.' ) ); if ( ! empty( $tmp_title ) ) { $attachment->post_title = $tmp_title; } } if ( empty( $attachment->post_title ) ) { $attachment->post_title = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) ); } $id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true, false ); if ( is_wp_error( $id ) ) { if ( 'db_update_error' === $id->get_error_code() ) { $id->add_data( array( 'status' => 500 ) ); } else { $id->add_data( array( 'status' => 400 ) ); } return $id; } $attachment = get_post( $id ); do_action( 'rest_insert_attachment', $attachment, $request, true ); return array( 'attachment_id' => $id, 'file' => $file, ); } protected function handle_featured_media( $featured_media, $post_id ) { $post_type = get_post_type( $post_id ); $thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ); if ( ! $thumbnail_support && get_post_mime_type( $post_id ) ) { if ( wp_attachment_is( 'audio', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ); } elseif ( wp_attachment_is( 'video', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ); } } if ( $thumbnail_support ) { return parent::handle_featured_media( $featured_media, $post_id ); } return new WP_Error( 'rest_no_featured_media', sprintf( __( 'This site does not support post thumbnails on attachments with MIME type %s.' ), get_post_mime_type( $post_id ) ), array( 'status' => 400 ) ); } public function update_item( $request ) { if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) { return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) ); } $attachment_before = get_post( $request['id'] ); $response = parent::update_item( $request ); if ( is_wp_error( $response ) ) { return $response; } $response = rest_ensure_response( $response ); $data = $response->get_data(); if ( isset( $request['alt_text'] ) ) { update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] ); } $attachment = get_post( $request['id'] ); if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $thumbnail_update = $this->handle_featured_media( $request['featured_media'], $attachment->ID ); if ( is_wp_error( $thumbnail_update ) ) { return $thumbnail_update; } } $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_attachment', $attachment, $request, false ); wp_after_insert_post( $attachment, true, $attachment_before ); $response = $this->prepare_item_for_response( $attachment, $request ); $response = rest_ensure_response( $response ); return $response; } public function post_process_item( $request ) { switch ( $request['action'] ) { case 'create-image-subsizes': require_once ABSPATH . 'wp-admin/includes/image.php'; wp_update_image_subsizes( $request['id'] ); break; } $request['context'] = 'edit'; return $this->prepare_item_for_response( get_post( $request['id'] ), $request ); } public function post_process_item_permissions_check( $request ) { return $this->update_item_permissions_check( $request ); } public function edit_media_item_permissions_check( $request ) { if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( 'rest_cannot_edit_image', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return $this->update_item_permissions_check( $request ); } public function edit_media_item( $request ) { require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_id = $request['id']; $image_file = wp_get_original_image_path( $attachment_id ); $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( ! $image_meta || ! $image_file || ! wp_image_file_matches_image_meta( $request['src'], $image_meta, $attachment_id ) ) { return new WP_Error( 'rest_unknown_attachment', __( 'Unable to get meta information for file.' ), array( 'status' => 404 ) ); } $supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/heic' ); $mime_type = get_post_mime_type( $attachment_id ); if ( ! in_array( $mime_type, $supported_types, true ) ) { return new WP_Error( 'rest_cannot_edit_file_type', __( 'This type of file cannot be edited.' ), array( 'status' => 400 ) ); } if ( isset( $request['modifiers'] ) ) { $modifiers = $request['modifiers']; } else { $modifiers = array(); if ( isset( $request['flip']['horizontal'] ) || isset( $request['flip']['vertical'] ) ) { $flip_args = array( 'vertical' => isset( $request['flip']['vertical'] ) ? (bool) $request['flip']['vertical'] : false, 'horizontal' => isset( $request['flip']['horizontal'] ) ? (bool) $request['flip']['horizontal'] : false, ); $modifiers[] = array( 'type' => 'flip', 'args' => array( 'flip' => $flip_args, ), ); } if ( ! empty( $request['rotation'] ) ) { $modifiers[] = array( 'type' => 'rotate', 'args' => array( 'angle' => $request['rotation'], ), ); } if ( isset( $request['x'], $request['y'], $request['width'], $request['height'] ) ) { $modifiers[] = array( 'type' => 'crop', 'args' => array( 'left' => $request['x'], 'top' => $request['y'], 'width' => $request['width'], 'height' => $request['height'], ), ); } if ( 0 === count( $modifiers ) ) { return new WP_Error( 'rest_image_not_edited', __( 'The image was not edited. Edit the image before applying the changes.' ), array( 'status' => 400 ) ); } } $image_file_to_edit = $image_file; if ( ! file_exists( $image_file_to_edit ) ) { $image_file_to_edit = _load_image_to_edit_path( $attachment_id ); } $image_editor = wp_get_image_editor( $image_file_to_edit ); if ( is_wp_error( $image_editor ) ) { return new WP_Error( 'rest_unknown_image_file_type', __( 'Unable to edit this image.' ), array( 'status' => 500 ) ); } foreach ( $modifiers as $modifier ) { $args = $modifier['args']; switch ( $modifier['type'] ) { case 'flip': $result = $image_editor->flip( $args['flip']['vertical'], $args['flip']['horizontal'] ); if ( is_wp_error( $result ) ) { return new WP_Error( 'rest_image_flip_failed', __( 'Unable to flip this image.' ), array( 'status' => 500 ) ); } break; case 'rotate': $rotate = 0 - $args['angle']; if ( 0 !== $rotate ) { $result = $image_editor->rotate( $rotate ); if ( is_wp_error( $result ) ) { return new WP_Error( 'rest_image_rotation_failed', __( 'Unable to rotate this image.' ), array( 'status' => 500 ) ); } } break; case 'crop': $size = $image_editor->get_size(); $crop_x = (int) round( ( $size['width'] * $args['left'] ) / 100.0 ); $crop_y = (int) round( ( $size['height'] * $args['top'] ) / 100.0 ); $width = (int) round( ( $size['width'] * $args['width'] ) / 100.0 ); $height = (int) round( ( $size['height'] * $args['height'] ) / 100.0 ); if ( $size['width'] !== $width || $size['height'] !== $height ) { $result = $image_editor->crop( $crop_x, $crop_y, $width, $height ); if ( is_wp_error( $result ) ) { return new WP_Error( 'rest_image_crop_failed', __( 'Unable to crop this image.' ), array( 'status' => 500 ) ); } } break; } } $image_ext = pathinfo( $image_file, PATHINFO_EXTENSION ); $image_name = wp_basename( $image_file, ".{$image_ext}" ); if ( preg_match( '/-edited(-\d+)?$/', $image_name ) ) { $image_name = preg_replace( '/-edited(-\d+)?$/', '-edited', $image_name ); } else { $image_name .= '-edited'; } $filename = "{$image_name}.{$image_ext}"; $uploads = wp_upload_dir(); $filename = wp_unique_filename( $uploads['path'], $filename ); $saved = $image_editor->save( $uploads['path'] . "/$filename" ); if ( is_wp_error( $saved ) ) { return $saved; } $original_attachment_post = get_post( $attachment_id ); $new_attachment_post = $this->prepare_item_for_database( $request ); $new_attachment_post->post_mime_type = $saved['mime-type']; $new_attachment_post->guid = $uploads['url'] . "/$filename"; unset( $new_attachment_post->ID ); $new_attachment_post->post_title = $new_attachment_post->post_title ?? $original_attachment_post->post_title ?? $image_name; $new_attachment_post->post_excerpt = $new_attachment_post->post_excerpt ?? $original_attachment_post->post_excerpt ?? ''; $new_attachment_post->post_content = $new_attachment_post->post_content ?? $original_attachment_post->post_content ?? ''; $new_attachment_post->post_parent = $new_attachment_post->post_parent ?? 0; $new_attachment_id = wp_insert_attachment( wp_slash( (array) $new_attachment_post ), $saved['path'], 0, true ); if ( is_wp_error( $new_attachment_id ) ) { if ( 'db_update_error' === $new_attachment_id->get_error_code() ) { $new_attachment_id->add_data( array( 'status' => 500 ) ); } else { $new_attachment_id->add_data( array( 'status' => 400 ) ); } return $new_attachment_id; } $image_alt = isset( $request['alt_text'] ) ? sanitize_text_field( $request['alt_text'] ) : get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $image_alt ) ) { update_post_meta( $new_attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) ); } if ( wp_is_serving_rest_request() ) { header( 'X-WP-Upload-Attachment-ID: ' . $new_attachment_id ); } $new_image_meta = wp_generate_attachment_metadata( $new_attachment_id, $saved['path'] ); if ( isset( $image_meta['image_meta'] ) && isset( $new_image_meta['image_meta'] ) && is_array( $new_image_meta['image_meta'] ) ) { foreach ( (array) $image_meta['image_meta'] as $key => $value ) { if ( empty( $new_image_meta['image_meta'][ $key ] ) && ! empty( $value ) ) { $new_image_meta['image_meta'][ $key ] = $value; } } } if ( ! empty( $new_image_meta['image_meta']['orientation'] ) ) { $new_image_meta['image_meta']['orientation'] = 1; } $new_image_meta['parent_image'] = array( 'attachment_id' => $attachment_id, 'file' => _wp_relative_upload_path( $image_file ), ); $new_image_meta = apply_filters( 'wp_edited_image_metadata', $new_image_meta, $new_attachment_id, $attachment_id ); wp_update_attachment_metadata( $new_attachment_id, $new_image_meta ); $response = $this->prepare_item_for_response( get_post( $new_attachment_id ), $request ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $new_attachment_id ) ) ); return $response; } protected function prepare_item_for_database( $request ) { $prepared_attachment = parent::prepare_item_for_database( $request ); if ( isset( $request['caption'] ) ) { if ( is_string( $request['caption'] ) ) { $prepared_attachment->post_excerpt = $request['caption']; } elseif ( isset( $request['caption']['raw'] ) ) { $prepared_attachment->post_excerpt = $request['caption']['raw']; } } if ( isset( $request['description'] ) ) { if ( is_string( $request['description'] ) ) { $prepared_attachment->post_content = $request['description']; } elseif ( isset( $request['description']['raw'] ) ) { $prepared_attachment->post_content = $request['description']['raw']; } } if ( isset( $request['post'] ) ) { $prepared_attachment->post_parent = (int) $request['post']; } return $prepared_attachment; } public function prepare_item_for_response( $item, $request ) { $post = $item; $response = parent::prepare_item_for_response( $post, $request ); $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'description', $fields, true ) ) { $data['description'] = array( 'raw' => $post->post_content, 'rendered' => apply_filters( 'the_content', $post->post_content ), ); } if ( in_array( 'caption', $fields, true ) ) { $caption = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); $caption = apply_filters( 'the_excerpt', $caption ); $data['caption'] = array( 'raw' => $post->post_excerpt, 'rendered' => $caption, ); } if ( in_array( 'alt_text', $fields, true ) ) { $data['alt_text'] = get_post_meta( $post->ID, '_wp_attachment_image_alt', true ); } if ( in_array( 'media_type', $fields, true ) ) { $data['media_type'] = wp_attachment_is_image( $post->ID ) ? 'image' : 'file'; } if ( in_array( 'mime_type', $fields, true ) ) { $data['mime_type'] = $post->post_mime_type; } if ( in_array( 'media_details', $fields, true ) ) { $data['media_details'] = wp_get_attachment_metadata( $post->ID ); if ( empty( $data['media_details'] ) ) { $data['media_details'] = new stdClass(); } elseif ( ! empty( $data['media_details']['sizes'] ) ) { foreach ( $data['media_details']['sizes'] as $size => &$size_data ) { if ( isset( $size_data['mime-type'] ) ) { $size_data['mime_type'] = $size_data['mime-type']; unset( $size_data['mime-type'] ); } $image_src = wp_get_attachment_image_src( $post->ID, $size ); if ( ! $image_src ) { continue; } $size_data['source_url'] = $image_src[0]; } $full_src = wp_get_attachment_image_src( $post->ID, 'full' ); if ( ! empty( $full_src ) ) { $data['media_details']['sizes']['full'] = array( 'file' => wp_basename( $full_src[0] ), 'width' => $full_src[1], 'height' => $full_src[2], 'mime_type' => $post->post_mime_type, 'source_url' => $full_src[0], ); } } else { $data['media_details']['sizes'] = new stdClass(); } } if ( in_array( 'post', $fields, true ) ) { $data['post'] = ! empty( $post->post_parent ) ? (int) $post->post_parent : null; } if ( in_array( 'source_url', $fields, true ) ) { $data['source_url'] = wp_get_attachment_url( $post->ID ); } if ( in_array( 'missing_image_sizes', $fields, true ) ) { require_once ABSPATH . 'wp-admin/includes/image.php'; $data['missing_image_sizes'] = array_keys( wp_get_missing_image_subsizes( $post->ID ) ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $links = $response->get_links(); $response = rest_ensure_response( $data ); foreach ( $links as $rel => $rel_links ) { foreach ( $rel_links as $link ) { $response->add_link( $rel, $link['href'], $link['attributes'] ); } } return apply_filters( 'rest_prepare_attachment', $response, $post, $request ); } protected function prepare_links( $post ) { $links = parent::prepare_links( $post ); if ( ! empty( $post->post_parent ) ) { $post = get_post( $post->post_parent ); if ( ! empty( $post ) ) { $links['https://api.w.org/attached-to'] = array( 'href' => rest_url( rest_get_route_for_post( $post ) ), 'embeddable' => true, 'post_type' => $post->post_type, 'id' => $post->ID, ); } } return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); $schema['properties']['alt_text'] = array( 'description' => __( 'Alternative text to display when attachment is not displayed.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['caption'] = array( 'description' => __( 'The attachment caption.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Caption for the attachment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML caption for the attachment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); $schema['properties']['description'] = array( 'description' => __( 'The attachment description.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Description for the attachment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML description for the attachment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); $schema['properties']['media_type'] = array( 'description' => __( 'Attachment type.' ), 'type' => 'string', 'enum' => array( 'image', 'file' ), 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['mime_type'] = array( 'description' => __( 'The attachment MIME type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['media_details'] = array( 'description' => __( 'Details about the media file, specific to its type.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['post'] = array( 'description' => __( 'The ID for the associated post of the attachment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); $schema['properties']['source_url'] = array( 'description' => __( 'URL to the original attachment file.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['missing_image_sizes'] = array( 'description' => __( 'List of the missing image sizes of the attachment.' ), 'type' => 'array', 'items' => array( 'type' => 'string' ), 'context' => array( 'edit' ), 'readonly' => true, ); unset( $schema['properties']['password'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } protected function upload_from_data( $data, $headers, $time = null ) { if ( empty( $data ) ) { return new WP_Error( 'rest_upload_no_data', __( 'No data supplied.' ), array( 'status' => 400 ) ); } if ( empty( $headers['content_type'] ) ) { return new WP_Error( 'rest_upload_no_content_type', __( 'No Content-Type supplied.' ), array( 'status' => 400 ) ); } if ( empty( $headers['content_disposition'] ) ) { return new WP_Error( 'rest_upload_no_content_disposition', __( 'No Content-Disposition supplied.' ), array( 'status' => 400 ) ); } $filename = self::get_filename_from_disposition( $headers['content_disposition'] ); if ( empty( $filename ) ) { return new WP_Error( 'rest_upload_invalid_disposition', __( 'Invalid Content-Disposition supplied. Content-Disposition needs to be formatted as `attachment; filename="image.png"` or similar.' ), array( 'status' => 400 ) ); } if ( ! empty( $headers['content_md5'] ) ) { $content_md5 = array_shift( $headers['content_md5'] ); $expected = trim( $content_md5 ); $actual = md5( $data ); if ( $expected !== $actual ) { return new WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) ); } } $type = array_shift( $headers['content_type'] ); require_once ABSPATH . 'wp-admin/includes/file.php'; $tmpfname = wp_tempnam( $filename ); $fp = fopen( $tmpfname, 'w+' ); if ( ! $fp ) { return new WP_Error( 'rest_upload_file_error', __( 'Could not open file handle.' ), array( 'status' => 500 ) ); } fwrite( $fp, $data ); fclose( $fp ); $file_data = array( 'error' => null, 'tmp_name' => $tmpfname, 'name' => $filename, 'type' => $type, ); $size_check = self::check_upload_size( $file_data ); if ( is_wp_error( $size_check ) ) { return $size_check; } $overrides = array( 'test_form' => false, ); $sideloaded = wp_handle_sideload( $file_data, $overrides, $time ); if ( isset( $sideloaded['error'] ) ) { @unlink( $tmpfname ); return new WP_Error( 'rest_upload_sideload_error', $sideloaded['error'], array( 'status' => 500 ) ); } return $sideloaded; } public static function get_filename_from_disposition( $disposition_header ) { $filename = null; foreach ( $disposition_header as $value ) { $value = trim( $value ); if ( ! str_contains( $value, ';' ) ) { continue; } list( , $attr_parts ) = explode( ';', $value, 2 ); $attr_parts = explode( ';', $attr_parts ); $attributes = array(); foreach ( $attr_parts as $part ) { if ( ! str_contains( $part, '=' ) ) { continue; } list( $key, $value ) = explode( '=', $part, 2 ); $attributes[ trim( $key ) ] = trim( $value ); } if ( empty( $attributes['filename'] ) ) { continue; } $filename = trim( $attributes['filename'] ); if ( str_starts_with( $filename, '"' ) && str_ends_with( $filename, '"' ) ) { $filename = substr( $filename, 1, -1 ); } } return $filename; } public function get_collection_params() { $params = parent::get_collection_params(); $params['status']['default'] = 'inherit'; $params['status']['items']['enum'] = array( 'inherit', 'private', 'trash' ); $media_types = array_keys( $this->get_media_types() ); $params['media_type'] = array( 'default' => null, 'description' => __( 'Limit result set to attachments of a particular media type or media types.' ), 'type' => 'array', 'items' => array( 'type' => 'string', 'enum' => $media_types, ), ); $params['mime_type'] = array( 'default' => null, 'description' => __( 'Limit result set to attachments of a particular MIME type or MIME types.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); return $params; } protected function upload_from_file( $files, $headers, $time = null ) { if ( empty( $files ) ) { return new WP_Error( 'rest_upload_no_data', __( 'No data supplied.' ), array( 'status' => 400 ) ); } if ( ! empty( $headers['content_md5'] ) ) { $content_md5 = array_shift( $headers['content_md5'] ); $expected = trim( $content_md5 ); $actual = md5_file( $files['file']['tmp_name'] ); if ( $expected !== $actual ) { return new WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) ); } } $overrides = array( 'test_form' => false, ); if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) { $overrides['action'] = 'wp_handle_mock_upload'; } $size_check = self::check_upload_size( $files['file'] ); if ( is_wp_error( $size_check ) ) { return $size_check; } require_once ABSPATH . 'wp-admin/includes/file.php'; $file = wp_handle_upload( $files['file'], $overrides, $time ); if ( isset( $file['error'] ) ) { return new WP_Error( 'rest_upload_unknown_error', $file['error'], array( 'status' => 500 ) ); } return $file; } protected function get_media_types() { $media_types = array(); foreach ( get_allowed_mime_types() as $mime_type ) { $parts = explode( '/', $mime_type ); if ( ! isset( $media_types[ $parts[0] ] ) ) { $media_types[ $parts[0] ] = array(); } $media_types[ $parts[0] ][] = $mime_type; } return $media_types; } protected function check_upload_size( $file ) { if ( ! is_multisite() ) { return true; } if ( get_site_option( 'upload_space_check_disabled' ) ) { return true; } $space_left = get_upload_space_available(); $file_size = filesize( $file['tmp_name'] ); if ( $space_left < $file_size ) { return new WP_Error( 'rest_upload_limited_space', sprintf( __( 'Not enough space to upload. %s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) ), array( 'status' => 400 ) ); } if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) { return new WP_Error( 'rest_upload_file_too_big', sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) ), array( 'status' => 400 ) ); } require_once ABSPATH . 'wp-admin/includes/ms.php'; if ( upload_is_user_over_quota( false ) ) { return new WP_Error( 'rest_upload_user_quota_exceeded', __( 'You have used your space quota. Please delete files before uploading.' ), array( 'status' => 400 ) ); } return true; } protected function get_edit_media_item_args() { $args = array( 'src' => array( 'description' => __( 'URL to the edited image file.' ), 'type' => 'string', 'format' => 'uri', 'required' => true, ), 'modifiers' => array( 'description' => __( 'Array of image edits.' ), 'type' => 'array', 'minItems' => 1, 'items' => array( 'description' => __( 'Image edit.' ), 'type' => 'object', 'required' => array( 'type', 'args', ), 'oneOf' => array( array( 'title' => __( 'Flip' ), 'properties' => array( 'type' => array( 'description' => __( 'Flip type.' ), 'type' => 'string', 'enum' => array( 'flip' ), ), 'args' => array( 'description' => __( 'Flip arguments.' ), 'type' => 'object', 'required' => array( 'flip', ), 'properties' => array( 'flip' => array( 'description' => __( 'Flip direction.' ), 'type' => 'object', 'required' => array( 'horizontal', 'vertical', ), 'properties' => array( 'horizontal' => array( 'description' => __( 'Whether to flip in the horizontal direction.' ), 'type' => 'boolean', ), 'vertical' => array( 'description' => __( 'Whether to flip in the vertical direction.' ), 'type' => 'boolean', ), ), ), ), ), ), ), array( 'title' => __( 'Rotation' ), 'properties' => array( 'type' => array( 'description' => __( 'Rotation type.' ), 'type' => 'string', 'enum' => array( 'rotate' ), ), 'args' => array( 'description' => __( 'Rotation arguments.' ), 'type' => 'object', 'required' => array( 'angle', ), 'properties' => array( 'angle' => array( 'description' => __( 'Angle to rotate clockwise in degrees.' ), 'type' => 'number', ), ), ), ), ), array( 'title' => __( 'Crop' ), 'properties' => array( 'type' => array( 'description' => __( 'Crop type.' ), 'type' => 'string', 'enum' => array( 'crop' ), ), 'args' => array( 'description' => __( 'Crop arguments.' ), 'type' => 'object', 'required' => array( 'left', 'top', 'width', 'height', ), 'properties' => array( 'left' => array( 'description' => __( 'Horizontal position from the left to begin the crop as a percentage of the image width.' ), 'type' => 'number', ), 'top' => array( 'description' => __( 'Vertical position from the top to begin the crop as a percentage of the image height.' ), 'type' => 'number', ), 'width' => array( 'description' => __( 'Width of the crop as a percentage of the image width.' ), 'type' => 'number', ), 'height' => array( 'description' => __( 'Height of the crop as a percentage of the image height.' ), 'type' => 'number', ), ), ), ), ), ), ), ), 'rotation' => array( 'description' => __( 'The amount to rotate the image clockwise in degrees. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'integer', 'minimum' => 0, 'exclusiveMinimum' => true, 'maximum' => 360, 'exclusiveMaximum' => true, ), 'x' => array( 'description' => __( 'As a percentage of the image, the x position to start the crop from. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'y' => array( 'description' => __( 'As a percentage of the image, the y position to start the crop from. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'width' => array( 'description' => __( 'As a percentage of the image, the width to crop the image to. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'height' => array( 'description' => __( 'As a percentage of the image, the height to crop the image to. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), ); $update_item_args = $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ); if ( isset( $update_item_args['caption'] ) ) { $args['caption'] = $update_item_args['caption']; } if ( isset( $update_item_args['description'] ) ) { $args['description'] = $update_item_args['description']; } if ( isset( $update_item_args['title'] ) ) { $args['title'] = $update_item_args['title']; } if ( isset( $update_item_args['post'] ) ) { $args['post'] = $update_item_args['post']; } if ( isset( $update_item_args['alt_text'] ) ) { $args['alt_text'] = $update_item_args['alt_text']; } return $args; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-global-styles-controller.php';
class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { protected $allow_batch = array( 'v1' => false ); public function __construct( $post_type = 'wp_global_styles' ) { parent::__construct( $post_type ); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)/variations', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_theme_items' ), 'permission_callback' => array( $this, 'get_theme_items_permissions_check' ), 'args' => array( 'stylesheet' => array( 'description' => __( 'The theme identifier' ), 'type' => 'string', ), ), 'allow_batch' => $this->allow_batch, ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/themes/(?P<stylesheet>%s)', $this->rest_base, '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?' ), array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_theme_item' ), 'permission_callback' => array( $this, 'get_theme_item_permissions_check' ), 'args' => array( 'stylesheet' => array( 'description' => __( 'The theme identifier' ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), ), ), 'allow_batch' => $this->allow_batch, ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\/\d+]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'ID of global styles config.' ), 'type' => 'integer', ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), 'allow_batch' => $this->allow_batch, ) ); } public function _sanitize_global_styles_callback( $stylesheet ) { return urldecode( $stylesheet ); } protected function get_post( $id ) { $error = new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exists with that ID.' ), array( 'status' => 404 ) ); $id = (int) $id; if ( $id <= 0 ) { return $error; } $post = get_post( $id ); if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { return $error; } return $post; } public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_read_permission( $post ) ) { return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function check_read_permission( $post ) { return current_user_can( 'read_post', $post->ID ); } public function update_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function prepare_item_for_database( $request ) { $changes = new stdClass(); $changes->ID = $request['id']; $post = get_post( $request['id'] ); $existing_config = array(); if ( $post ) { $existing_config = json_decode( $post->post_content, true ); $json_decoding_error = json_last_error(); if ( JSON_ERROR_NONE !== $json_decoding_error || ! isset( $existing_config['isGlobalStylesUserThemeJSON'] ) || ! $existing_config['isGlobalStylesUserThemeJSON'] ) { $existing_config = array(); } } if ( isset( $request['styles'] ) || isset( $request['settings'] ) ) { $config = array(); if ( isset( $request['styles'] ) ) { if ( isset( $request['styles']['css'] ) ) { $css_validation_result = $this->validate_custom_css( $request['styles']['css'] ); if ( is_wp_error( $css_validation_result ) ) { return $css_validation_result; } } $config['styles'] = $request['styles']; } elseif ( isset( $existing_config['styles'] ) ) { $config['styles'] = $existing_config['styles']; } $variations = WP_Theme_JSON_Resolver::get_style_variations( 'block' ); wp_register_block_style_variations_from_theme_json_partials( $variations ); if ( isset( $request['settings'] ) ) { $config['settings'] = $request['settings']; } elseif ( isset( $existing_config['settings'] ) ) { $config['settings'] = $existing_config['settings']; } $config['isGlobalStylesUserThemeJSON'] = true; $config['version'] = WP_Theme_JSON::LATEST_SCHEMA; $changes->post_content = wp_json_encode( $config ); } if ( isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $changes->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $changes->post_title = $request['title']['raw']; } } return $changes; } public function prepare_item_for_response( $post, $request ) { $raw_config = json_decode( $post->post_content, true ); $is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; $config = array(); $theme_json = null; if ( $is_global_styles_user_theme_json ) { $theme_json = new WP_Theme_JSON( $raw_config, 'custom' ); $config = $theme_json->get_raw_data(); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $post->ID; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $post->post_title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data['title']['rendered'] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass(); } if ( rest_is_field_included( 'styles', $fields ) ) { $data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass(); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $post->ID ); if ( $theme_json ) { $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json ); if ( ! empty( $resolved_theme_uris ) ) { $links['https://api.w.org/theme-file'] = $resolved_theme_uris; } } $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $post, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return $response; } protected function prepare_links( $id ) { $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); $links = array( 'self' => array( 'href' => rest_url( trailingslashit( $base ) . $id ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( post_type_supports( $this->post_type, 'revisions' ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $id ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%d/revisions', $base, $id ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); } return $links; } protected function get_available_actions( $post, $request ) { $rels = array(); $post_type = get_post_type_object( $post->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'edit_css' ) ) { $rels[] = 'https://api.w.org/action-edit-css'; } return $rels; } public function get_collection_params() { return array(); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of global styles config.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'styles' => array( 'description' => __( 'Global styles.' ), 'type' => array( 'object' ), 'context' => array( 'view', 'edit' ), ), 'settings' => array( 'description' => __( 'Global settings.' ), 'type' => array( 'object' ), 'context' => array( 'view', 'edit' ), ), 'title' => array( 'description' => __( 'Title of the global styles variation.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the global styles variation, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML title for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_theme_item_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } if ( current_user_can( 'edit_theme_options' ) ) { return true; } return new WP_Error( 'rest_cannot_read_global_styles', __( 'Sorry, you are not allowed to access the global styles on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } public function get_theme_item( $request ) { if ( get_stylesheet() !== $request['stylesheet'] ) { return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $theme = WP_Theme_JSON_Resolver::get_merged_data( 'theme' ); $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = $theme->get_settings(); } if ( rest_is_field_included( 'styles', $fields ) ) { $raw_data = $theme->get_raw_data(); $data['styles'] = isset( $raw_data['styles'] ) ? $raw_data['styles'] : array(); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ), ), ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme ); if ( ! empty( $resolved_theme_uris ) ) { $links['https://api.w.org/theme-file'] = $resolved_theme_uris; } $response->add_links( $links ); } return $response; } public function get_theme_items_permissions_check( $request ) { return $this->get_theme_item_permissions_check( $request ); } public function get_theme_items( $request ) { if ( get_stylesheet() !== $request['stylesheet'] ) { return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $response = array(); $partials = WP_Theme_JSON_Resolver::get_style_variations( 'block' ); wp_register_block_style_variations_from_theme_json_partials( $partials ); $variations = WP_Theme_JSON_Resolver::get_style_variations(); foreach ( $variations as $variation ) { $variation_theme_json = new WP_Theme_JSON( $variation ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $variation_theme_json ); $data = rest_ensure_response( $variation ); if ( ! empty( $resolved_theme_uris ) ) { $data->add_links( array( 'https://api.w.org/theme-file' => $resolved_theme_uris, ) ); } $response[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $response ); } protected function validate_custom_css( $css ) { if ( preg_match( '#</?\w+#', $css ) ) { return new WP_Error( 'rest_custom_css_illegal_markup', __( 'Markup is not allowed in CSS.' ), array( 'status' => 400 ) ); } return true; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-types-controller.php';
class WP_REST_Post_Types_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'types'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<type>[\w-]+)', array( 'args' => array( 'type' => array( 'description' => __( 'An alphanumeric identifier for the post type.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => '__return_true', 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $data = array(); $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( 'edit' === $request['context'] && ! current_user_can( $type->cap->edit_posts ) ) { continue; } $post_type = $this->prepare_item_for_response( $type, $request ); $data[ $type->name ] = $this->prepare_response_for_collection( $post_type ); } return rest_ensure_response( $data ); } public function get_item( $request ) { $obj = get_post_type_object( $request['type'] ); if ( empty( $obj ) ) { return new WP_Error( 'rest_type_invalid', __( 'Invalid post type.' ), array( 'status' => 404 ) ); } if ( empty( $obj->show_in_rest ) ) { return new WP_Error( 'rest_cannot_read_type', __( 'Cannot view post type.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( $obj->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } $data = $this->prepare_item_for_response( $obj, $request ); return rest_ensure_response( $data ); } public function prepare_item_for_response( $item, $request ) { $post_type = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_post_type', new WP_REST_Response( array() ), $post_type, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $post_type->name, 'objects' ), array( 'show_in_rest' => true ) ); $taxonomies = wp_list_pluck( $taxonomies, 'name' ); $base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name; $namespace = ! empty( $post_type->rest_namespace ) ? $post_type->rest_namespace : 'wp/v2'; $supports = get_all_post_type_supports( $post_type->name ); $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'capabilities', $fields ) ) { $data['capabilities'] = $post_type->cap; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $post_type->description; } if ( rest_is_field_included( 'hierarchical', $fields ) ) { $data['hierarchical'] = $post_type->hierarchical; } if ( rest_is_field_included( 'has_archive', $fields ) ) { $data['has_archive'] = $post_type->has_archive; } if ( rest_is_field_included( 'visibility', $fields ) ) { $data['visibility'] = array( 'show_in_nav_menus' => (bool) $post_type->show_in_nav_menus, 'show_ui' => (bool) $post_type->show_ui, ); } if ( rest_is_field_included( 'viewable', $fields ) ) { $data['viewable'] = is_post_type_viewable( $post_type ); } if ( rest_is_field_included( 'labels', $fields ) ) { $data['labels'] = $post_type->labels; } if ( rest_is_field_included( 'name', $fields ) ) { $data['name'] = $post_type->label; } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $post_type->name; } if ( rest_is_field_included( 'icon', $fields ) ) { $data['icon'] = $post_type->menu_icon; } if ( rest_is_field_included( 'supports', $fields ) ) { $data['supports'] = $supports; } if ( rest_is_field_included( 'taxonomies', $fields ) ) { $data['taxonomies'] = array_values( $taxonomies ); } if ( rest_is_field_included( 'rest_base', $fields ) ) { $data['rest_base'] = $base; } if ( rest_is_field_included( 'rest_namespace', $fields ) ) { $data['rest_namespace'] = $namespace; } if ( rest_is_field_included( 'template', $fields ) ) { $data['template'] = $post_type->template ?? array(); } if ( rest_is_field_included( 'template_lock', $fields ) ) { $data['template_lock'] = ! empty( $post_type->template_lock ) ? $post_type->template_lock : false; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $post_type ) ); } return apply_filters( 'rest_prepare_post_type', $response, $post_type, $request ); } protected function prepare_links( $post_type ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'https://api.w.org/items' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $post_type->name ) ), ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'type', 'type' => 'object', 'properties' => array( 'capabilities' => array( 'description' => __( 'All capabilities used by the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'A human-readable description of the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hierarchical' => array( 'description' => __( 'Whether or not the post type should have children.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'viewable' => array( 'description' => __( 'Whether or not the post type can be viewed.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'labels' => array( 'description' => __( 'Human-readable labels for the post type for various contexts.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The title for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'supports' => array( 'description' => __( 'All features, supported by the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'has_archive' => array( 'description' => __( 'If the value is a string, the value will be used as the archive slug. If the value is false the post type has no archive.' ), 'type' => array( 'string', 'boolean' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxonomies' => array( 'description' => __( 'Taxonomies associated with post type.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rest_base' => array( 'description' => __( 'REST base route for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rest_namespace' => array( 'description' => __( 'REST route\'s namespace for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'visibility' => array( 'description' => __( 'The visibility settings for the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, 'properties' => array( 'show_ui' => array( 'description' => __( 'Whether to generate a default UI for managing this post type.' ), 'type' => 'boolean', ), 'show_in_nav_menus' => array( 'description' => __( 'Whether to make the post type available for selection in navigation menus.' ), 'type' => 'boolean', ), ), ), 'icon' => array( 'description' => __( 'The icon for the post type.' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'template' => array( 'type' => array( 'array' ), 'description' => __( 'The block template associated with the post type.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'template_lock' => array( 'type' => array( 'string', 'boolean' ), 'enum' => array( 'all', 'insert', 'contentOnly', false ), 'description' => __( 'The template_lock associated with the post type, or false if none.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-statuses-controller.php';
class WP_REST_Post_Statuses_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'statuses'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<status>[\w-]+)', array( 'args' => array( 'status' => array( 'description' => __( 'An alphanumeric identifier for the status.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to manage post statuses.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { $data = array(); $statuses = get_post_stati( array( 'internal' => false ), 'object' ); $statuses['trash'] = get_post_status_object( 'trash' ); foreach ( $statuses as $obj ) { $ret = $this->check_read_permission( $obj ); if ( ! $ret ) { continue; } $status = $this->prepare_item_for_response( $obj, $request ); $data[ $obj->name ] = $this->prepare_response_for_collection( $status ); } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { $status = get_post_status_object( $request['status'] ); if ( empty( $status ) ) { return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) ); } $check = $this->check_read_permission( $status ); if ( ! $check ) { return new WP_Error( 'rest_cannot_read_status', __( 'Cannot view status.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function check_read_permission( $status ) { if ( true === $status->public ) { return true; } if ( false === $status->internal || 'trash' === $status->name ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } } return false; } public function get_item( $request ) { $obj = get_post_status_object( $request['status'] ); if ( empty( $obj ) ) { return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $obj, $request ); return rest_ensure_response( $data ); } public function prepare_item_for_response( $item, $request ) { $status = $item; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'name', $fields, true ) ) { $data['name'] = $status->label; } if ( in_array( 'private', $fields, true ) ) { $data['private'] = (bool) $status->private; } if ( in_array( 'protected', $fields, true ) ) { $data['protected'] = (bool) $status->protected; } if ( in_array( 'public', $fields, true ) ) { $data['public'] = (bool) $status->public; } if ( in_array( 'queryable', $fields, true ) ) { $data['queryable'] = (bool) $status->publicly_queryable; } if ( in_array( 'show_in_list', $fields, true ) ) { $data['show_in_list'] = (bool) $status->show_in_admin_all_list; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $status->name; } if ( in_array( 'date_floating', $fields, true ) ) { $data['date_floating'] = $status->date_floating; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $rest_url = rest_url( rest_get_route_for_post_type_items( 'post' ) ); if ( 'publish' === $status->name ) { $response->add_link( 'archives', $rest_url ); } else { $response->add_link( 'archives', add_query_arg( 'status', $status->name, $rest_url ) ); } return apply_filters( 'rest_prepare_status', $response, $status, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'status', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The title for the status.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'private' => array( 'description' => __( 'Whether posts with this status should be private.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether posts with this status should be protected.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'public' => array( 'description' => __( 'Whether posts of this status should be shown in the front end of the site.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'queryable' => array( 'description' => __( 'Whether posts with this status should be publicly-queryable.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'show_in_list' => array( 'description' => __( 'Whether to include posts in the edit listing for their post type.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the status.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'date_floating' => array( 'description' => __( 'Whether posts of this status may have floating published dates.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-revisions-controller.php';
class WP_REST_Revisions_Controller extends WP_REST_Controller { private $parent_post_type; protected $meta; private $parent_controller; private $parent_base; public function __construct( $parent_post_type ) { $this->parent_post_type = $parent_post_type; $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Posts_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Post_Meta_Fields( $parent_post_type ); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as revisions do not support trashing.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } protected function get_parent( $parent_post_id ) { $error = new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) ); if ( (int) $parent_post_id <= 0 ) { return $error; } $parent_post = get_post( (int) $parent_post_id ); if ( empty( $parent_post ) || empty( $parent_post->ID ) || $this->parent_post_type !== $parent_post->post_type ) { return $error; } return $parent_post; } public function get_items_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'edit_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function get_revision( $id ) { $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $revision = get_post( (int) $id ); if ( empty( $revision ) || empty( $revision->ID ) || 'revision' !== $revision->post_type ) { return $error; } return $revision; } public function get_items( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) { return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['orderby'] ) && 'include' === $request['orderby'] && empty( $request['include'] ) ) { return new WP_Error( 'rest_orderby_include_missing_include', __( 'You need to define an include parameter to order by include.' ), array( 'status' => 400 ) ); } $is_head_request = $request->is_method( 'HEAD' ); if ( wp_revisions_enabled( $parent ) ) { $registered = $this->get_collection_params(); $args = array( 'post_parent' => $parent->ID, 'post_type' => 'revision', 'post_status' => 'inherit', 'posts_per_page' => -1, 'orderby' => 'date ID', 'order' => 'DESC', 'suppress_filters' => true, ); $parameter_mappings = array( 'exclude' => 'post__not_in', 'include' => 'post__in', 'offset' => 'offset', 'order' => 'order', 'orderby' => 'orderby', 'page' => 'paged', 'per_page' => 'posts_per_page', 'search' => 's', ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $args[ $wp_param ] = $request[ $api_param ]; } } if ( isset( $args['orderby'] ) && 'date' === $args['orderby'] ) { $args['orderby'] = 'date ID'; } if ( $is_head_request ) { $args['fields'] = 'ids'; $args['update_post_term_cache'] = false; $args['update_post_meta_cache'] = false; } $args = apply_filters( 'rest_revision_query', $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); $revisions_query = new WP_Query(); $revisions = $revisions_query->query( $query_args ); $offset = isset( $query_args['offset'] ) ? (int) $query_args['offset'] : 0; $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_revisions = $revisions_query->found_posts; if ( $total_revisions < 1 ) { unset( $query_args['paged'], $query_args['offset'] ); $count_query = new WP_Query(); $query_args['fields'] = 'ids'; $query_args['posts_per_page'] = 1; $query_args['update_post_meta_cache'] = false; $query_args['update_post_term_cache'] = false; $count_query->query( $query_args ); $total_revisions = $count_query->found_posts; } if ( $revisions_query->query_vars['posts_per_page'] > 0 ) { $max_pages = (int) ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] ); } else { $max_pages = $total_revisions > 0 ? 1 : 0; } if ( $total_revisions > 0 ) { if ( $offset >= $total_revisions ) { return new WP_Error( 'rest_revision_invalid_offset_number', __( 'The offset number requested is larger than or equal to the number of available revisions.' ), array( 'status' => 400 ) ); } elseif ( ! $offset && $page > $max_pages ) { return new WP_Error( 'rest_revision_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } } } else { $revisions = array(); $total_revisions = 0; $max_pages = 0; $page = (int) $request['page']; } if ( ! $is_head_request ) { $response = array(); foreach ( $revisions as $revision ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } $response = rest_ensure_response( $response ); } else { $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $base_path = rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ); $base = add_query_arg( urlencode_deep( $request_params ), $base_path ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function get_item_permissions_check( $request ) { return $this->get_items_permissions_check( $request ); } public function get_item( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } if ( (int) $parent->ID !== (int) $revision->post_parent ) { return new WP_Error( 'rest_revision_parent_id_mismatch', sprintf( __( 'The revision does not belong to the specified parent with id of "%d"' ), $parent->ID ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $revision, $request ); return rest_ensure_response( $response ); } public function delete_item_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'delete_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } $response = $this->get_items_permissions_check( $request ); if ( ! $response || is_wp_error( $response ) ) { return $response; } if ( ! current_user_can( 'delete_post', $revision->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this revision.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Revisions do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $previous = $this->prepare_item_for_response( $revision, $request ); $result = wp_delete_post( $request['id'], true ); do_action( 'rest_delete_revision', $result, $request ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); return $response; } protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = array(); foreach ( $prepared_args as $key => $value ) { $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); } if ( isset( $query_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } return $query_args; } public function prepare_item_for_response( $item, $request ) { $post = $item; $GLOBALS['post'] = $post; setup_postdata( $post ); if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_revision', new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'author', $fields, true ) ) { $data['author'] = (int) $post->post_author; } if ( in_array( 'date', $fields, true ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( in_array( 'date_gmt', $fields, true ) ) { $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt ); } if ( in_array( 'id', $fields, true ) ) { $data['id'] = $post->ID; } if ( in_array( 'modified', $fields, true ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( in_array( 'modified_gmt', $fields, true ) ) { $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt ); } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $post->post_parent; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $post->post_name; } if ( in_array( 'guid', $fields, true ) ) { $data['guid'] = array( 'rendered' => apply_filters( 'get_the_guid', $post->guid, $post->ID ), 'raw' => $post->guid, ); } if ( in_array( 'title', $fields, true ) ) { $data['title'] = array( 'raw' => $post->post_title, 'rendered' => get_the_title( $post->ID ), ); } if ( in_array( 'content', $fields, true ) ) { $data['content'] = array( 'raw' => $post->post_content, 'rendered' => apply_filters( 'the_content', $post->post_content ), ); } if ( in_array( 'excerpt', $fields, true ) ) { $data['excerpt'] = array( 'raw' => $post->post_excerpt, 'rendered' => $this->prepare_excerpt_response( $post->post_excerpt, $post ), ); } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $post->ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( ! empty( $data['parent'] ) ) { $response->add_link( 'parent', rest_url( rest_get_route_for_post( $data['parent'] ) ) ); } return apply_filters( 'rest_prepare_revision', $response, $post, $request ); } protected function prepare_date_response( $date_gmt, $date = null ) { if ( '0000-00-00 00:00:00' === $date_gmt ) { return null; } if ( isset( $date ) ) { return mysql_to_rfc3339( $date ); } return mysql_to_rfc3339( $date_gmt ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => "{$this->parent_post_type}-revision", 'type' => 'object', 'properties' => array( 'author' => array( 'description' => __( 'The ID for the author of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'date' => array( 'description' => __( "The date the revision was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the revision was published, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'guid' => array( 'description' => __( 'GUID for the revision, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'modified' => array( 'description' => __( "The date the revision was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'modified_gmt' => array( 'description' => __( 'The date the revision was last modified, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the revision unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $parent_schema = $this->parent_controller->get_item_schema(); if ( ! empty( $parent_schema['properties']['title'] ) ) { $schema['properties']['title'] = $parent_schema['properties']['title']; } if ( ! empty( $parent_schema['properties']['content'] ) ) { $schema['properties']['content'] = $parent_schema['properties']['content']; } if ( ! empty( $parent_schema['properties']['excerpt'] ) ) { $schema['properties']['excerpt'] = $parent_schema['properties']['excerpt']; } if ( ! empty( $parent_schema['properties']['guid'] ) ) { $schema['properties']['guid'] = $parent_schema['properties']['guid']; } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; unset( $query_params['per_page']['default'] ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'date', 'id', 'include', 'relevance', 'slug', 'include_slugs', 'title', ), ); return $query_params; } protected function prepare_excerpt_response( $excerpt, $post ) { $excerpt = apply_filters( 'the_excerpt', $excerpt, $post ); if ( empty( $excerpt ) ) { return ''; } return $excerpt; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php';
class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Controller { private $parent_controller; protected $parent_base; protected $parent_post_type; public function __construct( $parent_post_type = 'wp_global_styles' ) { parent::__construct( $parent_post_type ); $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Global_Styles_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the global styles revision.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'Unique identifier for the global styles revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } protected function get_decoded_global_styles_json( $raw_json ) { $decoded_json = json_decode( $raw_json, true ); if ( is_array( $decoded_json ) && isset( $decoded_json['isGlobalStylesUserThemeJSON'] ) && true === $decoded_json['isGlobalStylesUserThemeJSON'] ) { return $decoded_json; } return new WP_Error( 'rest_global_styles_not_found', __( 'Cannot find user global styles revisions.' ), array( 'status' => 404 ) ); } public function get_items( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $global_styles_config = $this->get_decoded_global_styles_json( $parent->post_content ); if ( is_wp_error( $global_styles_config ) ) { return $global_styles_config; } $is_head_request = $request->is_method( 'HEAD' ); if ( wp_revisions_enabled( $parent ) ) { $registered = $this->get_collection_params(); $query_args = array( 'post_parent' => $parent->ID, 'post_type' => 'revision', 'post_status' => 'inherit', 'posts_per_page' => -1, 'orderby' => 'date ID', 'order' => 'DESC', ); $parameter_mappings = array( 'offset' => 'offset', 'page' => 'paged', 'per_page' => 'posts_per_page', ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $query_args[ $wp_param ] = $request[ $api_param ]; } } if ( $is_head_request ) { $query_args['fields'] = 'ids'; $query_args['update_post_term_cache'] = false; $query_args['update_post_meta_cache'] = false; } $revisions_query = new WP_Query(); $revisions = $revisions_query->query( $query_args ); $offset = isset( $query_args['offset'] ) ? (int) $query_args['offset'] : 0; $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_revisions = $revisions_query->found_posts; if ( $total_revisions < 1 ) { unset( $query_args['paged'], $query_args['offset'] ); $count_query = new WP_Query(); $query_args['fields'] = 'ids'; $query_args['posts_per_page'] = 1; $query_args['update_post_meta_cache'] = false; $query_args['update_post_term_cache'] = false; $count_query->query( $query_args ); $total_revisions = $count_query->found_posts; } if ( $revisions_query->query_vars['posts_per_page'] > 0 ) { $max_pages = (int) ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] ); } else { $max_pages = $total_revisions > 0 ? 1 : 0; } if ( $total_revisions > 0 ) { if ( $offset >= $total_revisions ) { return new WP_Error( 'rest_revision_invalid_offset_number', __( 'The offset number requested is larger than or equal to the number of available revisions.' ), array( 'status' => 400 ) ); } elseif ( ! $offset && $page > $max_pages ) { return new WP_Error( 'rest_revision_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } } } else { $revisions = array(); $total_revisions = 0; $max_pages = 0; $page = (int) $request['page']; } if ( ! $is_head_request ) { $response = array(); foreach ( $revisions as $revision ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } $response = rest_ensure_response( $response ); } else { $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $base_path = rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ); $base = add_query_arg( urlencode_deep( $request_params ), $base_path ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function prepare_item_for_response( $post, $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $parent = $this->get_parent( $request['parent'] ); $global_styles_config = $this->get_decoded_global_styles_json( $post->post_content ); if ( is_wp_error( $global_styles_config ) ) { return $global_styles_config; } $fields = $this->get_fields_for_response( $request ); $data = array(); $theme_json = null; if ( ! empty( $global_styles_config['styles'] ) || ! empty( $global_styles_config['settings'] ) ) { $theme_json = new WP_Theme_JSON( $global_styles_config, 'custom' ); $global_styles_config = $theme_json->get_raw_data(); if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = ! empty( $global_styles_config['settings'] ) ? $global_styles_config['settings'] : new stdClass(); } if ( rest_is_field_included( 'styles', $fields ) ) { $data['styles'] = ! empty( $global_styles_config['styles'] ) ? $global_styles_config['styles'] : new stdClass(); } } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $post->post_author; } if ( rest_is_field_included( 'date', $fields ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( rest_is_field_included( 'date_gmt', $fields ) ) { $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt ); } if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = (int) $post->ID; } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( rest_is_field_included( 'modified_gmt', $fields ) ) { $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt ); } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = (int) $parent->ID; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json ); if ( ! empty( $resolved_theme_uris ) ) { $response->add_links( array( 'https://api.w.org/theme-file' => $resolved_theme_uris, ) ); } return $response; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); $parent_schema = $this->parent_controller->get_item_schema(); $schema['properties'] = array_merge( $schema['properties'], $parent_schema['properties'] ); unset( $schema['properties']['guid'], $schema['properties']['slug'], $schema['properties']['meta'], $schema['properties']['content'], $schema['properties']['title'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); unset( $query_params['exclude'], $query_params['include'], $query_params['search'], $query_params['order'], $query_params['orderby'] ); return $query_params; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-template-revisions-controller.php';
class WP_REST_Template_Revisions_Controller extends WP_REST_Revisions_Controller { private $parent_post_type; private $parent_controller; private $parent_base; public function __construct( $parent_post_type ) { parent::__construct( $parent_post_type ); $this->parent_post_type = $parent_post_type; $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Templates_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s', $this->parent_base, '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', '[\/\w%-]+', $this->rest_base ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s/%s', $this->parent_base, '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', '[\/\w%-]+', $this->rest_base, '(?P<id>[\d]+)' ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as revisions do not support trashing.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } protected function get_parent( $parent_template_id ) { $template = get_block_template( $parent_template_id, $this->parent_post_type ); if ( ! $template ) { return new WP_Error( 'rest_post_invalid_parent', __( 'Invalid template parent ID.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } $parent_post_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0; if ( $parent_post_id <= 0 ) { return new WP_Error( 'rest_invalid_template', __( 'Templates based on theme files can\'t have revisions.' ), array( 'status' => WP_Http::BAD_REQUEST ) ); } return get_post( $template->wp_id ); } public function prepare_item_for_response( $item, $request ) { $template = _build_block_template_result_from_post( $item ); $response = $this->parent_controller->prepare_item_for_response( $template, $request ); if ( $request->is_method( 'HEAD' ) ) { return $response; } $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->post_parent; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template ); $response->add_links( $links ); } return $response; } public function delete_item_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'delete_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this revision.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function prepare_links( $template ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ), ), 'parent' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ), ), ); return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = $this->parent_controller->get_item_schema(); $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-autosaves-controller.php';
class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { private $parent_post_type; private $parent_controller; private $revisions_controller; private $parent_base; public function __construct( $parent_post_type ) { $this->parent_post_type = $parent_post_type; $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Posts_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $revisions_controller = $post_type_object->get_revisions_rest_controller(); if ( ! $revisions_controller ) { $revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type ); } $this->revisions_controller = $revisions_controller; $this->rest_base = 'autosaves'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<id>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the autosave.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'The ID for the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } protected function get_parent( $parent_id ) { return $this->revisions_controller->get_parent( $parent_id ); } public function get_items_permissions_check( $request ) { $parent = $this->get_parent( $request['id'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'edit_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view autosaves of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function create_item_permissions_check( $request ) { $id = $request->get_param( 'id' ); if ( empty( $id ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid item ID.' ), array( 'status' => 404 ) ); } return $this->parent_controller->update_item_permissions_check( $request ); } public function create_item( $request ) { if ( ! defined( 'WP_RUN_CORE_TESTS' ) && ! defined( 'DOING_AUTOSAVE' ) ) { define( 'DOING_AUTOSAVE', true ); } $post = $this->get_parent( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $prepared_post = $this->parent_controller->prepare_item_for_database( $request ); $prepared_post->ID = $post->ID; $user_id = get_current_user_id(); if ( ! function_exists( 'wp_check_post_lock' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; } $post_lock = wp_check_post_lock( $post->ID ); $is_draft = 'draft' === $post->post_status || 'auto-draft' === $post->post_status; if ( $is_draft && (int) $post->post_author === $user_id && ! $post_lock ) { $autosave_id = wp_update_post( wp_slash( (array) $prepared_post ), true ); } else { $autosave_id = $this->create_post_autosave( (array) $prepared_post, (array) $request->get_param( 'meta' ) ); } if ( is_wp_error( $autosave_id ) ) { return $autosave_id; } $autosave = get_post( $autosave_id ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $autosave, $request ); $response = rest_ensure_response( $response ); return $response; } public function get_item( $request ) { $parent_id = (int) $request->get_param( 'parent' ); if ( $parent_id <= 0 ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) ); } $autosave = wp_get_post_autosave( $parent_id ); if ( ! $autosave ) { return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this post.' ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $autosave, $request ); return $response; } public function get_items( $request ) { $parent = $this->get_parent( $request['id'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $response = array(); $parent_id = $parent->ID; $revisions = wp_get_post_revisions( $parent_id, array( 'check_enabled' => false ) ); foreach ( $revisions as $revision ) { if ( str_contains( $revision->post_name, "{$parent_id}-autosave" ) ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } } return rest_ensure_response( $response ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = $this->revisions_controller->get_item_schema(); $schema['properties']['preview_link'] = array( 'description' => __( 'Preview link for the post.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'edit' ), 'readonly' => true, ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function create_post_autosave( $post_data, array $meta = array() ) { $post_id = (int) $post_data['ID']; $post = get_post( $post_id ); if ( is_wp_error( $post ) ) { return $post; } $autosave_is_different = false; $new_autosave = _wp_post_revision_data( $post_data, true ); foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) { $autosave_is_different = true; break; } } if ( ! empty( $meta ) ) { $revisioned_meta_keys = wp_post_revision_meta_keys( $post->post_type ); foreach ( $revisioned_meta_keys as $meta_key ) { $old_meta = get_metadata_raw( 'post', $post_id, $meta_key, true ); $new_meta = isset( $meta[ $meta_key ] ) ? $meta[ $meta_key ] : ''; if ( $new_meta !== $old_meta ) { $autosave_is_different = true; break; } } } $user_id = get_current_user_id(); $old_autosave = wp_get_post_autosave( $post_id, $user_id ); if ( ! $autosave_is_different && $old_autosave ) { return $old_autosave->ID; } if ( $old_autosave ) { $new_autosave['ID'] = $old_autosave->ID; $new_autosave['post_author'] = $user_id; do_action( 'wp_creating_autosave', $new_autosave ); $revision_id = wp_update_post( wp_slash( $new_autosave ) ); } else { $revision_id = _wp_put_post_revision( $post_data, true ); } if ( is_wp_error( $revision_id ) || 0 === $revision_id ) { return $revision_id; } if ( ! empty( $meta ) ) { foreach ( $revisioned_meta_keys as $meta_key ) { if ( isset( $meta[ $meta_key ] ) ) { update_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta[ $meta_key ] ) ); } } } return $revision_id; } public function prepare_item_for_response( $item, $request ) { $post = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_autosave', new WP_REST_Response( array() ), $post, $request ); } $response = $this->revisions_controller->prepare_item_for_response( $post, $request ); $fields = $this->get_fields_for_response( $request ); if ( in_array( 'preview_link', $fields, true ) ) { $parent_id = wp_is_post_autosave( $post ); $preview_post_id = false === $parent_id ? $post->ID : $parent_id; $preview_query_args = array(); if ( false !== $parent_id ) { $preview_query_args['preview_id'] = $parent_id; $preview_query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $parent_id ); } $response->data['preview_link'] = get_preview_post_link( $preview_post_id, $preview_query_args ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $response->data = $this->add_additional_fields_to_object( $response->data, $request ); $response->data = $this->filter_response_by_context( $response->data, $context ); return apply_filters( 'rest_prepare_autosave', $response, $post, $request ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php';
class WP_REST_Template_Autosaves_Controller extends WP_REST_Autosaves_Controller { private $parent_post_type; private $parent_controller; private $revisions_controller; private $parent_base; public function __construct( $parent_post_type ) { parent::__construct( $parent_post_type ); $this->parent_post_type = $parent_post_type; $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Templates_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $revisions_controller = $post_type_object->get_revisions_rest_controller(); if ( ! $revisions_controller ) { $revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type ); } $this->revisions_controller = $revisions_controller; $this->rest_base = 'autosaves'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/(?P<id>%s%s)/%s', $this->parent_base, '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', '[\/\w%-]+', $this->rest_base ), array( 'args' => array( 'id' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s/%s', $this->parent_base, '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', '[\/\w%-]+', $this->rest_base, '(?P<id>[\d]+)' ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), 'id' => array( 'description' => __( 'The ID for the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function prepare_item_for_response( $item, $request ) { $template = _build_block_template_result_from_post( $item ); $response = $this->parent_controller->prepare_item_for_response( $template, $request ); if ( $request->is_method( 'HEAD' ) ) { return $response; } $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->post_parent; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template ); $response->add_links( $links ); } return $response; } public function get_item( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $autosave = wp_get_post_autosave( $parent->ID ); if ( ! $autosave ) { return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this template.' ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $autosave, $request ); return $response; } protected function get_parent( $parent_id ) { return $this->revisions_controller->get_parent( $parent_id ); } protected function prepare_links( $template ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ), ), 'parent' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ), ), ); return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = $this->revisions_controller->get_item_schema(); return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-taxonomies-controller.php';
class WP_REST_Taxonomies_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'taxonomies'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<taxonomy>[\w-]+)', array( 'args' => array( 'taxonomy' => array( 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { if ( ! empty( $request['type'] ) ) { $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); } else { $taxonomies = get_taxonomies( '', 'objects' ); } foreach ( $taxonomies as $taxonomy ) { if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->assign_terms ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $registered = $this->get_collection_params(); if ( isset( $registered['type'] ) && ! empty( $request['type'] ) ) { $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); } else { $taxonomies = get_taxonomies( '', 'objects' ); } $data = array(); foreach ( $taxonomies as $tax_type => $value ) { if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->assign_terms ) ) ) { continue; } $tax = $this->prepare_item_for_response( $value, $request ); $tax = $this->prepare_response_for_collection( $tax ); $data[ $tax_type ] = $tax; } if ( empty( $data ) ) { $data = (object) $data; } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { $tax_obj = get_taxonomy( $request['taxonomy'] ); if ( $tax_obj ) { if ( empty( $tax_obj->show_in_rest ) ) { return false; } if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->assign_terms ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } } return true; } public function get_item( $request ) { $tax_obj = get_taxonomy( $request['taxonomy'] ); if ( empty( $tax_obj ) ) { return new WP_Error( 'rest_taxonomy_invalid', __( 'Invalid taxonomy.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $tax_obj, $request ); return rest_ensure_response( $data ); } public function prepare_item_for_response( $item, $request ) { $taxonomy = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_taxonomy', new WP_REST_Response( array() ), $taxonomy, $request ); } $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'name', $fields, true ) ) { $data['name'] = $taxonomy->label; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $taxonomy->name; } if ( in_array( 'capabilities', $fields, true ) ) { $data['capabilities'] = $taxonomy->cap; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $taxonomy->description; } if ( in_array( 'labels', $fields, true ) ) { $data['labels'] = $taxonomy->labels; } if ( in_array( 'types', $fields, true ) ) { $data['types'] = array_values( $taxonomy->object_type ); } if ( in_array( 'show_cloud', $fields, true ) ) { $data['show_cloud'] = $taxonomy->show_tagcloud; } if ( in_array( 'hierarchical', $fields, true ) ) { $data['hierarchical'] = $taxonomy->hierarchical; } if ( in_array( 'rest_base', $fields, true ) ) { $data['rest_base'] = $base; } if ( in_array( 'rest_namespace', $fields, true ) ) { $data['rest_namespace'] = $taxonomy->rest_namespace; } if ( in_array( 'visibility', $fields, true ) ) { $data['visibility'] = array( 'public' => (bool) $taxonomy->public, 'publicly_queryable' => (bool) $taxonomy->publicly_queryable, 'show_admin_column' => (bool) $taxonomy->show_admin_column, 'show_in_nav_menus' => (bool) $taxonomy->show_in_nav_menus, 'show_in_quick_edit' => (bool) $taxonomy->show_in_quick_edit, 'show_ui' => (bool) $taxonomy->show_ui, ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $taxonomy ) ); } return apply_filters( 'rest_prepare_taxonomy', $response, $taxonomy, $request ); } protected function prepare_links( $taxonomy ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'https://api.w.org/items' => array( 'href' => rest_url( rest_get_route_for_taxonomy_items( $taxonomy->name ) ), ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'taxonomy', 'type' => 'object', 'properties' => array( 'capabilities' => array( 'description' => __( 'All capabilities used by the taxonomy.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'A human-readable description of the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hierarchical' => array( 'description' => __( 'Whether or not the taxonomy should have children.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'labels' => array( 'description' => __( 'Human-readable labels for the taxonomy for various contexts.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The title for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'show_cloud' => array( 'description' => __( 'Whether or not the term cloud should be displayed.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'types' => array( 'description' => __( 'Types associated with the taxonomy.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rest_base' => array( 'description' => __( 'REST base route for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rest_namespace' => array( 'description' => __( 'REST namespace route for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'visibility' => array( 'description' => __( 'The visibility settings for the taxonomy.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, 'properties' => array( 'public' => array( 'description' => __( 'Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.' ), 'type' => 'boolean', ), 'publicly_queryable' => array( 'description' => __( 'Whether the taxonomy is publicly queryable.' ), 'type' => 'boolean', ), 'show_ui' => array( 'description' => __( 'Whether to generate a default UI for managing this taxonomy.' ), 'type' => 'boolean', ), 'show_admin_column' => array( 'description' => __( 'Whether to allow automatic creation of taxonomy columns on associated post-types table.' ), 'type' => 'boolean', ), 'show_in_nav_menus' => array( 'description' => __( 'Whether to make the taxonomy available for selection in navigation menus.' ), 'type' => 'boolean', ), 'show_in_quick_edit' => array( 'description' => __( 'Whether to show the taxonomy in the quick/bulk edit panel.' ), 'type' => 'boolean', ), ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $new_params = array(); $new_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $new_params['type'] = array( 'description' => __( 'Limit results to taxonomies associated with a specific post type.' ), 'type' => 'string', ); return $new_params; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.php';
class WP_REST_Terms_Controller extends WP_REST_Controller { protected $taxonomy; protected $meta; protected $sort_column; protected $total_terms; protected $allow_batch = array( 'v1' => true ); public function __construct( $taxonomy ) { $this->taxonomy = $taxonomy; $tax_obj = get_taxonomy( $taxonomy ); $this->rest_base = ! empty( $tax_obj->rest_base ) ? $tax_obj->rest_base : $tax_obj->name; $this->namespace = ! empty( $tax_obj->rest_namespace ) ? $tax_obj->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Term_Meta_Fields( $taxonomy ); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the term.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as terms do not support trashing.' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function check_read_terms_permission_for_post( $post, $request ) { if ( ! is_object_in_taxonomy( $post->post_type, $this->taxonomy ) ) { return false; } if ( is_post_publicly_viewable( $post ) ) { return true; } if ( current_user_can( 'read_post', $post->ID ) ) { return true; } return false; } public function get_items_permissions_check( $request ) { $tax_obj = get_taxonomy( $this->taxonomy ); if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return false; } if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->edit_terms ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['post'] ) ) { $post = get_post( $request['post'] ); if ( ! $post ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 400, ) ); } if ( ! $this->check_read_terms_permission_for_post( $post, $request ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view terms for this post.' ), array( 'status' => rest_authorization_required_code(), ) ); } } return true; } public function get_items( $request ) { $registered = $this->get_collection_params(); $parameter_mappings = array( 'exclude' => 'exclude', 'include' => 'include', 'order' => 'order', 'orderby' => 'orderby', 'post' => 'post', 'hide_empty' => 'hide_empty', 'per_page' => 'number', 'search' => 'search', 'slug' => 'slug', ); $prepared_args = array( 'taxonomy' => $this->taxonomy ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } if ( isset( $prepared_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'include_slugs' => 'slug__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $prepared_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { $prepared_args['offset'] = $request['offset']; } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } $taxonomy_obj = get_taxonomy( $this->taxonomy ); if ( $taxonomy_obj->hierarchical && isset( $registered['parent'], $request['parent'] ) ) { if ( 0 === $request['parent'] ) { $prepared_args['parent'] = 0; } else { if ( $request['parent'] ) { $prepared_args['parent'] = $request['parent']; } } } if ( empty( $prepared_args['post'] ) && isset( $taxonomy_obj->args ) && is_array( $taxonomy_obj->args ) ) { $prepared_args = array_merge( $prepared_args, $taxonomy_obj->args ); } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { $prepared_args['fields'] = 'ids'; $prepared_args['update_term_meta_cache'] = false; } $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request ); if ( ! empty( $prepared_args['post'] ) ) { $query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $prepared_args ); $prepared_args['object_ids'] = $prepared_args['post']; } else { $query_result = get_terms( $prepared_args ); } $count_args = $prepared_args; unset( $count_args['number'], $count_args['offset'] ); $total_terms = wp_count_terms( $count_args ); if ( ! $total_terms ) { $total_terms = 0; } if ( ! $is_head_request ) { $response = array(); foreach ( $query_result as $term ) { if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { continue; } $data = $this->prepare_item_for_response( $term, $request ); $response[] = $this->prepare_response_for_collection( $data ); } } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $response ); $per_page = (int) $prepared_args['number']; $page = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); $response->header( 'X-WP-Total', (int) $total_terms ); $max_pages = (int) ceil( $total_terms / $per_page ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( rest_get_route_for_taxonomy_items( $this->taxonomy ) ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } protected function get_term( $id ) { $error = new WP_Error( 'rest_term_invalid', __( 'Term does not exist.' ), array( 'status' => 404 ) ); if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return $error; } if ( (int) $id <= 0 ) { return $error; } $term = get_term( (int) $id, $this->taxonomy ); if ( empty( $term ) || $term->taxonomy !== $this->taxonomy ) { return $error; } return $term; } public function get_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } public function create_item_permissions_check( $request ) { if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return false; } $taxonomy_obj = get_taxonomy( $this->taxonomy ); if ( ( is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) || ( ! is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function create_item( $request ) { if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); $term = wp_insert_term( wp_slash( $prepared_term->name ), $this->taxonomy, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $term ) ) { $term_id = $term->get_error_data( 'term_exists' ); if ( $term_id ) { $existing_term = get_term( $term_id, $this->taxonomy ); $term->add_data( $existing_term->term_id, 'term_exists' ); $term->add_data( array( 'status' => 400, 'term_id' => $term_id, ) ); } return $term; } $term = get_term( $term['term_id'], $this->taxonomy ); do_action( "rest_insert_{$this->taxonomy}", $term, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, true ); $response = $this->prepare_item_for_response( $term, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( $this->namespace . '/' . $this->rest_base . '/' . $term->term_id ) ); return $response; } public function update_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'edit_term', $term->term_id ) ) { return new WP_Error( 'rest_cannot_update', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function update_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); if ( ! empty( $prepared_term ) ) { $update = wp_update_term( $term->term_id, $term->taxonomy, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $update ) ) { return $update; } } $term = get_term( $term->term_id, $this->taxonomy ); do_action( "rest_insert_{$this->taxonomy}", $term, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, false ); $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } public function delete_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'delete_term', $term->term_id ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Terms do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $request->set_param( 'context', 'view' ); $previous = $this->prepare_item_for_response( $term, $request ); $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { return new WP_Error( 'rest_cannot_delete', __( 'The term cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); do_action( "rest_delete_{$this->taxonomy}", $term, $response, $request ); return $response; } public function prepare_item_for_database( $request ) { $prepared_term = new stdClass(); $schema = $this->get_item_schema(); if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_term->name = $request['name']; } if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { $prepared_term->slug = $request['slug']; } if ( isset( $request['taxonomy'] ) && ! empty( $schema['properties']['taxonomy'] ) ) { $prepared_term->taxonomy = $request['taxonomy']; } if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { $prepared_term->description = $request['description']; } if ( isset( $request['parent'] ) && ! empty( $schema['properties']['parent'] ) ) { $parent_term_id = 0; $requested_parent = (int) $request['parent']; if ( $requested_parent ) { $parent_term = get_term( $requested_parent, $this->taxonomy ); if ( $parent_term instanceof WP_Term ) { $parent_term_id = $parent_term->term_id; } } $prepared_term->parent = $parent_term_id; } return apply_filters( "rest_pre_insert_{$this->taxonomy}", $prepared_term, $request ); } public function prepare_item_for_response( $item, $request ) { if ( $request->is_method( 'HEAD' ) ) { return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response( array() ), $item, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = (int) $item->term_id; } if ( in_array( 'count', $fields, true ) ) { $data['count'] = (int) $item->count; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $item->description; } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_term_link( $item ); } if ( in_array( 'name', $fields, true ) ) { $data['name'] = $item->name; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $item->slug; } if ( in_array( 'taxonomy', $fields, true ) ) { $data['taxonomy'] = $item->taxonomy; } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->parent; } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $item->term_id, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $item ) ); } return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $item, $request ); } protected function prepare_links( $term ) { $links = array( 'self' => array( 'href' => rest_url( rest_get_route_for_term( $term ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_taxonomy_items( $this->taxonomy ) ), ), 'about' => array( 'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $this->taxonomy ) ), ), ); if ( $term->parent ) { $parent_term = get_term( (int) $term->parent, $term->taxonomy ); if ( $parent_term ) { $links['up'] = array( 'href' => rest_url( rest_get_route_for_term( $parent_term ) ), 'embeddable' => true, ); } } $taxonomy_obj = get_taxonomy( $term->taxonomy ); if ( empty( $taxonomy_obj->object_type ) ) { return $links; } $post_type_links = array(); foreach ( $taxonomy_obj->object_type as $type ) { $rest_path = rest_get_route_for_post_type_items( $type ); if ( empty( $rest_path ) ) { continue; } $post_type_links[] = array( 'href' => add_query_arg( $this->rest_base, $term->term_id, rest_url( $rest_path ) ), ); } if ( ! empty( $post_type_links ) ) { $links['https://api.w.org/post_type'] = $post_type_links; } return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the term.' ), 'type' => 'integer', 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), 'count' => array( 'description' => __( 'Number of published posts for the term.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'HTML description of the term.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'link' => array( 'description' => __( 'URL of the term.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'HTML title for the term.' ), 'type' => 'string', 'context' => array( 'view', 'embed', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), 'required' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the term unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'embed', 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'taxonomy' => array( 'description' => __( 'Type attribution for the term.' ), 'type' => 'string', 'enum' => array( $this->taxonomy ), 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), ), ); $taxonomy = get_taxonomy( $this->taxonomy ); if ( $taxonomy->hierarchical ) { $schema['properties']['parent'] = array( 'description' => __( 'The parent term ID.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $taxonomy = get_taxonomy( $this->taxonomy ); $query_params['context']['default'] = 'view'; $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); if ( ! $taxonomy->hierarchical ) { $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); } $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'asc', 'enum' => array( 'asc', 'desc', ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by term attribute.' ), 'type' => 'string', 'default' => 'name', 'enum' => array( 'id', 'include', 'name', 'slug', 'include_slugs', 'term_group', 'description', 'count', ), ); $query_params['hide_empty'] = array( 'description' => __( 'Whether to hide terms not assigned to any posts.' ), 'type' => 'boolean', 'default' => false, ); if ( $taxonomy->hierarchical ) { $query_params['parent'] = array( 'description' => __( 'Limit result set to terms assigned to a specific parent.' ), 'type' => 'integer', ); } $query_params['post'] = array( 'description' => __( 'Limit result set to terms assigned to a specific post.' ), 'type' => 'integer', 'default' => null, ); $query_params['slug'] = array( 'description' => __( 'Limit result set to terms with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); return apply_filters( "rest_{$this->taxonomy}_collection_params", $query_params, $taxonomy ); } protected function check_is_taxonomy_allowed( $taxonomy ) { $taxonomy_obj = get_taxonomy( $taxonomy ); if ( $taxonomy_obj && ! empty( $taxonomy_obj->show_in_rest ) ) { return true; } return false; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-menu-items-controller.php';
class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller { protected function get_nav_menu_item( $id ) { $post = $this->get_post( $id ); if ( is_wp_error( $post ) ) { return $post; } return wp_setup_nav_menu_item( $post ); } public function get_items_permissions_check( $request ) { $has_permission = parent::get_items_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } public function get_item_permissions_check( $request ) { $permission_check = parent::get_item_permissions_check( $request ); if ( true !== $permission_check ) { return $permission_check; } return $this->check_has_read_only_access( $request ); } protected function check_has_read_only_access( $request ) { $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( current_user_can( 'edit_theme_options' ) ) { return true; } if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu items.' ), array( 'status' => rest_authorization_required_code() ) ); } public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $prepared_nav_item = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_nav_item ) ) { return $prepared_nav_item; } $prepared_nav_item = (array) $prepared_nav_item; $nav_menu_item_id = wp_update_nav_menu_item( $prepared_nav_item['menu-id'], $prepared_nav_item['menu-item-db-id'], wp_slash( $prepared_nav_item ), false ); if ( is_wp_error( $nav_menu_item_id ) ) { if ( 'db_insert_error' === $nav_menu_item_id->get_error_code() ) { $nav_menu_item_id->add_data( array( 'status' => 500 ) ); } else { $nav_menu_item_id->add_data( array( 'status' => 400 ) ); } return $nav_menu_item_id; } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); if ( is_wp_error( $nav_menu_item ) ) { $nav_menu_item->add_data( array( 'status' => 404 ) ); return $nav_menu_item; } do_action( 'rest_insert_nav_menu_item', $nav_menu_item, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $nav_menu_item_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); $fields_update = $this->update_additional_fields_for_object( $nav_menu_item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_nav_menu_item', $nav_menu_item, $request, true ); $post = get_post( $nav_menu_item_id ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $nav_menu_item_id ) ) ); return $response; } public function update_item( $request ) { $valid_check = $this->get_nav_menu_item( $request['id'] ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } $post_before = get_post( $request['id'] ); $prepared_nav_item = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_nav_item ) ) { return $prepared_nav_item; } $prepared_nav_item = (array) $prepared_nav_item; $nav_menu_item_id = wp_update_nav_menu_item( $prepared_nav_item['menu-id'], $prepared_nav_item['menu-item-db-id'], wp_slash( $prepared_nav_item ), false ); if ( is_wp_error( $nav_menu_item_id ) ) { if ( 'db_update_error' === $nav_menu_item_id->get_error_code() ) { $nav_menu_item_id->add_data( array( 'status' => 500 ) ); } else { $nav_menu_item_id->add_data( array( 'status' => 400 ) ); } return $nav_menu_item_id; } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); if ( is_wp_error( $nav_menu_item ) ) { $nav_menu_item->add_data( array( 'status' => 404 ) ); return $nav_menu_item; } do_action( 'rest_insert_nav_menu_item', $nav_menu_item, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $nav_menu_item->ID ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $nav_menu_item_id ); $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); $fields_update = $this->update_additional_fields_for_object( $nav_menu_item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_nav_menu_item', $nav_menu_item, $request, false ); wp_after_insert_post( $post, true, $post_before ); $response = $this->prepare_item_for_response( get_post( $nav_menu_item_id ), $request ); return rest_ensure_response( $response ); } public function delete_item( $request ) { $menu_item = $this->get_nav_menu_item( $request['id'] ); if ( is_wp_error( $menu_item ) ) { return $menu_item; } if ( ! $request['force'] ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Menu items do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $previous = $this->prepare_item_for_response( get_post( $request['id'] ), $request ); $result = wp_delete_post( $request['id'], true ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); do_action( 'rest_delete_nav_menu_item', $menu_item, $response, $request ); return $response; } protected function prepare_item_for_database( $request ) { $menu_item_db_id = $request['id']; $menu_item_obj = $this->get_nav_menu_item( $menu_item_db_id ); if ( ! is_wp_error( $menu_item_obj ) ) { $position = ( 0 === $menu_item_obj->menu_order ) ? 1 : $menu_item_obj->menu_order; $prepared_nav_item = array( 'menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => $menu_item_obj->object_id, 'menu-item-object' => $menu_item_obj->object, 'menu-item-parent-id' => $menu_item_obj->menu_item_parent, 'menu-item-position' => $position, 'menu-item-type' => $menu_item_obj->type, 'menu-item-title' => $menu_item_obj->title, 'menu-item-url' => $menu_item_obj->url, 'menu-item-description' => $menu_item_obj->description, 'menu-item-attr-title' => $menu_item_obj->attr_title, 'menu-item-target' => $menu_item_obj->target, 'menu-item-classes' => $menu_item_obj->classes, 'menu-item-xfn' => explode( ' ', $menu_item_obj->xfn ), 'menu-item-status' => $menu_item_obj->post_status, 'menu-id' => $this->get_menu_id( $menu_item_db_id ), ); } else { $prepared_nav_item = array( 'menu-id' => 0, 'menu-item-db-id' => 0, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 1, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => array(), 'menu-item-xfn' => array(), 'menu-item-status' => 'publish', ); } $mapping = array( 'menu-item-db-id' => 'id', 'menu-item-object-id' => 'object_id', 'menu-item-object' => 'object', 'menu-item-parent-id' => 'parent', 'menu-item-position' => 'menu_order', 'menu-item-type' => 'type', 'menu-item-url' => 'url', 'menu-item-description' => 'description', 'menu-item-attr-title' => 'attr_title', 'menu-item-target' => 'target', 'menu-item-classes' => 'classes', 'menu-item-xfn' => 'xfn', 'menu-item-status' => 'status', ); $schema = $this->get_item_schema(); foreach ( $mapping as $original => $api_request ) { if ( isset( $request[ $api_request ] ) ) { $prepared_nav_item[ $original ] = $request[ $api_request ]; } } $taxonomy = get_taxonomy( 'nav_menu' ); $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( ! empty( $request[ $base ] ) ) { $prepared_nav_item['menu-id'] = absint( $request[ $base ] ); } if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $prepared_nav_item['menu-item-title'] = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $prepared_nav_item['menu-item-title'] = $request['title']['raw']; } } $error = new WP_Error(); if ( ! $prepared_nav_item['menu-item-object'] ) { if ( 'taxonomy' === $prepared_nav_item['menu-item-type'] ) { $original = get_term( absint( $prepared_nav_item['menu-item-object-id'] ) ); if ( empty( $original ) || is_wp_error( $original ) ) { $error->add( 'rest_term_invalid_id', __( 'Invalid term ID.' ), array( 'status' => 400 ) ); } else { $prepared_nav_item['menu-item-object'] = get_term_field( 'taxonomy', $original ); } } elseif ( 'post_type' === $prepared_nav_item['menu-item-type'] ) { $original = get_post( absint( $prepared_nav_item['menu-item-object-id'] ) ); if ( empty( $original ) ) { $error->add( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 400 ) ); } else { $prepared_nav_item['menu-item-object'] = get_post_type( $original ); } } } if ( 'post_type_archive' === $prepared_nav_item['menu-item-type'] ) { $post_type = $prepared_nav_item['menu-item-object'] ? $prepared_nav_item['menu-item-object'] : false; $original = get_post_type_object( $post_type ); if ( ! $original ) { $error->add( 'rest_post_invalid_type', __( 'Invalid post type.' ), array( 'status' => 400 ) ); } } if ( 'custom' === $prepared_nav_item['menu-item-type'] ) { if ( '' === $prepared_nav_item['menu-item-title'] ) { $error->add( 'rest_title_required', __( 'The title is required when using a custom menu item type.' ), array( 'status' => 400 ) ); } if ( empty( $prepared_nav_item['menu-item-url'] ) ) { $error->add( 'rest_url_required', __( 'The url is required when using a custom menu item type.' ), array( 'status' => 400 ) ); } } if ( $error->has_errors() ) { return $error; } foreach ( array( 'menu-item-xfn', 'menu-item-classes' ) as $key ) { $prepared_nav_item[ $key ] = implode( ' ', $prepared_nav_item[ $key ] ); } if ( 'publish' !== $prepared_nav_item['menu-item-status'] ) { $prepared_nav_item['menu-item-status'] = 'draft'; } $prepared_nav_item = (object) $prepared_nav_item; return apply_filters( 'rest_pre_insert_nav_menu_item', $prepared_nav_item, $request ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $menu_item = $this->get_nav_menu_item( $item->ID ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $menu_item->ID; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $menu_item->title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $title = apply_filters( 'the_title', $menu_item->title, $menu_item->ID ); $data['title']['rendered'] = $title; remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $menu_item->post_status; } if ( rest_is_field_included( 'url', $fields ) ) { $data['url'] = $menu_item->url; } if ( rest_is_field_included( 'attr_title', $fields ) ) { $data['attr_title'] = $menu_item->attr_title; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $menu_item->description; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $menu_item->type; } if ( rest_is_field_included( 'type_label', $fields ) ) { $data['type_label'] = $menu_item->type_label; } if ( rest_is_field_included( 'object', $fields ) ) { $data['object'] = $menu_item->object; } if ( rest_is_field_included( 'object_id', $fields ) ) { $data['object_id'] = absint( $menu_item->object_id ); } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = (int) $menu_item->menu_item_parent; } if ( rest_is_field_included( 'menu_order', $fields ) ) { $data['menu_order'] = (int) $menu_item->menu_order; } if ( rest_is_field_included( 'target', $fields ) ) { $data['target'] = $menu_item->target; } if ( rest_is_field_included( 'classes', $fields ) ) { $data['classes'] = (array) $menu_item->classes; } if ( rest_is_field_included( 'xfn', $fields ) ) { $data['xfn'] = array_map( 'sanitize_html_class', explode( ' ', $menu_item->xfn ) ); } if ( rest_is_field_included( 'invalid', $fields ) ) { $data['invalid'] = (bool) $menu_item->_invalid; } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $menu_item->ID, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( rest_is_field_included( $base, $fields ) ) { $terms = get_the_terms( $item, $taxonomy->name ); if ( ! is_array( $terms ) ) { continue; } $term_ids = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); if ( 'nav_menu' === $taxonomy->name ) { $data[ $base ] = $term_ids ? array_shift( $term_ids ) : 0; } else { $data[ $base ] = $term_ids; } } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $item, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return apply_filters( 'rest_prepare_nav_menu_item', $response, $menu_item, $request ); } protected function prepare_links( $post ) { $links = parent::prepare_links( $post ); $menu_item = $this->get_nav_menu_item( $post->ID ); if ( empty( $menu_item->object_id ) ) { return $links; } $path = ''; $type = ''; $key = $menu_item->type; if ( 'post_type' === $menu_item->type ) { $path = rest_get_route_for_post( $menu_item->object_id ); $type = get_post_type( $menu_item->object_id ); } elseif ( 'taxonomy' === $menu_item->type ) { $path = rest_get_route_for_term( $menu_item->object_id ); $type = get_term_field( 'taxonomy', $menu_item->object_id ); } if ( $path && $type ) { $links['https://api.w.org/menu-item-object'][] = array( 'href' => rest_url( $path ), $key => $type, 'embeddable' => true, ); } return $links; } protected function get_schema_links() { $links = parent::get_schema_links(); $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" ); $links[] = array( 'rel' => 'https://api.w.org/menu-item-object', 'title' => __( 'Get linked object.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'object' => array( 'type' => 'integer', ), ), ), ); return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', ); $schema['properties']['title'] = array( 'description' => __( 'The title for the object.' ), 'type' => array( 'string', 'object' ), 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the object, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML title for the object, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); $schema['properties']['id'] = array( 'description' => __( 'Unique identifier for the object.' ), 'type' => 'integer', 'default' => 0, 'minimum' => 0, 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['type_label'] = array( 'description' => __( 'The singular label used to describe this type of menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['type'] = array( 'description' => __( 'The family of objects originally represented, such as "post_type" or "taxonomy".' ), 'type' => 'string', 'enum' => array( 'taxonomy', 'post_type', 'post_type_archive', 'custom' ), 'context' => array( 'view', 'edit', 'embed' ), 'default' => 'custom', ); $schema['properties']['status'] = array( 'description' => __( 'A named status for the object.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'default' => 'publish', 'context' => array( 'view', 'edit', 'embed' ), ); $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the object.' ), 'type' => 'integer', 'minimum' => 0, 'default' => 0, 'context' => array( 'view', 'edit', 'embed' ), ); $schema['properties']['attr_title'] = array( 'description' => __( 'Text for the title attribute of the link element for this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['classes'] = array( 'description' => __( 'Class names for the link element of this menu item.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => static function ( $value ) { return array_map( 'sanitize_html_class', wp_parse_list( $value ) ); }, ), ); $schema['properties']['description'] = array( 'description' => __( 'The description of this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['menu_order'] = array( 'description' => __( 'The DB ID of the nav_menu_item that is this item\'s menu parent, if any, otherwise 0.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'integer', 'minimum' => 1, 'default' => 1, ); $schema['properties']['object'] = array( 'description' => __( 'The type of object originally represented, such as "category", "post", or "attachment".' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_key', ), ); $schema['properties']['object_id'] = array( 'description' => __( 'The database ID of the original object this menu item represents, for example the ID for posts or the term_id for categories.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'integer', 'minimum' => 0, 'default' => 0, ); $schema['properties']['target'] = array( 'description' => __( 'The target attribute of the link element for this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( '_blank', '', ), ); $schema['properties']['url'] = array( 'description' => __( 'The URL to which this menu item points.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'validate_callback' => static function ( $url ) { if ( '' === $url ) { return true; } if ( sanitize_url( $url ) ) { return true; } return new WP_Error( 'rest_invalid_url', __( 'Invalid URL.' ) ); }, ), ); $schema['properties']['xfn'] = array( 'description' => __( 'The XFN relationship expressed in the link of this menu item.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => static function ( $value ) { return array_map( 'sanitize_html_class', wp_parse_list( $value ) ); }, ), ); $schema['properties']['invalid'] = array( 'description' => __( 'Whether the menu item represents an object that no longer exists.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'boolean', 'readonly' => true, ); $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $schema['properties'][ $base ] = array( 'description' => sprintf( __( 'The terms assigned to the object in the %s taxonomy.' ), $taxonomy->name ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ); if ( 'nav_menu' === $taxonomy->name ) { $schema['properties'][ $base ]['type'] = 'integer'; unset( $schema['properties'][ $base ]['items'] ); } } $schema['properties']['meta'] = $this->meta->get_field_schema(); $schema_links = $this->get_schema_links(); if ( $schema_links ) { $schema['links'] = $schema_links; } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['menu_order'] = array( 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'asc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.' ), 'type' => 'string', 'default' => 'menu_order', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', 'menu_order', ), ); $query_params['per_page']['default'] = 100; return $query_params; } protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = parent::prepare_items_query( $prepared_args, $request ); if ( isset( $query_args['orderby'], $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', 'menu_order' => 'menu_order', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } $query_args['update_menu_item_cache'] = true; return $query_args; } protected function get_menu_id( $menu_item_id ) { $menu_ids = wp_get_post_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) ); $menu_id = 0; if ( $menu_ids && ! is_wp_error( $menu_ids ) ) { $menu_id = array_shift( $menu_ids ); } return $menu_id; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-menus-controller.php';
class WP_REST_Menus_Controller extends WP_REST_Terms_Controller { public function get_items_permissions_check( $request ) { $has_permission = parent::get_items_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } public function get_item_permissions_check( $request ) { $has_permission = parent::get_item_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } protected function get_term( $id ) { $term = parent::get_term( $id ); if ( is_wp_error( $term ) ) { return $term; } $nav_term = wp_get_nav_menu_object( $term ); $nav_term->auto_add = $this->get_menu_auto_add( $nav_term->term_id ); return $nav_term; } protected function check_has_read_only_access( $request ) { $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( current_user_can( 'edit_theme_options' ) ) { return true; } if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menus.' ), array( 'status' => rest_authorization_required_code() ) ); } public function prepare_item_for_response( $term, $request ) { $nav_menu = wp_get_nav_menu_object( $term ); $response = parent::prepare_item_for_response( $nav_menu, $request ); $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( rest_is_field_included( 'locations', $fields ) ) { $data['locations'] = $this->get_menu_locations( $nav_menu->term_id ); } if ( rest_is_field_included( 'auto_add', $fields ) ) { $data['auto_add'] = $this->get_menu_auto_add( $nav_menu->term_id ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $term ) ); } return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $term, $request ); } protected function prepare_links( $term ) { $links = parent::prepare_links( $term ); $locations = $this->get_menu_locations( $term->term_id ); foreach ( $locations as $location ) { $url = rest_url( sprintf( 'wp/v2/menu-locations/%s', $location ) ); $links['https://api.w.org/menu-location'][] = array( 'href' => $url, 'embeddable' => true, ); } return $links; } public function prepare_item_for_database( $request ) { $prepared_term = parent::prepare_item_for_database( $request ); $schema = $this->get_item_schema(); if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_term->{'menu-name'} = $request['name']; } return $prepared_term; } public function create_item( $request ) { if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = wp_get_nav_menu_object( (int) $request['parent'] ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); $term = wp_update_nav_menu_object( 0, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $term ) ) { if ( in_array( 'menu_exists', $term->get_error_codes(), true ) ) { $existing_term = get_term_by( 'name', $prepared_term->{'menu-name'}, $this->taxonomy ); $term->add_data( $existing_term->term_id, 'menu_exists' ); $term->add_data( array( 'status' => 400, 'term_id' => $existing_term->term_id, ) ); } else { $term->add_data( array( 'status' => 400 ) ); } return $term; } $term = $this->get_term( $term ); do_action( "rest_insert_{$this->taxonomy}", $term, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $locations_update = $this->handle_locations( $term->term_id, $request ); if ( is_wp_error( $locations_update ) ) { return $locations_update; } $this->handle_auto_add( $term->term_id, $request ); $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'view' ); do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, true ); $response = $this->prepare_item_for_response( $term, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( $this->namespace . '/' . $this->rest_base . '/' . $term->term_id ) ); return $response; } public function update_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); if ( ! empty( $prepared_term ) ) { if ( ! isset( $prepared_term->{'menu-name'} ) ) { $prepared_term->{'menu-name'} = $term->name; } $update = wp_update_nav_menu_object( $term->term_id, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $update ) ) { return $update; } } $term = get_term( $term->term_id, $this->taxonomy ); do_action( "rest_insert_{$this->taxonomy}", $term, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $locations_update = $this->handle_locations( $term->term_id, $request ); if ( is_wp_error( $locations_update ) ) { return $locations_update; } $this->handle_auto_add( $term->term_id, $request ); $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'view' ); do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, false ); $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } public function delete_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( ! $request['force'] ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Menus do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $request->set_param( 'context', 'view' ); $previous = $this->prepare_item_for_response( $term, $request ); $result = wp_delete_nav_menu( $term ); if ( ! $result || is_wp_error( $result ) ) { return new WP_Error( 'rest_cannot_delete', __( 'The menu cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); do_action( "rest_delete_{$this->taxonomy}", $term, $response, $request ); return $response; } protected function get_menu_auto_add( $menu_id ) { $nav_menu_option = (array) get_option( 'nav_menu_options', array( 'auto_add' => array() ) ); return in_array( $menu_id, $nav_menu_option['auto_add'], true ); } protected function handle_auto_add( $menu_id, $request ) { if ( ! isset( $request['auto_add'] ) ) { return true; } $nav_menu_option = (array) get_option( 'nav_menu_options', array( 'auto_add' => array() ) ); if ( ! isset( $nav_menu_option['auto_add'] ) ) { $nav_menu_option['auto_add'] = array(); } $auto_add = $request['auto_add']; $i = array_search( $menu_id, $nav_menu_option['auto_add'], true ); if ( $auto_add && false === $i ) { $nav_menu_option['auto_add'][] = $menu_id; } elseif ( ! $auto_add && false !== $i ) { array_splice( $nav_menu_option['auto_add'], $i, 1 ); } $update = update_option( 'nav_menu_options', $nav_menu_option ); do_action( 'wp_update_nav_menu', $menu_id ); return $update; } protected function get_menu_locations( $menu_id ) { $locations = get_nav_menu_locations(); $menu_locations = array(); foreach ( $locations as $location => $assigned_menu_id ) { if ( $menu_id === $assigned_menu_id ) { $menu_locations[] = $location; } } return $menu_locations; } protected function handle_locations( $menu_id, $request ) { if ( ! isset( $request['locations'] ) ) { return true; } $menu_locations = get_registered_nav_menus(); $menu_locations = array_keys( $menu_locations ); $new_locations = array(); foreach ( $request['locations'] as $location ) { if ( ! in_array( $location, $menu_locations, true ) ) { return new WP_Error( 'rest_invalid_menu_location', __( 'Invalid menu location.' ), array( 'status' => 400, 'location' => $location, ) ); } $new_locations[ $location ] = $menu_id; } $assigned_menu = get_nav_menu_locations(); foreach ( $assigned_menu as $location => $term_id ) { if ( $term_id === $menu_id ) { unset( $assigned_menu[ $location ] ); } } $new_assignments = array_merge( $assigned_menu, $new_locations ); set_theme_mod( 'nav_menu_locations', $new_assignments ); return true; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); unset( $schema['properties']['count'], $schema['properties']['link'], $schema['properties']['taxonomy'] ); $schema['properties']['locations'] = array( 'description' => __( 'The locations assigned to the menu.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => static function ( $locations, $request, $param ) { $valid = rest_validate_request_arg( $locations, $request, $param ); if ( true !== $valid ) { return $valid; } $locations = rest_sanitize_request_arg( $locations, $request, $param ); foreach ( $locations as $location ) { if ( ! array_key_exists( $location, get_registered_nav_menus() ) ) { return new WP_Error( 'rest_invalid_menu_location', __( 'Invalid menu location.' ), array( 'location' => $location, ) ); } } return true; }, ), ); $schema['properties']['auto_add'] = array( 'description' => __( 'Whether to automatically add top level pages to this menu.' ), 'context' => array( 'view', 'edit' ), 'type' => 'boolean', ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-menu-locations-controller.php';
class WP_REST_Menu_Locations_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'menu-locations'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<location>[\w-]+)', array( 'args' => array( 'location' => array( 'description' => __( 'An alphanumeric identifier for the menu location.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { return $this->check_has_read_only_access( $request ); } public function get_items( $request ) { $data = array(); foreach ( get_registered_nav_menus() as $name => $description ) { $location = new stdClass(); $location->name = $name; $location->description = $description; $location = $this->prepare_item_for_response( $location, $request ); $data[ $name ] = $this->prepare_response_for_collection( $location ); } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { return $this->check_has_read_only_access( $request ); } public function get_item( $request ) { $registered_menus = get_registered_nav_menus(); if ( ! array_key_exists( $request['location'], $registered_menus ) ) { return new WP_Error( 'rest_menu_location_invalid', __( 'Invalid menu location.' ), array( 'status' => 404 ) ); } $location = new stdClass(); $location->name = $request['location']; $location->description = $registered_menus[ $location->name ]; $data = $this->prepare_item_for_response( $location, $request ); return rest_ensure_response( $data ); } protected function check_has_read_only_access( $request ) { $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu locations.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function prepare_item_for_response( $item, $request ) { $location = $item; $locations = get_nav_menu_locations(); $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'name', $fields ) ) { $data['name'] = $location->name; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $location->description; } if ( rest_is_field_included( 'menu', $fields ) ) { $data['menu'] = (int) $menu; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $location ) ); } return apply_filters( 'rest_prepare_menu_location', $response, $location, $request ); } protected function prepare_links( $location ) { $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); $links = array( 'self' => array( 'href' => rest_url( trailingslashit( $base ) . $location->name ), ), 'collection' => array( 'href' => rest_url( $base ), ), ); $locations = get_nav_menu_locations(); $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; if ( $menu ) { $path = rest_get_route_for_term( $menu ); if ( $path ) { $url = rest_url( $path ); $links['https://api.w.org/menu'][] = array( 'href' => $url, 'embeddable' => true, ); } } return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'menu-location', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The name of the menu location.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'The description of the menu location.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'menu' => array( 'description' => __( 'The ID of the assigned menu.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php';
class WP_REST_Users_Controller extends WP_REST_Controller { protected $meta; protected $allow_batch = array( 'v1' => true ); public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'users'; $this->meta = new WP_REST_User_Meta_Fields(); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the user.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as users do not support trashing.' ), ), 'reassign' => array( 'type' => 'integer', 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 'required' => true, 'sanitize_callback' => array( $this, 'check_reassign' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/me', array( array( 'methods' => WP_REST_Server::READABLE, 'permission_callback' => '__return_true', 'callback' => array( $this, 'get_current_item' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_current_item' ), 'permission_callback' => array( $this, 'update_current_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_current_item' ), 'permission_callback' => array( $this, 'delete_current_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as users do not support trashing.' ), ), 'reassign' => array( 'type' => 'integer', 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 'required' => true, 'sanitize_callback' => array( $this, 'check_reassign' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function check_reassign( $value, $request, $param ) { if ( is_numeric( $value ) ) { return $value; } if ( empty( $value ) || false === $value || 'false' === $value ) { return false; } return new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); } public function get_items_permissions_check( $request ) { if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by role.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['capabilities'] ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by capability.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_forbidden_orderby', __( 'Sorry, you are not allowed to order users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'authors' === $request['who'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( post_type_supports( $type->name, 'author' ) && current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_forbidden_who', __( 'Sorry, you are not allowed to query users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { $registered = $this->get_collection_params(); $parameter_mappings = array( 'exclude' => 'exclude', 'include' => 'include', 'order' => 'order', 'per_page' => 'number', 'search' => 'search', 'roles' => 'role__in', 'capabilities' => 'capability__in', 'slug' => 'nicename__in', ); $prepared_args = array(); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { $prepared_args['offset'] = $request['offset']; } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } if ( isset( $registered['orderby'] ) ) { $orderby_possibles = array( 'id' => 'ID', 'include' => 'include', 'name' => 'display_name', 'registered_date' => 'registered', 'slug' => 'user_nicename', 'include_slugs' => 'nicename__in', 'email' => 'user_email', 'url' => 'user_url', ); $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; } if ( isset( $registered['who'] ) && ! empty( $request['who'] ) && 'authors' === $request['who'] ) { $prepared_args['who'] = 'authors'; } elseif ( ! current_user_can( 'list_users' ) ) { $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); } if ( ! empty( $request['has_published_posts'] ) ) { $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) ? get_post_types( array( 'show_in_rest' => true ), 'names' ) : (array) $request['has_published_posts']; } if ( ! empty( $prepared_args['search'] ) ) { if ( ! current_user_can( 'list_users' ) ) { $prepared_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'display_name' ); } $search_columns = $request->get_param( 'search_columns' ); $valid_columns = isset( $prepared_args['search_columns'] ) ? $prepared_args['search_columns'] : array( 'ID', 'user_login', 'user_nicename', 'user_email', 'display_name' ); $search_columns_mapping = array( 'id' => 'ID', 'username' => 'user_login', 'slug' => 'user_nicename', 'email' => 'user_email', 'name' => 'display_name', ); $search_columns = array_map( static function ( $column ) use ( $search_columns_mapping ) { return $search_columns_mapping[ $column ]; }, $search_columns ); $search_columns = array_intersect( $search_columns, $valid_columns ); if ( ! empty( $search_columns ) ) { $prepared_args['search_columns'] = $search_columns; } $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { $prepared_args['fields'] = 'id'; } $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request ); $query = new WP_User_Query( $prepared_args ); if ( ! $is_head_request ) { $users = array(); foreach ( $query->get_results() as $user ) { if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { continue; } $data = $this->prepare_item_for_response( $user, $request ); $users[] = $this->prepare_response_for_collection( $data ); } } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $users ); $per_page = (int) $prepared_args['number']; $page = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); $prepared_args['fields'] = 'ID'; $total_users = $query->get_total(); if ( $total_users < 1 ) { unset( $prepared_args['number'], $prepared_args['offset'] ); $prepared_args['number'] = 1; $prepared_args['fields'] = 'ID'; $count_query = new WP_User_Query( $prepared_args ); $total_users = $count_query->get_total(); } $response->header( 'X-WP-Total', (int) $total_users ); $max_pages = (int) ceil( $total_users / $per_page ); $response->header( 'X-WP-TotalPages', $max_pages ); $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } protected function get_user( $id ) { $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $user = get_userdata( (int) $id ); if ( empty( $user ) || ! $user->exists() ) { return $error; } if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) { return $error; } return $user; } public function get_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $types = get_post_types( array( 'show_in_rest' => true ), 'names' ); if ( get_current_user_id() === $user->ID ) { return true; } if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) && ! count_user_posts( $user->ID, $types ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $user = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $user ); return $response; } public function get_current_item( $request ) { $current_user_id = get_current_user_id(); if ( empty( $current_user_id ) ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } $user = wp_get_current_user(); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); return $response; } public function create_item_permissions_check( $request ) { if ( ! current_user_can( 'create_users' ) ) { return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create new users.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_user_exists', __( 'Cannot create existing user.' ), array( 'status' => 400 ) ); } $schema = $this->get_item_schema(); if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { $check_permission = $this->check_role_update( $request['id'], $request['roles'] ); if ( is_wp_error( $check_permission ) ) { return $check_permission; } } $user = $this->prepare_item_for_database( $request ); if ( is_multisite() ) { $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) { $error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); foreach ( $ret['errors']->errors as $code => $messages ) { foreach ( $messages as $message ) { $error->add( $code, $message ); } $error_data = $error->get_error_data( $code ); if ( $error_data ) { $error->add_data( $error_data, $code ); } } return $error; } } if ( is_multisite() ) { $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); if ( ! $user_id ) { return new WP_Error( 'rest_user_create', __( 'Error creating new user.' ), array( 'status' => 500 ) ); } $user->ID = $user_id; $user_id = wp_update_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } $result = add_user_to_blog( get_site()->id, $user_id, '' ); if ( is_wp_error( $result ) ) { return $result; } } else { $user_id = wp_insert_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } } $user = get_user_by( 'id', $user_id ); do_action( 'rest_insert_user', $user, $request, true ); if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { array_map( array( $user, 'add_role' ), $request['roles'] ); } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $user_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $user = get_user_by( 'id', $user_id ); $fields_update = $this->update_additional_fields_for_object( $user, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_user', $user, $request, true ); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user_id ) ) ); return $response; } public function update_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } if ( ! empty( $request['roles'] ) ) { if ( ! current_user_can( 'promote_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_edit_roles', __( 'Sorry, you are not allowed to edit roles of this user.' ), array( 'status' => rest_authorization_required_code() ) ); } $request_params = array_keys( $request->get_params() ); sort( $request_params ); if ( array( 'id', 'roles' ) === $request_params ) { return true; } } if ( ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function update_item( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $id = $user->ID; $owner_id = false; if ( is_string( $request['email'] ) ) { $owner_id = email_exists( $request['email'] ); } if ( $owner_id && $owner_id !== $id ) { return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) { return new WP_Error( 'rest_user_invalid_argument', __( 'Username is not editable.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) { return new WP_Error( 'rest_user_invalid_slug', __( 'Invalid slug.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['roles'] ) ) { $check_permission = $this->check_role_update( $id, $request['roles'] ); if ( is_wp_error( $check_permission ) ) { return $check_permission; } } $user = $this->prepare_item_for_database( $request ); $user->ID = $id; $user_id = wp_update_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } $user = get_user_by( 'id', $user_id ); do_action( 'rest_insert_user', $user, $request, false ); if ( ! empty( $request['roles'] ) ) { array_map( array( $user, 'add_role' ), $request['roles'] ); } $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $user = get_user_by( 'id', $user_id ); $fields_update = $this->update_additional_fields_for_object( $user, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_user', $user, $request, false ); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); return $response; } public function update_current_item_permissions_check( $request ) { $request['id'] = get_current_user_id(); return $this->update_item_permissions_check( $request ); } public function update_current_item( $request ) { $request['id'] = get_current_user_id(); return $this->update_item( $request ); } public function delete_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_user', $user->ID ) ) { return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { if ( is_multisite() ) { return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 501 ) ); } $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $id = $user->ID; $reassign = false === $request['reassign'] ? null : absint( $request['reassign'] ); $force = isset( $request['force'] ) ? (bool) $request['force'] : false; if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Users do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { return new WP_Error( 'rest_user_invalid_reassign', __( 'Invalid user ID for reassignment.' ), array( 'status' => 400 ) ); } } $request->set_param( 'context', 'edit' ); $previous = $this->prepare_item_for_response( $user, $request ); require_once ABSPATH . 'wp-admin/includes/user.php'; $result = wp_delete_user( $id, $reassign ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); do_action( 'rest_delete_user', $user, $response, $request ); return $response; } public function delete_current_item_permissions_check( $request ) { $request['id'] = get_current_user_id(); return $this->delete_item_permissions_check( $request ); } public function delete_current_item( $request ) { $request['id'] = get_current_user_id(); return $this->delete_item( $request ); } public function prepare_item_for_response( $item, $request ) { $user = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_user', new WP_REST_Response( array() ), $user, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = $user->ID; } if ( in_array( 'username', $fields, true ) ) { $data['username'] = $user->user_login; } if ( in_array( 'name', $fields, true ) ) { $data['name'] = $user->display_name; } if ( in_array( 'first_name', $fields, true ) ) { $data['first_name'] = $user->first_name; } if ( in_array( 'last_name', $fields, true ) ) { $data['last_name'] = $user->last_name; } if ( in_array( 'email', $fields, true ) ) { $data['email'] = $user->user_email; } if ( in_array( 'url', $fields, true ) ) { $data['url'] = $user->user_url; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $user->description; } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename ); } if ( in_array( 'locale', $fields, true ) ) { $data['locale'] = get_user_locale( $user ); } if ( in_array( 'nickname', $fields, true ) ) { $data['nickname'] = $user->nickname; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $user->user_nicename; } if ( in_array( 'roles', $fields, true ) && ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) ) { $data['roles'] = array_values( $user->roles ); } if ( in_array( 'registered_date', $fields, true ) ) { $data['registered_date'] = gmdate( 'c', strtotime( $user->user_registered ) ); } if ( in_array( 'capabilities', $fields, true ) ) { $data['capabilities'] = (object) $user->allcaps; } if ( in_array( 'extra_capabilities', $fields, true ) ) { $data['extra_capabilities'] = (object) $user->caps; } if ( in_array( 'avatar_urls', $fields, true ) ) { $data['avatar_urls'] = rest_get_avatar_urls( $user ); } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $user->ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'embed'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $user ) ); } return apply_filters( 'rest_prepare_user', $response, $user, $request ); } protected function prepare_links( $user ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); return $links; } protected function prepare_item_for_database( $request ) { $prepared_user = new stdClass(); $schema = $this->get_item_schema(); if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) { $prepared_user->user_email = $request['email']; } if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) { $prepared_user->user_login = $request['username']; } if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) { $prepared_user->user_pass = $request['password']; } if ( isset( $request['id'] ) ) { $prepared_user->ID = absint( $request['id'] ); } if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_user->display_name = $request['name']; } if ( isset( $request['first_name'] ) && ! empty( $schema['properties']['first_name'] ) ) { $prepared_user->first_name = $request['first_name']; } if ( isset( $request['last_name'] ) && ! empty( $schema['properties']['last_name'] ) ) { $prepared_user->last_name = $request['last_name']; } if ( isset( $request['nickname'] ) && ! empty( $schema['properties']['nickname'] ) ) { $prepared_user->nickname = $request['nickname']; } if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { $prepared_user->user_nicename = $request['slug']; } if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { $prepared_user->description = $request['description']; } if ( isset( $request['url'] ) && ! empty( $schema['properties']['url'] ) ) { $prepared_user->user_url = $request['url']; } if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) { $prepared_user->locale = $request['locale']; } if ( isset( $request['roles'] ) ) { $prepared_user->role = false; } return apply_filters( 'rest_pre_insert_user', $prepared_user, $request ); } protected function check_role_update( $user_id, $roles ) { global $wp_roles; foreach ( $roles as $role ) { if ( ! isset( $wp_roles->role_objects[ $role ] ) ) { return new WP_Error( 'rest_user_invalid_role', sprintf( __( 'The role %s does not exist.' ), $role ), array( 'status' => 400 ) ); } $potential_role = $wp_roles->role_objects[ $role ]; if ( ! ( is_multisite() && current_user_can( 'manage_sites' ) ) && get_current_user_id() === $user_id && ! $potential_role->has_cap( 'edit_users' ) ) { return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => rest_authorization_required_code() ) ); } require_once ABSPATH . 'wp-admin/includes/user.php'; $editable_roles = get_editable_roles(); if ( empty( $editable_roles[ $role ] ) ) { return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => 403 ) ); } } return true; } public function check_username( $value, $request, $param ) { $username = (string) $value; if ( ! validate_username( $username ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ), array( 'status' => 400 ) ); } $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) ); } return $username; } public function check_user_password( $value, $request, $param ) { $password = (string) $value; if ( empty( $password ) ) { return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) ); } if ( str_contains( $password, '\\' ) ) { return new WP_Error( 'rest_user_invalid_password', sprintf( __( 'Passwords cannot contain the "%s" character.' ), '\\' ), array( 'status' => 400 ) ); } return $password; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'user', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the user.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'username' => array( 'description' => __( 'Login name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'required' => true, 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_username' ), ), ), 'name' => array( 'description' => __( 'Display name for the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'first_name' => array( 'description' => __( 'First name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'last_name' => array( 'description' => __( 'Last name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'email' => array( 'description' => __( 'The email address for the user.' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'edit' ), 'required' => true, ), 'url' => array( 'description' => __( 'URL of the user.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ), 'description' => array( 'description' => __( 'Description of the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'link' => array( 'description' => __( 'Author URL of the user.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'locale' => array( 'description' => __( 'Locale for the user.' ), 'type' => 'string', 'enum' => array_merge( array( '', 'en_US' ), get_available_languages() ), 'context' => array( 'edit' ), ), 'nickname' => array( 'description' => __( 'The nickname for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'registered_date' => array( 'description' => __( 'Registration date for the user.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'edit' ), 'readonly' => true, ), 'roles' => array( 'description' => __( 'Roles assigned to the user.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'edit' ), ), 'password' => array( 'description' => __( 'Password for the user (never included).' ), 'type' => 'string', 'context' => array(), 'required' => true, 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_user_password' ), ), ), 'capabilities' => array( 'description' => __( 'All capabilities assigned to the user.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'extra_capabilities' => array( 'description' => __( 'Any extra capabilities assigned to the user.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), ), ); if ( get_option( 'show_avatars' ) ) { $avatar_properties = array(); $avatar_sizes = rest_get_avatar_sizes(); foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['avatar_urls'] = array( 'description' => __( 'Avatar URLs for the user.' ), 'type' => 'object', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, 'properties' => $avatar_properties, ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'default' => 'asc', 'description' => __( 'Order sort attribute ascending or descending.' ), 'enum' => array( 'asc', 'desc' ), 'type' => 'string', ); $query_params['orderby'] = array( 'default' => 'name', 'description' => __( 'Sort collection by user attribute.' ), 'enum' => array( 'id', 'include', 'name', 'registered_date', 'slug', 'include_slugs', 'email', 'url', ), 'type' => 'string', ); $query_params['slug'] = array( 'description' => __( 'Limit result set to users with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['roles'] = array( 'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['capabilities'] = array( 'description' => __( 'Limit result set to users matching at least one specific capability provided. Accepts csv list or single capability.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['who'] = array( 'description' => __( 'Limit result set to users who are considered authors.' ), 'type' => 'string', 'enum' => array( 'authors', ), ); $query_params['has_published_posts'] = array( 'description' => __( 'Limit result set to users who have published posts.' ), 'type' => array( 'boolean', 'array' ), 'items' => array( 'type' => 'string', 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), ), ); $query_params['search_columns'] = array( 'default' => array(), 'description' => __( 'Array of column names to be searched.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'email', 'name', 'id', 'username', 'slug' ), 'type' => 'string', ), ); return apply_filters( 'rest_user_collection_params', $query_params ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php';
class WP_REST_Comments_Controller extends WP_REST_Controller { protected $meta; public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'comments'; $this->meta = new WP_REST_Comment_Meta_Fields(); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the comment.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'password' => array( 'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ), 'type' => 'string', ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), 'password' => array( 'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ), 'type' => 'string', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $is_note = 'note' === $request['type']; $is_edit_context = 'edit' === $request['context']; $protected_params = array( 'author', 'author_exclude', 'author_email', 'type', 'status' ); $forbidden_params = array(); if ( ! empty( $request['post'] ) ) { foreach ( (array) $request['post'] as $post_id ) { $post = get_post( $post_id ); if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } elseif ( 0 === $post_id && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to read comments without a post.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( $post && $is_note && ! $this->check_post_type_supports_notes( $post->post_type ) ) { if ( current_user_can( 'edit_post', $post->ID ) ) { return new WP_Error( 'rest_comment_not_supported_post_type', __( 'Sorry, this post type does not support notes.' ), array( 'status' => 403 ) ); } foreach ( $protected_params as $param ) { if ( 'status' === $param ) { if ( 'approve' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( 'type' === $param ) { if ( 'comment' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( ! empty( $request[ $param ] ) ) { $forbidden_params[] = $param; } } return new WP_Error( 'rest_forbidden_param', sprintf( __( 'Query parameter not permitted: %s' ), implode( ', ', $forbidden_params ) ), array( 'status' => rest_authorization_required_code() ) ); } } } if ( $is_edit_context && $is_note && ! empty( $request['post'] ) ) { foreach ( (array) $request['post'] as $post_id ) { if ( ! current_user_can( 'edit_post', $post_id ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit comments.' ), array( 'status' => rest_authorization_required_code() ) ); } } } elseif ( $is_edit_context && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit comments.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'edit_posts' ) ) { foreach ( $protected_params as $param ) { if ( 'status' === $param ) { if ( 'approve' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( 'type' === $param ) { if ( 'comment' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( ! empty( $request[ $param ] ) ) { $forbidden_params[] = $param; } } if ( ! empty( $forbidden_params ) ) { return new WP_Error( 'rest_forbidden_param', sprintf( __( 'Query parameter not permitted: %s' ), implode( ', ', $forbidden_params ) ), array( 'status' => rest_authorization_required_code() ) ); } } return true; } public function get_items( $request ) { $registered = $this->get_collection_params(); $parameter_mappings = array( 'author' => 'author__in', 'author_email' => 'author_email', 'author_exclude' => 'author__not_in', 'exclude' => 'comment__not_in', 'include' => 'comment__in', 'offset' => 'offset', 'order' => 'order', 'parent' => 'parent__in', 'parent_exclude' => 'parent__not_in', 'per_page' => 'number', 'post' => 'post__in', 'search' => 'search', 'status' => 'status', 'type' => 'type', ); $prepared_args = array(); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } foreach ( array( 'author_email', 'search' ) as $param ) { if ( ! isset( $prepared_args[ $param ] ) ) { $prepared_args[ $param ] = ''; } } if ( isset( $registered['orderby'] ) ) { $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); } $prepared_args['no_found_rows'] = false; $prepared_args['update_comment_post_cache'] = true; $prepared_args['date_query'] = array(); if ( isset( $registered['before'], $request['before'] ) ) { $prepared_args['date_query'][0]['before'] = $request['before']; } if ( isset( $registered['after'], $request['after'] ) ) { $prepared_args['date_query'][0]['after'] = $request['after']; } if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { $prepared_args['fields'] = 'ids'; $prepared_args['update_comment_meta_cache'] = false; } $prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request ); $query = new WP_Comment_Query(); $query_result = $query->query( $prepared_args ); if ( ! $is_head_request ) { $comments = array(); foreach ( $query_result as $comment ) { if ( ! $this->check_read_permission( $comment, $request ) ) { continue; } $data = $this->prepare_item_for_response( $comment, $request ); $comments[] = $this->prepare_response_for_collection( $data ); } } $total_comments = (int) $query->found_comments; $max_pages = (int) $query->max_num_pages; if ( $total_comments < 1 ) { unset( $prepared_args['number'], $prepared_args['offset'] ); $query = new WP_Comment_Query(); $prepared_args['count'] = true; $prepared_args['orderby'] = 'none'; $prepared_args['update_comment_meta_cache'] = false; $total_comments = $query->query( $prepared_args ); $max_pages = (int) ceil( $total_comments / $request['per_page'] ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $comments ); $response->header( 'X-WP-Total', $total_comments ); $response->header( 'X-WP-TotalPages', $max_pages ); $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $request['page'] > 1 ) { $prev_page = $request['page'] - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $request['page'] ) { $next_page = $request['page'] + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } protected function get_comment( $id ) { $error = new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $id = (int) $id; $comment = get_comment( $id ); if ( empty( $comment ) ) { return $error; } if ( ! empty( $comment->comment_post_ID ) ) { $post = get_post( (int) $comment->comment_post_ID ); if ( empty( $post ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) ); } } return $comment; } public function get_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $edit_cap = 'note' === $comment->comment_type ? array( 'edit_comment', $comment->comment_ID ) : array( 'moderate_comments' ); if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( ...$edit_cap ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit comments.' ), array( 'status' => rest_authorization_required_code() ) ); } $post = get_post( $comment->comment_post_ID ); if ( ! $this->check_read_permission( $comment, $request ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to read this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( $post && ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $data = $this->prepare_item_for_response( $comment, $request ); $response = rest_ensure_response( $data ); return $response; } public function create_item_permissions_check( $request ) { $is_note = ! empty( $request['type'] ) && 'note' === $request['type']; if ( ! is_user_logged_in() && $is_note ) { return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) ); } if ( ! is_user_logged_in() ) { if ( get_option( 'comment_registration' ) ) { return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) ); } $allow_anonymous = apply_filters( 'rest_allow_anonymous_comments', false, $request ); if ( ! $allow_anonymous ) { return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) ); } } if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_comment_invalid_author', sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author' ), array( 'status' => rest_authorization_required_code() ) ); } if ( isset( $request['author_ip'] ) && ! current_user_can( 'moderate_comments' ) ) { if ( empty( $_SERVER['REMOTE_ADDR'] ) || $request['author_ip'] !== $_SERVER['REMOTE_ADDR'] ) { return new WP_Error( 'rest_comment_invalid_author_ip', sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author_ip' ), array( 'status' => rest_authorization_required_code() ) ); } } if ( $is_note && ! empty( $request['post'] ) && ! current_user_can( 'edit_post', (int) $request['post'] ) ) { return new WP_Error( 'rest_cannot_create_note', __( 'Sorry, you are not allowed to create notes for this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $edit_cap = $is_note ? array( 'edit_post', (int) $request['post'] ) : array( 'moderate_comments' ); if ( isset( $request['status'] ) && ! current_user_can( ...$edit_cap ) ) { return new WP_Error( 'rest_comment_invalid_status', sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'status' ), array( 'status' => rest_authorization_required_code() ) ); } if ( empty( $request['post'] ) ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Sorry, you are not allowed to create this comment without a post.' ), array( 'status' => 403 ) ); } $post = get_post( (int) $request['post'] ); if ( ! $post ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Sorry, you are not allowed to create this comment without a post.' ), array( 'status' => 403 ) ); } if ( $is_note && ! $this->check_post_type_supports_notes( $post->post_type ) ) { return new WP_Error( 'rest_comment_not_supported_post_type', __( 'Sorry, this post type does not support notes.' ), array( 'status' => 403 ) ); } if ( 'draft' === $post->post_status && ! $is_note ) { return new WP_Error( 'rest_comment_draft_post', __( 'Sorry, you are not allowed to create a comment on this post.' ), array( 'status' => 403 ) ); } if ( 'trash' === $post->post_status ) { return new WP_Error( 'rest_comment_trash_post', __( 'Sorry, you are not allowed to create a comment on this post.' ), array( 'status' => 403 ) ); } if ( ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! comments_open( $post->ID ) && ! $is_note ) { return new WP_Error( 'rest_comment_closed', __( 'Sorry, comments are closed for this item.' ), array( 'status' => 403 ) ); } return true; } public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_comment_exists', __( 'Cannot create existing comment.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['type'] ) && ! in_array( $request['type'], array( 'comment', 'note' ), true ) ) { return new WP_Error( 'rest_invalid_comment_type', __( 'Cannot create a comment with that type.' ), array( 'status' => 400 ) ); } $prepared_comment = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_comment ) ) { return $prepared_comment; } $prepared_comment['comment_type'] = $request['type']; if ( ! isset( $prepared_comment['comment_content'] ) ) { $prepared_comment['comment_content'] = ''; } if ( isset( $request['meta']['_wp_note_status'] ) ) { $prepared_comment['meta']['_wp_note_status'] = $request['meta']['_wp_note_status']; } if ( ! $this->check_is_comment_content_allowed( $prepared_comment ) ) { return new WP_Error( 'rest_comment_content_invalid', __( 'Invalid comment content.' ), array( 'status' => 400 ) ); } if ( ! isset( $prepared_comment['comment_date_gmt'] ) ) { $prepared_comment['comment_date_gmt'] = current_time( 'mysql', true ); } $missing_author = empty( $prepared_comment['user_id'] ) && empty( $prepared_comment['comment_author'] ) && empty( $prepared_comment['comment_author_email'] ) && empty( $prepared_comment['comment_author_url'] ); if ( is_user_logged_in() && $missing_author ) { $user = wp_get_current_user(); $prepared_comment['user_id'] = $user->ID; $prepared_comment['comment_author'] = $user->display_name; $prepared_comment['comment_author_email'] = $user->user_email; $prepared_comment['comment_author_url'] = $user->user_url; } if ( get_option( 'require_name_email' ) ) { if ( empty( $prepared_comment['comment_author'] ) || empty( $prepared_comment['comment_author_email'] ) ) { return new WP_Error( 'rest_comment_author_data_required', __( 'Creating a comment requires valid author name and email values.' ), array( 'status' => 400 ) ); } } if ( ! isset( $prepared_comment['comment_author_email'] ) ) { $prepared_comment['comment_author_email'] = ''; } if ( ! isset( $prepared_comment['comment_author_url'] ) ) { $prepared_comment['comment_author_url'] = ''; } if ( ! isset( $prepared_comment['comment_agent'] ) ) { $prepared_comment['comment_agent'] = ''; } $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_comment ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = $check_comment_lengths->get_error_code(); return new WP_Error( $error_code, __( 'Comment field exceeds maximum length allowed.' ), array( 'status' => 400 ) ); } $prepared_comment['comment_approved'] = 'note' === $prepared_comment['comment_type'] ? '1' : wp_allow_comment( $prepared_comment, true ); if ( is_wp_error( $prepared_comment['comment_approved'] ) ) { $error_code = $prepared_comment['comment_approved']->get_error_code(); $error_message = $prepared_comment['comment_approved']->get_error_message(); if ( 'comment_duplicate' === $error_code ) { return new WP_Error( $error_code, $error_message, array( 'status' => 409 ) ); } if ( 'comment_flood' === $error_code ) { return new WP_Error( $error_code, $error_message, array( 'status' => 400 ) ); } return $prepared_comment['comment_approved']; } $prepared_comment = apply_filters( 'rest_pre_insert_comment', $prepared_comment, $request ); if ( is_wp_error( $prepared_comment ) ) { return $prepared_comment; } $comment_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_comment ) ) ); if ( ! $comment_id ) { return new WP_Error( 'rest_comment_failed_create', __( 'Creating comment failed.' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { $this->handle_status_param( $request['status'], $comment_id ); } $comment = get_comment( $comment_id ); do_action( 'rest_insert_comment', $comment, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $comment_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $comment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; $request->set_param( 'context', $context ); do_action( 'rest_after_insert_comment', $comment, $request, true ); $response = $this->prepare_item_for_response( $comment, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment_id ) ) ); return $response; } public function update_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } if ( ! $this->check_edit_permission( $comment ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function update_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $id = $comment->comment_ID; if ( isset( $request['type'] ) && get_comment_type( $id ) !== $request['type'] ) { return new WP_Error( 'rest_comment_invalid_type', __( 'Sorry, you are not allowed to change the comment type.' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_args ) ) { return $prepared_args; } if ( ! empty( $prepared_args['comment_post_ID'] ) ) { $post = get_post( $prepared_args['comment_post_ID'] ); if ( empty( $post ) ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Invalid post ID.' ), array( 'status' => 403 ) ); } } if ( empty( $prepared_args ) && isset( $request['status'] ) ) { $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { return new WP_Error( 'rest_comment_failed_edit', __( 'Updating comment status failed.' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { return $prepared_args; } if ( ! $this->check_is_comment_content_allowed( $prepared_args ) ) { return new WP_Error( 'rest_comment_content_invalid', __( 'Invalid comment content.' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = $check_comment_lengths->get_error_code(); return new WP_Error( $error_code, __( 'Comment field exceeds maximum length allowed.' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ), true ); if ( is_wp_error( $updated ) ) { return new WP_Error( 'rest_comment_failed_edit', __( 'Updating comment failed.' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { $this->handle_status_param( $request['status'], $id ); } } $comment = get_comment( $id ); do_action( 'rest_insert_comment', $comment, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $comment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); do_action( 'rest_after_insert_comment', $comment, $request, false ); $response = $this->prepare_item_for_response( $comment, $request ); return rest_ensure_response( $response ); } public function delete_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } if ( ! $this->check_edit_permission( $comment ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; $supports_trash = apply_filters( 'rest_comment_trashable', ( EMPTY_TRASH_DAYS > 0 ), $comment ); $request->set_param( 'context', 'edit' ); if ( $force ) { $previous = $this->prepare_item_for_response( $comment, $request ); $result = wp_delete_comment( $comment->comment_ID, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { if ( ! $supports_trash ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( "The comment does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $comment->comment_approved ) { return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $comment->comment_ID ); $comment = get_comment( $comment->comment_ID ); $response = $this->prepare_item_for_response( $comment, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The comment cannot be deleted.' ), array( 'status' => 500 ) ); } do_action( 'rest_delete_comment', $comment, $response, $request ); return $response; } public function prepare_item_for_response( $item, $request ) { $comment = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_comment', new WP_REST_Response( array() ), $comment, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = (int) $comment->comment_ID; } if ( in_array( 'post', $fields, true ) ) { $data['post'] = (int) $comment->comment_post_ID; } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $comment->comment_parent; } if ( in_array( 'author', $fields, true ) ) { $data['author'] = (int) $comment->user_id; } if ( in_array( 'author_name', $fields, true ) ) { $data['author_name'] = $comment->comment_author; } if ( in_array( 'author_email', $fields, true ) ) { $data['author_email'] = $comment->comment_author_email; } if ( in_array( 'author_url', $fields, true ) ) { $data['author_url'] = $comment->comment_author_url; } if ( in_array( 'author_ip', $fields, true ) ) { $data['author_ip'] = $comment->comment_author_IP; } if ( in_array( 'author_user_agent', $fields, true ) ) { $data['author_user_agent'] = $comment->comment_agent; } if ( in_array( 'date', $fields, true ) ) { $data['date'] = mysql_to_rfc3339( $comment->comment_date ); } if ( in_array( 'date_gmt', $fields, true ) ) { $data['date_gmt'] = mysql_to_rfc3339( $comment->comment_date_gmt ); } if ( in_array( 'content', $fields, true ) ) { $data['content'] = array( 'rendered' => apply_filters( 'comment_text', $comment->comment_content, $comment, array() ), 'raw' => $comment->comment_content, ); } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_comment_link( $comment ); } if ( in_array( 'status', $fields, true ) ) { $data['status'] = $this->prepare_status_response( $comment->comment_approved ); } if ( in_array( 'type', $fields, true ) ) { $data['type'] = get_comment_type( $comment->comment_ID ); } if ( in_array( 'author_avatar_urls', $fields, true ) ) { $data['author_avatar_urls'] = rest_get_avatar_urls( $comment ); } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $comment->comment_ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $comment ) ); } return apply_filters( 'rest_prepare_comment', $response, $comment, $request ); } protected function prepare_links( $comment ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); if ( 0 !== (int) $comment->user_id ) { $links['author'] = array( 'href' => rest_url( 'wp/v2/users/' . $comment->user_id ), 'embeddable' => true, ); } if ( 0 !== (int) $comment->comment_post_ID ) { $post = get_post( $comment->comment_post_ID ); $post_route = rest_get_route_for_post( $post ); if ( ! empty( $post->ID ) && $post_route ) { $links['up'] = array( 'href' => rest_url( $post_route ), 'embeddable' => true, 'post_type' => $post->post_type, ); } } if ( 0 !== (int) $comment->comment_parent ) { $links['in-reply-to'] = array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_parent ) ), 'embeddable' => true, ); } $comment_children = $comment->get_children( array( 'count' => true, 'orderby' => 'none', 'type' => 'all', ) ); if ( ! empty( $comment_children ) ) { $args = array( 'parent' => $comment->comment_ID, ); $rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) ); $links['children'] = array( 'href' => $rest_url, 'embeddable' => true, ); } if ( isset( $links['children'] ) && 'note' === $comment->comment_type ) { $args = array( 'parent' => $comment->comment_ID, 'type' => $comment->comment_type, 'status' => 'all', ); $rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) ); $links['children'] = array( 'href' => $rest_url, 'embeddable' => true, ); } return $links; } protected function normalize_query_param( $query_param ) { $prefix = 'comment_'; switch ( $query_param ) { case 'id': $normalized = $prefix . 'ID'; break; case 'post': $normalized = $prefix . 'post_ID'; break; case 'parent': $normalized = $prefix . 'parent'; break; case 'include': $normalized = 'comment__in'; break; default: $normalized = $prefix . $query_param; break; } return $normalized; } protected function prepare_status_response( $comment_approved ) { switch ( $comment_approved ) { case 'hold': case '0': $status = 'hold'; break; case 'approve': case '1': $status = 'approved'; break; case 'spam': case 'trash': default: $status = $comment_approved; break; } return $status; } protected function prepare_item_for_database( $request ) { $prepared_comment = array(); if ( isset( $request['content'] ) && is_string( $request['content'] ) ) { $prepared_comment['comment_content'] = trim( $request['content'] ); } elseif ( isset( $request['content']['raw'] ) && is_string( $request['content']['raw'] ) ) { $prepared_comment['comment_content'] = trim( $request['content']['raw'] ); } if ( isset( $request['post'] ) ) { $prepared_comment['comment_post_ID'] = (int) $request['post']; } if ( isset( $request['parent'] ) ) { $prepared_comment['comment_parent'] = $request['parent']; } if ( isset( $request['author'] ) ) { $user = new WP_User( $request['author'] ); if ( $user->exists() ) { $prepared_comment['user_id'] = $user->ID; $prepared_comment['comment_author'] = $user->display_name; $prepared_comment['comment_author_email'] = $user->user_email; $prepared_comment['comment_author_url'] = $user->user_url; } else { return new WP_Error( 'rest_comment_author_invalid', __( 'Invalid comment author ID.' ), array( 'status' => 400 ) ); } } if ( isset( $request['author_name'] ) ) { $prepared_comment['comment_author'] = $request['author_name']; } if ( isset( $request['author_email'] ) ) { $prepared_comment['comment_author_email'] = $request['author_email']; } if ( isset( $request['author_url'] ) ) { $prepared_comment['comment_author_url'] = $request['author_url']; } if ( isset( $request['author_ip'] ) && current_user_can( 'moderate_comments' ) ) { $prepared_comment['comment_author_IP'] = $request['author_ip']; } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( $_SERVER['REMOTE_ADDR'] ) ) { $prepared_comment['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; } else { $prepared_comment['comment_author_IP'] = '127.0.0.1'; } if ( ! empty( $request['author_user_agent'] ) ) { $prepared_comment['comment_agent'] = $request['author_user_agent']; } elseif ( $request->get_header( 'user_agent' ) ) { $prepared_comment['comment_agent'] = $request->get_header( 'user_agent' ); } if ( ! empty( $request['date'] ) ) { $date_data = rest_get_date_with_gmt( $request['date'] ); if ( ! empty( $date_data ) ) { list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; } } elseif ( ! empty( $request['date_gmt'] ) ) { $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) ) { list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; } } return apply_filters( 'rest_preprocess_comment', $prepared_comment, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'comment', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the comment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'author' => array( 'description' => __( 'The ID of the user object, if author was a user.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'author_email' => array( 'description' => __( 'Email address for the comment author.' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_comment_author_email' ), 'validate_callback' => null, ), ), 'author_ip' => array( 'description' => __( 'IP address for the comment author.' ), 'type' => 'string', 'format' => 'ip', 'context' => array( 'edit' ), ), 'author_name' => array( 'description' => __( 'Display name for the comment author.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'author_url' => array( 'description' => __( 'URL for the comment author.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), ), 'author_user_agent' => array( 'description' => __( 'User agent for the comment author.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'content' => array( 'description' => __( 'The content for the comment.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => null, ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the comment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML content for the comment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), 'date' => array( 'description' => __( "The date the comment was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the comment was published, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'link' => array( 'description' => __( 'URL to the comment.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'parent' => array( 'description' => __( 'The ID for the parent of the comment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'default' => 0, ), 'post' => array( 'description' => __( 'The ID of the associated post object.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'default' => 0, ), 'status' => array( 'description' => __( 'State of the comment.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_key', ), ), 'type' => array( 'description' => __( 'Type of the comment.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, 'default' => 'comment', ), ), ); if ( get_option( 'show_avatars' ) ) { $avatar_properties = array(); $avatar_sizes = rest_get_avatar_sizes(); foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['author_avatar_urls'] = array( 'description' => __( 'Avatar URLs for the comment author.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, 'properties' => $avatar_properties, ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['after'] = array( 'description' => __( 'Limit response to comments published after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['author'] = array( 'description' => __( 'Limit result set to comments assigned to specific user IDs. Requires authorization.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['author_exclude'] = array( 'description' => __( 'Ensure result set excludes comments assigned to specific user IDs. Requires authorization.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['author_email'] = array( 'default' => null, 'description' => __( 'Limit result set to that from a specific author email. Requires authorization.' ), 'format' => 'email', 'type' => 'string', ); $query_params['before'] = array( 'description' => __( 'Limit response to comments published before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc', ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by comment attribute.' ), 'type' => 'string', 'default' => 'date_gmt', 'enum' => array( 'date', 'date_gmt', 'id', 'include', 'post', 'parent', 'type', ), ); $query_params['parent'] = array( 'default' => array(), 'description' => __( 'Limit result set to comments of specific parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['parent_exclude'] = array( 'default' => array(), 'description' => __( 'Ensure result set excludes specific parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['post'] = array( 'default' => array(), 'description' => __( 'Limit result set to comments assigned to specific post IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['status'] = array( 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $query_params['type'] = array( 'default' => 'comment', 'description' => __( 'Limit result set to comments assigned a specific type. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $query_params['password'] = array( 'description' => __( 'The password for the post if it is password protected.' ), 'type' => 'string', ); return apply_filters( 'rest_comment_collection_params', $query_params ); } protected function handle_status_param( $new_status, $comment_id ) { $old_status = wp_get_comment_status( $comment_id ); if ( $new_status === $old_status ) { return false; } switch ( $new_status ) { case 'approved': case 'approve': case '1': $changed = wp_set_comment_status( $comment_id, 'approve' ); break; case 'hold': case '0': $changed = wp_set_comment_status( $comment_id, 'hold' ); break; case 'spam': $changed = wp_spam_comment( $comment_id ); break; case 'unspam': $changed = wp_unspam_comment( $comment_id ); break; case 'trash': $changed = wp_trash_comment( $comment_id ); break; case 'untrash': $changed = wp_untrash_comment( $comment_id ); break; default: $changed = false; break; } return $changed; } protected function check_read_post_permission( $post, $request ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { return false; } $posts_controller = $post_type->get_rest_controller(); if ( ! $posts_controller instanceof WP_REST_Posts_Controller ) { $posts_controller = new WP_REST_Posts_Controller( $post->post_type ); } $has_password_filter = false; $requested_post = ! empty( $request['post'] ) && ( ! is_array( $request['post'] ) || 1 === count( $request['post'] ) ); $requested_comment = ! empty( $request['id'] ); if ( ( $requested_post || $requested_comment ) && $posts_controller->can_access_password_content( $post, $request ) ) { add_filter( 'post_password_required', '__return_false' ); $has_password_filter = true; } if ( post_password_required( $post ) ) { $result = current_user_can( 'edit_post', $post->ID ); } else { $result = $posts_controller->check_read_permission( $post ); } if ( $has_password_filter ) { remove_filter( 'post_password_required', '__return_false' ); } return $result; } protected function check_read_permission( $comment, $request ) { if ( 'note' !== $comment->comment_type && ! empty( $comment->comment_post_ID ) ) { $post = get_post( $comment->comment_post_ID ); if ( $post ) { if ( $this->check_read_post_permission( $post, $request ) && 1 === (int) $comment->comment_approved ) { return true; } } } if ( 0 === get_current_user_id() ) { return false; } if ( empty( $comment->comment_post_ID ) && ! current_user_can( 'moderate_comments' ) ) { return false; } if ( ! empty( $comment->user_id ) && get_current_user_id() === (int) $comment->user_id ) { return true; } return current_user_can( 'edit_comment', $comment->comment_ID ); } protected function check_edit_permission( $comment ) { if ( 0 === (int) get_current_user_id() ) { return false; } if ( current_user_can( 'moderate_comments' ) ) { return true; } return current_user_can( 'edit_comment', $comment->comment_ID ); } public function check_comment_author_email( $value, $request, $param ) { $email = (string) $value; if ( empty( $email ) ) { return $email; } $check_email = rest_validate_request_arg( $email, $request, $param ); if ( is_wp_error( $check_email ) ) { return $check_email; } return $email; } protected function check_is_comment_content_allowed( $prepared_comment ) { if ( ! isset( $prepared_comment['comment_content'] ) ) { return true; } $check = wp_parse_args( $prepared_comment, array( 'comment_post_ID' => 0, 'comment_author' => null, 'comment_author_email' => null, 'comment_author_url' => null, 'comment_parent' => 0, 'user_id' => 0, ) ); $allow_empty = apply_filters( 'allow_empty_comment', false, $check ); if ( $allow_empty ) { return true; } if ( isset( $check['comment_type'] ) && 'note' === $check['comment_type'] && isset( $check['meta']['_wp_note_status'] ) && in_array( $check['meta']['_wp_note_status'], array( 'resolved', 'reopen' ), true ) ) { return true; } return '' !== $check['comment_content']; } private function check_post_type_supports_notes( $post_type ) { $supports = get_all_post_type_supports( $post_type ); if ( ! isset( $supports['editor'] ) ) { return false; } if ( ! is_array( $supports['editor'] ) ) { return false; } foreach ( $supports['editor'] as $item ) { if ( ! empty( $item['notes'] ) ) { return true; } } return false; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-search-controller.php';
class WP_REST_Search_Controller extends WP_REST_Controller { const PROP_ID = 'id'; const PROP_TITLE = 'title'; const PROP_URL = 'url'; const PROP_TYPE = 'type'; const PROP_SUBTYPE = 'subtype'; const TYPE_ANY = 'any'; protected $search_handlers = array(); public function __construct( array $search_handlers ) { $this->namespace = 'wp/v2'; $this->rest_base = 'search'; foreach ( $search_handlers as $search_handler ) { if ( ! $search_handler instanceof WP_REST_Search_Handler ) { _doing_it_wrong( __METHOD__, sprintf( __( 'REST search handlers must extend the %s class.' ), 'WP_REST_Search_Handler' ), '5.0.0' ); continue; } $this->search_handlers[ $search_handler->get_type() ] = $search_handler; } } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permission_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permission_check( $request ) { return true; } public function get_items( $request ) { $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return $handler; } $result = $handler->search_items( $request ); if ( ! isset( $result[ WP_REST_Search_Handler::RESULT_IDS ] ) || ! is_array( $result[ WP_REST_Search_Handler::RESULT_IDS ] ) || ! isset( $result[ WP_REST_Search_Handler::RESULT_TOTAL ] ) ) { return new WP_Error( 'rest_search_handler_error', __( 'Internal search handler error.' ), array( 'status' => 500 ) ); } $ids = $result[ WP_REST_Search_Handler::RESULT_IDS ]; $is_head_request = $request->is_method( 'HEAD' ); if ( ! $is_head_request ) { $results = array(); foreach ( $ids as $id ) { $data = $this->prepare_item_for_response( $id, $request ); $results[] = $this->prepare_response_for_collection( $data ); } } $total = (int) $result[ WP_REST_Search_Handler::RESULT_TOTAL ]; $page = (int) $request['page']; $per_page = (int) $request['per_page']; $max_pages = (int) ceil( $total / $per_page ); if ( $page > $max_pages && $total > 0 ) { return new WP_Error( 'rest_search_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $results ); $response->header( 'X-WP-Total', $total ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $base = add_query_arg( urlencode_deep( $request_params ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_link = add_query_arg( 'page', $page - 1, $base ); $response->link_header( 'prev', $prev_link ); } if ( $page < $max_pages ) { $next_link = add_query_arg( 'page', $page + 1, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function prepare_item_for_response( $item, $request ) { $item_id = $item; $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return new WP_REST_Response(); } $fields = $this->get_fields_for_response( $request ); $data = $handler->prepare_item( $item_id, $fields ); $data = $this->add_additional_fields_to_object( $data, $request ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $handler->prepare_item_links( $item_id ); $links['collection'] = array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ); $response->add_links( $links ); } return $response; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $types = array(); $subtypes = array(); foreach ( $this->search_handlers as $search_handler ) { $types[] = $search_handler->get_type(); $subtypes = array_merge( $subtypes, $search_handler->get_subtypes() ); } $types = array_unique( $types ); $subtypes = array_unique( $subtypes ); $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'search-result', 'type' => 'object', 'properties' => array( self::PROP_ID => array( 'description' => __( 'Unique identifier for the object.' ), 'type' => array( 'integer', 'string' ), 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_TITLE => array( 'description' => __( 'The title for the object.' ), 'type' => 'string', 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_URL => array( 'description' => __( 'URL to the object.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_TYPE => array( 'description' => __( 'Object type.' ), 'type' => 'string', 'enum' => $types, 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_SUBTYPE => array( 'description' => __( 'Object subtype.' ), 'type' => 'string', 'enum' => $subtypes, 'context' => array( 'view', 'embed' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $types = array(); $subtypes = array(); foreach ( $this->search_handlers as $search_handler ) { $types[] = $search_handler->get_type(); $subtypes = array_merge( $subtypes, $search_handler->get_subtypes() ); } $types = array_unique( $types ); $subtypes = array_unique( $subtypes ); $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params[ self::PROP_TYPE ] = array( 'default' => $types[0], 'description' => __( 'Limit results to items of an object type.' ), 'type' => 'string', 'enum' => $types, ); $query_params[ self::PROP_SUBTYPE ] = array( 'default' => self::TYPE_ANY, 'description' => __( 'Limit results to items of one or more object subtypes.' ), 'type' => 'array', 'items' => array( 'enum' => array_merge( $subtypes, array( self::TYPE_ANY ) ), 'type' => 'string', ), 'sanitize_callback' => array( $this, 'sanitize_subtypes' ), ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); return $query_params; } public function sanitize_subtypes( $subtypes, $request, $parameter ) { $subtypes = wp_parse_slug_list( $subtypes ); $subtypes = rest_parse_request_arg( $subtypes, $request, $parameter ); if ( is_wp_error( $subtypes ) ) { return $subtypes; } if ( in_array( self::TYPE_ANY, $subtypes, true ) ) { return array( self::TYPE_ANY ); } $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return $handler; } return array_intersect( $subtypes, $handler->get_subtypes() ); } protected function get_search_handler( $request ) { $type = $request->get_param( self::PROP_TYPE ); if ( ! $type || ! is_string( $type ) || ! isset( $this->search_handlers[ $type ] ) ) { return new WP_Error( 'rest_search_invalid_type', __( 'Invalid type parameter.' ), array( 'status' => 400 ) ); } return $this->search_handlers[ $type ]; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-blocks-controller.php';
class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller { public function check_read_permission( $post ) { if ( ! current_user_can( 'read_post', $post->ID ) ) { return false; } return parent::check_read_permission( $post ); } public function filter_response_by_context( $data, $context ) { $data = parent::filter_response_by_context( $data, $context ); unset( $data['title']['rendered'] ); unset( $data['content']['rendered'] ); $data['wp_pattern_sync_status'] = isset( $data['meta']['wp_pattern_sync_status'] ) ? $data['meta']['wp_pattern_sync_status'] : ''; unset( $data['meta']['wp_pattern_sync_status'] ); return $data; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); $schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' ); $schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' ); unset( $schema['properties']['title']['properties']['rendered'] ); unset( $schema['properties']['content']['properties']['rendered'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-types-controller.php';
class WP_REST_Block_Types_Controller extends WP_REST_Controller { const NAME_PATTERN = '^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$'; protected $block_registry; protected $style_registry; public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-types'; $this->block_registry = WP_Block_Type_Registry::get_instance(); $this->style_registry = WP_Block_Styles_Registry::get_instance(); } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<namespace>[a-zA-Z0-9_-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<namespace>[a-zA-Z0-9_-]+)/(?P<name>[a-zA-Z0-9_-]+)', array( 'args' => array( 'name' => array( 'description' => __( 'Block name.' ), 'type' => 'string', ), 'namespace' => array( 'description' => __( 'Block namespace.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { return $this->check_read_permission(); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $data = array(); $block_types = $this->block_registry->get_all_registered(); $registered = $this->get_collection_params(); $namespace = ''; if ( isset( $registered['namespace'] ) && ! empty( $request['namespace'] ) ) { $namespace = $request['namespace']; } foreach ( $block_types as $obj ) { if ( $namespace ) { list ( $block_namespace ) = explode( '/', $obj->name ); if ( $namespace !== $block_namespace ) { continue; } } $block_type = $this->prepare_item_for_response( $obj, $request ); $data[] = $this->prepare_response_for_collection( $block_type ); } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { $check = $this->check_read_permission(); if ( is_wp_error( $check ) ) { return $check; } $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); $block_type = $this->get_block( $block_name ); if ( is_wp_error( $block_type ) ) { return $block_type; } return true; } protected function check_read_permission() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_block_type_cannot_view', __( 'Sorry, you are not allowed to manage block types.' ), array( 'status' => rest_authorization_required_code() ) ); } protected function get_block( $name ) { $block_type = $this->block_registry->get_registered( $name ); if ( empty( $block_type ) ) { return new WP_Error( 'rest_block_type_invalid', __( 'Invalid block type.' ), array( 'status' => 404 ) ); } return $block_type; } public function get_item( $request ) { $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); $block_type = $this->get_block( $block_name ); if ( is_wp_error( $block_type ) ) { return $block_type; } $data = $this->prepare_item_for_response( $block_type, $request ); return rest_ensure_response( $data ); } public function prepare_item_for_response( $item, $request ) { $block_type = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_block_type', new WP_REST_Response( array() ), $block_type, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'attributes', $fields ) ) { $data['attributes'] = $block_type->get_attributes(); } if ( rest_is_field_included( 'is_dynamic', $fields ) ) { $data['is_dynamic'] = $block_type->is_dynamic(); } $schema = $this->get_item_schema(); $deprecated_fields = array( 'editor_script', 'script', 'view_script', 'editor_style', 'style', ); $extra_fields = array_merge( array( 'api_version', 'name', 'title', 'description', 'icon', 'category', 'keywords', 'parent', 'ancestor', 'allowed_blocks', 'provides_context', 'uses_context', 'selectors', 'supports', 'styles', 'textdomain', 'example', 'editor_script_handles', 'script_handles', 'view_script_handles', 'view_script_module_ids', 'editor_style_handles', 'style_handles', 'view_style_handles', 'variations', 'block_hooks', ), $deprecated_fields ); foreach ( $extra_fields as $extra_field ) { if ( rest_is_field_included( $extra_field, $fields ) ) { if ( isset( $block_type->$extra_field ) ) { $field = $block_type->$extra_field; if ( in_array( $extra_field, $deprecated_fields, true ) && is_array( $field ) ) { $field = ! empty( $field ) ? array_shift( $field ) : ''; } } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) { $field = $schema['properties'][ $extra_field ]['default']; } else { $field = ''; } $data[ $extra_field ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $extra_field ] ); } } if ( rest_is_field_included( 'styles', $fields ) ) { $styles = $this->style_registry->get_registered_styles_for_block( $block_type->name ); $styles = array_values( $styles ); $data['styles'] = wp_parse_args( $styles, $data['styles'] ); $data['styles'] = array_filter( $data['styles'] ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $block_type ) ); } return apply_filters( 'rest_prepare_block_type', $response, $block_type, $request ); } protected function prepare_links( $block_type ) { list( $namespace ) = explode( '/', $block_type->name ); $links = array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $block_type->name ) ), ), 'up' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $namespace ) ), ), ); if ( $block_type->is_dynamic() ) { $links['https://api.w.org/render-block'] = array( 'href' => add_query_arg( 'context', 'edit', rest_url( sprintf( '%s/%s/%s', 'wp/v2', 'block-renderer', $block_type->name ) ) ), ); } return $links; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $inner_blocks_definition = array( 'description' => __( 'The list of inner blocks used in the example.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The name of the inner block.' ), 'type' => 'string', 'pattern' => self::NAME_PATTERN, 'required' => true, ), 'attributes' => array( 'description' => __( 'The attributes of the inner block.' ), 'type' => 'object', ), 'innerBlocks' => array( 'description' => __( "A list of the inner block's own inner blocks. This is a recursive definition following the parent innerBlocks schema." ), 'type' => 'array', ), ), ), ); $example_definition = array( 'description' => __( 'Block example.' ), 'type' => array( 'object', 'null' ), 'default' => null, 'properties' => array( 'attributes' => array( 'description' => __( 'The attributes used in the example.' ), 'type' => 'object', ), 'innerBlocks' => $inner_blocks_definition, ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $keywords_definition = array( 'description' => __( 'Block keywords.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $icon_definition = array( 'description' => __( 'Icon of block type.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $category_definition = array( 'description' => __( 'Block category.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-type', 'type' => 'object', 'properties' => array( 'api_version' => array( 'description' => __( 'Version of block API.' ), 'type' => 'integer', 'default' => 1, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'title' => array( 'description' => __( 'Title of block type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Unique name identifying the block type.' ), 'type' => 'string', 'pattern' => self::NAME_PATTERN, 'required' => true, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of block type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'icon' => $icon_definition, 'attributes' => array( 'description' => __( 'Block attributes.' ), 'type' => array( 'object', 'null' ), 'properties' => array(), 'default' => null, 'additionalProperties' => array( 'type' => 'object', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'provides_context' => array( 'description' => __( 'Context provided by blocks of this type.' ), 'type' => 'object', 'properties' => array(), 'additionalProperties' => array( 'type' => 'string', ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'uses_context' => array( 'description' => __( 'Context values inherited by blocks of this type.' ), 'type' => 'array', 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'selectors' => array( 'description' => __( 'Custom CSS selectors.' ), 'type' => 'object', 'default' => array(), 'properties' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'supports' => array( 'description' => __( 'Block supports.' ), 'type' => 'object', 'default' => array(), 'properties' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'category' => $category_definition, 'is_dynamic' => array( 'description' => __( 'Is the block dynamically rendered.' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_script_handles' => array( 'description' => __( 'Editor script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'script_handles' => array( 'description' => __( 'Public facing and editor script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script_handles' => array( 'description' => __( 'Public facing script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script_module_ids' => array( 'description' => __( 'Public facing script module IDs.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_style_handles' => array( 'description' => __( 'Editor style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'style_handles' => array( 'description' => __( 'Public facing and editor style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_style_handles' => array( 'description' => __( 'Public facing style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'styles' => array( 'description' => __( 'Block style variations.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'Unique name identifying the style.' ), 'type' => 'string', 'required' => true, ), 'label' => array( 'description' => __( 'The human-readable label for the style.' ), 'type' => 'string', ), 'inline_style' => array( 'description' => __( 'Inline CSS code that registers the CSS class required for the style.' ), 'type' => 'string', ), 'style_handle' => array( 'description' => __( 'Contains the handle that defines the block style.' ), 'type' => 'string', ), ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'variations' => array( 'description' => __( 'Block variations.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The unique and machine-readable name.' ), 'type' => 'string', 'required' => true, ), 'title' => array( 'description' => __( 'A human-readable variation title.' ), 'type' => 'string', 'required' => true, ), 'description' => array( 'description' => __( 'A detailed variation description.' ), 'type' => 'string', 'required' => false, ), 'category' => $category_definition, 'icon' => $icon_definition, 'isDefault' => array( 'description' => __( 'Indicates whether the current variation is the default one.' ), 'type' => 'boolean', 'required' => false, 'default' => false, ), 'attributes' => array( 'description' => __( 'The initial values for attributes.' ), 'type' => 'object', ), 'innerBlocks' => $inner_blocks_definition, 'example' => $example_definition, 'scope' => array( 'description' => __( 'The list of scopes where the variation is applicable. When not provided, it assumes all available scopes.' ), 'type' => array( 'array', 'null' ), 'default' => null, 'items' => array( 'type' => 'string', 'enum' => array( 'block', 'inserter', 'transform' ), ), 'readonly' => true, ), 'keywords' => $keywords_definition, ), ), 'readonly' => true, 'context' => array( 'embed', 'view', 'edit' ), 'default' => null, ), 'textdomain' => array( 'description' => __( 'Public text domain.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'parent' => array( 'description' => __( 'Parent blocks.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'ancestor' => array( 'description' => __( 'Ancestor blocks.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'allowed_blocks' => array( 'description' => __( 'Allowed child block types.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'keywords' => $keywords_definition, 'example' => $example_definition, 'block_hooks' => array( 'description' => __( 'This block is automatically inserted near any occurrence of the block types used as keys of this map, into a relative position given by the corresponding value.' ), 'type' => 'object', 'patternProperties' => array( self::NAME_PATTERN => array( 'type' => 'string', 'enum' => array( 'before', 'after', 'first_child', 'last_child' ), ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); $deprecated_properties = array( 'editor_script' => array( 'description' => __( 'Editor script handle. DEPRECATED: Use `editor_script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'script' => array( 'description' => __( 'Public facing and editor script handle. DEPRECATED: Use `script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script' => array( 'description' => __( 'Public facing script handle. DEPRECATED: Use `view_script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_style' => array( 'description' => __( 'Editor style handle. DEPRECATED: Use `editor_style_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'style' => array( 'description' => __( 'Public facing and editor style handle. DEPRECATED: Use `style_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ); $this->schema['properties'] = array_merge( $this->schema['properties'], $deprecated_properties ); return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'namespace' => array( 'description' => __( 'Block namespace.' ), 'type' => 'string', ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-renderer-controller.php';
class WP_REST_Block_Renderer_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-renderer'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<name>[a-z0-9-]+/[a-z0-9-]+)', array( 'args' => array( 'name' => array( 'description' => __( 'Unique registered name for the block.' ), 'type' => 'string', ), ), array( 'methods' => array( WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ), 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'attributes' => array( 'description' => __( 'Attributes for the block.' ), 'type' => 'object', 'default' => array(), 'validate_callback' => static function ( $value, $request ) { $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] ); if ( ! $block ) { return true; } $schema = array( 'type' => 'object', 'properties' => $block->get_attributes(), 'additionalProperties' => false, ); return rest_validate_value_from_schema( $value, $schema ); }, 'sanitize_callback' => static function ( $value, $request ) { $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] ); if ( ! $block ) { return true; } $schema = array( 'type' => 'object', 'properties' => $block->get_attributes(), 'additionalProperties' => false, ); return rest_sanitize_value_from_schema( $value, $schema ); }, ), 'post_id' => array( 'description' => __( 'ID of the post context.' ), 'type' => 'integer', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_item_permissions_check( $request ) { global $post; $post_id = isset( $request['post_id'] ) ? (int) $request['post_id'] : 0; if ( $post_id > 0 ) { $post = get_post( $post_id ); if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { return new WP_Error( 'block_cannot_read', __( 'Sorry, you are not allowed to read blocks of this post.' ), array( 'status' => rest_authorization_required_code(), ) ); } } else { if ( ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'block_cannot_read', __( 'Sorry, you are not allowed to read blocks as this user.' ), array( 'status' => rest_authorization_required_code(), ) ); } } return true; } public function get_item( $request ) { global $post; $post_id = isset( $request['post_id'] ) ? (int) $request['post_id'] : 0; if ( $post_id > 0 ) { $post = get_post( $post_id ); setup_postdata( $post ); } $registry = WP_Block_Type_Registry::get_instance(); $registered = $registry->get_registered( $request['name'] ); if ( null === $registered || ! $registered->is_dynamic() ) { return new WP_Error( 'block_invalid', __( 'Invalid block.' ), array( 'status' => 404, ) ); } $attributes = $request->get_param( 'attributes' ); $block = array( 'blockName' => $request['name'], 'attrs' => $attributes, 'innerHTML' => '', 'innerContent' => array(), ); $data = array( 'rendered' => render_block( $block ), ); return rest_ensure_response( $data ); } public function get_item_schema() { if ( $this->schema ) { return $this->schema; } $this->schema = array( '$schema' => 'http://json-schema.org/schema#', 'title' => 'rendered-block', 'type' => 'object', 'properties' => array( 'rendered' => array( 'description' => __( 'The rendered block.' ), 'type' => 'string', 'required' => true, 'context' => array( 'edit' ), ), ), ); return $this->schema; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php';
class WP_REST_Settings_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'settings'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'args' => array(), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_item_permissions_check( $request ) { return current_user_can( 'manage_options' ); } public function get_item( $request ) { $options = $this->get_registered_options(); $response = array(); foreach ( $options as $name => $args ) { $response[ $name ] = apply_filters( 'rest_pre_get_setting', null, $name, $args ); if ( is_null( $response[ $name ] ) ) { $response[ $name ] = get_option( $args['option_name'], $args['schema']['default'] ); } $response[ $name ] = $this->prepare_value( $response[ $name ], $args['schema'] ); } return $response; } protected function prepare_value( $value, $schema ) { if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { return null; } return rest_sanitize_value_from_schema( $value, $schema ); } public function update_item( $request ) { $options = $this->get_registered_options(); $params = $request->get_params(); foreach ( $options as $name => $args ) { if ( ! array_key_exists( $name, $params ) ) { continue; } $updated = apply_filters( 'rest_pre_update_setting', false, $name, $request[ $name ], $args ); if ( $updated ) { continue; } if ( is_null( $request[ $name ] ) ) { if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) { return new WP_Error( 'rest_invalid_stored_value', sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); } delete_option( $args['option_name'] ); } else { update_option( $args['option_name'], $request[ $name ] ); } } return $this->get_item( $request ); } protected function get_registered_options() { $rest_options = array(); foreach ( get_registered_settings() as $name => $args ) { if ( empty( $args['show_in_rest'] ) ) { continue; } $rest_args = array(); if ( is_array( $args['show_in_rest'] ) ) { $rest_args = $args['show_in_rest']; } $defaults = array( 'name' => ! empty( $rest_args['name'] ) ? $rest_args['name'] : $name, 'schema' => array(), ); $rest_args = array_merge( $defaults, $rest_args ); $default_schema = array( 'type' => empty( $args['type'] ) ? null : $args['type'], 'title' => empty( $args['label'] ) ? '' : $args['label'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); $rest_args['option_name'] = $name; if ( empty( $rest_args['schema']['type'] ) ) { continue; } if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean', 'array', 'object' ), true ) ) { continue; } $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); $rest_options[ $rest_args['name'] ] = $rest_args; } return $rest_options; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $options = $this->get_registered_options(); $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings', 'type' => 'object', 'properties' => array(), ); foreach ( $options as $option_name => $option ) { $schema['properties'][ $option_name ] = $option['schema']; $schema['properties'][ $option_name ]['arg_options'] = array( 'sanitize_callback' => array( $this, 'sanitize_callback' ), ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function sanitize_callback( $value, $request, $param ) { if ( is_null( $value ) ) { return $value; } return rest_parse_request_arg( $value, $request, $param ); } protected function set_additional_properties_to_false( $schema ) { _deprecated_function( __METHOD__, '6.1.0', 'rest_default_additional_properties_to_false()' ); return rest_default_additional_properties_to_false( $schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php';
class WP_REST_Themes_Controller extends WP_REST_Controller { const PATTERN = '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?'; public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'themes'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<stylesheet>%s)', $this->rest_base, self::PATTERN ), array( 'args' => array( 'stylesheet' => array( 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_stylesheet_callback' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function _sanitize_stylesheet_callback( $stylesheet ) { return urldecode( $stylesheet ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) { return true; } $registered = $this->get_collection_params(); if ( isset( $registered['status'], $request['status'] ) && is_array( $request['status'] ) && array( 'active' ) === $request['status'] ) { return $this->check_read_active_theme_permission(); } return new WP_Error( 'rest_cannot_view_themes', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) ); } public function get_item_permissions_check( $request ) { if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) { return true; } $wp_theme = wp_get_theme( $request['stylesheet'] ); $current_theme = wp_get_theme(); if ( $this->is_same_theme( $wp_theme, $current_theme ) ) { return $this->check_read_active_theme_permission(); } return new WP_Error( 'rest_cannot_view_themes', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) ); } protected function check_read_active_theme_permission() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view_active_theme', __( 'Sorry, you are not allowed to view the active theme.' ), array( 'status' => rest_authorization_required_code() ) ); } public function get_item( $request ) { $wp_theme = wp_get_theme( $request['stylesheet'] ); if ( ! $wp_theme->exists() ) { return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $wp_theme, $request ); return rest_ensure_response( $data ); } public function get_items( $request ) { $themes = array(); $active_themes = wp_get_themes(); $current_theme = wp_get_theme(); $status = $request['status']; foreach ( $active_themes as $theme ) { $theme_status = ( $this->is_same_theme( $theme, $current_theme ) ) ? 'active' : 'inactive'; if ( is_array( $status ) && ! in_array( $theme_status, $status, true ) ) { continue; } $prepared = $this->prepare_item_for_response( $theme, $request ); $themes[] = $this->prepare_response_for_collection( $prepared ); } $response = rest_ensure_response( $themes ); $response->header( 'X-WP-Total', count( $themes ) ); $response->header( 'X-WP-TotalPages', 1 ); return $response; } public function prepare_item_for_response( $item, $request ) { $theme = $item; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'stylesheet', $fields ) ) { $data['stylesheet'] = $theme->get_stylesheet(); } if ( rest_is_field_included( 'template', $fields ) ) { $data['template'] = $theme->get_template(); } $plain_field_mappings = array( 'requires_php' => 'RequiresPHP', 'requires_wp' => 'RequiresWP', 'textdomain' => 'TextDomain', 'version' => 'Version', ); foreach ( $plain_field_mappings as $field => $header ) { if ( rest_is_field_included( $field, $fields ) ) { $data[ $field ] = $theme->get( $header ); } } if ( rest_is_field_included( 'screenshot', $fields ) ) { $data['screenshot'] = $theme->get_screenshot() ? $theme->get_screenshot() : ''; } $rich_field_mappings = array( 'author' => 'Author', 'author_uri' => 'AuthorURI', 'description' => 'Description', 'name' => 'Name', 'tags' => 'Tags', 'theme_uri' => 'ThemeURI', ); foreach ( $rich_field_mappings as $field => $header ) { if ( rest_is_field_included( "{$field}.raw", $fields ) ) { $data[ $field ]['raw'] = $theme->display( $header, false, true ); } if ( rest_is_field_included( "{$field}.rendered", $fields ) ) { $data[ $field ]['rendered'] = $theme->display( $header ); } } $current_theme = wp_get_theme(); if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = ( $this->is_same_theme( $theme, $current_theme ) ) ? 'active' : 'inactive'; } if ( rest_is_field_included( 'theme_supports', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { foreach ( get_registered_theme_features() as $feature => $config ) { if ( ! is_array( $config['show_in_rest'] ) ) { continue; } $name = $config['show_in_rest']['name']; if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) { continue; } if ( ! current_theme_supports( $feature ) ) { $data['theme_supports'][ $name ] = $config['show_in_rest']['schema']['default']; continue; } $support = get_theme_support( $feature ); if ( isset( $config['show_in_rest']['prepare_callback'] ) ) { $prepare = $config['show_in_rest']['prepare_callback']; } else { $prepare = array( $this, 'prepare_theme_support' ); } $prepared = $prepare( $support, $config, $feature, $request ); if ( is_wp_error( $prepared ) ) { continue; } $data['theme_supports'][ $name ] = $prepared; } } if ( rest_is_field_included( 'is_block_theme', $fields ) ) { $data['is_block_theme'] = $theme->is_block_theme(); } if ( rest_is_field_included( 'stylesheet_uri', $fields ) ) { if ( $this->is_same_theme( $theme, $current_theme ) ) { $data['stylesheet_uri'] = get_stylesheet_directory_uri(); } else { $data['stylesheet_uri'] = $theme->get_stylesheet_directory_uri(); } } if ( rest_is_field_included( 'template_uri', $fields ) ) { if ( $this->is_same_theme( $theme, $current_theme ) ) { $data['template_uri'] = get_template_directory_uri(); } else { $data['template_uri'] = $theme->get_template_directory_uri(); } } if ( rest_is_field_included( 'default_template_types', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { $default_template_types = array(); foreach ( get_default_block_template_types() as $slug => $template_type ) { $template_type['slug'] = (string) $slug; $default_template_types[] = $template_type; } $data['default_template_types'] = $default_template_types; } if ( rest_is_field_included( 'default_template_part_areas', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { $data['default_template_part_areas'] = get_allowed_block_template_part_areas(); } $data = $this->add_additional_fields_to_object( $data, $request ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $theme ) ); } return apply_filters( 'rest_prepare_theme', $response, $theme, $request ); } protected function prepare_links( $theme ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $theme->get_stylesheet() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); if ( $this->is_same_theme( $theme, wp_get_theme() ) ) { $id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id(); } else { $user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme ); $id = isset( $user_cpt['ID'] ) ? $user_cpt['ID'] : null; } if ( $id ) { $links['https://api.w.org/user-global-styles'] = array( 'href' => rest_url( 'wp/v2/global-styles/' . $id ), ); } if ( $theme->is_block_theme() && $this->is_same_theme( $theme, wp_get_theme() ) ) { $links['https://api.w.org/export-theme'] = array( 'href' => rest_url( 'wp-block-editor/v1/export' ), 'targetHints' => array( 'allow' => current_user_can( 'export' ) ? array( 'GET' ) : array(), ), ); } return $links; } protected function is_same_theme( $theme_a, $theme_b ) { return $theme_a->get_stylesheet() === $theme_b->get_stylesheet(); } protected function prepare_theme_support( $support, $args, $feature, $request ) { $schema = $args['show_in_rest']['schema']; if ( 'boolean' === $schema['type'] ) { return true; } if ( is_array( $support ) && ! $args['variadic'] ) { $support = $support[0]; } return rest_sanitize_value_from_schema( $support, $schema ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'theme', 'type' => 'object', 'properties' => array( 'stylesheet' => array( 'description' => __( 'The theme\'s stylesheet. This uniquely identifies the theme.' ), 'type' => 'string', 'readonly' => true, ), 'stylesheet_uri' => array( 'description' => __( 'The uri for the theme\'s stylesheet directory.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'template' => array( 'description' => __( 'The theme\'s template. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet.' ), 'type' => 'string', 'readonly' => true, ), 'template_uri' => array( 'description' => __( 'The uri for the theme\'s template directory. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet directory.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'author' => array( 'description' => __( 'The theme author.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme author\'s name, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'HTML for the theme author, transformed for display.' ), 'type' => 'string', ), ), ), 'author_uri' => array( 'description' => __( 'The website of the theme author.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The website of the theme author, as found in the theme header.' ), 'type' => 'string', 'format' => 'uri', ), 'rendered' => array( 'description' => __( 'The website of the theme author, transformed for display.' ), 'type' => 'string', 'format' => 'uri', ), ), ), 'description' => array( 'description' => __( 'A description of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme description, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The theme description, transformed for display.' ), 'type' => 'string', ), ), ), 'is_block_theme' => array( 'description' => __( 'Whether the theme is a block-based theme.' ), 'type' => 'boolean', 'readonly' => true, ), 'name' => array( 'description' => __( 'The name of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme name, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The theme name, transformed for display.' ), 'type' => 'string', ), ), ), 'requires_php' => array( 'description' => __( 'The minimum PHP version required for the theme to work.' ), 'type' => 'string', 'readonly' => true, ), 'requires_wp' => array( 'description' => __( 'The minimum WordPress version required for the theme to work.' ), 'type' => 'string', 'readonly' => true, ), 'screenshot' => array( 'description' => __( 'The theme\'s screenshot URL.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'tags' => array( 'description' => __( 'Tags indicating styles and features of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme tags, as found in the theme header.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ), 'rendered' => array( 'description' => __( 'The theme tags, transformed for display.' ), 'type' => 'string', ), ), ), 'textdomain' => array( 'description' => __( 'The theme\'s text domain.' ), 'type' => 'string', 'readonly' => true, ), 'theme_supports' => array( 'description' => __( 'Features supported by this theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array(), ), 'theme_uri' => array( 'description' => __( 'The URI of the theme\'s webpage.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The URI of the theme\'s webpage, as found in the theme header.' ), 'type' => 'string', 'format' => 'uri', ), 'rendered' => array( 'description' => __( 'The URI of the theme\'s webpage, transformed for display.' ), 'type' => 'string', 'format' => 'uri', ), ), ), 'version' => array( 'description' => __( 'The theme\'s current version.' ), 'type' => 'string', 'readonly' => true, ), 'status' => array( 'description' => __( 'A named status for the theme.' ), 'type' => 'string', 'enum' => array( 'inactive', 'active' ), ), 'default_template_types' => array( 'description' => __( 'A list of default template types.' ), 'type' => 'array', 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'slug' => array( 'type' => 'string', ), 'title' => array( 'type' => 'string', ), 'description' => array( 'type' => 'string', ), ), ), ), 'default_template_part_areas' => array( 'description' => __( 'A list of allowed area values for template parts.' ), 'type' => 'array', 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'area' => array( 'type' => 'string', ), 'label' => array( 'type' => 'string', ), 'description' => array( 'type' => 'string', ), 'icon' => array( 'type' => 'string', ), 'area_tag' => array( 'type' => 'string', ), ), ), ), ), ); foreach ( get_registered_theme_features() as $feature => $config ) { if ( ! is_array( $config['show_in_rest'] ) ) { continue; } $name = $config['show_in_rest']['name']; $schema['properties']['theme_supports']['properties'][ $name ] = $config['show_in_rest']['schema']; } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = array( 'status' => array( 'description' => __( 'Limit result set to themes assigned one or more statuses.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'active', 'inactive' ), 'type' => 'string', ), ), ); return apply_filters( 'rest_themes_collection_params', $query_params ); } public function sanitize_theme_status( $statuses, $request, $parameter ) { _deprecated_function( __METHOD__, '5.7.0' ); $statuses = wp_parse_slug_list( $statuses ); foreach ( $statuses as $status ) { $result = rest_validate_request_arg( $status, $request, $parameter ); if ( is_wp_error( $result ) ) { return $result; } } return $statuses; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-plugins-controller.php';
class WP_REST_Plugins_Controller extends WP_REST_Controller { const PATTERN = '[^.\/]+(?:\/[^.\/]+)?'; public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'plugins'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array( 'slug' => array( 'type' => 'string', 'required' => true, 'description' => __( 'WordPress.org plugin directory slug.' ), 'pattern' => '[\w\-]+', ), 'status' => array( 'description' => __( 'The plugin activation status.' ), 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), 'default' => 'inactive', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<plugin>' . self::PATTERN . ')', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'plugin' => array( 'type' => 'string', 'pattern' => self::PATTERN, 'validate_callback' => array( $this, 'validate_plugin_param' ), 'sanitize_callback' => array( $this, 'sanitize_plugin_param' ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_view_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $plugins = array(); foreach ( get_plugins() as $file => $data ) { if ( is_wp_error( $this->check_read_permission( $file ) ) ) { continue; } $data['_file'] = $file; if ( ! $this->does_plugin_match_request( $request, $data ) ) { continue; } $plugins[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $data, $request ) ); } return new WP_REST_Response( $plugins ); } public function get_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } public function get_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } return $this->prepare_item_for_response( $data, $request ); } protected function check_read_permission( $plugin ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! $this->is_plugin_installed( $plugin ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } if ( ! is_multisite() ) { return true; } if ( ! is_network_only_plugin( $plugin ) || is_plugin_active( $plugin ) || current_user_can( 'manage_network_plugins' ) ) { return true; } return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } public function create_item_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) ) { return new WP_Error( 'rest_cannot_install_plugin', __( 'Sorry, you are not allowed to install plugins on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' !== $request['status'] && ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate plugins.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } public function create_item( $request ) { global $wp_filesystem; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; $slug = $request['slug']; $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false, 'language_packs' => true, ), ) ); if ( is_wp_error( $api ) ) { if ( str_contains( $api->get_error_message(), 'Plugin not found.' ) ) { $api->add_data( array( 'status' => 404 ) ); } else { $api->add_data( array( 'status' => 500 ) ); } return $api; } $skin = new WP_Ajax_Upgrader_Skin(); $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->install( $api->download_link ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 500 ) ); return $result; } if ( is_wp_error( $skin->result ) ) { $skin->result->add_data( array( 'status' => 500 ) ); return $skin->result; } if ( $skin->get_errors()->has_errors() ) { $error = $skin->get_errors(); $error->add_data( array( 'status' => 500 ) ); return $error; } if ( is_null( $result ) ) { if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { return new WP_Error( 'unable_to_connect_to_filesystem', $wp_filesystem->errors->get_error_message(), array( 'status' => 500 ) ); } return new WP_Error( 'unable_to_connect_to_filesystem', __( 'Unable to connect to the filesystem. Please confirm your credentials.' ), array( 'status' => 500 ) ); } $file = $upgrader->plugin_info(); if ( ! $file ) { return new WP_Error( 'unable_to_determine_installed_plugin', __( 'Unable to determine what plugin was installed.' ), array( 'status' => 500 ) ); } if ( 'inactive' !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $file, $request['status'], 'inactive' ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } $changed_status = $this->handle_plugin_status( $file, $request['status'], 'inactive' ); if ( is_wp_error( $changed_status ) ) { return $changed_status; } } $installed_locales = array_values( get_available_languages() ); $installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales ); $language_packs = array_map( static function ( $item ) { return (object) $item; }, $api->language_packs ); $language_packs = array_filter( $language_packs, static function ( $pack ) use ( $installed_locales ) { return in_array( $pack->language, $installed_locales, true ); } ); if ( $language_packs ) { $lp_upgrader = new Language_Pack_Upgrader( $skin ); $lp_upgrader->bulk_upgrade( $language_packs ); } $path = WP_PLUGIN_DIR . '/' . $file; $data = get_plugin_data( $path, false, false ); $data['_file'] = $file; $response = $this->prepare_item_for_response( $data, $request ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $file, 0, - 4 ) ) ) ); return $response; } public function update_item_permissions_check( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } } return true; } public function update_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $handled = $this->handle_plugin_status( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $handled ) ) { return $handled; } } $this->update_additional_fields_for_object( $data, $request ); $request['context'] = 'edit'; return $this->prepare_item_for_response( $data, $request ); } public function delete_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'delete_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to delete plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } public function delete_item( $request ) { require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } if ( is_plugin_active( $request['plugin'] ) ) { return new WP_Error( 'rest_cannot_delete_active_plugin', __( 'Cannot delete an active plugin. Please deactivate it first.' ), array( 'status' => 400 ) ); } $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $prepared = $this->prepare_item_for_response( $data, $request ); $deleted = delete_plugins( array( $request['plugin'] ) ); if ( is_wp_error( $deleted ) ) { $deleted->add_data( array( 'status' => 500 ) ); return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $prepared->get_data(), ) ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $item = _get_plugin_data_markup_translate( $item['_file'], $item, false ); $marked = _get_plugin_data_markup_translate( $item['_file'], $item, true ); $data = array( 'plugin' => substr( $item['_file'], 0, - 4 ), 'status' => $this->get_plugin_status( $item['_file'] ), 'name' => $item['Name'], 'plugin_uri' => $item['PluginURI'], 'author' => $item['Author'], 'author_uri' => $item['AuthorURI'], 'description' => array( 'raw' => $item['Description'], 'rendered' => $marked['Description'], ), 'version' => $item['Version'], 'network_only' => $item['Network'], 'requires_wp' => $item['RequiresWP'], 'requires_php' => $item['RequiresPHP'], 'textdomain' => $item['TextDomain'], ); $data = $this->add_additional_fields_to_object( $data, $request ); $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $item ) ); } return apply_filters( 'rest_prepare_plugin', $response, $item, $request ); } protected function prepare_links( $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $item['_file'], 0, - 4 ) ) ), ), ); } protected function get_plugin_data( $plugin ) { $plugins = get_plugins(); if ( ! isset( $plugins[ $plugin ] ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } $data = $plugins[ $plugin ]; $data['_file'] = $plugin; return $data; } protected function get_plugin_status( $plugin ) { if ( is_plugin_active_for_network( $plugin ) ) { return 'network-active'; } if ( is_plugin_active( $plugin ) ) { return 'active'; } return 'inactive'; } protected function plugin_status_permission_check( $plugin, $new_status, $current_status ) { if ( is_multisite() && ( 'network-active' === $current_status || 'network-active' === $new_status ) && ! current_user_can( 'manage_network_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_network_plugins', __( 'Sorry, you are not allowed to manage network plugins.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ( 'active' === $new_status || 'network-active' === $new_status ) && ! current_user_can( 'activate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' === $new_status && ! current_user_can( 'deactivate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_deactivate_plugin', __( 'Sorry, you are not allowed to deactivate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function handle_plugin_status( $plugin, $new_status, $current_status ) { if ( 'inactive' === $new_status ) { deactivate_plugins( $plugin, false, 'network-active' === $current_status ); return true; } if ( 'active' === $new_status && 'network-active' === $current_status ) { return true; } $network_activate = 'network-active' === $new_status; if ( is_multisite() && ! $network_activate && is_network_only_plugin( $plugin ) ) { return new WP_Error( 'rest_network_only_plugin', __( 'Network only plugin must be network activated.' ), array( 'status' => 400 ) ); } $activated = activate_plugin( $plugin, '', $network_activate ); if ( is_wp_error( $activated ) ) { $activated->add_data( array( 'status' => 500 ) ); return $activated; } return true; } public function validate_plugin_param( $file ) { if ( ! is_string( $file ) || ! preg_match( '/' . self::PATTERN . '/u', $file ) ) { return false; } $validated = validate_file( plugin_basename( $file ) ); return 0 === $validated; } public function sanitize_plugin_param( $file ) { return plugin_basename( sanitize_text_field( $file . '.php' ) ); } protected function does_plugin_match_request( $request, $item ) { $search = $request['search']; if ( $search ) { $matched_search = false; foreach ( $item as $field ) { if ( is_string( $field ) && str_contains( strip_tags( $field ), $search ) ) { $matched_search = true; break; } } if ( ! $matched_search ) { return false; } } $status = $request['status']; if ( $status && ! in_array( $this->get_plugin_status( $item['_file'] ), $status, true ) ) { return false; } return true; } protected function is_plugin_installed( $plugin ) { return file_exists( WP_PLUGIN_DIR . '/' . $plugin ); } protected function is_filesystem_available() { $filesystem_method = get_filesystem_method(); if ( 'direct' === $filesystem_method ) { return true; } ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); ob_end_clean(); if ( $filesystem_credentials_are_stored ) { return true; } return new WP_Error( 'fs_unavailable', __( 'The filesystem is currently unavailable for managing plugins.' ), array( 'status' => 500 ) ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'plugin', 'type' => 'object', 'properties' => array( 'plugin' => array( 'description' => __( 'The plugin file.' ), 'type' => 'string', 'pattern' => self::PATTERN, 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'status' => array( 'description' => __( 'The plugin activation status.' ), 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The plugin name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'plugin_uri' => array( 'description' => __( 'The plugin\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author' => array( 'description' => __( 'The plugin author.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author_uri' => array( 'description' => __( 'Plugin author\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'description' => array( 'description' => __( 'The plugin description.' ), 'type' => 'object', 'readonly' => true, 'context' => array( 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'The raw plugin description.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The plugin description formatted for display.' ), 'type' => 'string', ), ), ), 'version' => array( 'description' => __( 'The plugin version number.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'network_only' => array( 'description' => __( 'Whether the plugin can only be activated network-wide.' ), 'type' => 'boolean', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_wp' => array( 'description' => __( 'Minimum required version of WordPress.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_php' => array( 'description' => __( 'Minimum required version of PHP.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'textdomain' => array( 'description' => __( 'The plugin\'s text domain.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['status'] = array( 'description' => __( 'Limits results to plugins with the given status.' ), 'type' => 'array', 'items' => array( 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), ), ); unset( $query_params['page'], $query_params['per_page'] ); return $query_params; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-directory-controller.php';
class WP_REST_Block_Directory_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-directory'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/search', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) || ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_block_directory_cannot_view', __( 'Sorry, you are not allowed to browse the block directory.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; $response = plugins_api( 'query_plugins', array( 'block' => $request['term'], 'per_page' => $request['per_page'], 'page' => $request['page'], ) ); if ( is_wp_error( $response ) ) { $response->add_data( array( 'status' => 500 ) ); return $response; } $result = array(); foreach ( $response->plugins as $plugin ) { if ( empty( $plugin['blocks'] ) ) { continue; } $data = $this->prepare_item_for_response( $plugin, $request ); $result[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $result ); } public function prepare_item_for_response( $item, $request ) { $plugin = $item; $fields = $this->get_fields_for_response( $request ); $block_data = reset( $plugin['blocks'] ); $block = array( 'name' => $block_data['name'], 'title' => ( $block_data['title'] ? $block_data['title'] : $plugin['name'] ), 'description' => wp_trim_words( $plugin['short_description'], 30, '...' ), 'id' => $plugin['slug'], 'rating' => $plugin['rating'] / 20, 'rating_count' => (int) $plugin['num_ratings'], 'active_installs' => (int) $plugin['active_installs'], 'author_block_rating' => $plugin['author_block_rating'] / 20, 'author_block_count' => (int) $plugin['author_block_count'], 'author' => wp_strip_all_tags( $plugin['author'] ), 'icon' => ( isset( $plugin['icons']['1x'] ) ? $plugin['icons']['1x'] : 'block-default' ), 'last_updated' => gmdate( 'Y-m-d\TH:i:s', strtotime( $plugin['last_updated'] ) ), 'humanized_updated' => sprintf( __( '%s ago' ), human_time_diff( strtotime( $plugin['last_updated'] ) ) ), ); $this->add_additional_fields_to_object( $block, $request ); $response = new WP_REST_Response( $block ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $plugin ) ); } return $response; } protected function prepare_links( $plugin ) { $links = array( 'https://api.w.org/install-plugin' => array( 'href' => add_query_arg( 'slug', urlencode( $plugin['slug'] ), rest_url( 'wp/v2/plugins' ) ), ), ); $plugin_file = $this->find_plugin_for_slug( $plugin['slug'] ); if ( $plugin_file ) { $links['https://api.w.org/plugin'] = array( 'href' => rest_url( 'wp/v2/plugins/' . substr( $plugin_file, 0, - 4 ) ), 'embeddable' => true, ); } return $links; } protected function find_plugin_for_slug( $slug ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $plugin_files = get_plugins( '/' . $slug ); if ( ! $plugin_files ) { return ''; } $plugin_files = array_keys( $plugin_files ); return $slug . '/' . reset( $plugin_files ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-directory-item', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The block name, in namespace/block-name format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'title' => array( 'description' => __( 'The block title, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'description' => array( 'description' => __( 'A short description of the block, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'id' => array( 'description' => __( 'The block slug.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'rating' => array( 'description' => __( 'The star rating of the block.' ), 'type' => 'number', 'context' => array( 'view' ), ), 'rating_count' => array( 'description' => __( 'The number of ratings.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'active_installs' => array( 'description' => __( 'The number sites that have activated this block.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'author_block_rating' => array( 'description' => __( 'The average rating of blocks published by the same author.' ), 'type' => 'number', 'context' => array( 'view' ), ), 'author_block_count' => array( 'description' => __( 'The number of blocks published by the same author.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'author' => array( 'description' => __( 'The WordPress.org username of the block author.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'icon' => array( 'description' => __( 'The block icon.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), ), 'last_updated' => array( 'description' => __( 'The date when the block was last updated.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view' ), ), 'humanized_updated' => array( 'description' => __( 'The date when the block was last updated, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['term'] = array( 'description' => __( 'Limit result set to blocks matching the search term.' ), 'type' => 'string', 'required' => true, 'minLength' => 1, ); unset( $query_params['search'] ); return apply_filters( 'rest_block_directory_collection_params', $query_params ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php';
class WP_REST_Edit_Site_Export_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'export'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'export' ), 'permission_callback' => array( $this, 'permissions_check' ), ), ) ); } public function permissions_check() { if ( current_user_can( 'export' ) ) { return true; } return new WP_Error( 'rest_cannot_export_templates', __( 'Sorry, you are not allowed to export templates and template parts.' ), array( 'status' => rest_authorization_required_code() ) ); } public function export() { $filename = wp_generate_block_templates_export_file(); if ( is_wp_error( $filename ) ) { $filename->add_data( array( 'status' => 500 ) ); return $filename; } $theme_name = basename( get_stylesheet() ); header( 'Content-Type: application/zip' ); header( 'Content-Disposition: attachment; filename=' . $theme_name . '.zip' ); header( 'Content-Length: ' . filesize( $filename ) ); flush(); readfile( $filename ); unlink( $filename ); exit; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php';
class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'pattern-directory'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/patterns', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_pattern_directory_cannot_view', __( 'Sorry, you are not allowed to browse the local block pattern directory.' ), array( 'status' => rest_authorization_required_code() ) ); } public function get_items( $request ) { $valid_query_args = array( 'offset' => true, 'order' => true, 'orderby' => true, 'page' => true, 'per_page' => true, 'search' => true, 'slug' => true, ); $query_args = array_intersect_key( $request->get_params(), $valid_query_args ); $query_args['locale'] = get_user_locale(); $query_args['wp-version'] = wp_get_wp_version(); $query_args['pattern-categories'] = isset( $request['category'] ) ? $request['category'] : false; $query_args['pattern-keywords'] = isset( $request['keyword'] ) ? $request['keyword'] : false; $query_args = array_filter( $query_args ); $transient_key = $this->get_transient_key( $query_args ); $raw_patterns = get_site_transient( $transient_key ); if ( ! $raw_patterns ) { $api_url = 'http://api.wordpress.org/patterns/1.0/?' . build_query( $query_args ); if ( wp_http_supports( array( 'ssl' ) ) ) { $api_url = set_url_scheme( $api_url, 'https' ); } $cache_ttl = 5; $wporg_response = wp_remote_get( $api_url ); $raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) ); if ( is_wp_error( $wporg_response ) ) { $raw_patterns = $wporg_response; } elseif ( ! is_array( $raw_patterns ) ) { $raw_patterns = new WP_Error( 'pattern_api_failed', sprintf( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ), array( 'response' => wp_remote_retrieve_body( $wporg_response ), ) ); } else { $cache_ttl = HOUR_IN_SECONDS; } set_site_transient( $transient_key, $raw_patterns, $cache_ttl ); } if ( is_wp_error( $raw_patterns ) ) { $raw_patterns->add_data( array( 'status' => 500 ) ); return $raw_patterns; } if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $response = array(); if ( $raw_patterns ) { foreach ( $raw_patterns as $pattern ) { $response[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $pattern, $request ) ); } } return new WP_REST_Response( $response ); } public function prepare_item_for_response( $item, $request ) { $raw_pattern = $item; $prepared_pattern = array( 'id' => absint( $raw_pattern->id ), 'title' => sanitize_text_field( $raw_pattern->title->rendered ), 'content' => wp_kses_post( $raw_pattern->pattern_content ), 'categories' => array_map( 'sanitize_title', $raw_pattern->category_slugs ), 'keywords' => array_map( 'sanitize_text_field', explode( ',', $raw_pattern->meta->wpop_keywords ) ), 'description' => sanitize_text_field( $raw_pattern->meta->wpop_description ), 'viewport_width' => absint( $raw_pattern->meta->wpop_viewport_width ), 'block_types' => array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ), ); $prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request ); $response = new WP_REST_Response( $prepared_pattern ); return apply_filters( 'rest_prepare_block_pattern', $response, $raw_pattern, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'pattern-directory-item', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'The pattern ID.' ), 'type' => 'integer', 'minimum' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'title' => array( 'description' => __( 'The pattern title, in human readable format.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'content' => array( 'description' => __( 'The pattern content.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( "The pattern's category slugs." ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'keywords' => array( 'description' => __( "The pattern's keywords." ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'A description of the pattern.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'viewport_width' => array( 'description' => __( 'The preferred width of the viewport when previewing a pattern, in pixels.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'block_types' => array( 'description' => __( 'The block types which can use this pattern.' ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'embed' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['per_page']['default'] = 100; $query_params['search']['minLength'] = 1; $query_params['context']['default'] = 'view'; $query_params['category'] = array( 'description' => __( 'Limit results to those matching a category ID.' ), 'type' => 'integer', 'minimum' => 1, ); $query_params['keyword'] = array( 'description' => __( 'Limit results to those matching a keyword ID.' ), 'type' => 'integer', 'minimum' => 1, ); $query_params['slug'] = array( 'description' => __( 'Limit results to those matching a pattern (slug).' ), 'type' => 'array', ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by post attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', 'favorite_count', ), ); return apply_filters( 'rest_pattern_directory_collection_params', $query_params ); } protected function get_transient_key( $query_args ) { if ( isset( $query_args['slug'] ) ) { $query_args['slug'] = wp_parse_list( $query_args['slug'] ); if ( empty( $query_args['slug'] ) ) { unset( $query_args['slug'] ); } else { sort( $query_args['slug'] ); } } return 'wp_remote_block_patterns_' . md5( serialize( $query_args ) ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-patterns-controller.php';
class WP_REST_Block_Patterns_Controller extends WP_REST_Controller { private $remote_patterns_loaded; protected static $categories_migration = array( 'buttons' => 'call-to-action', 'columns' => 'text', 'query' => 'posts', ); public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-patterns/patterns'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view the registered block patterns.' ), array( 'status' => rest_authorization_required_code() ) ); } public function get_items( $request ) { if ( ! $this->remote_patterns_loaded ) { _load_remote_block_patterns(); _load_remote_featured_patterns(); _register_remote_theme_patterns(); $this->remote_patterns_loaded = true; } $response = array(); $patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered(); foreach ( $patterns as $pattern ) { $migrated_pattern = $this->migrate_pattern_categories( $pattern ); $prepared_pattern = $this->prepare_item_for_response( $migrated_pattern, $request ); $response[] = $this->prepare_response_for_collection( $prepared_pattern ); } return rest_ensure_response( $response ); } protected function migrate_pattern_categories( $pattern ) { if ( ! isset( $pattern['categories'] ) || ! is_array( $pattern['categories'] ) ) { return $pattern; } foreach ( $pattern['categories'] as $index => $category ) { if ( isset( static::$categories_migration[ $category ] ) ) { $pattern['categories'][ $index ] = static::$categories_migration[ $category ]; } } return $pattern; } public function prepare_item_for_response( $item, $request ) { $blocks = parse_blocks( $item['content'] ); $blocks = resolve_pattern_blocks( $blocks ); $item['content'] = serialize_blocks( $blocks ); $fields = $this->get_fields_for_response( $request ); $keys = array( 'name' => 'name', 'title' => 'title', 'content' => 'content', 'description' => 'description', 'viewportWidth' => 'viewport_width', 'inserter' => 'inserter', 'categories' => 'categories', 'keywords' => 'keywords', 'blockTypes' => 'block_types', 'postTypes' => 'post_types', 'templateTypes' => 'template_types', 'source' => 'source', ); $data = array(); foreach ( $keys as $item_key => $rest_key ) { if ( isset( $item[ $item_key ] ) && rest_is_field_included( $rest_key, $fields ) ) { $data[ $rest_key ] = $item[ $item_key ]; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); return rest_ensure_response( $data ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-pattern', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The pattern name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'title' => array( 'description' => __( 'The pattern title, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'content' => array( 'description' => __( 'The pattern content.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The pattern detailed description.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'viewport_width' => array( 'description' => __( 'The pattern viewport width for inserter preview.' ), 'type' => 'number', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'inserter' => array( 'description' => __( 'Determines whether the pattern is visible in inserter.' ), 'type' => 'boolean', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( 'The pattern category slugs.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'keywords' => array( 'description' => __( 'The pattern keywords.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'block_types' => array( 'description' => __( 'Block types that the pattern is intended to be used with.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'post_types' => array( 'description' => __( 'An array of post types that the pattern is restricted to be used with.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'template_types' => array( 'description' => __( 'An array of template types where the pattern fits.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'source' => array( 'description' => __( 'Where the pattern comes from e.g. core' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( 'core', 'plugin', 'theme', 'pattern-directory/core', 'pattern-directory/theme', 'pattern-directory/featured', ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php';
class WP_REST_Block_Pattern_Categories_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-patterns/categories'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view the registered block pattern categories.' ), array( 'status' => rest_authorization_required_code() ) ); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $response = array(); $categories = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); foreach ( $categories as $category ) { $prepared_category = $this->prepare_item_for_response( $category, $request ); $response[] = $this->prepare_response_for_collection( $prepared_category ); } return rest_ensure_response( $response ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $keys = array( 'name', 'label', 'description' ); $data = array(); foreach ( $keys as $key ) { if ( isset( $item[ $key ] ) && rest_is_field_included( $key, $fields ) ) { $data[ $key ] = $item[ $key ]; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); return rest_ensure_response( $data ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-pattern-category', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The category name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'label' => array( 'description' => __( 'The category label, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The category description, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-application-passwords-controller.php';
class WP_REST_Application_Passwords_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'users/(?P<user_id>(?:[\d]+|me))/application-passwords'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema(), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_items' ), 'permission_callback' => array( $this, 'delete_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/introspect', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_current_item' ), 'permission_callback' => array( $this, 'get_current_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<uuid>[\w\-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'list_app_passwords', $user->ID ) ) { return new WP_Error( 'rest_cannot_list_application_passwords', __( 'Sorry, you are not allowed to list application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID ); $response = array(); foreach ( $passwords as $password ) { $response[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $password, $request ) ); } return new WP_REST_Response( $response ); } public function get_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'read_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_read_application_password', __( 'Sorry, you are not allowed to read this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item( $request ) { $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } return $this->prepare_item_for_response( $password, $request ); } public function create_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'create_app_password', $user->ID ) ) { return new WP_Error( 'rest_cannot_create_application_passwords', __( 'Sorry, you are not allowed to create application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function create_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) ); if ( is_wp_error( $created ) ) { return $created; } $password = $created[0]; $item = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] ); $item['new_password'] = WP_Application_Passwords::chunk_password( $password ); $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } do_action( 'rest_after_insert_application_password', $item, $request, true ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $item, $request ); $response->set_status( 201 ); $response->header( 'Location', $response->get_links()['self'][0]['href'] ); return $response; } public function update_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_edit_application_password', __( 'Sorry, you are not allowed to edit this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function update_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $item = $this->get_application_password( $request ); if ( is_wp_error( $item ) ) { return $item; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $saved = WP_Application_Passwords::update_application_password( $user->ID, $item['uuid'], wp_slash( (array) $prepared ) ); if ( is_wp_error( $saved ) ) { return $saved; } $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $item = WP_Application_Passwords::get_user_application_password( $user->ID, $item['uuid'] ); do_action( 'rest_after_insert_application_password', $item, $request, false ); $request->set_param( 'context', 'edit' ); return $this->prepare_item_for_response( $item, $request ); } public function delete_items_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_passwords', $user->ID ) ) { return new WP_Error( 'rest_cannot_delete_application_passwords', __( 'Sorry, you are not allowed to delete application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $deleted = WP_Application_Passwords::delete_all_application_passwords( $user->ID ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'count' => $deleted, ) ); } public function delete_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_delete_application_password', __( 'Sorry, you are not allowed to delete this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function delete_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } $request->set_param( 'context', 'edit' ); $previous = $this->prepare_item_for_response( $password, $request ); $deleted = WP_Application_Passwords::delete_application_password( $user->ID, $password['uuid'] ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } public function get_current_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( get_current_user_id() !== $user->ID ) { return new WP_Error( 'rest_cannot_introspect_app_password_for_non_authenticated_user', __( 'The authenticated application password can only be introspected for the current user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_current_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $uuid = rest_get_authenticated_app_password(); if ( ! $uuid ) { return new WP_Error( 'rest_no_authenticated_app_password', __( 'Cannot introspect application password.' ), array( 'status' => 404 ) ); } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $uuid ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 500 ) ); } return $this->prepare_item_for_response( $password, $request ); } protected function do_permissions_check( $request ) { _deprecated_function( __METHOD__, '5.7.0' ); $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_manage_application_passwords', __( 'Sorry, you are not allowed to manage application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function prepare_item_for_database( $request ) { $prepared = (object) array( 'name' => $request['name'], ); if ( $request['app_id'] && ! $request['uuid'] ) { $prepared->app_id = $request['app_id']; } return apply_filters( 'rest_pre_insert_application_password', $prepared, $request ); } public function prepare_item_for_response( $item, $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $fields = $this->get_fields_for_response( $request ); $prepared = array( 'uuid' => $item['uuid'], 'app_id' => empty( $item['app_id'] ) ? '' : $item['app_id'], 'name' => $item['name'], 'created' => gmdate( 'Y-m-d\TH:i:s', $item['created'] ), 'last_used' => $item['last_used'] ? gmdate( 'Y-m-d\TH:i:s', $item['last_used'] ) : null, 'last_ip' => $item['last_ip'] ? $item['last_ip'] : null, ); if ( isset( $item['new_password'] ) ) { $prepared['password'] = $item['new_password']; } $prepared = $this->add_additional_fields_to_object( $prepared, $request ); $prepared = $this->filter_response_by_context( $prepared, $request['context'] ); $response = new WP_REST_Response( $prepared ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $user, $item ) ); } return apply_filters( 'rest_prepare_application_password', $response, $item, $request ); } protected function prepare_links( WP_User $user, $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/users/%d/application-passwords/%s', $this->namespace, $user->ID, $item['uuid'] ) ), ), ); } protected function get_user( $request ) { if ( ! wp_is_application_passwords_available() ) { return new WP_Error( 'application_passwords_disabled', __( 'Application passwords are not available.' ), array( 'status' => 501 ) ); } $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); $id = $request['user_id']; if ( 'me' === $id ) { if ( ! is_user_logged_in() ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } $user = wp_get_current_user(); } else { $id = (int) $id; if ( $id <= 0 ) { return $error; } $user = get_userdata( $id ); } if ( empty( $user ) || ! $user->exists() ) { return $error; } if ( is_multisite() && ! user_can( $user->ID, 'manage_sites' ) && ! is_user_member_of_blog( $user->ID ) ) { return $error; } if ( ! wp_is_application_passwords_available_for_user( $user ) ) { return new WP_Error( 'application_passwords_disabled_for_user', __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' ), array( 'status' => 501 ) ); } return $user; } protected function get_application_password( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $request['uuid'] ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 404 ) ); } return $password; } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'application-password', 'type' => 'object', 'properties' => array( 'uuid' => array( 'description' => __( 'The unique identifier for the application password.' ), 'type' => 'string', 'format' => 'uuid', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'app_id' => array( 'description' => __( 'A UUID provided by the application to uniquely identify it. It is recommended to use an UUID v5 with the URL or DNS namespace.' ), 'type' => 'string', 'oneOf' => array( array( 'type' => 'string', 'format' => 'uuid', ), array( 'type' => 'string', 'enum' => array( '' ), ), ), 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The name of the application password.' ), 'type' => 'string', 'required' => true, 'context' => array( 'view', 'edit', 'embed' ), 'minLength' => 1, 'pattern' => '.*\S.*', ), 'password' => array( 'description' => __( 'The generated password. Only available after adding an application.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'created' => array( 'description' => __( 'The GMT date the application password was created.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_used' => array( 'description' => __( 'The GMT date the application password was last used.' ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_ip' => array( 'description' => __( 'The IP address the application password was last used by.' ), 'type' => array( 'string', 'null' ), 'format' => 'ip', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-site-health-controller.php';
class WP_REST_Site_Health_Controller extends WP_REST_Controller { private $site_health; public function __construct( $site_health ) { $this->namespace = 'wp-site-health/v1'; $this->rest_base = 'tests'; $this->site_health = $site_health; } public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'background-updates' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_background_updates' ), 'permission_callback' => function () { return $this->validate_request_permission( 'background_updates' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'loopback-requests' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_loopback_requests' ), 'permission_callback' => function () { return $this->validate_request_permission( 'loopback_requests' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'https-status' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_https_status' ), 'permission_callback' => function () { return $this->validate_request_permission( 'https_status' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'dotorg-communication' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_dotorg_communication' ), 'permission_callback' => function () { return $this->validate_request_permission( 'dotorg_communication' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'authorization-header' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_authorization_header' ), 'permission_callback' => function () { return $this->validate_request_permission( 'authorization_header' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s', 'directory-sizes' ), array( 'methods' => 'GET', 'callback' => array( $this, 'get_directory_sizes' ), 'permission_callback' => function () { return $this->validate_request_permission( 'directory_sizes' ) && ! is_multisite(); }, ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'page-cache' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_page_cache' ), 'permission_callback' => function () { return $this->validate_request_permission( 'page_cache' ); }, ), ) ); } protected function validate_request_permission( $check ) { $default_capability = 'view_site_health_checks'; $capability = apply_filters( "site_health_test_rest_capability_{$check}", $default_capability, $check ); return current_user_can( $capability ); } public function test_background_updates() { $this->load_admin_textdomain(); return $this->site_health->get_test_background_updates(); } public function test_dotorg_communication() { $this->load_admin_textdomain(); return $this->site_health->get_test_dotorg_communication(); } public function test_loopback_requests() { $this->load_admin_textdomain(); return $this->site_health->get_test_loopback_requests(); } public function test_https_status() { $this->load_admin_textdomain(); return $this->site_health->get_test_https_status(); } public function test_authorization_header() { $this->load_admin_textdomain(); return $this->site_health->get_test_authorization_header(); } public function test_page_cache() { $this->load_admin_textdomain(); return $this->site_health->get_test_page_cache(); } public function get_directory_sizes() { if ( ! class_exists( 'WP_Debug_Data' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php'; } $this->load_admin_textdomain(); $sizes_data = WP_Debug_Data::get_sizes(); $all_sizes = array( 'raw' => 0 ); foreach ( $sizes_data as $name => $value ) { $name = sanitize_text_field( $name ); $data = array(); if ( isset( $value['size'] ) ) { if ( is_string( $value['size'] ) ) { $data['size'] = sanitize_text_field( $value['size'] ); } else { $data['size'] = (int) $value['size']; } } if ( isset( $value['debug'] ) ) { if ( is_string( $value['debug'] ) ) { $data['debug'] = sanitize_text_field( $value['debug'] ); } else { $data['debug'] = (int) $value['debug']; } } if ( ! empty( $value['raw'] ) ) { $data['raw'] = (int) $value['raw']; } $all_sizes[ $name ] = $data; } if ( isset( $all_sizes['total_size']['debug'] ) && 'not available' === $all_sizes['total_size']['debug'] ) { return new WP_Error( 'not_available', __( 'Directory sizes could not be returned.' ), array( 'status' => 500 ) ); } return $all_sizes; } protected function load_admin_textdomain() { if ( ! is_admin() ) { $locale = determine_locale(); load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo", $locale ); } } public function get_item_schema() { if ( $this->schema ) { return $this->schema; } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'wp-site-health-test', 'type' => 'object', 'properties' => array( 'test' => array( 'type' => 'string', 'description' => __( 'The name of the test being run.' ), 'readonly' => true, ), 'label' => array( 'type' => 'string', 'description' => __( 'A label describing the test.' ), 'readonly' => true, ), 'status' => array( 'type' => 'string', 'description' => __( 'The status of the test.' ), 'enum' => array( 'good', 'recommended', 'critical' ), 'readonly' => true, ), 'badge' => array( 'type' => 'object', 'description' => __( 'The category this test is grouped in.' ), 'properties' => array( 'label' => array( 'type' => 'string', 'readonly' => true, ), 'color' => array( 'type' => 'string', 'enum' => array( 'blue', 'orange', 'red', 'green', 'purple', 'gray' ), 'readonly' => true, ), ), 'readonly' => true, ), 'description' => array( 'type' => 'string', 'description' => __( 'A more descriptive explanation of what the test looks for, and why it is important for the user.' ), 'readonly' => true, ), 'actions' => array( 'type' => 'string', 'description' => __( 'HTML containing an action to direct the user to where they can resolve the issue.' ), 'readonly' => true, ), ), ); return $this->schema; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-sidebars-controller.php';
class WP_REST_Sidebars_Controller extends WP_REST_Controller { protected $widgets_retrieved = false; public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'sidebars'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'The id of a registered sidebar' ), 'type' => 'string', ), 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $this->retrieve_widgets(); foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { $sidebar = $this->get_sidebar( $id ); if ( ! $sidebar ) { continue; } if ( $this->check_read_permission( $sidebar ) ) { return true; } } return $this->do_permissions_check(); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $this->retrieve_widgets(); $data = array(); $permissions_check = $this->do_permissions_check(); foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { $sidebar = $this->get_sidebar( $id ); if ( ! $sidebar ) { continue; } if ( is_wp_error( $permissions_check ) && ! $this->check_read_permission( $sidebar ) ) { continue; } $data[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $sidebar, $request ) ); } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { $this->retrieve_widgets(); $sidebar = $this->get_sidebar( $request['id'] ); if ( $sidebar && $this->check_read_permission( $sidebar ) ) { return true; } return $this->do_permissions_check(); } protected function check_read_permission( $sidebar ) { return ! empty( $sidebar['show_in_rest'] ); } public function get_item( $request ) { $this->retrieve_widgets(); $sidebar = $this->get_sidebar( $request['id'] ); if ( ! $sidebar ) { return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $sidebar, $request ); } public function update_item_permissions_check( $request ) { return $this->do_permissions_check(); } public function update_item( $request ) { if ( isset( $request['widgets'] ) ) { $sidebars = wp_get_sidebars_widgets(); foreach ( $sidebars as $sidebar_id => $widgets ) { foreach ( $widgets as $i => $widget_id ) { if ( $sidebar_id !== $request['id'] && in_array( $widget_id, $request['widgets'], true ) ) { unset( $sidebars[ $sidebar_id ][ $i ] ); } if ( $sidebar_id === $request['id'] && ! in_array( $widget_id, $request['widgets'], true ) ) { $sidebars['wp_inactive_widgets'][] = $widget_id; } } } $sidebars[ $request['id'] ] = $request['widgets']; wp_set_sidebars_widgets( $sidebars ); } $request['context'] = 'edit'; $sidebar = $this->get_sidebar( $request['id'] ); do_action( 'rest_save_sidebar', $sidebar, $request ); return $this->prepare_item_for_response( $sidebar, $request ); } protected function do_permissions_check() { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } protected function get_sidebar( $id ) { return wp_get_sidebar( $id ); } protected function retrieve_widgets() { if ( ! $this->widgets_retrieved ) { retrieve_widgets(); $this->widgets_retrieved = true; } } public function prepare_item_for_response( $item, $request ) { global $wp_registered_sidebars, $wp_registered_widgets; $raw_sidebar = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_sidebar', new WP_REST_Response( array() ), $raw_sidebar, $request ); } $id = $raw_sidebar['id']; $sidebar = array( 'id' => $id ); if ( isset( $wp_registered_sidebars[ $id ] ) ) { $registered_sidebar = $wp_registered_sidebars[ $id ]; $sidebar['status'] = 'active'; $sidebar['name'] = isset( $registered_sidebar['name'] ) ? $registered_sidebar['name'] : ''; $sidebar['description'] = isset( $registered_sidebar['description'] ) ? wp_sidebar_description( $id ) : ''; $sidebar['class'] = isset( $registered_sidebar['class'] ) ? $registered_sidebar['class'] : ''; $sidebar['before_widget'] = isset( $registered_sidebar['before_widget'] ) ? $registered_sidebar['before_widget'] : ''; $sidebar['after_widget'] = isset( $registered_sidebar['after_widget'] ) ? $registered_sidebar['after_widget'] : ''; $sidebar['before_title'] = isset( $registered_sidebar['before_title'] ) ? $registered_sidebar['before_title'] : ''; $sidebar['after_title'] = isset( $registered_sidebar['after_title'] ) ? $registered_sidebar['after_title'] : ''; } else { $sidebar['status'] = 'inactive'; $sidebar['name'] = $raw_sidebar['name']; $sidebar['description'] = ''; $sidebar['class'] = ''; } if ( wp_is_block_theme() ) { $sidebar['status'] = 'inactive'; } $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( 'widgets', $fields ) ) { $sidebars = wp_get_sidebars_widgets(); $widgets = array_filter( isset( $sidebars[ $sidebar['id'] ] ) ? $sidebars[ $sidebar['id'] ] : array(), static function ( $widget_id ) use ( $wp_registered_widgets ) { return isset( $wp_registered_widgets[ $widget_id ] ); } ); $sidebar['widgets'] = array_values( $widgets ); } $schema = $this->get_item_schema(); $data = array(); foreach ( $schema['properties'] as $property_id => $property ) { if ( isset( $sidebar[ $property_id ] ) && true === rest_validate_value_from_schema( $sidebar[ $property_id ], $property ) ) { $data[ $property_id ] = $sidebar[ $property_id ]; } elseif ( isset( $property['default'] ) ) { $data[ $property_id ] = $property['default']; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $sidebar ) ); } return apply_filters( 'rest_prepare_sidebar', $response, $raw_sidebar, $request ); } protected function prepare_links( $sidebar ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $sidebar['id'] ) ), ), 'https://api.w.org/widget' => array( 'href' => add_query_arg( 'sidebar', $sidebar['id'], rest_url( '/wp/v2/widgets' ) ), 'embeddable' => true, ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'sidebar', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Unique name identifying the sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'class' => array( 'description' => __( 'Extra CSS class to assign to the sidebar in the Widgets interface.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'before_widget' => array( 'description' => __( 'HTML content to prepend to each widget\'s HTML output when assigned to this sidebar. Default is an opening list item element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'after_widget' => array( 'description' => __( 'HTML content to append to each widget\'s HTML output when assigned to this sidebar. Default is a closing list item element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'before_title' => array( 'description' => __( 'HTML content to prepend to the sidebar title when displayed. Default is an opening h2 element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'after_title' => array( 'description' => __( 'HTML content to append to the sidebar title when displayed. Default is a closing h2 element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'status' => array( 'description' => __( 'Status of sidebar.' ), 'type' => 'string', 'enum' => array( 'active', 'inactive' ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'widgets' => array( 'description' => __( 'Nested widgets.' ), 'type' => 'array', 'items' => array( 'type' => array( 'object', 'string' ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-widget-types-controller.php';
class WP_REST_Widget_Types_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'widget-types'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)', array( 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/encode', array( 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', 'required' => true, ), 'instance' => array( 'description' => __( 'Current instance settings of the widget.' ), 'type' => 'object', ), 'form_data' => array( 'description' => __( 'Serialized widget form data to encode into instance settings.' ), 'type' => 'string', 'sanitize_callback' => static function ( $form_data ) { $array = array(); wp_parse_str( $form_data, $array ); return $array; }, ), ), array( 'methods' => WP_REST_Server::CREATABLE, 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'callback' => array( $this, 'encode_form_data' ), ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/render', array( array( 'methods' => WP_REST_Server::CREATABLE, 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'callback' => array( $this, 'render' ), 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', 'required' => true, ), 'instance' => array( 'description' => __( 'Current instance settings of the widget.' ), 'type' => 'object', ), ), ), ) ); } public function get_items_permissions_check( $request ) { return $this->check_read_permission(); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $data = array(); foreach ( $this->get_widgets() as $widget ) { $widget_type = $this->prepare_item_for_response( $widget, $request ); $data[] = $this->prepare_response_for_collection( $widget_type ); } return rest_ensure_response( $data ); } public function get_item_permissions_check( $request ) { $check = $this->check_read_permission(); if ( is_wp_error( $check ) ) { return $check; } $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { return $widget_type; } return true; } protected function check_read_permission() { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } public function get_widget( $id ) { foreach ( $this->get_widgets() as $widget ) { if ( $id === $widget['id'] ) { return $widget; } } return new WP_Error( 'rest_widget_type_invalid', __( 'Invalid widget type.' ), array( 'status' => 404 ) ); } protected function get_widgets() { global $wp_widget_factory, $wp_registered_widgets; $widgets = array(); foreach ( $wp_registered_widgets as $widget ) { $parsed_id = wp_parse_widget_id( $widget['id'] ); $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); $widget['id'] = $parsed_id['id_base']; $widget['is_multi'] = (bool) $widget_object; if ( isset( $widget['name'] ) ) { $widget['name'] = html_entity_decode( $widget['name'], ENT_QUOTES, get_bloginfo( 'charset' ) ); } if ( isset( $widget['description'] ) ) { $widget['description'] = html_entity_decode( $widget['description'], ENT_QUOTES, get_bloginfo( 'charset' ) ); } unset( $widget['callback'] ); $classname = ''; foreach ( (array) $widget['classname'] as $cn ) { if ( is_string( $cn ) ) { $classname .= '_' . $cn; } elseif ( is_object( $cn ) ) { $classname .= '_' . get_class( $cn ); } } $widget['classname'] = ltrim( $classname, '_' ); $widgets[ $widget['id'] ] = $widget; } ksort( $widgets ); return $widgets; } public function get_item( $request ) { $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { return $widget_type; } $data = $this->prepare_item_for_response( $widget_type, $request ); return rest_ensure_response( $data ); } public function prepare_item_for_response( $item, $request ) { $widget_type = $item; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_widget_type', new WP_REST_Response( array() ), $widget_type, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array( 'id' => $widget_type['id'], ); $schema = $this->get_item_schema(); $extra_fields = array( 'name', 'description', 'is_multi', 'classname', 'widget_class', 'option_name', 'customize_selective_refresh', ); foreach ( $extra_fields as $extra_field ) { if ( ! rest_is_field_included( $extra_field, $fields ) ) { continue; } if ( isset( $widget_type[ $extra_field ] ) ) { $field = $widget_type[ $extra_field ]; } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) { $field = $schema['properties'][ $extra_field ]['default']; } else { $field = ''; } $data[ $extra_field ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $extra_field ] ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $widget_type ) ); } return apply_filters( 'rest_prepare_widget_type', $response, $widget_type, $request ); } protected function prepare_links( $widget_type ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $widget_type['id'] ) ), ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'widget-type', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique slug identifying the widget type.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Human-readable name identifying the widget type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of the widget.' ), 'type' => 'string', 'default' => '', 'context' => array( 'view', 'edit', 'embed' ), ), 'is_multi' => array( 'description' => __( 'Whether the widget supports multiple instances' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'classname' => array( 'description' => __( 'Class name' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function encode_form_data( $request ) { global $wp_widget_factory; $id = $request['id']; $widget_object = $wp_widget_factory->get_widget_object( $id ); if ( ! $widget_object ) { return new WP_Error( 'rest_invalid_widget', __( 'Cannot preview a widget that does not extend WP_Widget.' ), array( 'status' => 400 ) ); } if ( isset( $request['number'] ) && is_numeric( $request['number'] ) ) { $widget_object->_set( (int) $request['number'] ); } else { $widget_object->_set( -1 ); } if ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { $serialized_instance = base64_decode( $request['instance']['encoded'] ); if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is malformed.' ), array( 'status' => 400 ) ); } $instance = unserialize( $serialized_instance ); } else { $instance = array(); } if ( isset( $request['form_data'][ "widget-$id" ] ) && is_array( $request['form_data'][ "widget-$id" ] ) ) { $new_instance = array_values( $request['form_data'][ "widget-$id" ] )[0]; $old_instance = $instance; $instance = $widget_object->update( $new_instance, $old_instance ); $instance = apply_filters( 'widget_update_callback', $instance, $new_instance, $old_instance, $widget_object ); } $serialized_instance = serialize( $instance ); $widget_key = $wp_widget_factory->get_widget_key( $id ); $response = array( 'form' => trim( $this->get_widget_form( $widget_object, $instance ) ), 'preview' => trim( $this->get_widget_preview( $widget_key, $instance ) ), 'instance' => array( 'encoded' => base64_encode( $serialized_instance ), 'hash' => wp_hash( $serialized_instance ), ), ); if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { $response['instance']['raw'] = empty( $instance ) ? new stdClass() : $instance; } return rest_ensure_response( $response ); } private function get_widget_preview( $widget, $instance ) { ob_start(); the_widget( $widget, $instance ); return ob_get_clean(); } private function get_widget_form( $widget_object, $instance ) { ob_start(); $instance = apply_filters( 'widget_form_callback', $instance, $widget_object ); if ( false !== $instance ) { $return = $widget_object->form( $instance ); do_action_ref_array( 'in_widget_form', array( &$widget_object, &$return, $instance ) ); } return ob_get_clean(); } public function render( $request ) { return array( 'preview' => $this->render_legacy_widget_preview_iframe( $request['id'], isset( $request['instance'] ) ? $request['instance'] : null ), ); } private function render_legacy_widget_preview_iframe( $id_base, $instance ) { if ( ! defined( 'IFRAME_REQUEST' ) ) { define( 'IFRAME_REQUEST', true ); } ob_start(); ?>
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="https://gmpg.org/xfn/11" />
<?php wp_head(); ?>
<style>
/* Reset theme styles */
html, body, #page, #content {
padding: 0 !important;
margin: 0 !important;
}
</style>
</head>
<body <?php body_class(); ?>>
<div id="page" class="site">
<div id="content" class="site-content">
<?php
$registry = WP_Block_Type_Registry::get_instance(); $block = $registry->get_registered( 'core/legacy-widget' ); echo $block->render( array( 'idBase' => $id_base, 'instance' => $instance, ) ); ?>
</div><!-- #content -->
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>
<?php
return ob_get_clean(); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-widgets-controller.php';
class WP_REST_Widgets_Controller extends WP_REST_Controller { protected $widgets_retrieved = false; protected $allow_batch = array( 'v1' => true ); public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'widgets'; } public function register_routes() { register_rest_route( $this->namespace, $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema(), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, $this->rest_base . '/(?P<id>[\w\-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'description' => __( 'Whether to force removal of the widget, or move it to the inactive sidebar.' ), 'type' => 'boolean', ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $this->retrieve_widgets(); if ( isset( $request['sidebar'] ) && $this->check_read_sidebar_permission( $request['sidebar'] ) ) { return true; } foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { if ( $this->check_read_sidebar_permission( $sidebar_id ) ) { return true; } } return $this->permissions_check( $request ); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $this->retrieve_widgets(); $prepared = array(); $permissions_check = $this->permissions_check( $request ); foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { if ( isset( $request['sidebar'] ) && $sidebar_id !== $request['sidebar'] ) { continue; } if ( is_wp_error( $permissions_check ) && ! $this->check_read_sidebar_permission( $sidebar_id ) ) { continue; } foreach ( $widget_ids as $widget_id ) { $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); if ( ! is_wp_error( $response ) ) { $prepared[] = $this->prepare_response_for_collection( $response ); } } } return new WP_REST_Response( $prepared ); } public function get_item_permissions_check( $request ) { $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( $sidebar_id && $this->check_read_sidebar_permission( $sidebar_id ) ) { return true; } return $this->permissions_check( $request ); } protected function check_read_sidebar_permission( $sidebar_id ) { $sidebar = wp_get_sidebar( $sidebar_id ); return ! empty( $sidebar['show_in_rest'] ); } public function get_item( $request ) { $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( is_null( $sidebar_id ) ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); } public function create_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function create_item( $request ) { $sidebar_id = $request['sidebar']; $widget_id = $this->save_widget( $request, $sidebar_id ); if ( is_wp_error( $widget_id ) ) { return $widget_id; } wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); $request['context'] = 'edit'; $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); if ( is_wp_error( $response ) ) { return $response; } $response->set_status( 201 ); return $response; } public function update_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function update_item( $request ) { global $wp_widget_factory; wp_get_sidebars_widgets(); $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); $parsed_id = wp_parse_widget_id( $widget_id ); $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); if ( is_null( $sidebar_id ) && $widget_object ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } if ( $request->has_param( 'instance' ) || $request->has_param( 'form_data' ) ) { $maybe_error = $this->save_widget( $request, $sidebar_id ); if ( is_wp_error( $maybe_error ) ) { return $maybe_error; } } if ( $request->has_param( 'sidebar' ) ) { if ( $sidebar_id !== $request['sidebar'] ) { $sidebar_id = $request['sidebar']; wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); } } $request['context'] = 'edit'; return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); } public function delete_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function delete_item( $request ) { global $wp_widget_factory, $wp_registered_widget_updates; wp_get_sidebars_widgets(); $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( is_null( $sidebar_id ) ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } $request['context'] = 'edit'; if ( $request['force'] ) { $response = $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); $parsed_id = wp_parse_widget_id( $widget_id ); $id_base = $parsed_id['id_base']; $original_post = $_POST; $original_request = $_REQUEST; $_POST = array( 'sidebar' => $sidebar_id, "widget-$id_base" => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1', ); $_REQUEST = $_POST; do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base ); $callback = $wp_registered_widget_updates[ $id_base ]['callback']; $params = $wp_registered_widget_updates[ $id_base ]['params']; if ( is_callable( $callback ) ) { ob_start(); call_user_func_array( $callback, $params ); ob_end_clean(); } $_POST = $original_post; $_REQUEST = $original_request; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); if ( $widget_object ) { $widget_object->updated = false; } wp_assign_widget_to_sidebar( $widget_id, '' ); $response->set_data( array( 'deleted' => true, 'previous' => $response->get_data(), ) ); } else { wp_assign_widget_to_sidebar( $widget_id, 'wp_inactive_widgets' ); $response = $this->prepare_item_for_response( array( 'sidebar_id' => 'wp_inactive_widgets', 'widget_id' => $widget_id, ), $request ); } do_action( 'rest_delete_widget', $widget_id, $sidebar_id, $response, $request ); return $response; } protected function permissions_check( $request ) { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } protected function retrieve_widgets() { if ( ! $this->widgets_retrieved ) { retrieve_widgets(); $this->widgets_retrieved = true; } } protected function save_widget( $request, $sidebar_id ) { global $wp_widget_factory, $wp_registered_widget_updates; require_once ABSPATH . 'wp-admin/includes/widgets.php'; if ( isset( $request['id'] ) ) { $id = $request['id']; $parsed_id = wp_parse_widget_id( $id ); $id_base = $parsed_id['id_base']; $number = isset( $parsed_id['number'] ) ? $parsed_id['number'] : null; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); $creating = false; } elseif ( $request['id_base'] ) { $id_base = $request['id_base']; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); $number = $widget_object ? next_widget_id_number( $id_base ) : null; $id = $widget_object ? $id_base . '-' . $number : $id_base; $creating = true; } else { return new WP_Error( 'rest_invalid_widget', __( 'Widget type (id_base) is required.' ), array( 'status' => 400 ) ); } if ( ! isset( $wp_registered_widget_updates[ $id_base ] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided widget type (id_base) cannot be updated.' ), array( 'status' => 400 ) ); } if ( isset( $request['instance'] ) ) { if ( ! $widget_object ) { return new WP_Error( 'rest_invalid_widget', __( 'Cannot set instance on a widget that does not extend WP_Widget.' ), array( 'status' => 400 ) ); } if ( isset( $request['instance']['raw'] ) ) { if ( empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'Widget type does not support raw instances.' ), array( 'status' => 400 ) ); } $instance = $request['instance']['raw']; } elseif ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { $serialized_instance = base64_decode( $request['instance']['encoded'] ); if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is malformed.' ), array( 'status' => 400 ) ); } $instance = unserialize( $serialized_instance ); } else { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is invalid. Must contain raw OR encoded and hash.' ), array( 'status' => 400 ) ); } $form_data = array( "widget-$id_base" => array( $number => $instance, ), 'sidebar' => $sidebar_id, ); } elseif ( isset( $request['form_data'] ) ) { $form_data = $request['form_data']; } else { $form_data = array(); } $original_post = $_POST; $original_request = $_REQUEST; foreach ( $form_data as $key => $value ) { $slashed_value = wp_slash( $value ); $_POST[ $key ] = $slashed_value; $_REQUEST[ $key ] = $slashed_value; } $callback = $wp_registered_widget_updates[ $id_base ]['callback']; $params = $wp_registered_widget_updates[ $id_base ]['params']; if ( is_callable( $callback ) ) { ob_start(); call_user_func_array( $callback, $params ); ob_end_clean(); } $_POST = $original_post; $_REQUEST = $original_request; if ( $widget_object ) { $widget_object->_set( $number ); $widget_object->_register_one( $number ); $widget_object->updated = false; } do_action( 'rest_after_save_widget', $id, $sidebar_id, $request, $creating ); return $id; } public function prepare_item_for_response( $item, $request ) { global $wp_widget_factory, $wp_registered_widgets; $widget_id = $item['widget_id']; $sidebar_id = $item['sidebar_id']; if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The requested widget is invalid.' ), array( 'status' => 500 ) ); } $widget = $wp_registered_widgets[ $widget_id ]; if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_widget', new WP_REST_Response( array() ), $widget, $request ); } $parsed_id = wp_parse_widget_id( $widget_id ); $fields = $this->get_fields_for_response( $request ); $prepared = array( 'id' => $widget_id, 'id_base' => $parsed_id['id_base'], 'sidebar' => $sidebar_id, 'rendered' => '', 'rendered_form' => null, 'instance' => null, ); if ( rest_is_field_included( 'rendered', $fields ) && 'wp_inactive_widgets' !== $sidebar_id ) { $prepared['rendered'] = trim( wp_render_widget( $widget_id, $sidebar_id ) ); } if ( rest_is_field_included( 'rendered_form', $fields ) ) { $rendered_form = wp_render_widget_control( $widget_id ); if ( ! is_null( $rendered_form ) ) { $prepared['rendered_form'] = trim( $rendered_form ); } } if ( rest_is_field_included( 'instance', $fields ) ) { $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); if ( $widget_object && isset( $parsed_id['number'] ) ) { $all_instances = $widget_object->get_settings(); $instance = $all_instances[ $parsed_id['number'] ]; $serialized_instance = serialize( $instance ); $prepared['instance']['encoded'] = base64_encode( $serialized_instance ); $prepared['instance']['hash'] = wp_hash( $serialized_instance ); if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { $prepared['instance']['raw'] = empty( $instance ) ? new stdClass() : $instance; } } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $prepared = $this->add_additional_fields_to_object( $prepared, $request ); $prepared = $this->filter_response_by_context( $prepared, $context ); $response = rest_ensure_response( $prepared ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $prepared ) ); } return apply_filters( 'rest_prepare_widget', $response, $widget, $request ); } protected function prepare_links( $prepared ) { $id_base = ! empty( $prepared['id_base'] ) ? $prepared['id_base'] : $prepared['id']; return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $prepared['id'] ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'about' => array( 'href' => rest_url( sprintf( 'wp/v2/widget-types/%s', $id_base ) ), 'embeddable' => true, ), 'https://api.w.org/sidebar' => array( 'href' => rest_url( sprintf( 'wp/v2/sidebars/%s/', $prepared['sidebar'] ) ), ), ); } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'sidebar' => array( 'description' => __( 'The sidebar to return widgets for.' ), 'type' => 'string', ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'widget', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the widget.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'id_base' => array( 'description' => __( 'The type of the widget. Corresponds to ID in widget-types endpoint.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'sidebar' => array( 'description' => __( 'The sidebar the widget belongs to.' ), 'type' => 'string', 'default' => 'wp_inactive_widgets', 'required' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML representation of the widget.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rendered_form' => array( 'description' => __( 'HTML representation of the widget admin form.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'instance' => array( 'description' => __( 'Instance settings of the widget, if supported.' ), 'type' => 'object', 'context' => array( 'edit' ), 'default' => null, 'properties' => array( 'encoded' => array( 'description' => __( 'Base64 encoded representation of the instance settings.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'hash' => array( 'description' => __( 'Cryptographic hash of the instance settings.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'raw' => array( 'description' => __( 'Unencoded instance settings, if supported.' ), 'type' => 'object', 'context' => array( 'edit' ), ), ), ), 'form_data' => array( 'description' => __( 'URL-encoded form data from the widget admin form. Used to update a widget that does not support instance. Write only.' ), 'type' => 'string', 'context' => array(), 'arg_options' => array( 'sanitize_callback' => static function ( $form_data ) { $array = array(); wp_parse_str( $form_data, $array ); return $array; }, ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-templates-controller.php';
class WP_REST_Templates_Controller extends WP_REST_Controller { protected $post_type; public function __construct( $post_type ) { $this->post_type = $post_type; $obj = get_post_type_object( $post_type ); $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/lookup', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_template_fallback' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'slug' => array( 'description' => __( 'The slug of the template to get the fallback for' ), 'type' => 'string', 'required' => true, ), 'is_custom' => array( 'description' => __( 'Indicates if a template is custom or part of the template hierarchy' ), 'type' => 'boolean', ), 'template_prefix' => array( 'description' => __( 'The template prefix for the created template. This is used to extract the main template type, e.g. in `taxonomy-books` extracts the `taxonomy`' ), 'type' => 'string', ), ), ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<id>%s%s)', $this->rest_base, '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', '[\/\w%-]+' ), array( 'args' => array( 'id' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_template_fallback( $request ) { $hierarchy = get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); do { $fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' ); array_shift( $hierarchy ); } while ( ! empty( $hierarchy ) && empty( $fallback_template->content ) ); $response = $fallback_template ? $this->prepare_item_for_response( $fallback_template, $request ) : new stdClass(); return rest_ensure_response( $response ); } protected function permissions_check( $request ) { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } public function _sanitize_template_id( $id ) { $id = urldecode( $id ); $last_slash_pos = strrpos( $id, '/' ); if ( false === $last_slash_pos ) { return $id; } $is_double_slashed = substr( $id, $last_slash_pos - 1, 1 ) === '/'; if ( $is_double_slashed ) { return $id; } return ( substr( $id, 0, $last_slash_pos ) . '/' . substr( $id, $last_slash_pos ) ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $query = array(); if ( isset( $request['wp_id'] ) ) { $query['wp_id'] = $request['wp_id']; } if ( isset( $request['area'] ) ) { $query['area'] = $request['area']; } if ( isset( $request['post_type'] ) ) { $query['post_type'] = $request['post_type']; } $templates = array(); foreach ( get_block_templates( $query, $this->post_type ) as $template ) { $data = $this->prepare_item_for_response( $template, $request ); $templates[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $templates ); } public function get_item_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } public function get_item( $request ) { if ( isset( $request['source'] ) && ( 'theme' === $request['source'] || 'plugin' === $request['source'] ) ) { $template = get_block_file_template( $request['id'], $this->post_type ); } else { $template = get_block_template( $request['id'], $this->post_type ); } if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $template, $request ); } public function update_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function update_item( $request ) { $template = get_block_template( $request['id'], $this->post_type ); if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } $post_before = get_post( $template->wp_id ); if ( isset( $request['source'] ) && 'theme' === $request['source'] ) { wp_delete_post( $template->wp_id, true ); $request->set_param( 'context', 'edit' ); $template = get_block_template( $request['id'], $this->post_type ); $response = $this->prepare_item_for_response( $template, $request ); return rest_ensure_response( $response ); } $changes = $this->prepare_item_for_database( $request ); if ( is_wp_error( $changes ) ) { return $changes; } if ( 'custom' === $template->source ) { $update = true; $result = wp_update_post( wp_slash( (array) $changes ), false ); } else { $update = false; $post_before = null; $result = wp_insert_post( wp_slash( (array) $changes ), false ); } if ( is_wp_error( $result ) ) { if ( 'db_update_error' === $result->get_error_code() ) { $result->add_data( array( 'status' => 500 ) ); } else { $result->add_data( array( 'status' => 400 ) ); } return $result; } $template = get_block_template( $request['id'], $this->post_type ); $fields_update = $this->update_additional_fields_for_object( $template, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); $post = get_post( $template->wp_id ); do_action( "rest_after_insert_{$this->post_type}", $post, $request, false ); wp_after_insert_post( $post, $update, $post_before ); $response = $this->prepare_item_for_response( $template, $request ); return rest_ensure_response( $response ); } public function create_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function create_item( $request ) { $prepared_post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_post ) ) { return $prepared_post; } $prepared_post->post_name = $request['slug']; $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true ); if ( is_wp_error( $post_id ) ) { if ( 'db_insert_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $posts = get_block_templates( array( 'wp_id' => $post_id ), $this->post_type ); if ( ! count( $posts ) ) { return new WP_Error( 'rest_template_insert_error', __( 'No templates exist with that id.' ), array( 'status' => 400 ) ); } $id = $posts[0]->id; $post = get_post( $post_id ); $template = get_block_template( $id, $this->post_type ); $fields_update = $this->update_additional_fields_for_object( $template, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } do_action( "rest_after_insert_{$this->post_type}", $post, $request, true ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $template, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $template->id ) ) ); return $response; } public function delete_item_permissions_check( $request ) { return $this->permissions_check( $request ); } public function delete_item( $request ) { $template = get_block_template( $request['id'], $this->post_type ); if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } if ( 'custom' !== $template->source ) { return new WP_Error( 'rest_invalid_template', __( 'Templates based on theme files can\'t be removed.' ), array( 'status' => 400 ) ); } $id = $template->wp_id; $force = (bool) $request['force']; $request->set_param( 'context', 'edit' ); if ( $force ) { $previous = $this->prepare_item_for_response( $template, $request ); $result = wp_delete_post( $id, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { if ( 'trash' === $template->status ) { return new WP_Error( 'rest_template_already_trashed', __( 'The template has already been deleted.' ), array( 'status' => 410 ) ); } $result = wp_trash_post( $id ); $template->status = 'trash'; $response = $this->prepare_item_for_response( $template, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The template cannot be deleted.' ), array( 'status' => 500 ) ); } return $response; } protected function prepare_item_for_database( $request ) { $template = $request['id'] ? get_block_template( $request['id'], $this->post_type ) : null; $changes = new stdClass(); if ( null === $template ) { $changes->post_type = $this->post_type; $changes->post_status = 'publish'; $changes->tax_input = array( 'wp_theme' => isset( $request['theme'] ) ? $request['theme'] : get_stylesheet(), ); } elseif ( 'custom' !== $template->source ) { $changes->post_name = $template->slug; $changes->post_type = $this->post_type; $changes->post_status = 'publish'; $changes->tax_input = array( 'wp_theme' => $template->theme, ); $changes->meta_input = array( 'origin' => $template->source, ); } else { $changes->post_name = $template->slug; $changes->ID = $template->wp_id; $changes->post_status = 'publish'; } if ( isset( $request['content'] ) ) { if ( is_string( $request['content'] ) ) { $changes->post_content = $request['content']; } elseif ( isset( $request['content']['raw'] ) ) { $changes->post_content = $request['content']['raw']; } } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_content = $template->content; } if ( isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $changes->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $changes->post_title = $request['title']['raw']; } } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_title = $template->title; } if ( isset( $request['description'] ) ) { $changes->post_excerpt = $request['description']; } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_excerpt = $template->description; } if ( 'wp_template' === $this->post_type && isset( $request['is_wp_suggestion'] ) ) { $changes->meta_input = wp_parse_args( array( 'is_wp_suggestion' => $request['is_wp_suggestion'], ), $changes->meta_input = array() ); } if ( 'wp_template_part' === $this->post_type ) { if ( isset( $request['area'] ) ) { $changes->tax_input['wp_template_part_area'] = _filter_block_template_part_area( $request['area'] ); } elseif ( null !== $template && 'custom' !== $template->source && $template->area ) { $changes->tax_input['wp_template_part_area'] = _filter_block_template_part_area( $template->area ); } elseif ( empty( $template->area ) ) { $changes->tax_input['wp_template_part_area'] = WP_TEMPLATE_PART_AREA_UNCATEGORIZED; } } if ( ! empty( $request['author'] ) ) { $post_author = (int) $request['author']; if ( get_current_user_id() !== $post_author ) { $user_obj = get_userdata( $post_author ); if ( ! $user_obj ) { return new WP_Error( 'rest_invalid_author', __( 'Invalid author ID.' ), array( 'status' => 400 ) ); } } $changes->post_author = $post_author; } return apply_filters( "rest_pre_insert_{$this->post_type}", $changes, $request ); } public function prepare_item_for_response( $item, $request ) { if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $blocks = parse_blocks( $item->content ); $blocks = resolve_pattern_blocks( $blocks ); $item->content = serialize_blocks( $blocks ); $template = $item; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $template->id; } if ( rest_is_field_included( 'theme', $fields ) ) { $data['theme'] = $template->theme; } if ( rest_is_field_included( 'content', $fields ) ) { $data['content'] = array(); } if ( rest_is_field_included( 'content.raw', $fields ) ) { $data['content']['raw'] = $template->content; } if ( rest_is_field_included( 'content.block_version', $fields ) ) { $data['content']['block_version'] = block_version( $template->content ); } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $template->slug; } if ( rest_is_field_included( 'source', $fields ) ) { $data['source'] = $template->source; } if ( rest_is_field_included( 'origin', $fields ) ) { $data['origin'] = $template->origin; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $template->type; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $template->description; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $template->title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { if ( $template->wp_id ) { $data['title']['rendered'] = apply_filters( 'the_title', $template->title, $template->wp_id ); } else { $data['title']['rendered'] = $template->title; } } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $template->status; } if ( rest_is_field_included( 'wp_id', $fields ) ) { $data['wp_id'] = (int) $template->wp_id; } if ( rest_is_field_included( 'has_theme_file', $fields ) ) { $data['has_theme_file'] = (bool) $template->has_theme_file; } if ( rest_is_field_included( 'is_custom', $fields ) && 'wp_template' === $template->type ) { $data['is_custom'] = $template->is_custom; } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $template->author; } if ( rest_is_field_included( 'area', $fields ) && 'wp_template_part' === $template->type ) { $data['area'] = $template->area; } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = mysql_to_rfc3339( $template->modified ); } if ( rest_is_field_included( 'author_text', $fields ) ) { $data['author_text'] = self::get_wp_templates_author_text_field( $template ); } if ( rest_is_field_included( 'original_source', $fields ) ) { $data['original_source'] = self::get_wp_templates_original_source_field( $template ); } if ( rest_is_field_included( 'plugin', $fields ) ) { $registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug ); if ( $registered_template ) { $data['plugin'] = $registered_template->plugin; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template->id ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions(); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return $response; } private static function get_wp_templates_original_source_field( $template_object ) { if ( 'wp_template' === $template_object->type || 'wp_template_part' === $template_object->type ) { if ( $template_object->has_theme_file && ( 'theme' === $template_object->origin || ( empty( $template_object->origin ) && in_array( $template_object->source, array( 'theme', 'custom', ), true ) ) ) ) { return 'theme'; } if ( 'plugin' === $template_object->origin ) { return 'plugin'; } if ( empty( $template_object->has_theme_file ) && 'custom' === $template_object->source && empty( $template_object->author ) ) { return 'site'; } } return 'user'; } private static function get_wp_templates_author_text_field( $template_object ) { $original_source = self::get_wp_templates_original_source_field( $template_object ); switch ( $original_source ) { case 'theme': $theme_name = wp_get_theme( $template_object->theme )->get( 'Name' ); return empty( $theme_name ) ? $template_object->theme : $theme_name; case 'plugin': if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( isset( $template_object->plugin ) ) { $plugins = wp_get_active_and_valid_plugins(); foreach ( $plugins as $plugin_file ) { $plugin_basename = plugin_basename( $plugin_file ); list( $plugin_slug, ) = explode( '/', $plugin_basename ); if ( $plugin_slug === $template_object->plugin ) { $plugin_data = get_plugin_data( $plugin_file ); if ( ! empty( $plugin_data['Name'] ) ) { return $plugin_data['Name']; } break; } } } $plugins = get_plugins(); $plugin_basename = plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) ); if ( isset( $plugins[ $plugin_basename ] ) && isset( $plugins[ $plugin_basename ]['Name'] ) ) { return $plugins[ $plugin_basename ]['Name']; } return isset( $template_object->plugin ) ? $template_object->plugin : $template_object->theme; case 'site': return get_bloginfo( 'name' ); case 'user': $author = get_user_by( 'id', $template_object->author ); if ( ! $author ) { return __( 'Unknown author' ); } return $author->get( 'display_name' ); } return ''; } protected function prepare_links( $id ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $id ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $this->post_type ) ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( post_type_supports( $this->post_type, 'revisions' ) ) { $template = get_block_template( $id, $this->post_type ); if ( $template instanceof WP_Block_Template && ! empty( $template->wp_id ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $template->wp_id ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%s/%s/revisions', $this->namespace, $this->rest_base, $id ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); if ( $revisions_count > 0 ) { $links['predecessor-version'] = array( 'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ), 'id' => $revisions['latest_id'], ); } } } return $links; } protected function get_available_actions() { $rels = array(); $post_type = get_post_type_object( $this->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'unfiltered_html' ) ) { $rels[] = 'https://api.w.org/action-unfiltered-html'; } return $rels; } public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'wp_id' => array( 'description' => __( 'Limit to the specified post id.' ), 'type' => 'integer', ), 'area' => array( 'description' => __( 'Limit to the specified template part area.' ), 'type' => 'string', ), 'post_type' => array( 'description' => __( 'Post type to get the templates for.' ), 'type' => 'string', ), ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'Unique slug identifying the template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'required' => true, 'minLength' => 1, 'pattern' => '[a-zA-Z0-9_\%-]+', ), 'theme' => array( 'description' => __( 'Theme identifier for the template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'type' => array( 'description' => __( 'Type of template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'source' => array( 'description' => __( 'Source of template' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'origin' => array( 'description' => __( 'Source of a customized template' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'content' => array( 'description' => __( 'Content of template.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the template, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'block_version' => array( 'description' => __( 'Version of the content block format used by the template.' ), 'type' => 'integer', 'context' => array( 'edit' ), 'readonly' => true, ), ), ), 'title' => array( 'description' => __( 'Title of template.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the template, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML title for the template, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), 'description' => array( 'description' => __( 'Description of template.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), ), 'status' => array( 'description' => __( 'Status of template.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'default' => 'publish', 'context' => array( 'embed', 'view', 'edit' ), ), 'wp_id' => array( 'description' => __( 'Post ID.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'has_theme_file' => array( 'description' => __( 'Theme file exists.' ), 'type' => 'bool', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'author' => array( 'description' => __( 'The ID for the author of the template.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'modified' => array( 'description' => __( "The date the template was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'author_text' => array( 'type' => 'string', 'description' => __( 'Human readable text for the author.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'original_source' => array( 'description' => __( 'Where the template originally comes from e.g. \'theme\'' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( 'theme', 'plugin', 'site', 'user', ), ), ), ); if ( 'wp_template' === $this->post_type ) { $schema['properties']['is_custom'] = array( 'description' => __( 'Whether a template is a custom template.' ), 'type' => 'bool', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $schema['properties']['plugin'] = array( 'type' => 'string', 'description' => __( 'Plugin that registered the template.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ); } if ( 'wp_template_part' === $this->post_type ) { $schema['properties']['area'] = array( 'description' => __( 'Where the template part is intended for use (header, footer, etc.)' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-url-details-controller.php';
class WP_REST_URL_Details_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'url-details'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'parse_url_details' ), 'args' => array( 'url' => array( 'required' => true, 'description' => __( 'The URL to process.' ), 'validate_callback' => 'wp_http_validate_url', 'sanitize_callback' => 'sanitize_url', 'type' => 'string', 'format' => 'uri', ), ), 'permission_callback' => array( $this, 'permissions_check' ), 'schema' => array( $this, 'get_public_item_schema' ), ), ) ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'url-details', 'type' => 'object', 'properties' => array( 'title' => array( 'description' => sprintf( __( 'The contents of the %s element from the URL.' ), '<title>' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'icon' => array( 'description' => sprintf( __( 'The favicon image link of the %s element from the URL.' ), '<link rel="icon">' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'description' => array( 'description' => sprintf( __( 'The content of the %s element from the URL.' ), '<meta name="description">' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'image' => array( 'description' => sprintf( __( 'The Open Graph image link of the %1$s or %2$s element from the URL.' ), '<meta property="og:image">', '<meta property="og:image:url">' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function parse_url_details( $request ) { $url = untrailingslashit( $request['url'] ); if ( empty( $url ) ) { return new WP_Error( 'rest_invalid_url', __( 'Invalid URL' ), array( 'status' => 404 ) ); } $cache_key = $this->build_cache_key_for_url( $url ); $cached_response = $this->get_cache( $cache_key ); if ( ! empty( $cached_response ) ) { $remote_url_response = $cached_response; } else { $remote_url_response = $this->get_remote_url( $url ); if ( is_wp_error( $remote_url_response ) || empty( $remote_url_response ) ) { return $remote_url_response; } $this->set_cache( $cache_key, $remote_url_response ); } $html_head = $this->get_document_head( $remote_url_response ); $meta_elements = $this->get_meta_with_content_elements( $html_head ); $data = $this->add_additional_fields_to_object( array( 'title' => $this->get_title( $html_head ), 'icon' => $this->get_icon( $html_head, $url ), 'description' => $this->get_description( $meta_elements ), 'image' => $this->get_image( $meta_elements, $url ), ), $request ); $response = rest_ensure_response( $data ); return apply_filters( 'rest_prepare_url_details', $response, $url, $request, $remote_url_response ); } public function permissions_check() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view_url_details', __( 'Sorry, you are not allowed to process remote URLs.' ), array( 'status' => rest_authorization_required_code() ) ); } private function get_remote_url( $url ) { $modified_user_agent = 'WP-URLDetails/' . get_bloginfo( 'version' ) . ' (+' . get_bloginfo( 'url' ) . ')'; $args = array( 'limit_response_size' => 150 * KB_IN_BYTES, 'user-agent' => $modified_user_agent, ); $args = apply_filters( 'rest_url_details_http_request_args', $args, $url ); $response = wp_safe_remote_get( $url, $args ); if ( WP_Http::OK !== wp_remote_retrieve_response_code( $response ) ) { return new WP_Error( 'no_response', __( 'URL not found. Response returned a non-200 status code for this URL.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } $remote_body = wp_remote_retrieve_body( $response ); if ( empty( $remote_body ) ) { return new WP_Error( 'no_content', __( 'Unable to retrieve body from response at this URL.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } return $remote_body; } private function get_title( $html ) { $pattern = '#<title[^>]*>(.*?)<\s*/\s*title>#is'; preg_match( $pattern, $html, $match_title ); if ( empty( $match_title[1] ) || ! is_string( $match_title[1] ) ) { return ''; } $title = trim( $match_title[1] ); return $this->prepare_metadata_for_output( $title ); } private function get_icon( $html, $url ) { $pattern = '#<link\s[^>]*rel=(?:[\"\']??)\s*(?:icon|shortcut icon|icon shortcut)\s*(?:[\"\']??)[^>]*\/?>#isU'; preg_match( $pattern, $html, $element ); if ( empty( $element[0] ) || ! is_string( $element[0] ) ) { return ''; } $element = trim( $element[0] ); $pattern = '#href=([\"\']??)([^\" >]*?)\\1[^>]*#isU'; preg_match( $pattern, $element, $icon ); if ( empty( $icon[2] ) || ! is_string( $icon[2] ) ) { return ''; } $icon = trim( $icon[2] ); $parsed_icon = parse_url( $icon ); if ( isset( $parsed_icon['scheme'] ) && 'data' === $parsed_icon['scheme'] ) { return $icon; } if ( ! is_string( $url ) || '' === $url ) { return $icon; } $parsed_url = parse_url( $url ); if ( isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) ) { $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/'; $icon = WP_Http::make_absolute_url( $icon, $root_url ); } return $icon; } private function get_description( $meta_elements ) { if ( empty( $meta_elements[0] ) ) { return ''; } $description = $this->get_metadata_from_meta_element( $meta_elements, 'name', '(?:description|og:description)' ); if ( '' === $description ) { return ''; } return $this->prepare_metadata_for_output( $description ); } private function get_image( $meta_elements, $url ) { $image = $this->get_metadata_from_meta_element( $meta_elements, 'property', '(?:og:image|og:image:url)' ); if ( '' === $image ) { return ''; } $parsed_url = parse_url( $url ); if ( isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) ) { $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/'; $image = WP_Http::make_absolute_url( $image, $root_url ); } return $image; } private function prepare_metadata_for_output( $metadata ) { $metadata = html_entity_decode( $metadata, ENT_QUOTES, get_bloginfo( 'charset' ) ); $metadata = wp_strip_all_tags( $metadata ); return $metadata; } private function build_cache_key_for_url( $url ) { return 'g_url_details_response_' . md5( $url ); } private function get_cache( $key ) { return get_site_transient( $key ); } private function set_cache( $key, $data = '' ) { $ttl = HOUR_IN_SECONDS; $cache_expiration = apply_filters( 'rest_url_details_cache_expiration', $ttl ); return set_site_transient( $key, $data, $cache_expiration ); } private function get_document_head( $html ) { $head_html = $html; $head_start = strpos( $html, '<head' ); if ( false === $head_start ) { return $html; } $head_end = strpos( $head_html, '</head>' ); if ( false === $head_end ) { $head_end = strpos( $head_html, '<body' ); if ( false === $head_end ) { return $html; } } $head_html = substr( $head_html, $head_start, $head_end ); $head_html .= '</head>'; return $head_html; } private function get_meta_with_content_elements( $html ) { $pattern = '#<meta\s' . '[^>]*' . 'content=(["\']??)(.*)\1' . '[^>]*' . '\/?>#' . 'isU'; preg_match_all( $pattern, $html, $elements ); return $elements; } private function get_metadata_from_meta_element( $meta_elements, $attr, $attr_value ) { if ( empty( $meta_elements[0] ) ) { return ''; } $metadata = ''; $pattern = '#' . $attr . '=([\"\']??)\s*' . $attr_value . '\s*\1' . '#isU'; foreach ( $meta_elements[0] as $index => $element ) { preg_match( $pattern, $element, $match ); if ( empty( $match ) ) { continue; } if ( isset( $meta_elements[2][ $index ] ) && is_string( $meta_elements[2][ $index ] ) ) { $metadata = trim( $meta_elements[2][ $index ] ); } break; } return $metadata; } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php';
class WP_REST_Navigation_Fallback_Controller extends WP_REST_Controller { private $post_type; public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'navigation-fallback'; $this->post_type = 'wp_navigation'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ), ), 'schema' => array( $this, 'get_item_schema' ), ) ); } public function get_item_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( 'edit_theme_options' ) || ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create Navigation Menus as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit Navigation Menus as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item( $request ) { $post = WP_Navigation_Fallback::get_fallback(); if ( empty( $post ) ) { return rest_ensure_response( new WP_Error( 'no_fallback_menu', __( 'No fallback menu found.' ), array( 'status' => 404 ) ) ); } $response = $this->prepare_item_for_response( $post, $request ); return $response; } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'navigation-fallback', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'The unique identifier for the Navigation Menu.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } public function prepare_item_for_response( $item, $request ) { $data = array(); $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = (int) $item->ID; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } return $response; } private function prepare_links( $post ) { return array( 'self' => array( 'href' => rest_url( rest_get_route_for_post( $post->ID ) ), 'embeddable' => true, ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-families-controller.php';
class WP_REST_Font_Families_Controller extends WP_REST_Posts_Controller { const LATEST_THEME_JSON_VERSION_SUPPORTED = 3; protected $allow_batch = false; public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( ! current_user_can( $post_type->cap->read ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font families.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( ! current_user_can( 'read_post', $post->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access this font family.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function validate_font_family_settings( $value, $request ) { $settings = json_decode( $value, true ); if ( null === $settings ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%s parameter must be a valid JSON string.' ), 'font_family_settings' ), array( 'status' => 400 ) ); } $schema = $this->get_item_schema()['properties']['font_family_settings']; $required = $schema['required']; if ( isset( $request['id'] ) ) { unset( $schema['required'] ); if ( isset( $settings['slug'] ) ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%s cannot be updated.' ), 'font_family_settings[slug]' ), array( 'status' => 400 ) ); } } $has_valid_settings = rest_validate_value_from_schema( $settings, $schema, 'font_family_settings' ); if ( is_wp_error( $has_valid_settings ) ) { $has_valid_settings->add_data( array( 'status' => 400 ) ); return $has_valid_settings; } foreach ( $required as $key ) { if ( isset( $settings[ $key ] ) && ! $settings[ $key ] ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%s cannot be empty.' ), "font_family_settings[ $key ]" ), array( 'status' => 400 ) ); } } return true; } public function sanitize_font_family_settings( $value ) { $settings = json_decode( $value, true ); $schema = $this->get_item_schema()['properties']['font_family_settings']['properties']; foreach ( $settings as $key => $value ) { $sanitize_callback = $schema[ $key ]['arg_options']['sanitize_callback']; $settings[ $key ] = call_user_func( $sanitize_callback, $value ); } return $settings; } public function create_item( $request ) { $settings = $request->get_param( 'font_family_settings' ); $query = new WP_Query( array( 'post_type' => $this->post_type, 'posts_per_page' => 1, 'name' => $settings['slug'], 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); if ( ! empty( $query->posts ) ) { return new WP_Error( 'rest_duplicate_font_family', sprintf( __( 'A font family with slug "%s" already exists.' ), $settings['slug'] ), array( 'status' => 400 ) ); } return parent::create_item( $request ); } public function delete_item( $request ) { $force = isset( $request['force'] ) ? (bool) $request['force'] : false; if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.' ), 'force=true' ), array( 'status' => 501 ) ); } return parent::delete_item( $request ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $item->ID; } if ( rest_is_field_included( 'theme_json_version', $fields ) ) { $data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED; } if ( rest_is_field_included( 'font_faces', $fields ) ) { $data['font_faces'] = $this->get_font_face_ids( $item->ID ); } if ( rest_is_field_included( 'font_family_settings', $fields ) ) { $data['font_family_settings'] = $this->get_settings_from_post( $item ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } return apply_filters( 'rest_prepare_wp_font_family', $response, $item, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.', 'default' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'theme_json_version' => array( 'description' => __( 'Version of the theme.json schema used for the typography settings.' ), 'type' => 'integer', 'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'minimum' => 2, 'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'context' => array( 'view', 'edit', 'embed' ), ), 'font_faces' => array( 'description' => __( 'The IDs of the child font faces in the font family.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), 'items' => array( 'type' => 'integer', ), ), 'font_family_settings' => array( 'description' => __( 'font-face definition in theme.json format.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'name' => array( 'description' => __( 'Name of the font family preset, translatable.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'slug' => array( 'description' => __( 'Kebab-case unique identifier for the font family preset.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', ), ), 'fontFamily' => array( 'description' => __( 'CSS font-family value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => array( 'WP_Font_Utils', 'sanitize_font_family' ), ), ), 'preview' => array( 'description' => __( 'URL to a preview image of the font family.' ), 'type' => 'string', 'format' => 'uri', 'default' => '', 'arg_options' => array( 'sanitize_callback' => 'sanitize_url', ), ), ), 'required' => array( 'name', 'slug', 'fontFamily' ), 'additionalProperties' => false, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_public_item_schema() { $schema = parent::get_public_item_schema(); foreach ( $schema['properties']['font_family_settings']['properties'] as &$property ) { unset( $property['arg_options'] ); } return $schema; } public function get_collection_params() { $query_params = parent::get_collection_params(); unset( $query_params['after'], $query_params['modified_after'], $query_params['before'], $query_params['modified_before'], $query_params['search'], $query_params['search_columns'], $query_params['status'] ); $query_params['orderby']['default'] = 'id'; $query_params['orderby']['enum'] = array( 'id', 'include' ); return apply_filters( 'rest_wp_font_family_collection_params', $query_params ); } public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { if ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) { $properties = $this->get_item_schema()['properties']; return array( 'theme_json_version' => $properties['theme_json_version'], 'font_family_settings' => array( 'description' => __( 'font-family declaration in theme.json format, encoded as a string.' ), 'type' => 'string', 'required' => true, 'validate_callback' => array( $this, 'validate_font_family_settings' ), 'sanitize_callback' => array( $this, 'sanitize_font_family_settings' ), ), ); } return parent::get_endpoint_args_for_item_schema( $method ); } protected function get_font_face_ids( $font_family_id ) { $query = new WP_Query( array( 'fields' => 'ids', 'post_parent' => $font_family_id, 'post_type' => 'wp_font_face', 'posts_per_page' => 99, 'order' => 'ASC', 'orderby' => 'id', 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); return $query->posts; } protected function prepare_links( $post ) { $links = parent::prepare_links( $post ); return array( 'self' => $links['self'], 'collection' => $links['collection'], 'font_faces' => $this->prepare_font_face_links( $post->ID ), ); } protected function prepare_font_face_links( $font_family_id ) { $font_face_ids = $this->get_font_face_ids( $font_family_id ); $links = array(); foreach ( $font_face_ids as $font_face_id ) { $links[] = array( 'embeddable' => true, 'href' => rest_url( sprintf( '%s/%s/%s/font-faces/%s', $this->namespace, $this->rest_base, $font_family_id, $font_face_id ) ), ); } return $links; } protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); $settings = $request->get_param( 'font_family_settings' ); if ( isset( $request['id'] ) ) { $existing_post = $this->get_post( $request['id'] ); if ( is_wp_error( $existing_post ) ) { return $existing_post; } $prepared_post->ID = $existing_post->ID; $existing_settings = $this->get_settings_from_post( $existing_post ); $settings = array_merge( $existing_settings, $settings ); } $prepared_post->post_type = $this->post_type; $prepared_post->post_status = 'publish'; $prepared_post->post_title = $settings['name']; $prepared_post->post_name = sanitize_title( $settings['slug'] ); unset( $settings['name'] ); unset( $settings['slug'] ); $prepared_post->post_content = wp_json_encode( $settings ); return $prepared_post; } protected function get_settings_from_post( $post ) { $settings_json = json_decode( $post->post_content, true ); return array( 'name' => isset( $post->post_title ) && $post->post_title ? $post->post_title : '', 'slug' => isset( $post->post_name ) && $post->post_name ? $post->post_name : '', 'fontFamily' => isset( $settings_json['fontFamily'] ) && $settings_json['fontFamily'] ? $settings_json['fontFamily'] : '', 'preview' => isset( $settings_json['preview'] ) && $settings_json['preview'] ? $settings_json['preview'] : '', ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-faces-controller.php';
class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller { const LATEST_THEME_JSON_VERSION_SUPPORTED = 3; protected $allow_batch = false; public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'font_family_id' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'required' => true, ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_create_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'font_family_id' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'required' => true, ), 'id' => array( 'description' => __( 'Unique identifier for the font face.' ), 'type' => 'integer', 'required' => true, ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.', 'default' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( ! current_user_can( $post_type->cap->read ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font faces.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( ! current_user_can( 'read_post', $post->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access this font face.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } public function validate_create_font_face_settings( $value, $request ) { $settings = json_decode( $value, true ); if ( null === $settings ) { return new WP_Error( 'rest_invalid_param', __( 'font_face_settings parameter must be a valid JSON string.' ), array( 'status' => 400 ) ); } $schema = $this->get_item_schema()['properties']['font_face_settings']; $has_valid_settings = rest_validate_value_from_schema( $settings, $schema, 'font_face_settings' ); if ( is_wp_error( $has_valid_settings ) ) { $has_valid_settings->add_data( array( 'status' => 400 ) ); return $has_valid_settings; } $required = $schema['required']; foreach ( $required as $key ) { if ( isset( $settings[ $key ] ) && ! $settings[ $key ] ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%s cannot be empty.' ), "font_face_setting[ $key ]" ), array( 'status' => 400 ) ); } } $srcs = is_array( $settings['src'] ) ? $settings['src'] : array( $settings['src'] ); $files = $request->get_file_params(); foreach ( $srcs as $src ) { $src = ltrim( $src ); if ( empty( $src ) ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%s values must be non-empty strings.' ), 'font_face_settings[src]' ), array( 'status' => 400 ) ); } if ( false === wp_http_validate_url( $src ) && ! isset( $files[ $src ] ) ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s value "%2$s" must be a valid URL or file reference.' ), 'font_face_settings[src]', $src ), array( 'status' => 400 ) ); } } foreach ( array_keys( $files ) as $file ) { if ( ! in_array( $file, $srcs, true ) ) { return new WP_Error( 'rest_invalid_param', sprintf( __( 'File %1$s must be used in %2$s.' ), $file, 'font_face_settings[src]' ), array( 'status' => 400 ) ); } } return true; } public function sanitize_font_face_settings( $value ) { $settings = json_decode( $value, true ); $schema = $this->get_item_schema()['properties']['font_face_settings']['properties']; foreach ( $settings as $key => $value ) { $sanitize_callback = $schema[ $key ]['arg_options']['sanitize_callback']; $settings[ $key ] = call_user_func( $sanitize_callback, $value ); } return $settings; } public function get_items( $request ) { $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } return parent::get_items( $request ); } public function get_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } if ( (int) $font_family->ID !== (int) $post->post_parent ) { return new WP_Error( 'rest_font_face_parent_id_mismatch', sprintf( __( 'The font face does not belong to the specified font family with id of "%d".' ), $font_family->ID ), array( 'status' => 404 ) ); } return parent::get_item( $request ); } public function create_item( $request ) { $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } $settings = $request->get_param( 'font_face_settings' ); $file_params = $request->get_file_params(); $query = new WP_Query( array( 'post_type' => $this->post_type, 'posts_per_page' => 1, 'title' => WP_Font_Utils::get_font_face_slug( $settings ), 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); if ( ! empty( $query->posts ) ) { return new WP_Error( 'rest_duplicate_font_face', __( 'A font face matching those settings already exists.' ), array( 'status' => 400 ) ); } if ( ! function_exists( 'wp_handle_upload' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } $srcs = is_string( $settings['src'] ) ? array( $settings['src'] ) : $settings['src']; $processed_srcs = array(); $font_file_meta = array(); foreach ( $srcs as $src ) { if ( ! isset( $file_params[ $src ] ) ) { $processed_srcs[] = $src; continue; } $file = $file_params[ $src ]; $font_file = $this->handle_font_file_upload( $file ); if ( is_wp_error( $font_file ) ) { return $font_file; } $processed_srcs[] = $font_file['url']; $font_file_meta[] = $this->relative_fonts_path( $font_file['file'] ); } $settings['src'] = count( $processed_srcs ) === 1 ? $processed_srcs[0] : $processed_srcs; $request->set_param( 'font_face_settings', $settings ); $font_face_post = parent::create_item( $request ); if ( is_wp_error( $font_face_post ) ) { return $font_face_post; } $font_face_id = $font_face_post->data['id']; foreach ( $font_file_meta as $font_file_path ) { add_post_meta( $font_face_id, '_wp_font_face_file', $font_file_path ); } return $font_face_post; } public function delete_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } if ( (int) $font_family->ID !== (int) $post->post_parent ) { return new WP_Error( 'rest_font_face_parent_id_mismatch', sprintf( __( 'The font face does not belong to the specified font family with id of "%d".' ), $font_family->ID ), array( 'status' => 404 ) ); } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.' ), 'force=true' ), array( 'status' => 501 ) ); } return parent::delete_item( $request ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $item->ID; } if ( rest_is_field_included( 'theme_json_version', $fields ) ) { $data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED; } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = $item->post_parent; } if ( rest_is_field_included( 'font_face_settings', $fields ) ) { $data['font_face_settings'] = $this->get_settings_from_post( $item ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } return apply_filters( 'rest_prepare_wp_font_face', $response, $item, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.', 'default' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'theme_json_version' => array( 'description' => __( 'Version of the theme.json schema used for the typography settings.' ), 'type' => 'integer', 'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'minimum' => 2, 'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'context' => array( 'view', 'edit', 'embed' ), ), 'parent' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'font_face_settings' => array( 'description' => __( 'font-face declaration in theme.json format.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'fontFamily' => array( 'description' => __( 'CSS font-family value.' ), 'type' => 'string', 'default' => '', 'arg_options' => array( 'sanitize_callback' => array( 'WP_Font_Utils', 'sanitize_font_family' ), ), ), 'fontStyle' => array( 'description' => __( 'CSS font-style value.' ), 'type' => 'string', 'default' => 'normal', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontWeight' => array( 'description' => __( 'List of available font weights, separated by a space.' ), 'default' => '400', 'type' => array( 'string', 'integer' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontDisplay' => array( 'description' => __( 'CSS font-display value.' ), 'type' => 'string', 'default' => 'fallback', 'enum' => array( 'auto', 'block', 'fallback', 'swap', 'optional', ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'src' => array( 'description' => __( 'Paths or URLs to the font files.' ), 'anyOf' => array( array( 'type' => 'string', ), array( 'type' => 'array', 'items' => array( 'type' => 'string', ), ), ), 'default' => array(), 'arg_options' => array( 'sanitize_callback' => function ( $value ) { return is_array( $value ) ? array_map( array( $this, 'sanitize_src' ), $value ) : $this->sanitize_src( $value ); }, ), ), 'fontStretch' => array( 'description' => __( 'CSS font-stretch value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'ascentOverride' => array( 'description' => __( 'CSS ascent-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'descentOverride' => array( 'description' => __( 'CSS descent-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontVariant' => array( 'description' => __( 'CSS font-variant value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontFeatureSettings' => array( 'description' => __( 'CSS font-feature-settings value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontVariationSettings' => array( 'description' => __( 'CSS font-variation-settings value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'lineGapOverride' => array( 'description' => __( 'CSS line-gap-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'sizeAdjust' => array( 'description' => __( 'CSS size-adjust value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'unicodeRange' => array( 'description' => __( 'CSS unicode-range value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'preview' => array( 'description' => __( 'URL to a preview image of the font face.' ), 'type' => 'string', 'format' => 'uri', 'default' => '', 'arg_options' => array( 'sanitize_callback' => 'sanitize_url', ), ), ), 'required' => array( 'fontFamily', 'src' ), 'additionalProperties' => false, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } public function get_public_item_schema() { $schema = parent::get_public_item_schema(); foreach ( $schema['properties']['font_face_settings']['properties'] as &$property ) { unset( $property['arg_options'] ); } return $schema; } public function get_collection_params() { $query_params = parent::get_collection_params(); unset( $query_params['after'], $query_params['modified_after'], $query_params['before'], $query_params['modified_before'], $query_params['search'], $query_params['search_columns'], $query_params['slug'], $query_params['status'] ); $query_params['orderby']['default'] = 'id'; $query_params['orderby']['enum'] = array( 'id', 'include' ); return apply_filters( 'rest_wp_font_face_collection_params', $query_params ); } public function get_create_params() { $properties = $this->get_item_schema()['properties']; return array( 'theme_json_version' => $properties['theme_json_version'], 'font_face_settings' => array( 'description' => __( 'font-face declaration in theme.json format, encoded as a string.' ), 'type' => 'string', 'required' => true, 'validate_callback' => array( $this, 'validate_create_font_face_settings' ), 'sanitize_callback' => array( $this, 'sanitize_font_face_settings' ), ), ); } protected function get_parent_font_family_post( $font_family_id ) { $error = new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.', 'default' ), array( 'status' => 404 ) ); if ( (int) $font_family_id <= 0 ) { return $error; } $font_family_post = get_post( (int) $font_family_id ); if ( empty( $font_family_post ) || empty( $font_family_post->ID ) || 'wp_font_family' !== $font_family_post->post_type ) { return $error; } return $font_family_post; } protected function prepare_links( $post ) { return array( 'self' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent . '/font-faces/' . $post->ID ), ), 'collection' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent . '/font-faces' ), ), 'parent' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent ), ), ); } protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); $settings = $request->get_param( 'font_face_settings' ); $title = WP_Font_Utils::get_font_face_slug( $settings ); $prepared_post->post_type = $this->post_type; $prepared_post->post_parent = $request['font_family_id']; $prepared_post->post_status = 'publish'; $prepared_post->post_title = $title; $prepared_post->post_name = sanitize_title( $title ); $prepared_post->post_content = wp_json_encode( $settings ); return $prepared_post; } protected function sanitize_src( $value ) { $value = ltrim( $value ); return false === wp_http_validate_url( $value ) ? (string) $value : sanitize_url( $value ); } protected function handle_font_file_upload( $file ) { add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); add_filter( 'upload_dir', '_wp_filter_font_directory' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), 'test_form' => false, 'mimes' => WP_Font_Utils::get_allowed_font_mime_types(), ); if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) { $overrides['action'] = 'wp_handle_mock_upload'; } $uploaded_file = wp_handle_upload( $file, $overrides ); remove_filter( 'upload_dir', '_wp_filter_font_directory' ); remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); return $uploaded_file; } public function handle_font_file_upload_error( $file, $message ) { $status = 500; $code = 'rest_font_upload_unknown_error'; if ( __( 'Sorry, you are not allowed to upload this file type.' ) === $message ) { $status = 400; $code = 'rest_font_upload_invalid_file_type'; } return new WP_Error( $code, $message, array( 'status' => $status ) ); } protected function relative_fonts_path( $path ) { $new_path = $path; $fonts_dir = wp_get_font_dir(); if ( str_starts_with( $new_path, $fonts_dir['basedir'] ) ) { $new_path = str_replace( $fonts_dir['basedir'], '', $new_path ); $new_path = ltrim( $new_path, '/' ); } return $new_path; } protected function get_settings_from_post( $post ) { $settings = json_decode( $post->post_content, true ); $properties = $this->get_item_schema()['properties']['font_face_settings']['properties']; if ( null === $settings ) { $settings = array( 'fontFamily' => '', 'src' => array(), ); } return array_intersect_key( $settings, $properties ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-collections-controller.php';
class WP_REST_Font_Collections_Controller extends WP_REST_Controller { public function __construct() { $this->rest_base = 'font-collections'; $this->namespace = 'wp/v2'; } public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<slug>[\/\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items( $request ) { $collections_all = WP_Font_Library::get_instance()->get_font_collections(); $page = $request['page']; $per_page = $request['per_page']; $total_items = count( $collections_all ); $max_pages = (int) ceil( $total_items / $per_page ); if ( $page > $max_pages && $total_items > 0 ) { return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $collections_page = array_slice( $collections_all, ( $page - 1 ) * $per_page, $per_page ); $is_head_request = $request->is_method( 'HEAD' ); $items = array(); foreach ( $collections_page as $collection ) { $item = $this->prepare_item_for_response( $collection, $request ); if ( is_wp_error( $item ) ) { continue; } if ( $is_head_request ) { continue; } $item = $this->prepare_response_for_collection( $item ); $items[] = $item; } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $items ); $response->header( 'X-WP-Total', (int) $total_items ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( $this->namespace . '/' . $this->rest_base ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function get_item( $request ) { $slug = $request->get_param( 'slug' ); $collection = WP_Font_Library::get_instance()->get_font_collection( $slug ); if ( ! $collection ) { return new WP_Error( 'rest_font_collection_not_found', __( 'Font collection not found.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $collection, $request ); } public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $item->slug; } $data_fields = array( 'name', 'description', 'font_families', 'categories' ); if ( ! empty( array_intersect( $fields, $data_fields ) ) ) { $collection_data = $item->get_data(); if ( is_wp_error( $collection_data ) ) { $collection_data->add_data( array( 'status' => 500 ) ); return $collection_data; } if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } foreach ( $data_fields as $field ) { if ( rest_is_field_included( $field, $fields ) ) { $data[ $field ] = $collection_data[ $field ]; } } } if ( $request->is_method( 'HEAD' ) ) { return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $response->data = $this->add_additional_fields_to_object( $response->data, $request ); $response->data = $this->filter_response_by_context( $response->data, $context ); return apply_filters( 'rest_prepare_font_collection', $response, $item, $request ); } public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'font-collection', 'type' => 'object', 'properties' => array( 'slug' => array( 'description' => __( 'Unique identifier for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The name for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The description for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'font_families' => array( 'description' => __( 'The font families for the font collection.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( 'The categories for the font collection.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } protected function prepare_links( $collection ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $collection->slug ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); } public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); unset( $query_params['search'] ); return apply_filters( 'rest_font_collections_collection_params', $query_params ); } public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_theme_options' ) ) { return true; } return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font collections.' ), array( 'status' => rest_authorization_required_code(), ) ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-abilities-v1-categories-controller.php';
declare( strict_types = 1 ); class WP_REST_Abilities_V1_Categories_Controller extends WP_REST_Controller { protected $namespace = 'wp-abilities/v1'; protected $rest_base = 'categories'; public function register_routes(): void { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<slug>[a-z0-9]+(?:-[a-z0-9]+)*)', array( 'args' => array( 'slug' => array( 'description' => __( 'Unique identifier for the ability category.' ), 'type' => 'string', 'pattern' => '^[a-z0-9]+(?:-[a-z0-9]+)*$', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items( $request ) { $categories = wp_get_ability_categories(); $page = $request['page']; $per_page = $request['per_page']; $offset = ( $page - 1 ) * $per_page; $total_categories = count( $categories ); $max_pages = (int) ceil( $total_categories / $per_page ); if ( $request->get_method() === 'HEAD' ) { $response = new WP_REST_Response( array() ); } else { $categories = array_slice( $categories, $offset, $per_page ); $data = array(); foreach ( $categories as $category ) { $item = $this->prepare_item_for_response( $category, $request ); $data[] = $this->prepare_response_for_collection( $item ); } $response = rest_ensure_response( $data ); } $response->header( 'X-WP-Total', (string) $total_categories ); $response->header( 'X-WP-TotalPages', (string) $max_pages ); $query_params = $request->get_query_params(); $base = add_query_arg( urlencode_deep( $query_params ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_page = $page - 1; $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $page < $max_pages ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function get_item( $request ) { $category = wp_get_ability_category( $request['slug'] ); if ( ! $category ) { return new WP_Error( 'rest_ability_category_not_found', __( 'Ability category not found.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $category, $request ); return rest_ensure_response( $data ); } public function get_items_permissions_check( $request ) { return current_user_can( 'read' ); } public function get_item_permissions_check( $request ) { return current_user_can( 'read' ); } public function prepare_item_for_response( $category, $request ) { $data = array( 'slug' => $category->get_slug(), 'label' => $category->get_label(), 'description' => $category->get_description(), 'meta' => $category->get_meta(), ); $context = $request['context'] ?? 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $category->get_slug() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'abilities' => array( 'href' => rest_url( sprintf( '%s/abilities?category=%s', $this->namespace, $category->get_slug() ) ), ), ); $response->add_links( $links ); } return $response; } public function get_item_schema(): array { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'ability-category', 'type' => 'object', 'properties' => array( 'slug' => array( 'description' => __( 'Unique identifier for the ability category.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'label' => array( 'description' => __( 'Display label for the category.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of the category.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta' => array( 'description' => __( 'Meta information about the category.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $schema ); } public function get_collection_params(): array { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'page' => array( 'description' => __( 'Current page of the collection.' ), 'type' => 'integer', 'default' => 1, 'minimum' => 1, ), 'per_page' => array( 'description' => __( 'Maximum number of items to be returned in result set.' ), 'type' => 'integer', 'default' => 50, 'minimum' => 1, 'maximum' => 100, ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-abilities-v1-list-controller.php';
declare( strict_types = 1 ); class WP_REST_Abilities_V1_List_Controller extends WP_REST_Controller { protected $namespace = 'wp-abilities/v1'; protected $rest_base = 'abilities'; public function register_routes(): void { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<name>[a-zA-Z0-9\-\/]+)', array( 'args' => array( 'name' => array( 'description' => __( 'Unique identifier for the ability.' ), 'type' => 'string', 'pattern' => '^[a-zA-Z0-9\-\/]+$', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } public function get_items( $request ) { $abilities = array_filter( wp_get_abilities(), static function ( $ability ) { return $ability->get_meta_item( 'show_in_rest' ); } ); $category = $request['category']; if ( ! empty( $category ) ) { $abilities = array_filter( $abilities, static function ( $ability ) use ( $category ) { return $ability->get_category() === $category; } ); $abilities = array_values( $abilities ); } $page = $request['page']; $per_page = $request['per_page']; $offset = ( $page - 1 ) * $per_page; $total_abilities = count( $abilities ); $max_pages = (int) ceil( $total_abilities / $per_page ); if ( $request->get_method() === 'HEAD' ) { $response = new WP_REST_Response( array() ); } else { $abilities = array_slice( $abilities, $offset, $per_page ); $data = array(); foreach ( $abilities as $ability ) { $item = $this->prepare_item_for_response( $ability, $request ); $data[] = $this->prepare_response_for_collection( $item ); } $response = rest_ensure_response( $data ); } $response->header( 'X-WP-Total', (string) $total_abilities ); $response->header( 'X-WP-TotalPages', (string) $max_pages ); $query_params = $request->get_query_params(); $base = add_query_arg( urlencode_deep( $query_params ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_page = $page - 1; $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $page < $max_pages ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } public function get_item( $request ) { $ability = wp_get_ability( $request['name'] ); if ( ! $ability || ! $ability->get_meta_item( 'show_in_rest' ) ) { return new WP_Error( 'rest_ability_not_found', __( 'Ability not found.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $ability, $request ); return rest_ensure_response( $data ); } public function get_items_permissions_check( $request ) { return current_user_can( 'read' ); } public function get_item_permissions_check( $request ) { return current_user_can( 'read' ); } private function normalize_schema_empty_object_defaults( array $schema ): array { if ( isset( $schema['type'] ) && 'object' === $schema['type'] && isset( $schema['default'] ) ) { $default = $schema['default']; if ( is_array( $default ) && empty( $default ) ) { $schema['default'] = (object) $default; } } return $schema; } public function prepare_item_for_response( $ability, $request ) { $data = array( 'name' => $ability->get_name(), 'label' => $ability->get_label(), 'description' => $ability->get_description(), 'category' => $ability->get_category(), 'input_schema' => $this->normalize_schema_empty_object_defaults( $ability->get_input_schema() ), 'output_schema' => $this->normalize_schema_empty_object_defaults( $ability->get_output_schema() ), 'meta' => $ability->get_meta(), ); $context = $request['context'] ?? 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $ability->get_name() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); $links['wp:action-run'] = array( 'href' => rest_url( sprintf( '%s/%s/%s/run', $this->namespace, $this->rest_base, $ability->get_name() ) ), ); $response->add_links( $links ); } return $response; } public function get_item_schema(): array { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'ability', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'Unique identifier for the ability.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'label' => array( 'description' => __( 'Display label for the ability.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of the ability.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'category' => array( 'description' => __( 'Ability category this ability belongs to.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'input_schema' => array( 'description' => __( 'JSON Schema for the ability input.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'output_schema' => array( 'description' => __( 'JSON Schema for the ability output.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta' => array( 'description' => __( 'Meta information about the ability.' ), 'type' => 'object', 'properties' => array( 'annotations' => array( 'description' => __( 'Annotations for the ability.' ), 'type' => array( 'boolean', 'null' ), 'default' => null, ), ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $schema ); } public function get_collection_params(): array { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'page' => array( 'description' => __( 'Current page of the collection.' ), 'type' => 'integer', 'default' => 1, 'minimum' => 1, ), 'per_page' => array( 'description' => __( 'Maximum number of items to be returned in result set.' ), 'type' => 'integer', 'default' => 50, 'minimum' => 1, 'maximum' => 100, ), 'category' => array( 'description' => __( 'Limit results to abilities in specific ability category.' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ), ); } }
###require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-abilities-v1-run-controller.php';
declare( strict_types = 1 ); class WP_REST_Abilities_V1_Run_Controller extends WP_REST_Controller { protected $namespace = 'wp-abilities/v1'; protected $rest_base = 'abilities'; public function register_routes(): void { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<name>[a-zA-Z0-9\-\/]+?)/run', array( 'args' => array( 'name' => array( 'description' => __( 'Unique identifier for the ability.' ), 'type' => 'string', 'pattern' => '^[a-zA-Z0-9\-\/]+$', ), ), array( 'methods' => WP_REST_Server::ALLMETHODS, 'callback' => array( $this, 'execute_ability' ), 'permission_callback' => array( $this, 'check_ability_permissions' ), 'args' => $this->get_run_args(), ), 'schema' => array( $this, 'get_run_schema' ), ) ); } public function execute_ability( $request ) { $ability = wp_get_ability( $request['name'] ); if ( ! $ability ) { return new WP_Error( 'rest_ability_not_found', __( 'Ability not found.' ), array( 'status' => 404 ) ); } $input = $this->get_input_from_request( $request ); $result = $ability->execute( $input ); if ( is_wp_error( $result ) ) { return $result; } return rest_ensure_response( $result ); } public function validate_request_method( string $request_method, array $annotations ) { $expected_method = 'POST'; if ( ! empty( $annotations['readonly'] ) ) { $expected_method = 'GET'; } elseif ( ! empty( $annotations['destructive'] ) && ! empty( $annotations['idempotent'] ) ) { $expected_method = 'DELETE'; } if ( $expected_method === $request_method ) { return true; } $error_message = __( 'Abilities that perform updates require POST method.' ); if ( 'GET' === $expected_method ) { $error_message = __( 'Read-only abilities require GET method.' ); } elseif ( 'DELETE' === $expected_method ) { $error_message = __( 'Abilities that perform destructive actions require DELETE method.' ); } return new WP_Error( 'rest_ability_invalid_method', $error_message, array( 'status' => 405 ) ); } public function check_ability_permissions( $request ) { $ability = wp_get_ability( $request['name'] ); if ( ! $ability || ! $ability->get_meta_item( 'show_in_rest' ) ) { return new WP_Error( 'rest_ability_not_found', __( 'Ability not found.' ), array( 'status' => 404 ) ); } $is_valid = $this->validate_request_method( $request->get_method(), $ability->get_meta_item( 'annotations' ) ); if ( is_wp_error( $is_valid ) ) { return $is_valid; } $input = $this->get_input_from_request( $request ); $input = $ability->normalize_input( $input ); $is_valid = $ability->validate_input( $input ); if ( is_wp_error( $is_valid ) ) { $is_valid->add_data( array( 'status' => 400 ) ); return $is_valid; } $result = $ability->check_permissions( $input ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => rest_authorization_required_code() ) ); return $result; } if ( ! $result ) { return new WP_Error( 'rest_ability_cannot_execute', __( 'Sorry, you are not allowed to execute this ability.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } private function get_input_from_request( $request ) { if ( in_array( $request->get_method(), array( 'GET', 'DELETE' ), true ) ) { $query_params = $request->get_query_params(); return $query_params['input'] ?? null; } $json_params = $request->get_json_params(); return $json_params['input'] ?? null; } public function get_run_args(): array { return array( 'input' => array( 'description' => __( 'Input parameters for the ability execution.' ), 'type' => array( 'integer', 'number', 'boolean', 'string', 'array', 'object', 'null' ), 'default' => null, ), ); } public function get_run_schema(): array { return array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'ability-execution', 'type' => 'object', 'properties' => array( 'result' => array( 'description' => __( 'The result of the ability execution.' ), 'type' => array( 'integer', 'number', 'boolean', 'string', 'array', 'object', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); } }
###require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php';
abstract class WP_REST_Meta_Fields { abstract protected function get_meta_type(); protected function get_meta_subtype() { return ''; } abstract protected function get_rest_field_type(); public function register_field() { _deprecated_function( __METHOD__, '5.6.0' ); register_rest_field( $this->get_rest_field_type(), 'meta', array( 'get_callback' => array( $this, 'get_value' ), 'update_callback' => array( $this, 'update_value' ), 'schema' => $this->get_field_schema(), ) ); } public function get_value( $object_id, $request ) { $fields = $this->get_registered_fields(); $response = array(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false ); if ( $args['single'] ) { if ( empty( $all_values ) ) { $value = $args['schema']['default']; } else { $value = $all_values[0]; } $value = $this->prepare_value_for_response( $value, $request, $args ); } else { $value = array(); if ( is_array( $all_values ) ) { foreach ( $all_values as $row ) { $value[] = $this->prepare_value_for_response( $row, $request, $args ); } } } $response[ $name ] = $value; } return $response; } protected function prepare_value_for_response( $value, $request, $args ) { if ( ! empty( $args['prepare_callback'] ) ) { $value = call_user_func( $args['prepare_callback'], $value, $request, $args ); } return $value; } public function update_value( $meta, $object_id ) { $fields = $this->get_registered_fields(); $error = new WP_Error(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; if ( ! array_key_exists( $name, $meta ) ) { continue; } $value = $meta[ $name ]; if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) { $args = $this->get_registered_fields()[ $meta_key ]; if ( $args['single'] ) { $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); if ( is_wp_error( rest_validate_value_from_schema( $current, $args['schema'] ) ) ) { $error->add( 'rest_invalid_stored_value', sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } } $result = $this->delete_meta_value( $object_id, $meta_key, $name ); if ( is_wp_error( $result ) ) { $error->merge_from( $result ); } continue; } if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { $error->add( 'rest_invalid_stored_value', sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } $is_valid = rest_validate_value_from_schema( $value, $args['schema'], 'meta.' . $name ); if ( is_wp_error( $is_valid ) ) { $is_valid->add_data( array( 'status' => 400 ) ); $error->merge_from( $is_valid ); continue; } $value = rest_sanitize_value_from_schema( $value, $args['schema'] ); if ( $args['single'] ) { $result = $this->update_meta_value( $object_id, $meta_key, $name, $value ); } else { $result = $this->update_multi_meta_value( $object_id, $meta_key, $name, $value ); } if ( is_wp_error( $result ) ) { $error->merge_from( $result ); continue; } } if ( $error->has_errors() ) { return $error; } return null; } protected function delete_meta_value( $object_id, $meta_key, $name ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_delete', sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return true; } if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return new WP_Error( 'rest_meta_database_error', __( 'Could not delete meta value from database.' ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } $current_values = get_metadata_raw( $meta_type, $object_id, $meta_key, false ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( ! is_array( $current_values ) ) { $current_values = array(); } $to_remove = $current_values; $to_add = $values; foreach ( $to_add as $add_key => $value ) { $remove_keys = array_keys( array_filter( $current_values, function ( $stored_value ) use ( $meta_key, $subtype, $value ) { return $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $value ); } ) ); if ( empty( $remove_keys ) ) { continue; } if ( count( $remove_keys ) > 1 ) { continue; } $remove_key = $remove_keys[0]; unset( $to_remove[ $remove_key ] ); unset( $to_add[ $add_key ] ); } $to_remove = array_map( 'maybe_unserialize', array_unique( array_map( 'maybe_serialize', $to_remove ) ) ); foreach ( $to_remove as $value ) { if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } foreach ( $to_add as $value ) { if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } return true; } protected function update_meta_value( $object_id, $meta_key, $name, $value ) { $meta_type = $this->get_meta_type(); $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( is_array( $old_value ) && 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) { return true; } if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } protected function is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $user_value ) { $args = $this->get_registered_fields()[ $meta_key ]; $sanitized = sanitize_meta( $meta_key, $user_value, $this->get_meta_type(), $subtype ); if ( in_array( $args['type'], array( 'string', 'number', 'integer', 'boolean' ), true ) ) { $sanitized = (string) $sanitized; } return $sanitized === $stored_value; } protected function get_registered_fields() { $registered = array(); $meta_type = $this->get_meta_type(); $meta_subtype = $this->get_meta_subtype(); $meta_keys = get_registered_meta_keys( $meta_type ); if ( ! empty( $meta_subtype ) ) { $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $meta_type, $meta_subtype ) ); } foreach ( $meta_keys as $name => $args ) { if ( empty( $args['show_in_rest'] ) ) { continue; } $rest_args = array(); if ( is_array( $args['show_in_rest'] ) ) { $rest_args = $args['show_in_rest']; } $default_args = array( 'name' => $name, 'single' => $args['single'], 'type' => ! empty( $args['type'] ) ? $args['type'] : null, 'schema' => array(), 'prepare_callback' => array( $this, 'prepare_value' ), ); $default_schema = array( 'type' => $default_args['type'], 'title' => empty( $args['label'] ) ? '' : $args['label'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); $rest_args = array_merge( $default_args, $rest_args ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; if ( null === $rest_args['schema']['default'] ) { $rest_args['schema']['default'] = static::get_empty_value_for_type( $type ); } $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { continue; } if ( empty( $rest_args['single'] ) ) { $rest_args['schema'] = array( 'type' => 'array', 'items' => $rest_args['schema'], ); } $registered[ $name ] = $rest_args; } return $registered; } public function get_field_schema() { $fields = $this->get_registered_fields(); $schema = array( 'description' => __( 'Meta fields.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array(), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => array( $this, 'check_meta_is_array' ), ), ); foreach ( $fields as $args ) { $schema['properties'][ $args['name'] ] = $args['schema']; } return $schema; } public static function prepare_value( $value, $request, $args ) { if ( $args['single'] ) { $schema = $args['schema']; } else { $schema = $args['schema']['items']; } if ( '' === $value && in_array( $schema['type'], array( 'boolean', 'integer', 'number' ), true ) ) { $value = static::get_empty_value_for_type( $schema['type'] ); } if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { return null; } return rest_sanitize_value_from_schema( $value, $schema ); } public function check_meta_is_array( $value, $request, $param ) { if ( ! is_array( $value ) ) { return false; } return $value; } protected function default_additional_properties_to_false( $schema ) { _deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' ); return rest_default_additional_properties_to_false( $schema ); } protected static function get_empty_value_for_type( $type ) { switch ( $type ) { case 'string': return ''; case 'boolean': return false; case 'integer': return 0; case 'number': return 0.0; case 'array': case 'object': return array(); default: return null; } } }
###require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php';
class WP_REST_Comment_Meta_Fields extends WP_REST_Meta_Fields { protected function get_meta_type() { return 'comment'; } protected function get_meta_subtype() { return 'comment'; } public function get_rest_field_type() { return 'comment'; } }
###require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php';
class WP_REST_Post_Meta_Fields extends WP_REST_Meta_Fields { protected $post_type; public function __construct( $post_type ) { $this->post_type = $post_type; } protected function get_meta_type() { return 'post'; } protected function get_meta_subtype() { return $this->post_type; } public function get_rest_field_type() { return $this->post_type; } }
###require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-term-meta-fields.php';
class WP_REST_Term_Meta_Fields extends WP_REST_Meta_Fields { protected $taxonomy; public function __construct( $taxonomy ) { $this->taxonomy = $taxonomy; } protected function get_meta_type() { return 'term'; } protected function get_meta_subtype() { return $this->taxonomy; } public function get_rest_field_type() { return 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy; } }
###require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-user-meta-fields.php';
class WP_REST_User_Meta_Fields extends WP_REST_Meta_Fields { protected function get_meta_type() { return 'user'; } protected function get_meta_subtype() { return 'user'; } public function get_rest_field_type() { return 'user'; } }
###require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-search-handler.php';
abstract class WP_REST_Search_Handler { const RESULT_IDS = 'ids'; const RESULT_TOTAL = 'total'; protected $type = ''; protected $subtypes = array(); public function get_type() { return $this->type; } public function get_subtypes() { return $this->subtypes; } abstract public function search_items( WP_REST_Request $request ); abstract public function prepare_item( $id, array $fields ); abstract public function prepare_item_links( $id ); }
###require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-post-search-handler.php';
class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler { public function __construct() { $this->type = 'post'; $this->subtypes = array_diff( array_values( get_post_types( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ), array( 'attachment' ) ); } public function search_items( WP_REST_Request $request ) { $post_types = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $post_types, true ) ) { $post_types = $this->subtypes; } $query_args = array( 'post_type' => $post_types, 'post_status' => 'publish', 'paged' => (int) $request['page'], 'posts_per_page' => (int) $request['per_page'], 'ignore_sticky_posts' => true, ); if ( ! empty( $request['search'] ) ) { $query_args['s'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['post__not_in'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['post__in'] = $request['include']; } $query_args = apply_filters( 'rest_post_search_query', $query_args, $request ); $query = new WP_Query(); $posts = $query->query( $query_args ); $found_ids = wp_list_pluck( $posts, 'ID' ); $total = $query->found_posts; return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } public function prepare_item( $id, array $fields ) { $post = get_post( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $post->ID; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { if ( post_type_supports( $post->post_type, 'title' ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } else { $data[ WP_REST_Search_Controller::PROP_TITLE ] = ''; } } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_permalink( $post->ID ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } if ( in_array( WP_REST_Search_Controller::PROP_SUBTYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_SUBTYPE ] = $post->post_type; } return $data; } public function prepare_item_links( $id ) { $post = get_post( $id ); $links = array(); $item_route = rest_get_route_for_post( $post ); if ( ! empty( $item_route ) ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( 'wp/v2/types/' . $post->post_type ), ); return $links; } public function protected_title_format() { return '%s'; } protected function detect_rest_item_route( $post ) { _deprecated_function( __METHOD__, '5.5.0', 'rest_get_route_for_post()' ); return rest_get_route_for_post( $post ); } }
###require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-term-search-handler.php';
class WP_REST_Term_Search_Handler extends WP_REST_Search_Handler { public function __construct() { $this->type = 'term'; $this->subtypes = array_values( get_taxonomies( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ); } public function search_items( WP_REST_Request $request ) { $taxonomies = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $taxonomies, true ) ) { $taxonomies = $this->subtypes; } $page = (int) $request['page']; $per_page = (int) $request['per_page']; $query_args = array( 'taxonomy' => $taxonomies, 'hide_empty' => false, 'offset' => ( $page - 1 ) * $per_page, 'number' => $per_page, ); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['exclude'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['include'] = $request['include']; } $query_args = apply_filters( 'rest_term_search_query', $query_args, $request ); $query = new WP_Term_Query(); $found_terms = $query->query( $query_args ); $found_ids = wp_list_pluck( $found_terms, 'term_id' ); unset( $query_args['offset'], $query_args['number'] ); $total = wp_count_terms( $query_args ); if ( ! $total ) { $total = 0; } return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } public function prepare_item( $id, array $fields ) { $term = get_term( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = $term->name; } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_term_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $term->taxonomy; } return $data; } public function prepare_item_links( $id ) { $term = get_term( $id ); $links = array(); $item_route = rest_get_route_for_term( $term ); if ( $item_route ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $term->taxonomy ) ), ); return $links; } }
###require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-post-format-search-handler.php';
class WP_REST_Post_Format_Search_Handler extends WP_REST_Search_Handler { public function __construct() { $this->type = 'post-format'; } public function search_items( WP_REST_Request $request ) { $format_strings = get_post_format_strings(); $format_slugs = array_keys( $format_strings ); $query_args = array(); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } $query_args = apply_filters( 'rest_post_format_search_query', $query_args, $request ); $found_ids = array(); foreach ( $format_slugs as $format_slug ) { if ( ! empty( $query_args['search'] ) ) { $format_string = get_post_format_string( $format_slug ); $format_slug_match = stripos( $format_slug, $query_args['search'] ) !== false; $format_string_match = stripos( $format_string, $query_args['search'] ) !== false; if ( ! $format_slug_match && ! $format_string_match ) { continue; } } $format_link = get_post_format_link( $format_slug ); if ( $format_link ) { $found_ids[] = $format_slug; } } $page = (int) $request['page']; $per_page = (int) $request['per_page']; return array( self::RESULT_IDS => array_slice( $found_ids, ( $page - 1 ) * $per_page, $per_page ), self::RESULT_TOTAL => count( $found_ids ), ); } public function prepare_item( $id, array $fields ) { $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_post_format_string( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_format_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } return $data; } public function prepare_item_links( $id ) { return array(); } }
###require ABSPATH . WPINC . '/sitemaps.php';
function wp_sitemaps_get_server() { global $wp_sitemaps; if ( empty( $wp_sitemaps ) ) { $wp_sitemaps = new WP_Sitemaps(); $wp_sitemaps->init(); do_action( 'wp_sitemaps_init', $wp_sitemaps ); } return $wp_sitemaps; } function wp_get_sitemap_providers() { $sitemaps = wp_sitemaps_get_server(); return $sitemaps->registry->get_providers(); } function wp_register_sitemap_provider( $name, WP_Sitemaps_Provider $provider ) { $sitemaps = wp_sitemaps_get_server(); return $sitemaps->registry->add_provider( $name, $provider ); } function wp_sitemaps_get_max_urls( $object_type ) { return apply_filters( 'wp_sitemaps_max_urls', 2000, $object_type ); } function get_sitemap_url( $name, $subtype_name = '', $page = 1 ) { $sitemaps = wp_sitemaps_get_server(); if ( ! $sitemaps ) { return false; } if ( 'index' === $name ) { return $sitemaps->index->get_index_url(); } $provider = $sitemaps->registry->get_provider( $name ); if ( ! $provider ) { return false; } if ( $subtype_name && ! in_array( $subtype_name, array_keys( $provider->get_object_subtypes() ), true ) ) { return false; } $page = absint( $page ); if ( 0 >= $page ) { $page = 1; } return $provider->get_sitemap_url( $subtype_name, $page ); }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps.php';
class WP_Sitemaps { public $index; public $registry; public $renderer; public function __construct() { $this->registry = new WP_Sitemaps_Registry(); $this->renderer = new WP_Sitemaps_Renderer(); $this->index = new WP_Sitemaps_Index( $this->registry ); } public function init() { $this->register_rewrites(); add_action( 'template_redirect', array( $this, 'render_sitemaps' ) ); if ( ! $this->sitemaps_enabled() ) { return; } $this->register_sitemaps(); add_filter( 'robots_txt', array( $this, 'add_robots' ), 0, 2 ); } public function sitemaps_enabled() { $is_enabled = (bool) get_option( 'blog_public' ); return (bool) apply_filters( 'wp_sitemaps_enabled', $is_enabled ); } public function register_sitemaps() { $providers = array( 'posts' => new WP_Sitemaps_Posts(), 'taxonomies' => new WP_Sitemaps_Taxonomies(), 'users' => new WP_Sitemaps_Users(), ); foreach ( $providers as $name => $provider ) { $this->registry->add_provider( $name, $provider ); } } public function register_rewrites() { add_rewrite_tag( '%sitemap%', '([^?]+)' ); add_rewrite_tag( '%sitemap-subtype%', '([^?]+)' ); add_rewrite_rule( '^wp-sitemap\.xml$', 'index.php?sitemap=index', 'top' ); add_rewrite_tag( '%sitemap-stylesheet%', '([^?]+)' ); add_rewrite_rule( '^wp-sitemap\.xsl$', 'index.php?sitemap-stylesheet=sitemap', 'top' ); add_rewrite_rule( '^wp-sitemap-index\.xsl$', 'index.php?sitemap-stylesheet=index', 'top' ); add_rewrite_rule( '^wp-sitemap-([a-z]+?)-([a-z\d_-]+?)-(\d+?)\.xml$', 'index.php?sitemap=$matches[1]&sitemap-subtype=$matches[2]&paged=$matches[3]', 'top' ); add_rewrite_rule( '^wp-sitemap-([a-z]+?)-(\d+?)\.xml$', 'index.php?sitemap=$matches[1]&paged=$matches[2]', 'top' ); } public function render_sitemaps() { global $wp_query; $sitemap = sanitize_text_field( get_query_var( 'sitemap' ) ); $object_subtype = sanitize_text_field( get_query_var( 'sitemap-subtype' ) ); $stylesheet_type = sanitize_text_field( get_query_var( 'sitemap-stylesheet' ) ); $paged = absint( get_query_var( 'paged' ) ); if ( ! ( $sitemap || $stylesheet_type ) ) { return; } if ( ! $this->sitemaps_enabled() ) { $wp_query->set_404(); status_header( 404 ); return; } if ( $stylesheet_type ) { $stylesheet = new WP_Sitemaps_Stylesheet(); $stylesheet->render_stylesheet( $stylesheet_type ); exit; } if ( 'index' === $sitemap ) { $sitemap_list = $this->index->get_sitemap_list(); $this->renderer->render_index( $sitemap_list ); exit; } $provider = $this->registry->get_provider( $sitemap ); if ( ! $provider ) { return; } if ( empty( $paged ) ) { $paged = 1; } $url_list = $provider->get_url_list( $paged, $object_subtype ); if ( empty( $url_list ) ) { $wp_query->set_404(); status_header( 404 ); return; } $this->renderer->render_sitemap( $url_list ); exit; } public function redirect_sitemapxml( $bypass, $query ) { _deprecated_function( __FUNCTION__, '6.7.0' ); if ( $bypass ) { return $bypass; } if ( 'sitemap-xml' === $query->get( 'pagename' ) || 'sitemap-xml' === $query->get( 'name' ) ) { wp_safe_redirect( $this->index->get_index_url() ); exit(); } return $bypass; } public function add_robots( $output, $is_public ) { if ( $is_public ) { $output .= "\nSitemap: " . esc_url( $this->index->get_index_url() ) . "\n"; } return $output; } }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps-index.php';
class WP_Sitemaps_Index { protected $registry; private $max_sitemaps = 50000; public function __construct( WP_Sitemaps_Registry $registry ) { $this->registry = $registry; } public function get_sitemap_list() { $sitemaps = array(); $providers = $this->registry->get_providers(); foreach ( $providers as $name => $provider ) { $sitemap_entries = $provider->get_sitemap_entries(); if ( ! $sitemap_entries ) { continue; } array_push( $sitemaps, ...$sitemap_entries ); if ( count( $sitemaps ) >= $this->max_sitemaps ) { break; } } return array_slice( $sitemaps, 0, $this->max_sitemaps, true ); } public function get_index_url() { global $wp_rewrite; if ( ! $wp_rewrite->using_permalinks() ) { return home_url( '/?sitemap=index' ); } return home_url( '/wp-sitemap.xml' ); } }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps-provider.php';
abstract class WP_Sitemaps_Provider { protected $name = ''; protected $object_type = ''; abstract public function get_url_list( $page_num, $object_subtype = '' ); abstract public function get_max_num_pages( $object_subtype = '' ); public function get_sitemap_type_data() { $sitemap_data = array(); $object_subtypes = $this->get_object_subtypes(); if ( empty( $object_subtypes ) ) { $sitemap_data[] = array( 'name' => '', 'pages' => $this->get_max_num_pages(), ); return $sitemap_data; } foreach ( $object_subtypes as $object_subtype_name => $data ) { $object_subtype_name = (string) $object_subtype_name; $sitemap_data[] = array( 'name' => $object_subtype_name, 'pages' => $this->get_max_num_pages( $object_subtype_name ), ); } return $sitemap_data; } public function get_sitemap_entries() { $sitemaps = array(); $sitemap_types = $this->get_sitemap_type_data(); foreach ( $sitemap_types as $type ) { for ( $page = 1; $page <= $type['pages']; $page++ ) { $sitemap_entry = array( 'loc' => $this->get_sitemap_url( $type['name'], $page ), ); $sitemap_entry = apply_filters( 'wp_sitemaps_index_entry', $sitemap_entry, $this->object_type, $type['name'], $page ); $sitemaps[] = $sitemap_entry; } } return $sitemaps; } public function get_sitemap_url( $name, $page ) { global $wp_rewrite; $params = array_filter( array( 'sitemap' => $this->name, 'sitemap-subtype' => $name, 'paged' => $page, ) ); $basename = sprintf( '/wp-sitemap-%1$s.xml', implode( '-', $params ) ); if ( ! $wp_rewrite->using_permalinks() ) { $basename = '/?' . http_build_query( $params, '', '&' ); } return home_url( $basename ); } public function get_object_subtypes() { return array(); } }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps-registry.php';
class WP_Sitemaps_Registry { private $providers = array(); public function add_provider( $name, WP_Sitemaps_Provider $provider ) { if ( isset( $this->providers[ $name ] ) ) { return false; } $provider = apply_filters( 'wp_sitemaps_add_provider', $provider, $name ); if ( ! $provider instanceof WP_Sitemaps_Provider ) { return false; } $this->providers[ $name ] = $provider; return true; } public function get_provider( $name ) { if ( ! is_string( $name ) || ! isset( $this->providers[ $name ] ) ) { return null; } return $this->providers[ $name ]; } public function get_providers() { return $this->providers; } }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps-renderer.php';
class WP_Sitemaps_Renderer { protected $stylesheet = ''; protected $stylesheet_index = ''; public function __construct() { $stylesheet_url = $this->get_sitemap_stylesheet_url(); if ( $stylesheet_url ) { $this->stylesheet = '<?xml-stylesheet type="text/xsl" href="' . esc_url( $stylesheet_url ) . '" ?>'; } $stylesheet_index_url = $this->get_sitemap_index_stylesheet_url(); if ( $stylesheet_index_url ) { $this->stylesheet_index = '<?xml-stylesheet type="text/xsl" href="' . esc_url( $stylesheet_index_url ) . '" ?>'; } } public function get_sitemap_stylesheet_url() { global $wp_rewrite; $sitemap_url = home_url( '/wp-sitemap.xsl' ); if ( ! $wp_rewrite->using_permalinks() ) { $sitemap_url = home_url( '/?sitemap-stylesheet=sitemap' ); } return apply_filters( 'wp_sitemaps_stylesheet_url', $sitemap_url ); } public function get_sitemap_index_stylesheet_url() { global $wp_rewrite; $sitemap_url = home_url( '/wp-sitemap-index.xsl' ); if ( ! $wp_rewrite->using_permalinks() ) { $sitemap_url = home_url( '/?sitemap-stylesheet=index' ); } return apply_filters( 'wp_sitemaps_stylesheet_index_url', $sitemap_url ); } public function render_index( $sitemaps ) { header( 'Content-Type: application/xml; charset=UTF-8' ); $this->check_for_simple_xml_availability(); $index_xml = $this->get_sitemap_index_xml( $sitemaps ); if ( ! empty( $index_xml ) ) { echo $index_xml; } } public function get_sitemap_index_xml( $sitemaps ) { $sitemap_index = new SimpleXMLElement( sprintf( '%1$s%2$s%3$s', '<?xml version="1.0" encoding="UTF-8" ?>', $this->stylesheet_index, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" />' ) ); foreach ( $sitemaps as $entry ) { $sitemap = $sitemap_index->addChild( 'sitemap' ); foreach ( $entry as $name => $value ) { if ( 'loc' === $name ) { $sitemap->addChild( $name, esc_url( $value ) ); } elseif ( 'lastmod' === $name ) { $sitemap->addChild( $name, esc_xml( $value ) ); } else { _doing_it_wrong( __METHOD__, sprintf( __( 'Fields other than %s are not currently supported for the sitemap index.' ), implode( ',', array( 'loc', 'lastmod' ) ) ), '5.5.0' ); } } } return $sitemap_index->asXML(); } public function render_sitemap( $url_list ) { header( 'Content-Type: application/xml; charset=UTF-8' ); $this->check_for_simple_xml_availability(); $sitemap_xml = $this->get_sitemap_xml( $url_list ); if ( ! empty( $sitemap_xml ) ) { echo $sitemap_xml; } } public function get_sitemap_xml( $url_list ) { $urlset = new SimpleXMLElement( sprintf( '%1$s%2$s%3$s', '<?xml version="1.0" encoding="UTF-8" ?>', $this->stylesheet, '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" />' ) ); foreach ( $url_list as $url_item ) { $url = $urlset->addChild( 'url' ); foreach ( $url_item as $name => $value ) { if ( 'loc' === $name ) { $url->addChild( $name, esc_url( $value ) ); } elseif ( in_array( $name, array( 'lastmod', 'changefreq', 'priority' ), true ) ) { $url->addChild( $name, esc_xml( $value ) ); } else { _doing_it_wrong( __METHOD__, sprintf( __( 'Fields other than %s are not currently supported for sitemaps.' ), implode( ',', array( 'loc', 'lastmod', 'changefreq', 'priority' ) ) ), '5.5.0' ); } } } return $urlset->asXML(); } private function check_for_simple_xml_availability() { if ( ! class_exists( 'SimpleXMLElement' ) ) { add_filter( 'wp_die_handler', static function () { return '_xml_wp_die_handler'; } ); wp_die( sprintf( esc_xml( __( 'Could not generate XML sitemap due to missing %s extension' ) ), 'SimpleXML' ), esc_xml( __( 'WordPress › Error' ) ), array( 'response' => 501, ) ); } } }
###require ABSPATH . WPINC . '/sitemaps/class-wp-sitemaps-stylesheet.php';
class WP_Sitemaps_Stylesheet { public function render_stylesheet( $type ) { header( 'Content-Type: application/xml; charset=UTF-8' ); if ( 'sitemap' === $type ) { echo $this->get_sitemap_stylesheet(); } if ( 'index' === $type ) { echo $this->get_sitemap_index_stylesheet(); } exit; } public function get_sitemap_stylesheet() { $css = $this->get_stylesheet_css(); $title = esc_xml( __( 'XML Sitemap' ) ); $description = esc_xml( __( 'This XML Sitemap is generated by WordPress to make your content more visible for search engines.' ) ); $learn_more = sprintf( '<a href="%s">%s</a>', esc_url( __( 'https://www.sitemaps.org/' ) ), esc_xml( __( 'Learn more about XML sitemaps.' ) ) ); $text = sprintf( esc_xml( __( 'Number of URLs in this XML Sitemap: %s.' ) ), '<xsl:value-of select="count( sitemap:urlset/sitemap:url )" />' ); $lang = get_language_attributes( 'html' ); $url = esc_xml( __( 'URL' ) ); $lastmod = esc_xml( __( 'Last Modified' ) ); $changefreq = esc_xml( __( 'Change Frequency' ) ); $priority = esc_xml( __( 'Priority' ) ); $xsl_content = <<<XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
exclude-result-prefixes="sitemap"
>
<xsl:output method="html" encoding="UTF-8" indent="yes" />
<!--
Set variables for whether lastmod, changefreq or priority occur for any url in the sitemap.
We do this up front because it can be expensive in a large sitemap.
-->
<xsl:variable name="has-lastmod" select="count( /sitemap:urlset/sitemap:url/sitemap:lastmod )" />
<xsl:variable name="has-changefreq" select="count( /sitemap:urlset/sitemap:url/sitemap:changefreq )" />
<xsl:variable name="has-priority" select="count( /sitemap:urlset/sitemap:url/sitemap:priority )" />
<xsl:template match="/">
<html {$lang}>
<head>
<title>{$title}</title>
<style>
{$css}
</style>
</head>
<body>
<div id="sitemap">
<div id="sitemap__header">
<h1>{$title}</h1>
<p>{$description}</p>
<p>{$learn_more}</p>
</div>
<div id="sitemap__content">
<p class="text">{$text}</p>
<table id="sitemap__table">
<thead>
<tr>
<th class="loc">{$url}</th>
<xsl:if test="\$has-lastmod">
<th class="lastmod">{$lastmod}</th>
</xsl:if>
<xsl:if test="\$has-changefreq">
<th class="changefreq">{$changefreq}</th>
</xsl:if>
<xsl:if test="\$has-priority">
<th class="priority">{$priority}</th>
</xsl:if>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td class="loc"><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc" /></a></td>
<xsl:if test="\$has-lastmod">
<td class="lastmod"><xsl:value-of select="sitemap:lastmod" /></td>
</xsl:if>
<xsl:if test="\$has-changefreq">
<td class="changefreq"><xsl:value-of select="sitemap:changefreq" /></td>
</xsl:if>
<xsl:if test="\$has-priority">
<td class="priority"><xsl:value-of select="sitemap:priority" /></td>
</xsl:if>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XSL;
return apply_filters( 'wp_sitemaps_stylesheet_content', $xsl_content ); } public function get_sitemap_index_stylesheet() { $css = $this->get_stylesheet_css(); $title = esc_xml( __( 'XML Sitemap' ) ); $description = esc_xml( __( 'This XML Sitemap is generated by WordPress to make your content more visible for search engines.' ) ); $learn_more = sprintf( '<a href="%s">%s</a>', esc_url( __( 'https://www.sitemaps.org/' ) ), esc_xml( __( 'Learn more about XML sitemaps.' ) ) ); $text = sprintf( esc_xml( __( 'Number of URLs in this XML Sitemap: %s.' ) ), '<xsl:value-of select="count( sitemap:sitemapindex/sitemap:sitemap )" />' ); $lang = get_language_attributes( 'html' ); $url = esc_xml( __( 'URL' ) ); $lastmod = esc_xml( __( 'Last Modified' ) ); $xsl_content = <<<XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
exclude-result-prefixes="sitemap"
>
<xsl:output method="html" encoding="UTF-8" indent="yes" />
<!--
Set variables for whether lastmod occurs for any sitemap in the index.
We do this up front because it can be expensive in a large sitemap.
-->
<xsl:variable name="has-lastmod" select="count( /sitemap:sitemapindex/sitemap:sitemap/sitemap:lastmod )" />
<xsl:template match="/">
<html {$lang}>
<head>
<title>{$title}</title>
<style>
{$css}
</style>
</head>
<body>
<div id="sitemap">
<div id="sitemap__header">
<h1>{$title}</h1>
<p>{$description}</p>
<p>{$learn_more}</p>
</div>
<div id="sitemap__content">
<p class="text">{$text}</p>
<table id="sitemap__table">
<thead>
<tr>
<th class="loc">{$url}</th>
<xsl:if test="\$has-lastmod">
<th class="lastmod">{$lastmod}</th>
</xsl:if>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
<tr>
<td class="loc"><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc" /></a></td>
<xsl:if test="\$has-lastmod">
<td class="lastmod"><xsl:value-of select="sitemap:lastmod" /></td>
</xsl:if>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XSL;
return apply_filters( 'wp_sitemaps_stylesheet_index_content', $xsl_content ); } public function get_stylesheet_css() { $text_align = is_rtl() ? 'right' : 'left'; $css = <<<EOF
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
color: #444;
}
#sitemap {
max-width: 980px;
margin: 0 auto;
}
#sitemap__table {
width: 100%;
border: solid 1px #ccc;
border-collapse: collapse;
}
#sitemap__table tr td.loc {
/*
* URLs should always be LTR.
* See https://core.trac.wordpress.org/ticket/16834
* and https://core.trac.wordpress.org/ticket/49949
*/
direction: ltr;
}
#sitemap__table tr th {
text-align: {$text_align};
}
#sitemap__table tr td,
#sitemap__table tr th {
padding: 10px;
}
#sitemap__table tr:nth-child(odd) td {
background-color: #eee;
}
a:hover {
text-decoration: none;
}
EOF;
return apply_filters( 'wp_sitemaps_stylesheet_css', $css ); } }
###require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-posts.php';
class WP_Sitemaps_Posts extends WP_Sitemaps_Provider { public function __construct() { $this->name = 'posts'; $this->object_type = 'post'; } public function get_object_subtypes() { $post_types = get_post_types( array( 'public' => true ), 'objects' ); unset( $post_types['attachment'] ); $post_types = array_filter( $post_types, 'is_post_type_viewable' ); return apply_filters( 'wp_sitemaps_post_types', $post_types ); } public function get_url_list( $page_num, $object_subtype = '' ) { $post_type = $object_subtype; $supported_types = $this->get_object_subtypes(); if ( ! isset( $supported_types[ $post_type ] ) ) { return array(); } $url_list = apply_filters( 'wp_sitemaps_posts_pre_url_list', null, $post_type, $page_num ); if ( null !== $url_list ) { return $url_list; } $args = $this->get_posts_query_args( $post_type ); $args['paged'] = $page_num; $query = new WP_Query( $args ); $url_list = array(); if ( 'page' === $post_type && 1 === $page_num && 'posts' === get_option( 'show_on_front' ) ) { $sitemap_entry = array( 'loc' => home_url( '/' ), ); $latest_posts = new WP_Query( array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); if ( ! empty( $latest_posts->posts ) ) { $posts = wp_list_sort( $latest_posts->posts, 'post_modified_gmt', 'DESC' ); $sitemap_entry['lastmod'] = wp_date( DATE_W3C, strtotime( $posts[0]->post_modified_gmt ) ); } $sitemap_entry = apply_filters( 'wp_sitemaps_posts_show_on_front_entry', $sitemap_entry ); $url_list[] = $sitemap_entry; } foreach ( $query->posts as $post ) { $sitemap_entry = array( 'loc' => get_permalink( $post ), 'lastmod' => wp_date( DATE_W3C, strtotime( $post->post_modified_gmt ) ), ); $sitemap_entry = apply_filters( 'wp_sitemaps_posts_entry', $sitemap_entry, $post, $post_type ); $url_list[] = $sitemap_entry; } return $url_list; } public function get_max_num_pages( $object_subtype = '' ) { if ( empty( $object_subtype ) ) { return 0; } $post_type = $object_subtype; $max_num_pages = apply_filters( 'wp_sitemaps_posts_pre_max_num_pages', null, $post_type ); if ( null !== $max_num_pages ) { return $max_num_pages; } $args = $this->get_posts_query_args( $post_type ); $args['fields'] = 'ids'; $args['no_found_rows'] = false; $query = new WP_Query( $args ); $min_num_pages = ( 'page' === $post_type && 'posts' === get_option( 'show_on_front' ) ) ? 1 : 0; return isset( $query->max_num_pages ) ? max( $min_num_pages, $query->max_num_pages ) : 1; } protected function get_posts_query_args( $post_type ) { $args = apply_filters( 'wp_sitemaps_posts_query_args', array( 'orderby' => 'ID', 'order' => 'ASC', 'post_type' => $post_type, 'posts_per_page' => wp_sitemaps_get_max_urls( $this->object_type ), 'post_status' => array( 'publish' ), 'no_found_rows' => true, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'ignore_sticky_posts' => true, ), $post_type ); return $args; } }
###require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-taxonomies.php';
class WP_Sitemaps_Taxonomies extends WP_Sitemaps_Provider { public function __construct() { $this->name = 'taxonomies'; $this->object_type = 'term'; } public function get_object_subtypes() { $taxonomies = get_taxonomies( array( 'public' => true ), 'objects' ); $taxonomies = array_filter( $taxonomies, 'is_taxonomy_viewable' ); return apply_filters( 'wp_sitemaps_taxonomies', $taxonomies ); } public function get_url_list( $page_num, $object_subtype = '' ) { $taxonomy = $object_subtype; $supported_types = $this->get_object_subtypes(); if ( ! isset( $supported_types[ $taxonomy ] ) ) { return array(); } $url_list = apply_filters( 'wp_sitemaps_taxonomies_pre_url_list', null, $taxonomy, $page_num ); if ( null !== $url_list ) { return $url_list; } $url_list = array(); $offset = ( $page_num - 1 ) * wp_sitemaps_get_max_urls( $this->object_type ); $args = $this->get_taxonomies_query_args( $taxonomy ); $args['fields'] = 'all'; $args['offset'] = $offset; $taxonomy_terms = new WP_Term_Query( $args ); if ( ! empty( $taxonomy_terms->terms ) ) { foreach ( $taxonomy_terms->terms as $term ) { $term_link = get_term_link( $term, $taxonomy ); if ( is_wp_error( $term_link ) ) { continue; } $sitemap_entry = array( 'loc' => $term_link, ); $sitemap_entry = apply_filters( 'wp_sitemaps_taxonomies_entry', $sitemap_entry, $term->term_id, $taxonomy, $term ); $url_list[] = $sitemap_entry; } } return $url_list; } public function get_max_num_pages( $object_subtype = '' ) { if ( empty( $object_subtype ) ) { return 0; } $taxonomy = $object_subtype; $max_num_pages = apply_filters( 'wp_sitemaps_taxonomies_pre_max_num_pages', null, $taxonomy ); if ( null !== $max_num_pages ) { return $max_num_pages; } $term_count = wp_count_terms( $this->get_taxonomies_query_args( $taxonomy ) ); return (int) ceil( (int) $term_count / wp_sitemaps_get_max_urls( $this->object_type ) ); } protected function get_taxonomies_query_args( $taxonomy ) { $args = apply_filters( 'wp_sitemaps_taxonomies_query_args', array( 'taxonomy' => $taxonomy, 'orderby' => 'term_order', 'number' => wp_sitemaps_get_max_urls( $this->object_type ), 'hide_empty' => true, 'hierarchical' => false, 'update_term_meta_cache' => false, ), $taxonomy ); return $args; } }
###require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-users.php';
class WP_Sitemaps_Users extends WP_Sitemaps_Provider { public function __construct() { $this->name = 'users'; $this->object_type = 'user'; } public function get_url_list( $page_num, $object_subtype = '' ) { $url_list = apply_filters( 'wp_sitemaps_users_pre_url_list', null, $page_num ); if ( null !== $url_list ) { return $url_list; } $args = $this->get_users_query_args(); $args['paged'] = $page_num; $query = new WP_User_Query( $args ); $users = $query->get_results(); $url_list = array(); foreach ( $users as $user ) { $sitemap_entry = array( 'loc' => get_author_posts_url( $user->ID ), ); $sitemap_entry = apply_filters( 'wp_sitemaps_users_entry', $sitemap_entry, $user ); $url_list[] = $sitemap_entry; } return $url_list; } public function get_max_num_pages( $object_subtype = '' ) { $max_num_pages = apply_filters( 'wp_sitemaps_users_pre_max_num_pages', null ); if ( null !== $max_num_pages ) { return $max_num_pages; } $args = $this->get_users_query_args(); $query = new WP_User_Query( $args ); $total_users = $query->get_total(); return (int) ceil( $total_users / wp_sitemaps_get_max_urls( $this->object_type ) ); } protected function get_users_query_args() { $public_post_types = get_post_types( array( 'public' => true, ) ); unset( $public_post_types['attachment'] ); unset( $public_post_types['page'] ); $args = apply_filters( 'wp_sitemaps_users_query_args', array( 'has_published_posts' => array_keys( $public_post_types ), 'number' => wp_sitemaps_get_max_urls( $this->object_type ), ) ); return $args; } }
###require ABSPATH . WPINC . '/class-wp-block-bindings-source.php';
final class WP_Block_Bindings_Source { public $name; public $label; private $get_value_callback; public $uses_context = null; public function __construct( string $name, array $source_properties ) { $this->name = $name; foreach ( $source_properties as $property_name => $property_value ) { $this->$property_name = $property_value; } } public function get_value( array $source_args, $block_instance, string $attribute_name ) { $value = call_user_func_array( $this->get_value_callback, array( $source_args, $block_instance, $attribute_name ) ); return apply_filters( 'block_bindings_source_value', $value, $this->name, $source_args, $block_instance, $attribute_name ); } public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } }
###require ABSPATH . WPINC . '/class-wp-block-bindings-registry.php';
final class WP_Block_Bindings_Registry { private $sources = array(); private static $instance = null; private $allowed_source_properties = array( 'label', 'get_value_callback', 'uses_context', ); private $supported_blocks = array( 'core/paragraph', 'core/heading', 'core/image', 'core/button', ); public function register( string $source_name, array $source_properties ) { if ( ! is_string( $source_name ) ) { _doing_it_wrong( __METHOD__, __( 'Block bindings source name must be a string.' ), '6.5.0' ); return false; } if ( preg_match( '/[A-Z]+/', $source_name ) ) { _doing_it_wrong( __METHOD__, __( 'Block bindings source names must not contain uppercase characters.' ), '6.5.0' ); return false; } $name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/'; if ( ! preg_match( $name_matcher, $source_name ) ) { _doing_it_wrong( __METHOD__, __( 'Block bindings source names must contain a namespace prefix. Example: my-plugin/my-custom-source' ), '6.5.0' ); return false; } if ( $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ), '6.5.0' ); return false; } if ( ! isset( $source_properties['label'] ) ) { _doing_it_wrong( __METHOD__, __( 'The $source_properties must contain a "label".' ), '6.5.0' ); return false; } if ( ! isset( $source_properties['get_value_callback'] ) ) { _doing_it_wrong( __METHOD__, __( 'The $source_properties must contain a "get_value_callback".' ), '6.5.0' ); return false; } if ( ! is_callable( $source_properties['get_value_callback'] ) ) { _doing_it_wrong( __METHOD__, __( 'The "get_value_callback" parameter must be a valid callback.' ), '6.5.0' ); return false; } if ( isset( $source_properties['uses_context'] ) && ! is_array( $source_properties['uses_context'] ) ) { _doing_it_wrong( __METHOD__, __( 'The "uses_context" parameter must be an array.' ), '6.5.0' ); return false; } if ( ! empty( array_diff( array_keys( $source_properties ), $this->allowed_source_properties ) ) ) { _doing_it_wrong( __METHOD__, __( 'The $source_properties array contains invalid properties.' ), '6.5.0' ); return false; } $source = new WP_Block_Bindings_Source( $source_name, $source_properties ); $this->sources[ $source_name ] = $source; return $source; } public function unregister( string $source_name ) { if ( ! $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block binding "%s" not found.' ), $source_name ), '6.5.0' ); return false; } $unregistered_source = $this->sources[ $source_name ]; unset( $this->sources[ $source_name ] ); return $unregistered_source; } public function get_all_registered() { return $this->sources; } public function get_registered( string $source_name ) { if ( ! $this->is_registered( $source_name ) ) { return null; } return $this->sources[ $source_name ]; } public function is_registered( $source_name ) { return isset( $source_name, $this->sources[ $source_name ] ); } public function __wakeup() { if ( ! $this->sources ) { return; } if ( ! is_array( $this->sources ) ) { throw new UnexpectedValueException(); } foreach ( $this->sources as $value ) { if ( ! $value instanceof WP_Block_Bindings_Source ) { throw new UnexpectedValueException(); } } } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } }
###require ABSPATH . WPINC . '/class-wp-block-editor-context.php';
final class WP_Block_Editor_Context { public $name = 'core/edit-post'; public $post = null; public function __construct( array $settings = array() ) { if ( isset( $settings['name'] ) ) { $this->name = $settings['name']; } if ( isset( $settings['post'] ) ) { $this->post = $settings['post']; } } }
###require ABSPATH . WPINC . '/class-wp-block-type.php';
class WP_Block_Type { public $api_version = 1; public $name; public $title = ''; public $category = null; public $parent = null; public $ancestor = null; public $allowed_blocks = null; public $icon = null; public $description = ''; public $keywords = array(); public $textdomain = null; public $styles = array(); private $variations = null; public $variation_callback = null; public $selectors = array(); public $supports = null; public $example = null; public $render_callback = null; public $attributes = null; private $uses_context = array(); public $provides_context = null; public $block_hooks = array(); public $editor_script_handles = array(); public $script_handles = array(); public $view_script_handles = array(); public $view_script_module_ids = array(); public $editor_style_handles = array(); public $style_handles = array(); public $view_style_handles = array(); private $deprecated_properties = array( 'editor_script', 'script', 'view_script', 'editor_style', 'style', ); const GLOBAL_ATTRIBUTES = array( 'lock' => array( 'type' => 'object' ), 'metadata' => array( 'type' => 'object' ), ); public function __construct( $block_type, $args = array() ) { $this->name = $block_type; $this->set_props( $args ); } public function __get( $name ) { if ( 'variations' === $name ) { return $this->get_variations(); } if ( 'uses_context' === $name ) { return $this->get_uses_context(); } if ( ! in_array( $name, $this->deprecated_properties, true ) ) { return; } $new_name = $name . '_handles'; if ( ! property_exists( $this, $new_name ) || ! is_array( $this->{$new_name} ) ) { return null; } if ( count( $this->{$new_name} ) > 1 ) { return $this->{$new_name}; } return isset( $this->{$new_name}[0] ) ? $this->{$new_name}[0] : null; } public function __isset( $name ) { if ( in_array( $name, array( 'variations', 'uses_context' ), true ) ) { return true; } if ( ! in_array( $name, $this->deprecated_properties, true ) ) { return false; } $new_name = $name . '_handles'; return isset( $this->{$new_name}[0] ); } public function __set( $name, $value ) { if ( ! in_array( $name, $this->deprecated_properties, true ) ) { $this->{$name} = $value; return; } $new_name = $name . '_handles'; if ( is_array( $value ) ) { $filtered = array_filter( $value, 'is_string' ); if ( count( $filtered ) !== count( $value ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The %s argument must be a string or a string array.' ), '<code>$value</code>' ), '6.1.0' ); } $this->{$new_name} = array_values( $filtered ); return; } if ( ! is_string( $value ) ) { return; } $this->{$new_name} = array( $value ); } public function render( $attributes = array(), $content = '' ) { if ( ! $this->is_dynamic() ) { return ''; } $attributes = $this->prepare_attributes_for_render( $attributes ); return (string) call_user_func( $this->render_callback, $attributes, $content ); } public function is_dynamic() { return is_callable( $this->render_callback ); } public function prepare_attributes_for_render( $attributes ) { if ( ! isset( $this->attributes ) ) { return $attributes; } foreach ( $attributes as $attribute_name => $value ) { if ( ! isset( $this->attributes[ $attribute_name ] ) ) { continue; } $schema = $this->attributes[ $attribute_name ]; $is_valid = rest_validate_value_from_schema( $value, $schema, $attribute_name ); if ( is_wp_error( $is_valid ) ) { unset( $attributes[ $attribute_name ] ); } } $missing_schema_attributes = array_diff_key( $this->attributes, $attributes ); foreach ( $missing_schema_attributes as $attribute_name => $schema ) { if ( isset( $schema['default'] ) ) { $attributes[ $attribute_name ] = $schema['default']; } } return $attributes; } public function set_props( $args ) { $args = wp_parse_args( $args, array( 'render_callback' => null, ) ); $args['name'] = $this->name; if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) { $args['attributes'] = array(); } foreach ( static::GLOBAL_ATTRIBUTES as $attr_key => $attr_schema ) { if ( ! array_key_exists( $attr_key, $args['attributes'] ) ) { $args['attributes'][ $attr_key ] = $attr_schema; } } $args = apply_filters( 'register_block_type_args', $args, $this->name ); foreach ( $args as $property_name => $property_value ) { $this->$property_name = $property_value; } } public function get_attributes() { return is_array( $this->attributes ) ? $this->attributes : array(); } public function get_variations() { if ( ! isset( $this->variations ) ) { $this->variations = array(); if ( is_callable( $this->variation_callback ) ) { $this->variations = call_user_func( $this->variation_callback ); } } return apply_filters( 'get_block_type_variations', $this->variations, $this ); } public function get_uses_context() { return apply_filters( 'get_block_type_uses_context', $this->uses_context, $this ); } }
###require ABSPATH . WPINC . '/class-wp-block-pattern-categories-registry.php';
final class WP_Block_Pattern_Categories_Registry { private $registered_categories = array(); private $registered_categories_outside_init = array(); private static $instance = null; public function register( $category_name, $category_properties ) { if ( ! isset( $category_name ) || ! is_string( $category_name ) ) { _doing_it_wrong( __METHOD__, __( 'Block pattern category name must be a string.' ), '5.5.0' ); return false; } $category = array_merge( array( 'name' => $category_name ), $category_properties ); $this->registered_categories[ $category_name ] = $category; if ( current_action() && 'init' !== current_action() ) { $this->registered_categories_outside_init[ $category_name ] = $category; } return true; } public function unregister( $category_name ) { if ( ! $this->is_registered( $category_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block pattern category "%s" not found.' ), $category_name ), '5.5.0' ); return false; } unset( $this->registered_categories[ $category_name ] ); unset( $this->registered_categories_outside_init[ $category_name ] ); return true; } public function get_registered( $category_name ) { if ( ! $this->is_registered( $category_name ) ) { return null; } return $this->registered_categories[ $category_name ]; } public function get_all_registered( $outside_init_only = false ) { return array_values( $outside_init_only ? $this->registered_categories_outside_init : $this->registered_categories ); } public function is_registered( $category_name ) { return isset( $category_name, $this->registered_categories[ $category_name ] ); } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } } function register_block_pattern_category( $category_name, $category_properties ) { return WP_Block_Pattern_Categories_Registry::get_instance()->register( $category_name, $category_properties ); } function unregister_block_pattern_category( $category_name ) { return WP_Block_Pattern_Categories_Registry::get_instance()->unregister( $category_name ); }
###require ABSPATH . WPINC . '/class-wp-block-patterns-registry.php';
final class WP_Block_Patterns_Registry { private $registered_patterns = array(); private $registered_patterns_outside_init = array(); private static $instance = null; public function register( $pattern_name, $pattern_properties ) { if ( ! isset( $pattern_name ) || ! is_string( $pattern_name ) ) { _doing_it_wrong( __METHOD__, __( 'Pattern name must be a string.' ), '5.5.0' ); return false; } if ( ! isset( $pattern_properties['title'] ) || ! is_string( $pattern_properties['title'] ) ) { _doing_it_wrong( __METHOD__, __( 'Pattern title must be a string.' ), '5.5.0' ); return false; } if ( ! isset( $pattern_properties['filePath'] ) ) { if ( ! isset( $pattern_properties['content'] ) || ! is_string( $pattern_properties['content'] ) ) { _doing_it_wrong( __METHOD__, __( 'Pattern content must be a string.' ), '5.5.0' ); return false; } } $pattern = array_merge( $pattern_properties, array( 'name' => $pattern_name ) ); $this->registered_patterns[ $pattern_name ] = $pattern; if ( current_action() && 'init' !== current_action() ) { $this->registered_patterns_outside_init[ $pattern_name ] = $pattern; } return true; } public function unregister( $pattern_name ) { if ( ! $this->is_registered( $pattern_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Pattern "%s" not found.' ), $pattern_name ), '5.5.0' ); return false; } unset( $this->registered_patterns[ $pattern_name ] ); unset( $this->registered_patterns_outside_init[ $pattern_name ] ); return true; } private function get_content( $pattern_name, $outside_init_only = false ) { if ( $outside_init_only ) { $patterns = &$this->registered_patterns_outside_init; } else { $patterns = &$this->registered_patterns; } $file_path = $patterns[ $pattern_name ]['filePath'] ?? ''; $is_stringy = is_string( $file_path ) || ( is_object( $file_path ) && method_exists( $file_path, '__toString' ) ); $pattern_path = $is_stringy ? realpath( (string) $file_path ) : null; if ( ! isset( $patterns[ $pattern_name ]['content'] ) && is_string( $pattern_path ) && ( str_ends_with( $pattern_path, '.php' ) || str_ends_with( $pattern_path, '.html' ) ) && is_file( $pattern_path ) && is_readable( $pattern_path ) ) { ob_start(); include $patterns[ $pattern_name ]['filePath']; $patterns[ $pattern_name ]['content'] = ob_get_clean(); unset( $patterns[ $pattern_name ]['filePath'] ); } return $patterns[ $pattern_name ]['content']; } public function get_registered( $pattern_name ) { if ( ! $this->is_registered( $pattern_name ) ) { return null; } $pattern = $this->registered_patterns[ $pattern_name ]; $content = $this->get_content( $pattern_name ); $pattern['content'] = apply_block_hooks_to_content( $content, $pattern, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); return $pattern; } public function get_all_registered( $outside_init_only = false ) { $patterns = $outside_init_only ? $this->registered_patterns_outside_init : $this->registered_patterns; $hooked_blocks = get_hooked_blocks(); foreach ( $patterns as $index => $pattern ) { $content = $this->get_content( $pattern['name'], $outside_init_only ); $patterns[ $index ]['content'] = apply_block_hooks_to_content( $content, $pattern, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); } return array_values( $patterns ); } public function is_registered( $pattern_name ) { return isset( $pattern_name, $this->registered_patterns[ $pattern_name ] ); } public function __wakeup() { if ( ! $this->registered_patterns ) { return; } if ( ! is_array( $this->registered_patterns ) ) { throw new UnexpectedValueException(); } foreach ( $this->registered_patterns as $value ) { if ( ! is_array( $value ) ) { throw new UnexpectedValueException(); } } $this->registered_patterns_outside_init = array(); } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } } function register_block_pattern( $pattern_name, $pattern_properties ) { return WP_Block_Patterns_Registry::get_instance()->register( $pattern_name, $pattern_properties ); } function unregister_block_pattern( $pattern_name ) { return WP_Block_Patterns_Registry::get_instance()->unregister( $pattern_name ); }
###require ABSPATH . WPINC . '/class-wp-block-styles-registry.php';
final class WP_Block_Styles_Registry { private $registered_block_styles = array(); private static $instance = null; public function register( $block_name, $style_properties ) { if ( ! is_string( $block_name ) && ! is_array( $block_name ) ) { _doing_it_wrong( __METHOD__, __( 'Block name must be a string or array.' ), '6.6.0' ); return false; } if ( ! isset( $style_properties['name'] ) || ! is_string( $style_properties['name'] ) ) { _doing_it_wrong( __METHOD__, __( 'Block style name must be a string.' ), '5.3.0' ); return false; } if ( str_contains( $style_properties['name'], ' ' ) ) { _doing_it_wrong( __METHOD__, __( 'Block style name must not contain any spaces.' ), '5.9.0' ); return false; } $block_style_name = $style_properties['name']; $block_names = is_string( $block_name ) ? array( $block_name ) : $block_name; if ( empty( $style_properties['label'] ) ) { $style_properties['label'] = $block_style_name; } foreach ( $block_names as $name ) { if ( ! isset( $this->registered_block_styles[ $name ] ) ) { $this->registered_block_styles[ $name ] = array(); } $this->registered_block_styles[ $name ][ $block_style_name ] = $style_properties; } return true; } public function unregister( $block_name, $block_style_name ) { if ( ! $this->is_registered( $block_name, $block_style_name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block "%1$s" does not contain a style named "%2$s".' ), $block_name, $block_style_name ), '5.3.0' ); return false; } unset( $this->registered_block_styles[ $block_name ][ $block_style_name ] ); return true; } public function get_registered( $block_name, $block_style_name ) { if ( ! $this->is_registered( $block_name, $block_style_name ) ) { return null; } return $this->registered_block_styles[ $block_name ][ $block_style_name ]; } public function get_all_registered() { return $this->registered_block_styles; } public function get_registered_styles_for_block( $block_name ) { if ( isset( $this->registered_block_styles[ $block_name ] ) ) { return $this->registered_block_styles[ $block_name ]; } return array(); } public function is_registered( $block_name, $block_style_name ) { return isset( $block_name, $block_style_name, $this->registered_block_styles[ $block_name ][ $block_style_name ] ); } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } }
###require ABSPATH . WPINC . '/class-wp-block-type-registry.php';
final class WP_Block_Type_Registry { private $registered_block_types = array(); private static $instance = null; public function register( $name, $args = array() ) { $block_type = null; if ( $name instanceof WP_Block_Type ) { $block_type = $name; $name = $block_type->name; } if ( ! is_string( $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must be strings.' ), '5.0.0' ); return false; } if ( preg_match( '/[A-Z]+/', $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must not contain uppercase characters.' ), '5.0.0' ); return false; } $name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/'; if ( ! preg_match( $name_matcher, $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must contain a namespace prefix. Example: my-plugin/my-custom-block-type' ), '5.0.0' ); return false; } if ( $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block type "%s" is already registered.' ), $name ), '5.0.0' ); return false; } if ( ! $block_type ) { $block_type = new WP_Block_Type( $name, $args ); } $this->registered_block_types[ $name ] = $block_type; return $block_type; } public function unregister( $name ) { if ( $name instanceof WP_Block_Type ) { $name = $name->name; } if ( ! $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block type "%s" is not registered.' ), $name ), '5.0.0' ); return false; } $unregistered_block_type = $this->registered_block_types[ $name ]; unset( $this->registered_block_types[ $name ] ); return $unregistered_block_type; } public function get_registered( $name ) { if ( ! $this->is_registered( $name ) ) { return null; } return $this->registered_block_types[ $name ]; } public function get_all_registered() { return $this->registered_block_types; } public function is_registered( $name ) { return isset( $name, $this->registered_block_types[ $name ] ); } public function __wakeup() { if ( ! $this->registered_block_types ) { return; } if ( ! is_array( $this->registered_block_types ) ) { throw new UnexpectedValueException(); } foreach ( $this->registered_block_types as $value ) { if ( ! $value instanceof WP_Block_Type ) { throw new UnexpectedValueException(); } } } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } }
###require ABSPATH . WPINC . '/class-wp-block.php';
class WP_Block { public $parsed_block; public $name; public $block_type; public $context = array(); protected $available_context = array(); protected $registry; public $inner_blocks = array(); public $inner_html = ''; public $inner_content = array(); public function __construct( $block, $available_context = array(), $registry = null ) { $this->parsed_block = $block; $this->name = $block['blockName']; if ( is_null( $registry ) ) { $registry = WP_Block_Type_Registry::get_instance(); } $this->registry = $registry; $this->block_type = $registry->get_registered( $this->name ); $this->available_context = $available_context; $this->refresh_context_dependents(); } public function refresh_context_dependents() { $this->available_context = array_merge( $this->available_context, $this->context ); if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { if ( array_key_exists( $context_name, $this->available_context ) ) { $this->context[ $context_name ] = $this->available_context[ $context_name ]; } } } $this->refresh_parsed_block_dependents(); } public function refresh_parsed_block_dependents() { if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { $child_context = $this->available_context; if ( ! empty( $this->block_type->provides_context ) ) { foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) { if ( array_key_exists( $attribute_name, $this->attributes ) ) { $child_context[ $context_name ] = $this->attributes[ $attribute_name ]; } } } $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $child_context, $this->registry ); } if ( ! empty( $this->parsed_block['innerHTML'] ) ) { $this->inner_html = $this->parsed_block['innerHTML']; } if ( ! empty( $this->parsed_block['innerContent'] ) ) { $this->inner_content = $this->parsed_block['innerContent']; } } public function __get( $name ) { if ( 'attributes' === $name ) { $this->attributes = isset( $this->parsed_block['attrs'] ) ? $this->parsed_block['attrs'] : array(); if ( ! is_null( $this->block_type ) ) { $this->attributes = $this->block_type->prepare_attributes_for_render( $this->attributes ); } return $this->attributes; } return null; } private function process_block_bindings() { $block_type = $this->name; $parsed_block = $this->parsed_block; $computed_attributes = array(); $supported_block_attributes = get_block_bindings_supported_attributes( $block_type ); if ( empty( $supported_block_attributes ) || empty( $parsed_block['attrs']['metadata']['bindings'] ) || ! is_array( $parsed_block['attrs']['metadata']['bindings'] ) ) { return $computed_attributes; } $bindings = $parsed_block['attrs']['metadata']['bindings']; if ( isset( $bindings['__default']['source'] ) && 'core/pattern-overrides' === $bindings['__default']['source'] ) { $updated_bindings = array(); foreach ( $supported_block_attributes as $attribute_name ) { $updated_bindings[ $attribute_name ] = isset( $bindings[ $attribute_name ] ) ? $bindings[ $attribute_name ] : array( 'source' => 'core/pattern-overrides' ); } $bindings = $updated_bindings; $computed_attributes['metadata'] = array_merge( $parsed_block['attrs']['metadata'], array( 'bindings' => $bindings ) ); } foreach ( $bindings as $attribute_name => $block_binding ) { if ( ! in_array( $attribute_name, $supported_block_attributes, true ) ) { continue; } if ( ! isset( $block_binding['source'] ) || ! is_string( $block_binding['source'] ) ) { continue; } $block_binding_source = get_block_bindings_source( $block_binding['source'] ); if ( null === $block_binding_source ) { continue; } if ( ! empty( $block_binding_source->uses_context ) ) { foreach ( $block_binding_source->uses_context as $context_name ) { if ( array_key_exists( $context_name, $this->available_context ) ) { $this->context[ $context_name ] = $this->available_context[ $context_name ]; } } } $source_args = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array(); $source_value = $block_binding_source->get_value( $source_args, $this, $attribute_name ); if ( ! is_null( $source_value ) ) { $computed_attributes[ $attribute_name ] = $source_value; } } return $computed_attributes; } private function replace_html( string $block_content, string $attribute_name, $source_value ) { $block_type = $this->block_type; if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) { return $block_content; } switch ( $block_type->attributes[ $attribute_name ]['source'] ) { case 'html': case 'rich-text': $block_reader = self::get_block_bindings_processor( $block_content ); $selectors = explode( ',', $block_type->attributes[ $attribute_name ]['selector'] ); $block_reader->next_tag(); $block_reader->set_bookmark( 'iterate-selectors' ); foreach ( $selectors as $selector ) { if ( strcasecmp( $block_reader->get_tag(), $selector ) === 0 || $block_reader->next_tag( array( 'tag_name' => $selector, ) ) ) { $block_reader->release_bookmark( 'iterate-selectors' ); $block_reader->replace_rich_text( wp_kses_post( $source_value ) ); return $block_reader->get_updated_html(); } else { $block_reader->seek( 'iterate-selectors' ); } } $block_reader->release_bookmark( 'iterate-selectors' ); return $block_content; case 'attribute': $amended_content = new WP_HTML_Tag_Processor( $block_content ); if ( ! $amended_content->next_tag( array( 'tag_name' => $block_type->attributes[ $attribute_name ]['selector'], ) ) ) { return $block_content; } $amended_content->set_attribute( $block_type->attributes[ $attribute_name ]['attribute'], $source_value ); return $amended_content->get_updated_html(); default: return $block_content; } } private static function get_block_bindings_processor( string $block_content ) { $internal_processor_class = new class('', WP_HTML_Processor::CONSTRUCTOR_UNLOCK_CODE) extends WP_HTML_Processor { public function replace_rich_text( $rich_text ) { if ( $this->is_tag_closer() || ! $this->expects_closer() ) { return false; } $depth = $this->get_current_depth(); $tag_name = $this->get_tag(); $this->set_bookmark( '_wp_block_bindings' ); $tag_opener = $this->bookmarks['__wp_block_bindings']; $start = $tag_opener->start + $tag_opener->length; while ( $this->next_token() && $this->get_current_depth() >= $depth ) { } if ( ! $this->is_tag_closer() || $tag_name !== $this->get_tag() ) { return false; } $this->set_bookmark( '_wp_block_bindings' ); $tag_closer = $this->bookmarks['__wp_block_bindings']; $end = $tag_closer->start; $this->lexical_updates[] = new WP_HTML_Text_Replacement( $start, $end - $start, $rich_text ); return true; } }; return $internal_processor_class::create_fragment( $block_content ); } public function render( $options = array() ) { global $post; $before_wp_enqueue_scripts_count = did_action( 'wp_enqueue_scripts' ); $before_styles_queue = wp_styles()->queue; $before_scripts_queue = wp_scripts()->queue; $before_script_modules_queue = wp_script_modules()->get_queue(); static $root_interactive_block = null; $interactivity_process_directives_enabled = apply_filters( 'interactivity_process_directives', true ); if ( $interactivity_process_directives_enabled && null === $root_interactive_block && ( ( isset( $this->block_type->supports['interactivity'] ) && true === $this->block_type->supports['interactivity'] ) || ! empty( $this->block_type->supports['interactivity']['interactive'] ) ) ) { $root_interactive_block = $this; } $options = wp_parse_args( $options, array( 'dynamic' => true, ) ); $computed_attributes = $this->process_block_bindings(); if ( ! empty( $computed_attributes ) ) { $this->attributes = array_merge( $this->attributes, $computed_attributes ); } $is_dynamic = $options['dynamic'] && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); $block_content = ''; if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) { $index = 0; foreach ( $this->inner_content as $chunk ) { if ( is_string( $chunk ) ) { $block_content .= $chunk; } else { $inner_block = $this->inner_blocks[ $index ]; $parent_block = $this; $pre_render = apply_filters( 'pre_render_block', null, $inner_block->parsed_block, $parent_block ); if ( ! is_null( $pre_render ) ) { $block_content .= $pre_render; } else { $source_block = $inner_block->parsed_block; $inner_block_context = $inner_block->context; $inner_block->parsed_block = apply_filters( 'render_block_data', $inner_block->parsed_block, $source_block, $parent_block ); $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); if ( $inner_block->context !== $inner_block_context ) { $inner_block->refresh_context_dependents(); } elseif ( $inner_block->parsed_block !== $source_block ) { $inner_block->refresh_parsed_block_dependents(); } $block_content .= $inner_block->render(); } ++$index; } } } if ( ! empty( $computed_attributes ) && ! empty( $block_content ) ) { foreach ( $computed_attributes as $attribute_name => $source_value ) { $block_content = $this->replace_html( $block_content, $attribute_name, $source_value ); } } if ( $is_dynamic ) { $global_post = $post; $parent = WP_Block_Supports::$block_to_render; WP_Block_Supports::$block_to_render = $this->parsed_block; $block_content = (string) call_user_func( $this->block_type->render_callback, $this->attributes, $block_content, $this ); WP_Block_Supports::$block_to_render = $parent; $post = $global_post; } if ( ( ! empty( $this->block_type->script_handles ) ) ) { foreach ( $this->block_type->script_handles as $script_handle ) { wp_enqueue_script( $script_handle ); } } if ( ! empty( $this->block_type->view_script_handles ) ) { foreach ( $this->block_type->view_script_handles as $view_script_handle ) { wp_enqueue_script( $view_script_handle ); } } if ( ! empty( $this->block_type->view_script_module_ids ) ) { foreach ( $this->block_type->view_script_module_ids as $view_script_module_id ) { wp_enqueue_script_module( $view_script_module_id ); } } if ( ( ! empty( $this->block_type->style_handles ) ) ) { foreach ( $this->block_type->style_handles as $style_handle ) { wp_enqueue_style( $style_handle ); } } if ( ( ! empty( $this->block_type->view_style_handles ) ) ) { foreach ( $this->block_type->view_style_handles as $view_style_handle ) { wp_enqueue_style( $view_style_handle ); } } $block_content = apply_filters( 'render_block', $block_content, $this->parsed_block, $this ); $block_content = apply_filters( "render_block_{$this->name}", $block_content, $this->parsed_block, $this ); if ( $root_interactive_block === $this ) { $block_content = wp_interactivity_process_directives( $block_content ); $root_interactive_block = null; } $after_styles_queue = wp_styles()->queue; $after_scripts_queue = wp_scripts()->queue; $after_script_modules_queue = wp_script_modules()->get_queue(); $just_did_wp_enqueue_scripts = ( did_action( 'wp_enqueue_scripts' ) !== $before_wp_enqueue_scripts_count ); $has_new_styles = ( $before_styles_queue !== $after_styles_queue ); $has_new_scripts = ( $before_scripts_queue !== $after_scripts_queue ); $has_new_script_modules = ( $before_script_modules_queue !== $after_script_modules_queue ); if ( ! $just_did_wp_enqueue_scripts && ( $has_new_styles || $has_new_scripts || $has_new_script_modules ) && ( trim( $block_content ) === '' && ! (bool) apply_filters( 'enqueue_empty_block_content_assets', false, $this->name ) ) ) { foreach ( array_diff( $after_styles_queue, $before_styles_queue ) as $handle ) { wp_dequeue_style( $handle ); } foreach ( array_diff( $after_scripts_queue, $before_scripts_queue ) as $handle ) { wp_dequeue_script( $handle ); } foreach ( array_diff( $after_script_modules_queue, $before_script_modules_queue ) as $handle ) { wp_dequeue_script_module( $handle ); } } return $block_content; } }
###require ABSPATH . WPINC . '/class-wp-block-list.php';
class WP_Block_List implements Iterator, ArrayAccess, Countable { protected $blocks; protected $available_context; protected $registry; public function __construct( $blocks, $available_context = array(), $registry = null ) { if ( ! $registry instanceof WP_Block_Type_Registry ) { $registry = WP_Block_Type_Registry::get_instance(); } $this->blocks = $blocks; $this->available_context = $available_context; $this->registry = $registry; } public function offsetExists( $offset ) { return isset( $this->blocks[ $offset ] ); } public function offsetGet( $offset ) { $block = $this->blocks[ $offset ]; if ( isset( $block ) && is_array( $block ) ) { $block = new WP_Block( $block, $this->available_context, $this->registry ); $this->blocks[ $offset ] = $block; } return $block; } public function offsetSet( $offset, $value ) { if ( is_null( $offset ) ) { $this->blocks[] = $value; } else { $this->blocks[ $offset ] = $value; } } public function offsetUnset( $offset ) { unset( $this->blocks[ $offset ] ); } public function rewind() { reset( $this->blocks ); } public function current() { return $this->offsetGet( $this->key() ); } public function key() { return key( $this->blocks ); } public function next() { next( $this->blocks ); } public function valid() { return null !== key( $this->blocks ); } public function count() { return count( $this->blocks ); } }
###require ABSPATH . WPINC . '/class-wp-block-metadata-registry.php';
class WP_Block_Metadata_Registry { private static $collections = array(); private static $last_matched_collection = null; private static $default_collection_roots = null; public static function register_collection( $path, $manifest ) { $path = rtrim( wp_normalize_path( $path ), '/' ); $collection_roots = self::get_default_collection_roots(); $collection_roots = apply_filters( 'wp_allowed_block_metadata_collection_roots', $collection_roots ); $collection_roots = array_unique( array_map( static function ( $allowed_root ) { return rtrim( wp_normalize_path( $allowed_root ), '/' ); }, $collection_roots ) ); if ( ! self::is_valid_collection_path( $path, $collection_roots ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Block metadata collections cannot be registered as one of the following directories or their parent directories: %s' ), esc_html( implode( wp_get_list_item_separator(), $collection_roots ) ) ), '6.7.2' ); return false; } if ( ! file_exists( $manifest ) ) { _doing_it_wrong( __METHOD__, __( 'The specified manifest file does not exist.' ), '6.7.0' ); return false; } self::$collections[ $path ] = array( 'manifest' => $manifest, 'metadata' => null, ); return true; } public static function get_metadata( $file_or_folder ) { $file_or_folder = wp_normalize_path( $file_or_folder ); $path = self::find_collection_path( $file_or_folder ); if ( ! $path ) { return null; } $collection = &self::$collections[ $path ]; if ( null === $collection['metadata'] ) { $collection['metadata'] = require $collection['manifest']; } $block_name = self::default_identifier_callback( $file_or_folder ); return isset( $collection['metadata'][ $block_name ] ) ? $collection['metadata'][ $block_name ] : null; } public static function get_collection_block_metadata_files( $path ) { $path = rtrim( wp_normalize_path( $path ), '/' ); if ( ! isset( self::$collections[ $path ] ) ) { _doing_it_wrong( __METHOD__, __( 'No registered block metadata collection was found for the provided path.' ), '6.8.0' ); return array(); } $collection = &self::$collections[ $path ]; if ( null === $collection['metadata'] ) { $collection['metadata'] = require $collection['manifest']; } return array_map( static function ( $block_name ) use ( $path ) { return "{$path}/{$block_name}/block.json"; }, array_keys( $collection['metadata'] ) ); } private static function find_collection_path( $file_or_folder ) { if ( empty( $file_or_folder ) ) { return null; } $path = rtrim( $file_or_folder, '/' ); if ( self::$last_matched_collection && str_starts_with( $path, self::$last_matched_collection ) ) { return self::$last_matched_collection; } $collection_paths = array_keys( self::$collections ); foreach ( $collection_paths as $collection_path ) { if ( str_starts_with( $path, $collection_path ) ) { self::$last_matched_collection = $collection_path; return $collection_path; } } return null; } public static function has_metadata( $file_or_folder ) { return null !== self::get_metadata( $file_or_folder ); } private static function default_identifier_callback( $path ) { if ( empty( $path ) ) { return ''; } if ( str_ends_with( $path, 'block.json' ) ) { return basename( dirname( $path ) ); } return basename( $path ); } private static function is_valid_collection_path( $path, $collection_roots ) { foreach ( $collection_roots as $allowed_root ) { if ( $allowed_root === $path ) { return false; } if ( str_starts_with( $allowed_root, $path ) ) { return false; } } return true; } private static function get_default_collection_roots() { if ( isset( self::$default_collection_roots ) ) { return self::$default_collection_roots; } $collection_roots = array( wp_normalize_path( ABSPATH . WPINC ), wp_normalize_path( WP_CONTENT_DIR ), wp_normalize_path( WPMU_PLUGIN_DIR ), wp_normalize_path( WP_PLUGIN_DIR ), ); $theme_roots = get_theme_roots(); if ( ! is_array( $theme_roots ) ) { $theme_roots = array( $theme_roots ); } foreach ( $theme_roots as $theme_root ) { $collection_roots[] = trailingslashit( wp_normalize_path( WP_CONTENT_DIR ) ) . ltrim( wp_normalize_path( $theme_root ), '/' ); } self::$default_collection_roots = array_unique( $collection_roots ); return self::$default_collection_roots; } }
require ABSPATH . WPINC . '/class-wp-block-parser-block.php';
require ABSPATH . WPINC . '/class-wp-block-parser-frame.php';
require ABSPATH . WPINC . '/class-wp-block-parser.php';
###require ABSPATH . WPINC . '/class-wp-classic-to-block-menu-converter.php';
class WP_Classic_To_Block_Menu_Converter { public static function convert( $menu ) { if ( ! is_nav_menu( $menu ) ) { return new WP_Error( 'invalid_menu', __( 'The menu provided is not a valid menu.' ) ); } $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); if ( empty( $menu_items ) ) { return ''; } _wp_menu_item_classes_by_context( $menu_items ); $menu_items_by_parent_id = static::group_by_parent_id( $menu_items ); $first_menu_item = isset( $menu_items_by_parent_id[0] ) ? $menu_items_by_parent_id[0] : array(); $inner_blocks = static::to_blocks( $first_menu_item, $menu_items_by_parent_id ); return serialize_blocks( $inner_blocks ); } private static function group_by_parent_id( $menu_items ) { $menu_items_by_parent_id = array(); foreach ( $menu_items as $menu_item ) { $menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item; } return $menu_items_by_parent_id; } private static function to_blocks( $menu_items, $menu_items_by_parent_id ) { if ( empty( $menu_items ) ) { return array(); } $blocks = array(); foreach ( $menu_items as $menu_item ) { $class_name = ! empty( $menu_item->classes ) ? implode( ' ', (array) $menu_item->classes ) : null; $id = ( null !== $menu_item->object_id && 'custom' !== $menu_item->object ) ? $menu_item->object_id : null; $opens_in_new_tab = null !== $menu_item->target && '_blank' === $menu_item->target; $rel = ( null !== $menu_item->xfn && '' !== $menu_item->xfn ) ? $menu_item->xfn : null; $kind = null !== $menu_item->type ? str_replace( '_', '-', $menu_item->type ) : 'custom'; $block = array( 'blockName' => isset( $menu_items_by_parent_id[ $menu_item->ID ] ) ? 'core/navigation-submenu' : 'core/navigation-link', 'attrs' => array( 'className' => $class_name, 'description' => $menu_item->description, 'id' => $id, 'kind' => $kind, 'label' => $menu_item->title, 'opensInNewTab' => $opens_in_new_tab, 'rel' => $rel, 'title' => $menu_item->attr_title, 'type' => $menu_item->object, 'url' => $menu_item->url, ), ); $block['innerBlocks'] = isset( $menu_items_by_parent_id[ $menu_item->ID ] ) ? static::to_blocks( $menu_items_by_parent_id[ $menu_item->ID ], $menu_items_by_parent_id ) : array(); $block['innerContent'] = array_map( 'serialize_block', $block['innerBlocks'] ); $blocks[] = $block; } return $blocks; } }
###require ABSPATH . WPINC . '/class-wp-navigation-fallback.php';
class WP_Navigation_Fallback { public static function update_wp_navigation_post_schema( $schema ) { $schema['properties']['status']['context'] = array_merge( $schema['properties']['status']['context'], array( 'embed' ) ); $schema['properties']['content']['context'] = array_merge( $schema['properties']['content']['context'], array( 'embed' ) ); $schema['properties']['content']['properties']['raw']['context'] = array_merge( $schema['properties']['content']['properties']['raw']['context'], array( 'embed' ) ); $schema['properties']['content']['properties']['rendered']['context'] = array_merge( $schema['properties']['content']['properties']['rendered']['context'], array( 'embed' ) ); $schema['properties']['content']['properties']['block_version']['context'] = array_merge( $schema['properties']['content']['properties']['block_version']['context'], array( 'embed' ) ); $schema['properties']['title']['properties']['raw']['context'] = array_merge( $schema['properties']['title']['properties']['raw']['context'], array( 'embed' ) ); return $schema; } public static function get_fallback() { $should_create_fallback = apply_filters( 'wp_navigation_should_create_fallback', true ); $fallback = static::get_most_recently_published_navigation(); if ( $fallback || ! $should_create_fallback ) { return $fallback; } $fallback = static::create_classic_menu_fallback(); if ( $fallback && ! is_wp_error( $fallback ) ) { return $fallback instanceof WP_Post ? $fallback : static::get_most_recently_published_navigation(); } $fallback = static::create_default_fallback(); if ( $fallback && ! is_wp_error( $fallback ) ) { return $fallback instanceof WP_Post ? $fallback : static::get_most_recently_published_navigation(); } return null; } private static function get_most_recently_published_navigation() { $parsed_args = array( 'post_type' => 'wp_navigation', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'order' => 'DESC', 'orderby' => 'date', 'post_status' => 'publish', 'posts_per_page' => 1, ); $navigation_post = new WP_Query( $parsed_args ); if ( count( $navigation_post->posts ) > 0 ) { return $navigation_post->posts[0]; } return null; } private static function create_classic_menu_fallback() { $classic_nav_menu = static::get_fallback_classic_menu(); if ( ! $classic_nav_menu ) { return new WP_Error( 'no_classic_menus', __( 'No Classic Menus found.' ) ); } $classic_nav_menu_blocks = WP_Classic_To_Block_Menu_Converter::convert( $classic_nav_menu ); if ( is_wp_error( $classic_nav_menu_blocks ) ) { return $classic_nav_menu_blocks; } if ( empty( $classic_nav_menu_blocks ) ) { return new WP_Error( 'cannot_convert_classic_menu', __( 'Unable to convert Classic Menu to blocks.' ) ); } $classic_menu_fallback = wp_insert_post( array( 'post_content' => $classic_nav_menu_blocks, 'post_title' => $classic_nav_menu->name, 'post_name' => $classic_nav_menu->slug, 'post_status' => 'publish', 'post_type' => 'wp_navigation', ), true ); return $classic_menu_fallback; } private static function get_fallback_classic_menu() { $classic_nav_menus = wp_get_nav_menus(); if ( ! $classic_nav_menus || is_wp_error( $classic_nav_menus ) ) { return null; } $nav_menu = static::get_nav_menu_at_primary_location(); if ( $nav_menu ) { return $nav_menu; } $nav_menu = static::get_nav_menu_with_primary_slug( $classic_nav_menus ); if ( $nav_menu ) { return $nav_menu; } return static::get_most_recently_created_nav_menu( $classic_nav_menus ); } private static function get_most_recently_created_nav_menu( $classic_nav_menus ) { usort( $classic_nav_menus, static function ( $a, $b ) { return $b->term_id - $a->term_id; } ); return $classic_nav_menus[0]; } private static function get_nav_menu_with_primary_slug( $classic_nav_menus ) { foreach ( $classic_nav_menus as $classic_nav_menu ) { if ( 'primary' === $classic_nav_menu->slug ) { return $classic_nav_menu; } } return null; } private static function get_nav_menu_at_primary_location() { $locations = get_nav_menu_locations(); if ( isset( $locations['primary'] ) ) { $primary_menu = wp_get_nav_menu_object( $locations['primary'] ); if ( $primary_menu ) { return $primary_menu; } } return null; } private static function create_default_fallback() { $default_blocks = static::get_default_fallback_blocks(); $default_fallback = wp_insert_post( array( 'post_content' => $default_blocks, 'post_title' => _x( 'Navigation', 'Title of a Navigation menu' ), 'post_name' => 'navigation', 'post_status' => 'publish', 'post_type' => 'wp_navigation', ), true ); return $default_fallback; } private static function get_default_fallback_blocks() { $registry = WP_Block_Type_Registry::get_instance(); return $registry->is_registered( 'core/page-list' ) ? '<!-- wp:page-list /-->' : ''; } }
###require ABSPATH . WPINC . '/block-bindings.php';
function register_block_bindings_source( string $source_name, array $source_properties ) { return WP_Block_Bindings_Registry::get_instance()->register( $source_name, $source_properties ); } function unregister_block_bindings_source( string $source_name ) { return WP_Block_Bindings_Registry::get_instance()->unregister( $source_name ); } function get_all_registered_block_bindings_sources() { return WP_Block_Bindings_Registry::get_instance()->get_all_registered(); } function get_block_bindings_source( string $source_name ) { return WP_Block_Bindings_Registry::get_instance()->get_registered( $source_name ); } function get_block_bindings_supported_attributes( $block_type ) { $block_bindings_supported_attributes = array( 'core/paragraph' => array( 'content' ), 'core/heading' => array( 'content' ), 'core/image' => array( 'id', 'url', 'title', 'alt', 'caption' ), 'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ), 'core/post-date' => array( 'datetime' ), 'core/navigation-link' => array( 'url' ), 'core/navigation-submenu' => array( 'url' ), ); $supported_block_attributes = isset( $block_type, $block_bindings_supported_attributes[ $block_type ] ) ? $block_bindings_supported_attributes[ $block_type ] : array(); $supported_block_attributes = apply_filters( 'block_bindings_supported_attributes', $supported_block_attributes, $block_type ); $supported_block_attributes = apply_filters( "block_bindings_supported_attributes_{$block_type}", $supported_block_attributes ); return $supported_block_attributes; }
###require ABSPATH . WPINC . '/block-bindings/pattern-overrides.php';
function _block_bindings_pattern_overrides_get_value( array $source_args, $block_instance, string $attribute_name ) { if ( empty( $block_instance->attributes['metadata']['name'] ) ) { return null; } $metadata_name = $block_instance->attributes['metadata']['name']; return _wp_array_get( $block_instance->context, array( 'pattern/overrides', $metadata_name, $attribute_name ), null ); } function _register_block_bindings_pattern_overrides_source() { register_block_bindings_source( 'core/pattern-overrides', array( 'label' => _x( 'Pattern Overrides', 'block bindings source' ), 'get_value_callback' => '_block_bindings_pattern_overrides_get_value', 'uses_context' => array( 'pattern/overrides' ), ) ); } add_action( 'init', '_register_block_bindings_pattern_overrides_source' );
###require ABSPATH . WPINC . '/block-bindings/post-data.php';
function _block_bindings_post_data_get_value( array $source_args, $block_instance ) { if ( empty( $source_args['field'] ) ) { if ( empty( $source_args['key'] ) ) { return null; } $field = $source_args['key']; } else { $field = $source_args['field']; } $block_name = $block_instance->name ?? ''; $is_navigation_block = in_array( $block_name, array( 'core/navigation-link', 'core/navigation-submenu' ), true ); if ( $is_navigation_block ) { $post_id = $block_instance->attributes['id'] ?? null; } else { $post_id = $block_instance->context['postId'] ?? null; } if ( empty( $post_id ) ) { return null; } $post = get_post( $post_id ); if ( ( ! is_post_publicly_viewable( $post ) && ! current_user_can( 'read_post', $post_id ) ) || post_password_required( $post ) ) { return null; } if ( 'date' === $field ) { return esc_attr( get_the_date( 'c', $post_id ) ); } if ( 'modified' === $field ) { if ( get_the_modified_date( 'U', $post_id ) > get_the_date( 'U', $post_id ) ) { return esc_attr( get_the_modified_date( 'c', $post_id ) ); } else { return ''; } } if ( 'link' === $field ) { $permalink = get_permalink( $post_id ); return false === $permalink ? null : esc_url( $permalink ); } } function _register_block_bindings_post_data_source() { register_block_bindings_source( 'core/post-data', array( 'label' => _x( 'Post Data', 'block bindings source' ), 'get_value_callback' => '_block_bindings_post_data_get_value', 'uses_context' => array( 'postId', 'postType' ), ) ); } add_action( 'init', '_register_block_bindings_post_data_source' );
###require ABSPATH . WPINC . '/block-bindings/post-meta.php';
function _block_bindings_post_meta_get_value( array $source_args, $block_instance ) { if ( empty( $source_args['key'] ) ) { return null; } if ( empty( $block_instance->context['postId'] ) ) { return null; } $post_id = $block_instance->context['postId']; $post = get_post( $post_id ); if ( ( ! is_post_publicly_viewable( $post ) && ! current_user_can( 'read_post', $post_id ) ) || post_password_required( $post ) ) { return null; } if ( is_protected_meta( $source_args['key'], 'post' ) ) { return null; } $meta_keys = get_registered_meta_keys( 'post', $block_instance->context['postType'] ); $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) ); if ( empty( $meta_keys[ $source_args['key'] ]['show_in_rest'] ) ) { return null; } return get_post_meta( $post_id, $source_args['key'], true ); } function _register_block_bindings_post_meta_source() { register_block_bindings_source( 'core/post-meta', array( 'label' => _x( 'Post Meta', 'block bindings source' ), 'get_value_callback' => '_block_bindings_post_meta_get_value', 'uses_context' => array( 'postId', 'postType' ), ) ); } add_action( 'init', '_register_block_bindings_post_meta_source' );
###require ABSPATH . WPINC . '/block-bindings/term-data.php';
function _block_bindings_term_data_get_value( array $source_args, $block_instance ) { if ( empty( $source_args['field'] ) ) { return null; } $block_name = $block_instance->name ?? ''; $is_navigation_block = in_array( $block_name, array( 'core/navigation-link', 'core/navigation-submenu' ), true ); if ( $is_navigation_block ) { $term_id = $block_instance->attributes['id'] ?? null; $type = $block_instance->attributes['type'] ?? ''; $taxonomy = ( 'tag' === $type ) ? 'post_tag' : $type; } else { $term_id = $block_instance->context['termId'] ?? null; $taxonomy = $block_instance->context['taxonomy'] ?? ''; } if ( empty( $term_id ) || empty( $taxonomy ) ) { return null; } $term = get_term( $term_id, $taxonomy ); if ( is_wp_error( $term ) || ! $term ) { return null; } $taxonomy_object = get_taxonomy( $taxonomy ); if ( ! $taxonomy_object || ! $taxonomy_object->publicly_queryable ) { if ( ! current_user_can( 'read' ) ) { return null; } } switch ( $source_args['field'] ) { case 'id': return esc_html( (string) $term_id ); case 'name': return esc_html( $term->name ); case 'link': $term_link = get_term_link( $term ); return is_wp_error( $term_link ) ? null : esc_url( $term_link ); case 'slug': return esc_html( $term->slug ); case 'description': return wp_kses_post( $term->description ); case 'parent': return esc_html( (string) $term->parent ); case 'count': return esc_html( (string) $term->count ); default: return null; } } function _register_block_bindings_term_data_source() { if ( get_block_bindings_source( 'core/term-data' ) ) { return; } register_block_bindings_source( 'core/term-data', array( 'label' => _x( 'Term Data', 'block bindings source' ), 'get_value_callback' => '_block_bindings_term_data_get_value', 'uses_context' => array( 'termId', 'taxonomy' ), ) ); } add_action( 'init', '_register_block_bindings_term_data_source' );
require ABSPATH . WPINC . '/blocks.php';
###require ABSPATH . WPINC . '/blocks/index.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } define( 'BLOCKS_PATH', ABSPATH . WPINC . '/blocks/' ); require BLOCKS_PATH . 'legacy-widget.php'; require BLOCKS_PATH . 'widget-group.php'; require BLOCKS_PATH . 'require-dynamic-blocks.php'; function register_core_block_style_handles() { $wp_version = wp_get_wp_version(); if ( ! wp_should_load_separate_core_block_assets() ) { return; } $blocks_url = includes_url( 'blocks/' ); $suffix = wp_scripts_get_suffix(); $wp_styles = wp_styles(); $style_fields = array( 'style' => 'style', 'editorStyle' => 'editor', ); static $core_blocks_meta; if ( ! $core_blocks_meta ) { $core_blocks_meta = require BLOCKS_PATH . 'blocks-json.php'; } $files = false; $transient_name = 'wp_core_block_css_files'; $can_use_cached = ! wp_is_development_mode( 'core' ); if ( $can_use_cached ) { $cached_files = get_transient( $transient_name ); if ( is_array( $cached_files ) && isset( $cached_files['version'] ) && $cached_files['version'] === $wp_version && isset( $cached_files['files'] ) ) { $files = $cached_files['files']; } } if ( ! $files ) { $files = glob( wp_normalize_path( BLOCKS_PATH . '**/**.css' ) ); $normalized_blocks_path = wp_normalize_path( BLOCKS_PATH ); $files = array_map( static function ( $file ) use ( $normalized_blocks_path ) { return str_replace( $normalized_blocks_path, '', $file ); }, $files ); if ( $can_use_cached ) { set_transient( $transient_name, array( 'version' => $wp_version, 'files' => $files, ) ); } } $register_style = static function ( $name, $filename, $style_handle ) use ( $blocks_url, $suffix, $wp_styles, $files ) { $style_path = "{$name}/{$filename}{$suffix}.css"; $path = wp_normalize_path( BLOCKS_PATH . $style_path ); if ( ! in_array( $style_path, $files, true ) ) { $wp_styles->add( $style_handle, false ); return; } $wp_styles->add( $style_handle, $blocks_url . $style_path ); $wp_styles->add_data( $style_handle, 'path', $path ); $rtl_file = "{$name}/{$filename}-rtl{$suffix}.css"; if ( is_rtl() && in_array( $rtl_file, $files, true ) ) { $wp_styles->add_data( $style_handle, 'rtl', 'replace' ); $wp_styles->add_data( $style_handle, 'suffix', $suffix ); $wp_styles->add_data( $style_handle, 'path', str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $path ) ); } }; foreach ( $core_blocks_meta as $name => $schema ) { $schema = apply_filters( 'block_type_metadata', $schema ); if ( ! isset( $schema['style'] ) ) { $schema['style'] = "wp-block-{$name}"; } if ( ! isset( $schema['editorStyle'] ) ) { $schema['editorStyle'] = "wp-block-{$name}-editor"; } $register_style( $name, 'theme', "wp-block-{$name}-theme" ); foreach ( $style_fields as $style_field => $filename ) { $style_handle = $schema[ $style_field ]; if ( is_array( $style_handle ) ) { continue; } $register_style( $name, $filename, $style_handle ); } } } add_action( 'init', 'register_core_block_style_handles', 9 ); function register_core_block_types_from_metadata() { $block_folders = require BLOCKS_PATH . 'require-static-blocks.php'; foreach ( $block_folders as $block_folder ) { register_block_type_from_metadata( BLOCKS_PATH . $block_folder ); } } add_action( 'init', 'register_core_block_types_from_metadata' ); function wp_register_core_block_metadata_collection() { wp_register_block_metadata_collection( BLOCKS_PATH, BLOCKS_PATH . 'blocks-json.php' ); } add_action( 'init', 'wp_register_core_block_metadata_collection', 9 );
###require ABSPATH . WPINC . '/block-editor.php';
function get_default_block_categories() { return array( array( 'slug' => 'text', 'title' => _x( 'Text', 'block category' ), 'icon' => null, ), array( 'slug' => 'media', 'title' => _x( 'Media', 'block category' ), 'icon' => null, ), array( 'slug' => 'design', 'title' => _x( 'Design', 'block category' ), 'icon' => null, ), array( 'slug' => 'widgets', 'title' => _x( 'Widgets', 'block category' ), 'icon' => null, ), array( 'slug' => 'theme', 'title' => _x( 'Theme', 'block category' ), 'icon' => null, ), array( 'slug' => 'embed', 'title' => _x( 'Embeds', 'block category' ), 'icon' => null, ), array( 'slug' => 'reusable', 'title' => _x( 'Patterns', 'block category' ), 'icon' => null, ), ); } function get_block_categories( $post_or_block_editor_context ) { $block_categories = get_default_block_categories(); $block_editor_context = $post_or_block_editor_context instanceof WP_Post ? new WP_Block_Editor_Context( array( 'post' => $post_or_block_editor_context, ) ) : $post_or_block_editor_context; $block_categories = apply_filters( 'block_categories_all', $block_categories, $block_editor_context ); if ( ! empty( $block_editor_context->post ) ) { $post = $block_editor_context->post; $block_categories = apply_filters_deprecated( 'block_categories', array( $block_categories, $post ), '5.8.0', 'block_categories_all' ); } return $block_categories; } function get_allowed_block_types( $block_editor_context ) { $allowed_block_types = true; $allowed_block_types = apply_filters( 'allowed_block_types_all', $allowed_block_types, $block_editor_context ); if ( ! empty( $block_editor_context->post ) ) { $post = $block_editor_context->post; $allowed_block_types = apply_filters_deprecated( 'allowed_block_types', array( $allowed_block_types, $post ), '5.8.0', 'allowed_block_types_all' ); } return $allowed_block_types; } function get_default_block_editor_settings() { $max_upload_size = 0; if ( current_user_can( 'upload_files' ) ) { $max_upload_size = wp_max_upload_size(); if ( ! $max_upload_size ) { $max_upload_size = 0; } } $image_size_names = apply_filters( 'image_size_names_choose', array( 'thumbnail' => __( 'Thumbnail' ), 'medium' => __( 'Medium' ), 'large' => __( 'Large' ), 'full' => __( 'Full Size' ), ) ); $available_image_sizes = array(); foreach ( $image_size_names as $image_size_slug => $image_size_name ) { $available_image_sizes[] = array( 'slug' => $image_size_slug, 'name' => $image_size_name, ); } $default_size = get_option( 'image_default_size', 'large' ); $image_default_size = in_array( $default_size, array_keys( $image_size_names ), true ) ? $default_size : 'large'; $image_dimensions = array(); $all_sizes = wp_get_registered_image_subsizes(); foreach ( $available_image_sizes as $size ) { $key = $size['slug']; if ( isset( $all_sizes[ $key ] ) ) { $image_dimensions[ $key ] = $all_sizes[ $key ]; } } $default_editor_styles_file = ABSPATH . WPINC . '/css/dist/block-editor/default-editor-styles.css'; static $default_editor_styles_file_contents = false; if ( ! $default_editor_styles_file_contents && file_exists( $default_editor_styles_file ) ) { $default_editor_styles_file_contents = file_get_contents( $default_editor_styles_file ); } $default_editor_styles = array(); if ( $default_editor_styles_file_contents ) { $default_editor_styles = array( array( 'css' => $default_editor_styles_file_contents ), ); } $editor_settings = array( 'alignWide' => get_theme_support( 'align-wide' ), 'allowedBlockTypes' => true, 'allowedMimeTypes' => get_allowed_mime_types(), 'defaultEditorStyles' => $default_editor_styles, 'blockCategories' => get_default_block_categories(), 'isRTL' => is_rtl(), 'imageDefaultSize' => $image_default_size, 'imageDimensions' => $image_dimensions, 'imageEditing' => true, 'imageSizes' => $available_image_sizes, 'maxUploadFileSize' => $max_upload_size, '__experimentalDashboardLink' => admin_url( '/' ), '__unstableGalleryWithImageBlocks' => true, ); $theme_settings = get_classic_theme_supports_block_editor_settings(); foreach ( $theme_settings as $key => $value ) { $editor_settings[ $key ] = $value; } return $editor_settings; } function get_legacy_widget_block_editor_settings() { $editor_settings = array(); $editor_settings['widgetTypesToHideFromLegacyWidgetBlock'] = apply_filters( 'widget_types_to_hide_from_legacy_widget_block', array( 'pages', 'calendar', 'archives', 'media_audio', 'media_image', 'media_gallery', 'media_video', 'search', 'text', 'categories', 'recent-posts', 'recent-comments', 'rss', 'tag_cloud', 'custom_html', 'block', ) ); return $editor_settings; } function _wp_get_iframed_editor_assets() { global $wp_styles, $wp_scripts; $current_wp_styles = $wp_styles; $current_wp_scripts = $wp_scripts; $wp_styles = new WP_Styles(); $wp_scripts = new WP_Scripts(); $wp_styles->registered = $current_wp_styles->registered; $wp_scripts->registered = $current_wp_scripts->registered; $wp_styles->done = wp_theme_has_theme_json() ? array( 'wp-reset-editor-styles' ) : array(); wp_enqueue_script( 'wp-polyfill' ); wp_enqueue_style( 'wp-edit-blocks' ); if ( current_theme_supports( 'wp-block-styles' ) ) { wp_enqueue_style( 'wp-block-library-theme' ); } add_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' ); do_action( 'enqueue_block_assets' ); remove_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' ); $block_registry = WP_Block_Type_Registry::get_instance(); foreach ( $block_registry->get_all_registered() as $block_type ) { if ( isset( $block_type->editor_style_handles ) && is_array( $block_type->editor_style_handles ) ) { foreach ( $block_type->editor_style_handles as $style_handle ) { wp_enqueue_style( $style_handle ); } } } $has_emoji_styles = has_action( 'wp_print_styles', 'print_emoji_styles' ); if ( $has_emoji_styles ) { remove_action( 'wp_print_styles', 'print_emoji_styles' ); } ob_start(); wp_print_styles(); wp_print_font_faces(); wp_print_font_faces_from_style_variations(); $styles = ob_get_clean(); if ( $has_emoji_styles ) { add_action( 'wp_print_styles', 'print_emoji_styles' ); } ob_start(); wp_print_head_scripts(); wp_print_footer_scripts(); $scripts = ob_get_clean(); $wp_styles = $current_wp_styles; $wp_scripts = $current_wp_scripts; return array( 'styles' => $styles, 'scripts' => $scripts, ); } function wp_get_first_block( $blocks, $block_name ) { foreach ( $blocks as $block ) { if ( $block_name === $block['blockName'] ) { return $block; } if ( ! empty( $block['innerBlocks'] ) ) { $found_block = wp_get_first_block( $block['innerBlocks'], $block_name ); if ( ! empty( $found_block ) ) { return $found_block; } } } return array(); } function wp_get_post_content_block_attributes() { global $post_ID; $is_block_theme = wp_is_block_theme(); if ( ! $is_block_theme || ! $post_ID ) { return null; } $template_slug = get_page_template_slug( $post_ID ); if ( ! $template_slug ) { $post_slug = 'singular'; $page_slug = 'singular'; $template_types = get_block_templates(); foreach ( $template_types as $template_type ) { if ( 'page' === $template_type->slug ) { $page_slug = 'page'; } if ( 'single' === $template_type->slug ) { $post_slug = 'single'; } } $what_post_type = get_post_type( $post_ID ); switch ( $what_post_type ) { case 'page': $template_slug = $page_slug; break; default: $template_slug = $post_slug; break; } } $current_template = get_block_templates( array( 'slug__in' => array( $template_slug ) ) ); if ( ! empty( $current_template ) ) { $template_blocks = parse_blocks( $current_template[0]->content ); $post_content_block = wp_get_first_block( $template_blocks, 'core/post-content' ); if ( isset( $post_content_block['attrs'] ) ) { return $post_content_block['attrs']; } } return null; } function get_block_editor_settings( array $custom_settings, $block_editor_context ) { $editor_settings = array_merge( get_default_block_editor_settings(), array( 'allowedBlockTypes' => get_allowed_block_types( $block_editor_context ), 'blockCategories' => get_block_categories( $block_editor_context ), ), $custom_settings ); $editor_settings['__experimentalBlockBindingsSupportedAttributes'] = array(); foreach ( array_keys( WP_Block_Type_Registry::get_instance()->get_all_registered() ) as $block_type ) { $supported_block_attributes = get_block_bindings_supported_attributes( $block_type ); if ( ! empty( $supported_block_attributes ) ) { $editor_settings['__experimentalBlockBindingsSupportedAttributes'][ $block_type ] = $supported_block_attributes; } } $global_styles = array(); $presets = array( array( 'css' => 'variables', '__unstableType' => 'presets', 'isGlobalStyles' => true, ), array( 'css' => 'presets', '__unstableType' => 'presets', 'isGlobalStyles' => true, ), ); foreach ( $presets as $preset_style ) { $actual_css = wp_get_global_stylesheet( array( $preset_style['css'] ) ); if ( '' !== $actual_css ) { $preset_style['css'] = $actual_css; $global_styles[] = $preset_style; } } if ( wp_theme_has_theme_json() ) { $block_classes = array( 'css' => 'styles', '__unstableType' => 'theme', 'isGlobalStyles' => true, ); $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) ); if ( '' !== $actual_css ) { $block_classes['css'] = $actual_css; $global_styles[] = $block_classes; } $global_styles[] = array( 'css' => wp_get_global_stylesheet( array( 'custom-css' ) ), '__unstableType' => 'user', 'isGlobalStyles' => true, ); } else { $block_classes = array( 'css' => 'base-layout-styles', '__unstableType' => 'base-layout', 'isGlobalStyles' => true, ); $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) ); if ( '' !== $actual_css ) { $block_classes['css'] = $actual_css; $global_styles[] = $block_classes; } } $editor_settings['styles'] = array_merge( $global_styles, get_block_editor_theme_styles() ); $editor_settings['__experimentalFeatures'] = wp_get_global_settings(); if ( isset( $editor_settings['__experimentalFeatures']['color']['palette'] ) ) { $colors_by_origin = $editor_settings['__experimentalFeatures']['color']['palette']; $editor_settings['colors'] = isset( $colors_by_origin['custom'] ) ? $colors_by_origin['custom'] : ( isset( $colors_by_origin['theme'] ) ? $colors_by_origin['theme'] : $colors_by_origin['default'] ); } if ( isset( $editor_settings['__experimentalFeatures']['color']['gradients'] ) ) { $gradients_by_origin = $editor_settings['__experimentalFeatures']['color']['gradients']; $editor_settings['gradients'] = isset( $gradients_by_origin['custom'] ) ? $gradients_by_origin['custom'] : ( isset( $gradients_by_origin['theme'] ) ? $gradients_by_origin['theme'] : $gradients_by_origin['default'] ); } if ( isset( $editor_settings['__experimentalFeatures']['typography']['fontSizes'] ) ) { $font_sizes_by_origin = $editor_settings['__experimentalFeatures']['typography']['fontSizes']; $editor_settings['fontSizes'] = isset( $font_sizes_by_origin['custom'] ) ? $font_sizes_by_origin['custom'] : ( isset( $font_sizes_by_origin['theme'] ) ? $font_sizes_by_origin['theme'] : $font_sizes_by_origin['default'] ); } if ( isset( $editor_settings['__experimentalFeatures']['color']['custom'] ) ) { $editor_settings['disableCustomColors'] = ! $editor_settings['__experimentalFeatures']['color']['custom']; unset( $editor_settings['__experimentalFeatures']['color']['custom'] ); } if ( isset( $editor_settings['__experimentalFeatures']['color']['customGradient'] ) ) { $editor_settings['disableCustomGradients'] = ! $editor_settings['__experimentalFeatures']['color']['customGradient']; unset( $editor_settings['__experimentalFeatures']['color']['customGradient'] ); } if ( isset( $editor_settings['__experimentalFeatures']['typography']['customFontSize'] ) ) { $editor_settings['disableCustomFontSizes'] = ! $editor_settings['__experimentalFeatures']['typography']['customFontSize']; unset( $editor_settings['__experimentalFeatures']['typography']['customFontSize'] ); } if ( isset( $editor_settings['__experimentalFeatures']['typography']['lineHeight'] ) ) { $editor_settings['enableCustomLineHeight'] = $editor_settings['__experimentalFeatures']['typography']['lineHeight']; unset( $editor_settings['__experimentalFeatures']['typography']['lineHeight'] ); } if ( isset( $editor_settings['__experimentalFeatures']['spacing']['units'] ) ) { $editor_settings['enableCustomUnits'] = $editor_settings['__experimentalFeatures']['spacing']['units']; unset( $editor_settings['__experimentalFeatures']['spacing']['units'] ); } if ( isset( $editor_settings['__experimentalFeatures']['spacing']['padding'] ) ) { $editor_settings['enableCustomSpacing'] = $editor_settings['__experimentalFeatures']['spacing']['padding']; unset( $editor_settings['__experimentalFeatures']['spacing']['padding'] ); } if ( isset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] ) ) { $editor_settings['disableCustomSpacingSizes'] = ! $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize']; unset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] ); } if ( isset( $editor_settings['__experimentalFeatures']['spacing']['spacingSizes'] ) ) { $spacing_sizes_by_origin = $editor_settings['__experimentalFeatures']['spacing']['spacingSizes']; $editor_settings['spacingSizes'] = isset( $spacing_sizes_by_origin['custom'] ) ? $spacing_sizes_by_origin['custom'] : ( isset( $spacing_sizes_by_origin['theme'] ) ? $spacing_sizes_by_origin['theme'] : $spacing_sizes_by_origin['default'] ); } $editor_settings['__unstableResolvedAssets'] = _wp_get_iframed_editor_assets(); $editor_settings['__unstableIsBlockBasedTheme'] = wp_is_block_theme(); $editor_settings['localAutosaveInterval'] = 15; $editor_settings['disableLayoutStyles'] = current_theme_supports( 'disable-layout-styles' ); $editor_settings['__experimentalDiscussionSettings'] = array( 'commentOrder' => get_option( 'comment_order' ), 'commentsPerPage' => get_option( 'comments_per_page' ), 'defaultCommentsPage' => get_option( 'default_comments_page' ), 'pageComments' => get_option( 'page_comments' ), 'threadComments' => get_option( 'thread_comments' ), 'threadCommentsDepth' => get_option( 'thread_comments_depth' ), 'defaultCommentStatus' => get_option( 'default_comment_status' ), 'avatarURL' => get_avatar_url( '', array( 'size' => 96, 'force_default' => true, 'default' => get_option( 'avatar_default' ), ) ), ); $post_content_block_attributes = wp_get_post_content_block_attributes(); if ( isset( $post_content_block_attributes ) ) { $editor_settings['postContentAttributes'] = $post_content_block_attributes; } $editor_settings['canUpdateBlockBindings'] = current_user_can( 'edit_block_binding', $block_editor_context ); $editor_settings = apply_filters( 'block_editor_settings_all', $editor_settings, $block_editor_context ); if ( ! empty( $block_editor_context->post ) ) { $post = $block_editor_context->post; $editor_settings = apply_filters_deprecated( 'block_editor_settings', array( $editor_settings, $post ), '5.8.0', 'block_editor_settings_all' ); } return $editor_settings; } function block_editor_rest_api_preload( array $preload_paths, $block_editor_context ) { global $post, $wp_scripts, $wp_styles; $preload_paths = apply_filters( 'block_editor_rest_api_preload_paths', $preload_paths, $block_editor_context ); if ( ! empty( $block_editor_context->post ) ) { $selected_post = $block_editor_context->post; $preload_paths = apply_filters_deprecated( 'block_editor_preload_paths', array( $preload_paths, $selected_post ), '5.8.0', 'block_editor_rest_api_preload_paths' ); } if ( empty( $preload_paths ) ) { return; } $backup_global_post = ! empty( $post ) ? clone $post : $post; $backup_wp_scripts = ! empty( $wp_scripts ) ? clone $wp_scripts : $wp_scripts; $backup_wp_styles = ! empty( $wp_styles ) ? clone $wp_styles : $wp_styles; foreach ( $preload_paths as &$path ) { if ( is_string( $path ) && ! str_starts_with( $path, '/' ) ) { $path = '/' . $path; continue; } if ( is_array( $path ) && is_string( $path[0] ) && ! str_starts_with( $path[0], '/' ) ) { $path[0] = '/' . $path[0]; } } unset( $path ); $preload_data = array_reduce( $preload_paths, 'rest_preload_api_request', array() ); $post = $backup_global_post; $wp_scripts = $backup_wp_scripts; $wp_styles = $backup_wp_styles; wp_add_inline_script( 'wp-api-fetch', sprintf( 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', wp_json_encode( $preload_data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); } function get_block_editor_theme_styles() { global $editor_styles; $styles = array(); if ( $editor_styles && current_theme_supports( 'editor-styles' ) ) { foreach ( $editor_styles as $style ) { if ( preg_match( '~^(https?:)?//~', $style ) ) { $response = wp_remote_get( $style ); if ( ! is_wp_error( $response ) ) { $styles[] = array( 'css' => wp_remote_retrieve_body( $response ), '__unstableType' => 'theme', 'isGlobalStyles' => false, ); } } else { $file = get_theme_file_path( $style ); if ( is_file( $file ) ) { $styles[] = array( 'css' => file_get_contents( $file ), 'baseURL' => get_theme_file_uri( $style ), '__unstableType' => 'theme', 'isGlobalStyles' => false, ); } } } } return $styles; } function get_classic_theme_supports_block_editor_settings() { $theme_settings = array( 'disableCustomColors' => get_theme_support( 'disable-custom-colors' ), 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), 'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ), 'disableLayoutStyles' => get_theme_support( 'disable-layout-styles' ), 'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ), 'enableCustomSpacing' => get_theme_support( 'custom-spacing' ), 'enableCustomUnits' => get_theme_support( 'custom-units' ), ); $color_palette = current( (array) get_theme_support( 'editor-color-palette' ) ); if ( false !== $color_palette ) { $theme_settings['colors'] = $color_palette; } $font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) ); if ( false !== $font_sizes ) { $theme_settings['fontSizes'] = $font_sizes; } $gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) ); if ( false !== $gradient_presets ) { $theme_settings['gradients'] = $gradient_presets; } $spacing_sizes = current( (array) get_theme_support( 'editor-spacing-sizes' ) ); if ( false !== $spacing_sizes ) { $theme_settings['spacingSizes'] = $spacing_sizes; } return $theme_settings; } function wp_initialize_site_preview_hooks() { if ( ! defined( 'IFRAME_REQUEST' ) && isset( $_GET['wp_site_preview'] ) && 1 === (int) $_GET['wp_site_preview'] && current_user_can( 'edit_theme_options' ) ) { define( 'IFRAME_REQUEST', true ); } }
require ABSPATH . WPINC . '/block-patterns.php';
###require ABSPATH . WPINC . '/class-wp-block-supports.php';
class WP_Block_Supports { private $block_supports = array(); public static $block_to_render = null; private static $instance = null; public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } public static function init() { $instance = self::get_instance(); $instance->register_attributes(); } public function register( $block_support_name, $block_support_config ) { $this->block_supports[ $block_support_name ] = array_merge( $block_support_config, array( 'name' => $block_support_name ) ); } public function apply_block_supports() { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( self::$block_to_render['blockName'] ); if ( ! $block_type || empty( $block_type ) ) { return array(); } $block_attributes = array_key_exists( 'attrs', self::$block_to_render ) && is_array( self::$block_to_render['attrs'] ) ? $block_type->prepare_attributes_for_render( self::$block_to_render['attrs'] ) : array(); $output = array(); foreach ( $this->block_supports as $block_support_config ) { if ( ! isset( $block_support_config['apply'] ) ) { continue; } $new_attributes = call_user_func( $block_support_config['apply'], $block_type, $block_attributes ); if ( ! empty( $new_attributes ) ) { foreach ( $new_attributes as $attribute_name => $attribute_value ) { if ( empty( $output[ $attribute_name ] ) ) { $output[ $attribute_name ] = $attribute_value; } else { $output[ $attribute_name ] .= " $attribute_value"; } } } } return $output; } private function register_attributes() { $block_registry = WP_Block_Type_Registry::get_instance(); $registered_block_types = $block_registry->get_all_registered(); foreach ( $registered_block_types as $block_type ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { continue; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } foreach ( $this->block_supports as $block_support_config ) { if ( ! isset( $block_support_config['register_attribute'] ) ) { continue; } call_user_func( $block_support_config['register_attribute'], $block_type ); } } } } function get_block_wrapper_attributes( $extra_attributes = array() ) { $new_attributes = WP_Block_Supports::get_instance()->apply_block_supports(); if ( empty( $new_attributes ) && empty( $extra_attributes ) ) { return ''; } $attributes_to_merge = array( 'style', 'class', 'id', 'aria-label' ); $attributes = array(); foreach ( $attributes_to_merge as $attribute_name ) { if ( empty( $new_attributes[ $attribute_name ] ) && empty( $extra_attributes[ $attribute_name ] ) ) { continue; } if ( empty( $new_attributes[ $attribute_name ] ) ) { $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ]; continue; } if ( empty( $extra_attributes[ $attribute_name ] ) ) { $attributes[ $attribute_name ] = $new_attributes[ $attribute_name ]; continue; } $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ] . ' ' . $new_attributes[ $attribute_name ]; } foreach ( $extra_attributes as $attribute_name => $value ) { if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) { $attributes[ $attribute_name ] = $value; } } if ( empty( $attributes ) ) { return ''; } $normalized_attributes = array(); foreach ( $attributes as $key => $value ) { $normalized_attributes[] = $key . '="' . esc_attr( $value ) . '"'; } return implode( ' ', $normalized_attributes ); }
###require ABSPATH . WPINC . '/block-supports/utils.php';
function wp_should_skip_block_supports_serialization( $block_type, $feature_set, $feature = null ) { if ( ! is_object( $block_type ) || ! $feature_set ) { return false; } $path = array( $feature_set, '__experimentalSkipSerialization' ); $skip_serialization = _wp_array_get( $block_type->supports, $path, false ); if ( is_array( $skip_serialization ) ) { return in_array( $feature, $skip_serialization, true ); } return $skip_serialization; }
###require ABSPATH . WPINC . '/block-supports/align.php';
function wp_register_alignment_support( $block_type ) { $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'align', $block_type->attributes ) ) { $block_type->attributes['align'] = array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', 'wide', 'full', '' ), ); } } } function wp_apply_alignment_support( $block_type, $block_attributes ) { $attributes = array(); $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { $has_block_alignment = array_key_exists( 'align', $block_attributes ); if ( $has_block_alignment ) { $attributes['class'] = sprintf( 'align%s', $block_attributes['align'] ); } } return $attributes; } WP_Block_Supports::get_instance()->register( 'align', array( 'register_attribute' => 'wp_register_alignment_support', 'apply' => 'wp_apply_alignment_support', ) );
###require ABSPATH . WPINC . '/block-supports/custom-classname.php';
function wp_register_custom_classname_support( $block_type ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); if ( $has_custom_classname_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'className', $block_type->attributes ) ) { $block_type->attributes['className'] = array( 'type' => 'string', ); } } } function wp_apply_custom_classname_support( $block_type, $block_attributes ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); $attributes = array(); if ( $has_custom_classname_support ) { $has_custom_classnames = array_key_exists( 'className', $block_attributes ); if ( $has_custom_classnames ) { $attributes['class'] = $block_attributes['className']; } } return $attributes; } WP_Block_Supports::get_instance()->register( 'custom-classname', array( 'register_attribute' => 'wp_register_custom_classname_support', 'apply' => 'wp_apply_custom_classname_support', ) );
###require ABSPATH . WPINC . '/block-supports/generated-classname.php';
function wp_get_block_default_classname( $block_name ) { $classname = 'wp-block-' . preg_replace( '/^core-/', '', str_replace( '/', '-', $block_name ) ); $classname = apply_filters( 'block_default_classname', $classname, $block_name ); return $classname; } function wp_apply_generated_classname_support( $block_type ) { $attributes = array(); $has_generated_classname_support = block_has_support( $block_type, 'className', true ); if ( $has_generated_classname_support ) { $block_classname = wp_get_block_default_classname( $block_type->name ); if ( $block_classname ) { $attributes['class'] = $block_classname; } } return $attributes; } WP_Block_Supports::get_instance()->register( 'generated-classname', array( 'apply' => 'wp_apply_generated_classname_support', ) );
###require ABSPATH . WPINC . '/block-supports/settings.php';
function _wp_get_presets_class_name( $block ) { return 'wp-settings-' . md5( serialize( $block ) ); } function _wp_add_block_level_presets_class( $block_content, $block ) { if ( ! $block_content ) { return $block_content; } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return $block_content; } $block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null; if ( empty( $block_settings ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( _wp_get_presets_class_name( $block ) ); } return $tags->get_updated_html(); } function _wp_add_block_level_preset_styles( $pre_render, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return null; } $block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null; if ( empty( $block_settings ) ) { return null; } $class_name = '.' . _wp_get_presets_class_name( $block ); $variables_root_selector = '*,[class*="wp-block"]'; $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); foreach ( $blocks as $block_type ) { $has_custom_selector = ( isset( $block_type->supports['__experimentalSelector'] ) && is_string( $block_type->supports['__experimentalSelector'] ) ) || ( isset( $block_type->selectors['root'] ) && is_string( $block_type->selectors['root'] ) ); if ( $has_custom_selector ) { $variables_root_selector .= ',' . wp_get_block_css_selector( $block_type ); } } $variables_root_selector = WP_Theme_JSON::scope_selector( $class_name, $variables_root_selector ); $theme_json_shape = WP_Theme_JSON::remove_insecure_properties( array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'settings' => $block_settings, ) ); $theme_json_object = new WP_Theme_JSON( $theme_json_shape ); $styles = ''; $styles .= $theme_json_object->get_stylesheet( array( 'variables' ), null, array( 'root_selector' => $variables_root_selector, 'scope' => $class_name, ) ); $styles .= $theme_json_object->get_stylesheet( array( 'presets' ), null, array( 'root_selector' => $class_name . ',' . $class_name . ' *', 'scope' => $class_name, ) ); if ( ! empty( $styles ) ) { wp_enqueue_block_support_styles( $styles ); } return null; } add_filter( 'render_block', '_wp_add_block_level_presets_class', 10, 2 ); add_filter( 'pre_render_block', '_wp_add_block_level_preset_styles', 10, 2 );
###require ABSPATH . WPINC . '/block-supports/elements.php';
function wp_get_elements_class_name( $block ) { return 'wp-elements-' . md5( serialize( $block ) ); } function wp_should_add_elements_class_name( $block, $options ) { if ( ! isset( $block['attrs']['style']['elements'] ) ) { return false; } $element_color_properties = array( 'button' => array( 'skip' => isset( $options['button']['skip'] ) ? $options['button']['skip'] : false, 'paths' => array( array( 'button', 'color', 'text' ), array( 'button', 'color', 'background' ), array( 'button', 'color', 'gradient' ), ), ), 'link' => array( 'skip' => isset( $options['link']['skip'] ) ? $options['link']['skip'] : false, 'paths' => array( array( 'link', 'color', 'text' ), array( 'link', ':hover', 'color', 'text' ), ), ), 'heading' => array( 'skip' => isset( $options['heading']['skip'] ) ? $options['heading']['skip'] : false, 'paths' => array( array( 'heading', 'color', 'text' ), array( 'heading', 'color', 'background' ), array( 'heading', 'color', 'gradient' ), array( 'h1', 'color', 'text' ), array( 'h1', 'color', 'background' ), array( 'h1', 'color', 'gradient' ), array( 'h2', 'color', 'text' ), array( 'h2', 'color', 'background' ), array( 'h2', 'color', 'gradient' ), array( 'h3', 'color', 'text' ), array( 'h3', 'color', 'background' ), array( 'h3', 'color', 'gradient' ), array( 'h4', 'color', 'text' ), array( 'h4', 'color', 'background' ), array( 'h4', 'color', 'gradient' ), array( 'h5', 'color', 'text' ), array( 'h5', 'color', 'background' ), array( 'h5', 'color', 'gradient' ), array( 'h6', 'color', 'text' ), array( 'h6', 'color', 'background' ), array( 'h6', 'color', 'gradient' ), ), ), ); $elements_style_attributes = $block['attrs']['style']['elements']; foreach ( $element_color_properties as $element_config ) { if ( $element_config['skip'] ) { continue; } foreach ( $element_config['paths'] as $path ) { if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) { return true; } } } return false; } function wp_render_elements_support_styles( $parsed_block ) { if ( is_string( $parsed_block ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( 'Use as a `pre_render_block` filter is deprecated. Use with `render_block_data` instead.' ) ); } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); $element_block_styles = isset( $parsed_block['attrs']['style']['elements'] ) ? $parsed_block['attrs']['style']['elements'] : null; if ( ! $element_block_styles ) { return $parsed_block; } $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); $skips_all_element_color_serialization = $skip_link_color_serialization && $skip_heading_color_serialization && $skip_button_color_serialization; if ( $skips_all_element_color_serialization ) { return $parsed_block; } $options = array( 'button' => array( 'skip' => $skip_button_color_serialization ), 'link' => array( 'skip' => $skip_link_color_serialization ), 'heading' => array( 'skip' => $skip_heading_color_serialization ), ); if ( ! wp_should_add_elements_class_name( $parsed_block, $options ) ) { return $parsed_block; } $class_name = wp_get_elements_class_name( $parsed_block ); $updated_class_name = isset( $parsed_block['attrs']['className'] ) ? $parsed_block['attrs']['className'] . " $class_name" : $class_name; _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); $element_types = array( 'button' => array( 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", 'skip' => $skip_button_color_serialization, ), 'link' => array( 'selector' => ".$class_name a:where(:not(.wp-element-button))", 'hover_selector' => ".$class_name a:where(:not(.wp-element-button)):hover", 'skip' => $skip_link_color_serialization, ), 'heading' => array( 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", 'skip' => $skip_heading_color_serialization, 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), ), ); foreach ( $element_types as $element_type => $element_config ) { if ( $element_config['skip'] ) { continue; } $element_style_object = isset( $element_block_styles[ $element_type ] ) ? $element_block_styles[ $element_type ] : null; if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => $element_config['selector'], 'context' => 'block-supports', ) ); if ( isset( $element_style_object[':hover'] ) ) { wp_style_engine_get_styles( $element_style_object[':hover'], array( 'selector' => $element_config['hover_selector'], 'context' => 'block-supports', ) ); } } if ( isset( $element_config['elements'] ) ) { foreach ( $element_config['elements'] as $element ) { $element_style_object = isset( $element_block_styles[ $element ] ) ? $element_block_styles[ $element ] : null; if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => ".$class_name $element", 'context' => 'block-supports', ) ); } } } } return $parsed_block; } function wp_render_elements_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? ''; preg_match( '/\bwp-elements-\S+\b/', $class_string, $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } add_filter( 'render_block', 'wp_render_elements_class_name', 10, 2 ); add_filter( 'render_block_data', 'wp_render_elements_support_styles', 10, 1 );
###require ABSPATH . WPINC . '/block-supports/colors.php';
function wp_register_colors_support( $block_type ) { $color_support = false; if ( $block_type instanceof WP_Block_Type ) { $color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false; } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false; $has_link_colors_support = isset( $color_support['link'] ) ? $color_support['link'] : false; $has_button_colors_support = isset( $color_support['button'] ) ? $color_support['button'] : false; $has_heading_colors_support = isset( $color_support['heading'] ) ? $color_support['heading'] : false; $has_color_support = $has_text_colors_support || $has_background_colors_support || $has_gradients_support || $has_link_colors_support || $has_button_colors_support || $has_heading_colors_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_color_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_background_colors_support && ! array_key_exists( 'backgroundColor', $block_type->attributes ) ) { $block_type->attributes['backgroundColor'] = array( 'type' => 'string', ); } if ( $has_text_colors_support && ! array_key_exists( 'textColor', $block_type->attributes ) ) { $block_type->attributes['textColor'] = array( 'type' => 'string', ); } if ( $has_gradients_support && ! array_key_exists( 'gradient', $block_type->attributes ) ) { $block_type->attributes['gradient'] = array( 'type' => 'string', ); } } function wp_apply_colors_support( $block_type, $block_attributes ) { $color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false; if ( is_array( $color_support ) && wp_should_skip_block_supports_serialization( $block_type, 'color' ) ) { return array(); } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false; $color_block_styles = array(); if ( $has_text_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'text' ) ) { $preset_text_color = array_key_exists( 'textColor', $block_attributes ) ? "var:preset|color|{$block_attributes['textColor']}" : null; $custom_text_color = isset( $block_attributes['style']['color']['text'] ) ? $block_attributes['style']['color']['text'] : null; $color_block_styles['text'] = $preset_text_color ? $preset_text_color : $custom_text_color; } if ( $has_background_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'background' ) ) { $preset_background_color = array_key_exists( 'backgroundColor', $block_attributes ) ? "var:preset|color|{$block_attributes['backgroundColor']}" : null; $custom_background_color = isset( $block_attributes['style']['color']['background'] ) ? $block_attributes['style']['color']['background'] : null; $color_block_styles['background'] = $preset_background_color ? $preset_background_color : $custom_background_color; } if ( $has_gradients_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'gradients' ) ) { $preset_gradient_color = array_key_exists( 'gradient', $block_attributes ) ? "var:preset|gradient|{$block_attributes['gradient']}" : null; $custom_gradient_color = isset( $block_attributes['style']['color']['gradient'] ) ? $block_attributes['style']['color']['gradient'] : null; $color_block_styles['gradient'] = $preset_gradient_color ? $preset_gradient_color : $custom_gradient_color; } $attributes = array(); $styles = wp_style_engine_get_styles( array( 'color' => $color_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } WP_Block_Supports::get_instance()->register( 'colors', array( 'register_attribute' => 'wp_register_colors_support', 'apply' => 'wp_apply_colors_support', ) );
###require ABSPATH . WPINC . '/block-supports/typography.php';
function wp_register_typography_support( $block_type ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return; } $typography_supports = isset( $block_type->supports['typography'] ) ? $block_type->supports['typography'] : false; if ( ! $typography_supports ) { return; } $has_font_family_support = isset( $typography_supports['__experimentalFontFamily'] ) ? $typography_supports['__experimentalFontFamily'] : false; $has_font_size_support = isset( $typography_supports['fontSize'] ) ? $typography_supports['fontSize'] : false; $has_font_style_support = isset( $typography_supports['__experimentalFontStyle'] ) ? $typography_supports['__experimentalFontStyle'] : false; $has_font_weight_support = isset( $typography_supports['__experimentalFontWeight'] ) ? $typography_supports['__experimentalFontWeight'] : false; $has_letter_spacing_support = isset( $typography_supports['__experimentalLetterSpacing'] ) ? $typography_supports['__experimentalLetterSpacing'] : false; $has_line_height_support = isset( $typography_supports['lineHeight'] ) ? $typography_supports['lineHeight'] : false; $has_text_align_support = isset( $typography_supports['textAlign'] ) ? $typography_supports['textAlign'] : false; $has_text_columns_support = isset( $typography_supports['textColumns'] ) ? $typography_supports['textColumns'] : false; $has_text_decoration_support = isset( $typography_supports['__experimentalTextDecoration'] ) ? $typography_supports['__experimentalTextDecoration'] : false; $has_text_transform_support = isset( $typography_supports['__experimentalTextTransform'] ) ? $typography_supports['__experimentalTextTransform'] : false; $has_writing_mode_support = isset( $typography_supports['__experimentalWritingMode'] ) ? $typography_supports['__experimentalWritingMode'] : false; $has_typography_support = $has_font_family_support || $has_font_size_support || $has_font_style_support || $has_font_weight_support || $has_letter_spacing_support || $has_line_height_support || $has_text_align_support || $has_text_columns_support || $has_text_decoration_support || $has_text_transform_support || $has_writing_mode_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_typography_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_font_size_support && ! array_key_exists( 'fontSize', $block_type->attributes ) ) { $block_type->attributes['fontSize'] = array( 'type' => 'string', ); } if ( $has_font_family_support && ! array_key_exists( 'fontFamily', $block_type->attributes ) ) { $block_type->attributes['fontFamily'] = array( 'type' => 'string', ); } } function wp_apply_typography_support( $block_type, $block_attributes ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return array(); } $typography_supports = isset( $block_type->supports['typography'] ) ? $block_type->supports['typography'] : false; if ( ! $typography_supports ) { return array(); } if ( wp_should_skip_block_supports_serialization( $block_type, 'typography' ) ) { return array(); } $has_font_family_support = isset( $typography_supports['__experimentalFontFamily'] ) ? $typography_supports['__experimentalFontFamily'] : false; $has_font_size_support = isset( $typography_supports['fontSize'] ) ? $typography_supports['fontSize'] : false; $has_font_style_support = isset( $typography_supports['__experimentalFontStyle'] ) ? $typography_supports['__experimentalFontStyle'] : false; $has_font_weight_support = isset( $typography_supports['__experimentalFontWeight'] ) ? $typography_supports['__experimentalFontWeight'] : false; $has_letter_spacing_support = isset( $typography_supports['__experimentalLetterSpacing'] ) ? $typography_supports['__experimentalLetterSpacing'] : false; $has_line_height_support = isset( $typography_supports['lineHeight'] ) ? $typography_supports['lineHeight'] : false; $has_text_align_support = isset( $typography_supports['textAlign'] ) ? $typography_supports['textAlign'] : false; $has_text_columns_support = isset( $typography_supports['textColumns'] ) ? $typography_supports['textColumns'] : false; $has_text_decoration_support = isset( $typography_supports['__experimentalTextDecoration'] ) ? $typography_supports['__experimentalTextDecoration'] : false; $has_text_transform_support = isset( $typography_supports['__experimentalTextTransform'] ) ? $typography_supports['__experimentalTextTransform'] : false; $has_writing_mode_support = isset( $typography_supports['__experimentalWritingMode'] ) ? $typography_supports['__experimentalWritingMode'] : false; $should_skip_font_size = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' ); $should_skip_font_family = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' ); $should_skip_font_style = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' ); $should_skip_font_weight = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' ); $should_skip_line_height = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' ); $should_skip_text_align = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textAlign' ); $should_skip_text_columns = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textColumns' ); $should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' ); $should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ); $should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ); $should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' ); $typography_block_styles = array(); if ( $has_font_size_support && ! $should_skip_font_size ) { $preset_font_size = array_key_exists( 'fontSize', $block_attributes ) ? "var:preset|font-size|{$block_attributes['fontSize']}" : null; $custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] ) ? $block_attributes['style']['typography']['fontSize'] : null; $typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : wp_get_typography_font_size_value( array( 'size' => $custom_font_size, ) ); } if ( $has_font_family_support && ! $should_skip_font_family ) { $preset_font_family = array_key_exists( 'fontFamily', $block_attributes ) ? "var:preset|font-family|{$block_attributes['fontFamily']}" : null; $custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] ) ? wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontFamily'], 'font-family' ) : null; $typography_block_styles['fontFamily'] = $preset_font_family ? $preset_font_family : $custom_font_family; } if ( $has_font_style_support && ! $should_skip_font_style && isset( $block_attributes['style']['typography']['fontStyle'] ) ) { $typography_block_styles['fontStyle'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontStyle'], 'font-style' ); } if ( $has_font_weight_support && ! $should_skip_font_weight && isset( $block_attributes['style']['typography']['fontWeight'] ) ) { $typography_block_styles['fontWeight'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontWeight'], 'font-weight' ); } if ( $has_line_height_support && ! $should_skip_line_height ) { $typography_block_styles['lineHeight'] = isset( $block_attributes['style']['typography']['lineHeight'] ) ? $block_attributes['style']['typography']['lineHeight'] : null; } if ( $has_text_align_support && ! $should_skip_text_align ) { $typography_block_styles['textAlign'] = isset( $block_attributes['style']['typography']['textAlign'] ) ? $block_attributes['style']['typography']['textAlign'] : null; } if ( $has_text_columns_support && ! $should_skip_text_columns && isset( $block_attributes['style']['typography']['textColumns'] ) ) { $typography_block_styles['textColumns'] = isset( $block_attributes['style']['typography']['textColumns'] ) ? $block_attributes['style']['typography']['textColumns'] : null; } if ( $has_text_decoration_support && ! $should_skip_text_decoration && isset( $block_attributes['style']['typography']['textDecoration'] ) ) { $typography_block_styles['textDecoration'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textDecoration'], 'text-decoration' ); } if ( $has_text_transform_support && ! $should_skip_text_transform && isset( $block_attributes['style']['typography']['textTransform'] ) ) { $typography_block_styles['textTransform'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textTransform'], 'text-transform' ); } if ( $has_letter_spacing_support && ! $should_skip_letter_spacing && isset( $block_attributes['style']['typography']['letterSpacing'] ) ) { $typography_block_styles['letterSpacing'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['letterSpacing'], 'letter-spacing' ); } if ( $has_writing_mode_support && ! $should_skip_writing_mode && isset( $block_attributes['style']['typography']['writingMode'] ) ) { $typography_block_styles['writingMode'] = isset( $block_attributes['style']['typography']['writingMode'] ) ? $block_attributes['style']['typography']['writingMode'] : null; } $attributes = array(); $classnames = array(); $styles = wp_style_engine_get_styles( array( 'typography' => $typography_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $classnames[] = $styles['classnames']; } if ( $has_text_align_support && ! $should_skip_text_align && isset( $block_attributes['style']['typography']['textAlign'] ) ) { $classnames[] = 'has-text-align-' . $block_attributes['style']['typography']['textAlign']; } if ( ! empty( $classnames ) ) { $attributes['class'] = implode( ' ', $classnames ); } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } function wp_typography_get_preset_inline_style_value( $style_value, $css_property ) { if ( empty( $style_value ) || ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) { return $style_value; } $index_to_splice = strrpos( $style_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) ); return sprintf( 'var(--wp--preset--%s--%s);', $css_property, $slug ); } function wp_render_typography_support( $block_content, $block ) { if ( ! empty( $block['attrs']['fitText'] ) && $block['attrs']['fitText'] && ! is_admin() ) { wp_enqueue_script_module( '@wordpress/block-editor/utils/fit-text-frontend' ); if ( ! empty( $block_content ) ) { $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag() ) { if ( ! $processor->get_attribute( 'data-wp-interactive' ) ) { $processor->set_attribute( 'data-wp-interactive', true ); } $processor->set_attribute( 'data-wp-context---core-fit-text', 'core/fit-text::{"fontSize":""}' ); $processor->set_attribute( 'data-wp-init---core-fit-text', 'core/fit-text::callbacks.init' ); $processor->set_attribute( 'data-wp-style--font-size', 'core/fit-text::context.fontSize' ); $block_content = $processor->get_updated_html(); } } return $block_content; } if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) { return $block_content; } $custom_font_size = $block['attrs']['style']['typography']['fontSize']; $fluid_font_size = wp_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); } return $block_content; } function wp_get_typography_value_and_unit( $raw_value, $options = array() ) { if ( ! is_string( $raw_value ) && ! is_int( $raw_value ) && ! is_float( $raw_value ) ) { _doing_it_wrong( __FUNCTION__, __( 'Raw size value must be a string, integer, or float.' ), '6.1.0' ); return null; } if ( empty( $raw_value ) ) { return null; } if ( is_numeric( $raw_value ) ) { $raw_value = $raw_value . 'px'; } $defaults = array( 'coerce_to' => '', 'root_size_value' => 16, 'acceptable_units' => array( 'rem', 'px', 'em' ), ); $options = wp_parse_args( $options, $defaults ); $acceptable_units_group = implode( '|', $options['acceptable_units'] ); $pattern = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/'; preg_match( $pattern, $raw_value, $matches ); if ( ! isset( $matches[1] ) || ! isset( $matches[2] ) ) { return null; } $value = $matches[1]; $unit = $matches[2]; if ( 'px' === $options['coerce_to'] && ( 'em' === $unit || 'rem' === $unit ) ) { $value = $value * $options['root_size_value']; $unit = $options['coerce_to']; } if ( 'px' === $unit && ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) ) { $value = $value / $options['root_size_value']; $unit = $options['coerce_to']; } if ( ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) && ( 'em' === $unit || 'rem' === $unit ) ) { $unit = $options['coerce_to']; } return array( 'value' => round( $value, 3 ), 'unit' => $unit, ); } function wp_get_computed_fluid_typography_value( $args = array() ) { $maximum_viewport_width_raw = isset( $args['maximum_viewport_width'] ) ? $args['maximum_viewport_width'] : null; $minimum_viewport_width_raw = isset( $args['minimum_viewport_width'] ) ? $args['minimum_viewport_width'] : null; $maximum_font_size_raw = isset( $args['maximum_font_size'] ) ? $args['maximum_font_size'] : null; $minimum_font_size_raw = isset( $args['minimum_font_size'] ) ? $args['minimum_font_size'] : null; $scale_factor = isset( $args['scale_factor'] ) ? $args['scale_factor'] : null; $minimum_font_size = wp_get_typography_value_and_unit( $minimum_font_size_raw ); $font_size_unit = isset( $minimum_font_size['unit'] ) ? $minimum_font_size['unit'] : 'rem'; $maximum_font_size = wp_get_typography_value_and_unit( $maximum_font_size_raw, array( 'coerce_to' => $font_size_unit, ) ); if ( ! $maximum_font_size || ! $minimum_font_size ) { return null; } $minimum_font_size_rem = wp_get_typography_value_and_unit( $minimum_font_size_raw, array( 'coerce_to' => 'rem', ) ); $maximum_viewport_width = wp_get_typography_value_and_unit( $maximum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); $minimum_viewport_width = wp_get_typography_value_and_unit( $minimum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); if ( ! $minimum_viewport_width || ! $maximum_viewport_width ) { return null; } $linear_factor_denominator = $maximum_viewport_width['value'] - $minimum_viewport_width['value']; if ( empty( $linear_factor_denominator ) ) { return null; } $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $linear_factor_denominator ) ); $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 ); $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled; $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)"; return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)"; } function wp_get_typography_font_size_value( $preset, $settings = array() ) { if ( ! isset( $preset['size'] ) ) { return null; } $fluid_font_size_settings = $preset['fluid'] ?? null; if ( false === $fluid_font_size_settings || empty( $preset['size'] ) ) { return $preset['size']; } if ( is_bool( $settings ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( '`boolean` type for second argument `$settings` is deprecated. Use `array()` instead.' ) ); $settings = array( 'typography' => array( 'fluid' => $settings, ), ); } $global_settings = wp_get_global_settings(); $settings = wp_parse_args( $settings, $global_settings ); $typography_settings = $settings['typography'] ?? array(); if ( empty( $typography_settings['fluid'] ) && empty( $fluid_font_size_settings ) ) { return $preset['size']; } $fluid_settings = isset( $typography_settings['fluid'] ) ? $typography_settings['fluid'] : array(); $layout_settings = isset( $settings['layout'] ) ? $settings['layout'] : array(); $default_maximum_viewport_width = '1600px'; $default_minimum_viewport_width = '320px'; $default_minimum_font_size_factor_max = 0.75; $default_minimum_font_size_factor_min = 0.25; $default_scale_factor = 1; $default_minimum_font_size_limit = '14px'; $minimum_viewport_width = isset( $fluid_settings['minViewportWidth'] ) ? $fluid_settings['minViewportWidth'] : $default_minimum_viewport_width; $maximum_viewport_width = isset( $layout_settings['wideSize'] ) && ! empty( wp_get_typography_value_and_unit( $layout_settings['wideSize'] ) ) ? $layout_settings['wideSize'] : $default_maximum_viewport_width; if ( isset( $fluid_settings['maxViewportWidth'] ) ) { $maximum_viewport_width = $fluid_settings['maxViewportWidth']; } $has_min_font_size = isset( $fluid_settings['minFontSize'] ) && ! empty( wp_get_typography_value_and_unit( $fluid_settings['minFontSize'] ) ); $minimum_font_size_limit = $has_min_font_size ? $fluid_settings['minFontSize'] : $default_minimum_font_size_limit; $minimum_font_size_raw = isset( $fluid_font_size_settings['min'] ) ? $fluid_font_size_settings['min'] : null; $maximum_font_size_raw = isset( $fluid_font_size_settings['max'] ) ? $fluid_font_size_settings['max'] : null; $preferred_size = wp_get_typography_value_and_unit( $preset['size'] ); if ( empty( $preferred_size['unit'] ) ) { return $preset['size']; } $minimum_font_size_limit = wp_get_typography_value_and_unit( $minimum_font_size_limit, array( 'coerce_to' => $preferred_size['unit'], ) ); if ( ! empty( $minimum_font_size_limit ) && ( ! $minimum_font_size_raw && ! $maximum_font_size_raw ) ) { if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) { return $preset['size']; } } if ( ! $maximum_font_size_raw ) { $maximum_font_size_raw = $preferred_size['value'] . $preferred_size['unit']; } if ( ! $minimum_font_size_raw ) { $preferred_font_size_in_px = 'px' === $preferred_size['unit'] ? $preferred_size['value'] : $preferred_size['value'] * 16; $minimum_font_size_factor = min( max( 1 - 0.075 * log( $preferred_font_size_in_px, 2 ), $default_minimum_font_size_factor_min ), $default_minimum_font_size_factor_max ); $calculated_minimum_font_size = round( $preferred_size['value'] * $minimum_font_size_factor, 3 ); if ( ! empty( $minimum_font_size_limit ) && $calculated_minimum_font_size <= $minimum_font_size_limit['value'] ) { $minimum_font_size_raw = $minimum_font_size_limit['value'] . $minimum_font_size_limit['unit']; } else { $minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit']; } } $fluid_font_size_value = wp_get_computed_fluid_typography_value( array( 'minimum_viewport_width' => $minimum_viewport_width, 'maximum_viewport_width' => $maximum_viewport_width, 'minimum_font_size' => $minimum_font_size_raw, 'maximum_font_size' => $maximum_font_size_raw, 'scale_factor' => $default_scale_factor, ) ); if ( ! empty( $fluid_font_size_value ) ) { return $fluid_font_size_value; } return $preset['size']; } WP_Block_Supports::get_instance()->register( 'typography', array( 'register_attribute' => 'wp_register_typography_support', 'apply' => 'wp_apply_typography_support', ) );
###require ABSPATH . WPINC . '/block-supports/border.php';
function wp_register_border_support( $block_type ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( block_has_support( $block_type, '__experimentalBorder' ) && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( wp_has_border_feature_support( $block_type, 'color' ) && ! array_key_exists( 'borderColor', $block_type->attributes ) ) { $block_type->attributes['borderColor'] = array( 'type' => 'string', ); } } function wp_apply_border_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) { return array(); } $border_block_styles = array(); $has_border_color_support = wp_has_border_feature_support( $block_type, 'color' ); $has_border_width_support = wp_has_border_feature_support( $block_type, 'width' ); if ( wp_has_border_feature_support( $block_type, 'radius' ) && isset( $block_attributes['style']['border']['radius'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) ) { $border_radius = $block_attributes['style']['border']['radius']; if ( is_numeric( $border_radius ) ) { $border_radius .= 'px'; } $border_block_styles['radius'] = $border_radius; } if ( wp_has_border_feature_support( $block_type, 'style' ) && isset( $block_attributes['style']['border']['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ) { $border_block_styles['style'] = $block_attributes['style']['border']['style']; } if ( $has_border_width_support && isset( $block_attributes['style']['border']['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ) { $border_width = $block_attributes['style']['border']['width']; if ( is_numeric( $border_width ) ) { $border_width .= 'px'; } $border_block_styles['width'] = $border_width; } if ( $has_border_color_support && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ) { $preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null; $custom_border_color = isset( $block_attributes['style']['border']['color'] ) ? $block_attributes['style']['border']['color'] : null; $border_block_styles['color'] = $preset_border_color ? $preset_border_color : $custom_border_color; } if ( $has_border_color_support || $has_border_width_support ) { foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { $border = isset( $block_attributes['style']['border'][ $side ] ) ? $block_attributes['style']['border'][ $side ] : null; $border_side_values = array( 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null, 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null, 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null, ); $border_block_styles[ $side ] = $border_side_values; } } $attributes = array(); $styles = wp_style_engine_get_styles( array( 'border' => $border_block_styles ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) { if ( $block_type instanceof WP_Block_Type ) { $block_type_supports_border = isset( $block_type->supports['__experimentalBorder'] ) ? $block_type->supports['__experimentalBorder'] : $default_value; if ( true === $block_type_supports_border ) { return true; } } return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); } WP_Block_Supports::get_instance()->register( 'border', array( 'register_attribute' => 'wp_register_border_support', 'apply' => 'wp_apply_border_support', ) );
###require ABSPATH . WPINC . '/block-supports/layout.php';
function wp_get_layout_definitions() { $layout_definitions = array( 'default' => array( 'name' => 'default', 'slug' => 'flow', 'className' => 'is-layout-flow', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'constrained' => array( 'name' => 'constrained', 'slug' => 'constrained', 'className' => 'is-layout-constrained', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))', 'rules' => array( 'max-width' => 'var(--wp--style--global--content-size)', 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > .alignwide', 'rules' => array( 'max-width' => 'var(--wp--style--global--wide-size)', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'flex' => array( 'name' => 'flex', 'slug' => 'flex', 'className' => 'is-layout-flex', 'displayMode' => 'flex', 'baseStyles' => array( array( 'selector' => '', 'rules' => array( 'flex-wrap' => 'wrap', 'align-items' => 'center', ), ), array( 'selector' => ' > :is(*, div)', 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), 'grid' => array( 'name' => 'grid', 'slug' => 'grid', 'className' => 'is-layout-grid', 'displayMode' => 'grid', 'baseStyles' => array( array( 'selector' => ' > :is(*, div)', 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), ); return $layout_definitions; } function wp_register_layout_support( $block_type ) { $support_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); if ( $support_layout ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'layout', $block_type->attributes ) ) { $block_type->attributes['layout'] = array( 'type' => 'object', ); } } } function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) { $layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default'; $layout_styles = array(); if ( 'default' === $layout_type ) { if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'constrained' === $layout_type ) { $content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : ''; $wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : ''; $justify_content = isset( $layout['justifyContent'] ) ? $layout['justifyContent'] : 'center'; $all_max_width_value = $content_size ? $content_size : $wide_size; $wide_max_width_value = $wide_size ? $wide_size : $content_size; $all_max_width_value = safecss_filter_attr( explode( ';', $all_max_width_value )[0] ); $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] ); $margin_left = 'left' === $justify_content ? '0 !important' : 'auto !important'; $margin_right = 'right' === $justify_content ? '0 !important' : 'auto !important'; if ( $content_size || $wide_size ) { array_push( $layout_styles, array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'max-width' => $all_max_width_value, 'margin-left' => $margin_left, 'margin-right' => $margin_right, ), ), array( 'selector' => "$selector > .alignwide", 'declarations' => array( 'max-width' => $wide_max_width_value ), ), array( 'selector' => "$selector .alignfull", 'declarations' => array( 'max-width' => 'none' ), ) ); } if ( isset( $block_spacing ) ) { $block_spacing_values = wp_style_engine_get_styles( array( 'spacing' => $block_spacing, ) ); if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) { $padding_right = $block_spacing_values['declarations']['padding-right']; if ( '0' === $padding_right ) { $padding_right = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-right' => "calc($padding_right * -1)" ), ); } if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) { $padding_left = $block_spacing_values['declarations']['padding-left']; if ( '0' === $padding_left ) { $padding_left = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-left' => "calc($padding_left * -1)" ), ); } } if ( 'left' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-left' => '0 !important' ), ); } if ( 'right' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-right' => '0 !important' ), ); } if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'flex' === $layout_type ) { $layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal'; $justify_content_options = array( 'left' => 'flex-start', 'right' => 'flex-end', 'center' => 'center', ); $vertical_alignment_options = array( 'top' => 'flex-start', 'center' => 'center', 'bottom' => 'flex-end', ); if ( 'horizontal' === $layout_orientation ) { $justify_content_options += array( 'space-between' => 'space-between' ); $vertical_alignment_options += array( 'stretch' => 'stretch' ); } else { $justify_content_options += array( 'stretch' => 'stretch' ); $vertical_alignment_options += array( 'space-between' => 'space-between' ); } if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-wrap' => 'nowrap' ), ); } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { $process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value; } if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); if ( null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } if ( 'horizontal' === $layout_orientation ) { if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-direction' => 'column' ), ); if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] ), ); } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => 'flex-start' ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } } elseif ( 'grid' === $layout_type ) { if ( ! empty( $layout['columnCount'] ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(' . $layout['columnCount'] . ', minmax(0, 1fr))' ), ); } else { $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))', 'container-type' => 'inline-size', ), ); } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { $process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value; } if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); if ( null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } } if ( ! empty( $layout_styles ) ) { return wp_style_engine_get_stylesheet_from_css_rules( $layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); } return ''; } function wp_render_layout_support_flag( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_supports_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); $child_layout = isset( $block['attrs']['style']['layout'] ) ? $block['attrs']['style']['layout'] : null; if ( ! $block_supports_layout && ! $child_layout ) { return $block_content; } $outer_class_names = array(); if ( $child_layout ) { $container_content_class = wp_unique_id_from_values( array( 'layout' => array_intersect_key( $block['attrs']['style']['layout'] ?? array(), array_flip( array( 'selfStretch', 'flexSize', 'columnStart', 'columnSpan', 'rowStart', 'rowSpan' ) ) ), 'parentLayout' => array_intersect_key( $block['parentLayout'] ?? array(), array_flip( array( 'minimumColumnWidth', 'columnCount' ) ) ), ), 'wp-container-content-' ); $child_layout_declarations = array(); $child_layout_styles = array(); $self_stretch = isset( $child_layout['selfStretch'] ) ? $child_layout['selfStretch'] : null; if ( 'fixed' === $self_stretch && isset( $child_layout['flexSize'] ) ) { $child_layout_declarations['flex-basis'] = $child_layout['flexSize']; $child_layout_declarations['box-sizing'] = 'border-box'; } elseif ( 'fill' === $self_stretch ) { $child_layout_declarations['flex-grow'] = '1'; } if ( isset( $child_layout['columnSpan'] ) ) { $column_span = $child_layout['columnSpan']; $child_layout_declarations['grid-column'] = "span $column_span"; } if ( isset( $child_layout['rowSpan'] ) ) { $row_span = $child_layout['rowSpan']; $child_layout_declarations['grid-row'] = "span $row_span"; } $child_layout_styles[] = array( 'selector' => ".$container_content_class", 'declarations' => $child_layout_declarations, ); if ( isset( $child_layout['columnSpan'] ) && ( isset( $block['parentLayout']['minimumColumnWidth'] ) || ! isset( $block['parentLayout']['columnCount'] ) ) ) { $column_span_number = floatval( $child_layout['columnSpan'] ); $parent_column_width = isset( $block['parentLayout']['minimumColumnWidth'] ) ? $block['parentLayout']['minimumColumnWidth'] : '12rem'; $parent_column_value = floatval( $parent_column_width ); $parent_column_unit = explode( $parent_column_value, $parent_column_width ); if ( count( $parent_column_unit ) <= 1 ) { $parent_column_unit = 'rem'; $parent_column_value = 12; } else { $parent_column_unit = $parent_column_unit[1]; if ( ! in_array( $parent_column_unit, array( 'px', 'rem', 'em' ), true ) ) { $parent_column_unit = 'rem'; } } $default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5; $container_query_value = $column_span_number * $parent_column_value + ( $column_span_number - 1 ) * $default_gap_value; $container_query_value = $container_query_value . $parent_column_unit; $child_layout_styles[] = array( 'rules_group' => "@container (max-width: $container_query_value )", 'selector' => ".$container_content_class", 'declarations' => array( 'grid-column' => '1/-1', ), ); } $child_css = wp_style_engine_get_stylesheet_from_css_rules( $child_layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); if ( $child_css ) { $outer_class_names[] = $container_content_class; } } $processor = new WP_HTML_Tag_Processor( $block_content ); if ( ! $processor->next_tag() ) { return $block_content; } if ( ! $block_supports_layout && ! empty( $outer_class_names ) ) { foreach ( $outer_class_names as $class_name ) { $processor->add_class( $class_name ); } return $processor->get_updated_html(); } elseif ( ! $block_supports_layout ) { return $block_content; } $global_settings = wp_get_global_settings(); $fallback_layout = isset( $block_type->supports['layout']['default'] ) ? $block_type->supports['layout']['default'] : array(); if ( empty( $fallback_layout ) ) { $fallback_layout = isset( $block_type->supports['__experimentalLayout']['default'] ) ? $block_type->supports['__experimentalLayout']['default'] : array(); } $used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $fallback_layout; $class_names = array(); $layout_definitions = wp_get_layout_definitions(); if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) { $used_layout['type'] = 'constrained'; } $root_padding_aware_alignments = isset( $global_settings['useRootPaddingAwareAlignments'] ) ? $global_settings['useRootPaddingAwareAlignments'] : false; if ( $root_padding_aware_alignments && isset( $used_layout['type'] ) && 'constrained' === $used_layout['type'] ) { $class_names[] = 'has-global-padding'; } if ( ! empty( $block['attrs']['layout']['orientation'] ) ) { $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] ); } if ( ! empty( $block['attrs']['layout']['justifyContent'] ) ) { $class_names[] = 'is-content-justification-' . sanitize_title( $block['attrs']['layout']['justifyContent'] ); } if ( ! empty( $block['attrs']['layout']['flexWrap'] ) && 'nowrap' === $block['attrs']['layout']['flexWrap'] ) { $class_names[] = 'is-nowrap'; } if ( isset( $used_layout['type'] ) ) { $layout_classname = isset( $layout_definitions[ $used_layout['type'] ]['className'] ) ? $layout_definitions[ $used_layout['type'] ]['className'] : ''; } else { $layout_classname = isset( $layout_definitions['default']['className'] ) ? $layout_definitions['default']['className'] : ''; } if ( $layout_classname && is_string( $layout_classname ) ) { $class_names[] = sanitize_title( $layout_classname ); } if ( ! current_theme_supports( 'disable-layout-styles' ) ) { $gap_value = isset( $block['attrs']['style']['spacing']['blockGap'] ) ? $block['attrs']['style']['spacing']['blockGap'] : null; if ( is_array( $gap_value ) ) { foreach ( $gap_value as $key => $value ) { $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; } } else { $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; } $fallback_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) ? $block_type->supports['spacing']['blockGap']['__experimentalDefault'] : '0.5em'; $block_spacing = isset( $block['attrs']['style']['spacing'] ) ? $block['attrs']['style']['spacing'] : null; $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); $block_gap = isset( $global_settings['spacing']['blockGap'] ) ? $global_settings['spacing']['blockGap'] : null; $has_block_gap_support = isset( $block_gap ); $container_class = wp_unique_id_from_values( array( $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing, ), 'wp-container-' . sanitize_title( $block['blockName'] ) . '-is-layout-' ); $style = wp_get_layout_style( ".$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing ); if ( ! empty( $style ) ) { $class_names[] = $container_class; } } $split_block_name = explode( '/', $block['blockName'] ); $full_block_name = 'core' === $split_block_name[0] ? end( $split_block_name ) : implode( '-', $split_block_name ); $class_names[] = 'wp-block-' . $full_block_name . '-' . $layout_classname; if ( ! empty( $outer_class_names ) ) { foreach ( $outer_class_names as $outer_class_name ) { $processor->add_class( $outer_class_name ); } } $inner_block_wrapper_classes = null; $first_chunk = isset( $block['innerContent'][0] ) ? $block['innerContent'][0] : null; if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) { $first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk ); while ( $first_chunk_processor->next_tag() ) { $class_attribute = $first_chunk_processor->get_attribute( 'class' ); if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) { $inner_block_wrapper_classes = $class_attribute; } } } do { if ( ! $inner_block_wrapper_classes ) { break; } $class_attribute = $processor->get_attribute( 'class' ); if ( is_string( $class_attribute ) && str_contains( $class_attribute, $inner_block_wrapper_classes ) ) { break; } } while ( $processor->next_tag() ); foreach ( $class_names as $class_name ) { $processor->add_class( $class_name ); } return $processor->get_updated_html(); } function wp_add_parent_layout_to_parsed_block( $parsed_block, $source_block, $parent_block ) { if ( $parent_block && isset( $parent_block->parsed_block['attrs']['layout'] ) ) { $parsed_block['parentLayout'] = $parent_block->parsed_block['attrs']['layout']; } return $parsed_block; } add_filter( 'render_block_data', 'wp_add_parent_layout_to_parsed_block', 10, 3 ); WP_Block_Supports::get_instance()->register( 'layout', array( 'register_attribute' => 'wp_register_layout_support', ) ); add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 ); function wp_restore_group_inner_container( $block_content, $block ) { $tag_name = isset( $block['attrs']['tagName'] ) ? $block['attrs']['tagName'] : 'div'; $group_with_inner_container_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/U', preg_quote( $tag_name, '/' ) ); if ( wp_theme_has_theme_json() || 1 === preg_match( $group_with_inner_container_regex, $block_content ) || ( isset( $block['attrs']['layout']['type'] ) && ( 'flex' === $block['attrs']['layout']['type'] || 'grid' === $block['attrs']['layout']['type'] ) ) ) { return $block_content; } $layout_classes = array(); $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group' ) ) ) { foreach ( $processor->class_list() as $class_name ) { if ( str_contains( $class_name, 'is-layout-' ) ) { $layout_classes[] = $class_name; $processor->remove_class( $class_name ); } } } $content_without_layout_classes = $processor->get_updated_html(); $replace_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group[^>]*>)(.*)(<\/%1$s>\s*$)/ms', preg_quote( $tag_name, '/' ) ); $updated_content = preg_replace_callback( $replace_regex, static function ( $matches ) { return $matches[1] . '<div class="wp-block-group__inner-container">' . $matches[2] . '</div>' . $matches[3]; }, $content_without_layout_classes ); if ( ! empty( $layout_classes ) ) { $processor = new WP_HTML_Tag_Processor( $updated_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group__inner-container' ) ) ) { foreach ( $layout_classes as $class_name ) { $processor->add_class( $class_name ); } } $updated_content = $processor->get_updated_html(); } return $updated_content; } add_filter( 'render_block_core/group', 'wp_restore_group_inner_container', 10, 2 ); function wp_restore_image_outer_container( $block_content, $block ) { if ( wp_theme_has_theme_json() ) { return $block_content; } $figure_processor = new WP_HTML_Tag_Processor( $block_content ); if ( ! $figure_processor->next_tag( 'FIGURE' ) || ! $figure_processor->has_class( 'wp-block-image' ) || ! ( $figure_processor->has_class( 'alignleft' ) || $figure_processor->has_class( 'aligncenter' ) || $figure_processor->has_class( 'alignright' ) ) ) { return $block_content; } $wrapper_processor = new WP_HTML_Tag_Processor( '<div>' ); $wrapper_processor->next_token(); $wrapper_processor->set_attribute( 'class', is_string( $block['attrs']['className'] ?? null ) ? "wp-block-image {$block['attrs']['className']}" : 'wp-block-image' ); $figure_processor->remove_class( 'wp-block-image' ); foreach ( $wrapper_processor->class_list() as $class_name ) { $figure_processor->remove_class( $class_name ); } return "{$wrapper_processor->get_updated_html()}{$figure_processor->get_updated_html()}</div>"; } add_filter( 'render_block_core/image', 'wp_restore_image_outer_container', 10, 2 );
###require ABSPATH . WPINC . '/block-supports/position.php';
function wp_register_position_support( $block_type ) { $has_position_support = block_has_support( $block_type, 'position', false ); if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_position_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } function wp_render_position_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $has_position_support = block_has_support( $block_type, 'position', false ); if ( ! $has_position_support || empty( $block['attrs']['style']['position'] ) ) { return $block_content; } $global_settings = wp_get_global_settings(); $theme_has_sticky_support = isset( $global_settings['position']['sticky'] ) ? $global_settings['position']['sticky'] : false; $theme_has_fixed_support = isset( $global_settings['position']['fixed'] ) ? $global_settings['position']['fixed'] : false; $allowed_position_types = array(); if ( true === $theme_has_sticky_support ) { $allowed_position_types[] = 'sticky'; } if ( true === $theme_has_fixed_support ) { $allowed_position_types[] = 'fixed'; } $style_attribute = isset( $block['attrs']['style'] ) ? $block['attrs']['style'] : null; $class_name = wp_unique_id( 'wp-container-' ); $selector = ".$class_name"; $position_styles = array(); $position_type = isset( $style_attribute['position']['type'] ) ? $style_attribute['position']['type'] : ''; $wrapper_classes = array(); if ( in_array( $position_type, $allowed_position_types, true ) ) { $wrapper_classes[] = $class_name; $wrapper_classes[] = 'is-position-' . $position_type; $sides = array( 'top', 'right', 'bottom', 'left' ); foreach ( $sides as $side ) { $side_value = isset( $style_attribute['position'][ $side ] ) ? $style_attribute['position'][ $side ] : null; if ( null !== $side_value ) { if ( 'top' === $side && ( 'fixed' === $position_type || 'sticky' === $position_type ) ) { if ( '0' === $side_value || 0 === $side_value ) { $side_value = '0px'; } $side_value = "calc($side_value + var(--wp-admin--admin-bar--position-offset, 0px))"; } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( $side => $side_value, ), ); } } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( 'position' => $position_type, 'z-index' => '10', ), ); } if ( ! empty( $position_styles ) ) { wp_style_engine_get_stylesheet_from_css_rules( $position_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); $content = new WP_HTML_Tag_Processor( $block_content ); $content->next_tag(); foreach ( $wrapper_classes as $class ) { $content->add_class( $class ); } return (string) $content; } return $block_content; } WP_Block_Supports::get_instance()->register( 'position', array( 'register_attribute' => 'wp_register_position_support', ) ); add_filter( 'render_block', 'wp_render_position_support', 10, 2 );
###require ABSPATH . WPINC . '/block-supports/spacing.php';
function wp_register_spacing_support( $block_type ) { $has_spacing_support = block_has_support( $block_type, 'spacing', false ); if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_spacing_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } function wp_apply_spacing_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'spacing' ) ) { return array(); } $attributes = array(); $has_padding_support = block_has_support( $block_type, array( 'spacing', 'padding' ), false ); $has_margin_support = block_has_support( $block_type, array( 'spacing', 'margin' ), false ); $block_styles = isset( $block_attributes['style'] ) ? $block_attributes['style'] : null; if ( ! $block_styles ) { return $attributes; } $skip_padding = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'padding' ); $skip_margin = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'margin' ); $spacing_block_styles = array( 'padding' => null, 'margin' => null, ); if ( $has_padding_support && ! $skip_padding ) { $spacing_block_styles['padding'] = isset( $block_styles['spacing']['padding'] ) ? $block_styles['spacing']['padding'] : null; } if ( $has_margin_support && ! $skip_margin ) { $spacing_block_styles['margin'] = isset( $block_styles['spacing']['margin'] ) ? $block_styles['spacing']['margin'] : null; } $styles = wp_style_engine_get_styles( array( 'spacing' => $spacing_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } WP_Block_Supports::get_instance()->register( 'spacing', array( 'register_attribute' => 'wp_register_spacing_support', 'apply' => 'wp_apply_spacing_support', ) );
###require ABSPATH . WPINC . '/block-supports/dimensions.php';
function wp_register_dimensions_support( $block_type ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_dimensions_support = block_has_support( $block_type, 'dimensions', false ); if ( $has_dimensions_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } function wp_apply_dimensions_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) { return array(); } $attributes = array(); $has_min_height_support = block_has_support( $block_type, array( 'dimensions', 'minHeight' ), false ); $block_styles = isset( $block_attributes['style'] ) ? $block_attributes['style'] : null; if ( ! $block_styles ) { return $attributes; } $skip_min_height = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'minHeight' ); $dimensions_block_styles = array(); $dimensions_block_styles['minHeight'] = null; if ( $has_min_height_support && ! $skip_min_height ) { $dimensions_block_styles['minHeight'] = isset( $block_styles['dimensions']['minHeight'] ) ? $block_styles['dimensions']['minHeight'] : null; } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } function wp_render_dimensions_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_aspect_ratio_support = block_has_support( $block_type, array( 'dimensions', 'aspectRatio' ), false ); if ( ! $has_aspect_ratio_support || wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'aspectRatio' ) ) { return $block_content; } $dimensions_block_styles = array(); $dimensions_block_styles['aspectRatio'] = $block_attributes['style']['dimensions']['aspectRatio'] ?? null; if ( isset( $dimensions_block_styles['aspectRatio'] ) ) { $dimensions_block_styles['minHeight'] = 'unset'; } elseif ( isset( $block_attributes['style']['dimensions']['minHeight'] ) || isset( $block_attributes['minHeight'] ) ) { $dimensions_block_styles['aspectRatio'] = 'unset'; } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); $updated_style = ''; if ( ! empty( $existing_style ) ) { $updated_style = $existing_style; if ( ! str_ends_with( $existing_style, ';' ) ) { $updated_style .= ';'; } } $updated_style .= $styles['css']; $tags->set_attribute( 'style', $updated_style ); if ( ! empty( $styles['classnames'] ) ) { foreach ( explode( ' ', $styles['classnames'] ) as $class_name ) { if ( str_contains( $class_name, 'aspect-ratio' ) && ! isset( $block_attributes['style']['dimensions']['aspectRatio'] ) ) { continue; } $tags->add_class( $class_name ); } } } return $tags->get_updated_html(); } return $block_content; } add_filter( 'render_block', 'wp_render_dimensions_support', 10, 2 ); WP_Block_Supports::get_instance()->register( 'dimensions', array( 'register_attribute' => 'wp_register_dimensions_support', 'apply' => 'wp_apply_dimensions_support', ) );
###require ABSPATH . WPINC . '/block-supports/duotone.php';
WP_Block_Supports::get_instance()->register( 'duotone', array( 'register_attribute' => array( 'WP_Duotone', 'register_duotone_support' ), ) ); add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 3 ); add_filter( 'render_block_core/image', array( 'WP_Duotone', 'restore_image_outer_container' ), 10, 1 ); add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_block_styles' ), 9 ); add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_global_styles' ), 11 ); add_action( 'wp_footer', array( 'WP_Duotone', 'output_footer_assets' ), 10 ); add_filter( 'block_editor_settings_all', array( 'WP_Duotone', 'add_editor_settings' ), 10 ); add_filter( 'block_type_metadata_settings', array( 'WP_Duotone', 'migrate_experimental_duotone_support_flag' ), 10, 2 );
###require ABSPATH . WPINC . '/block-supports/shadow.php';
function wp_register_shadow_support( $block_type ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( array_key_exists( 'shadow', $block_type->attributes ) ) { $block_type->attributes['shadow'] = array( 'type' => 'string', ); } } function wp_apply_shadow_support( $block_type, $block_attributes ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support || wp_should_skip_block_supports_serialization( $block_type, 'shadow' ) ) { return array(); } $shadow_block_styles = array(); $custom_shadow = $block_attributes['style']['shadow'] ?? null; $shadow_block_styles['shadow'] = $custom_shadow; $attributes = array(); $styles = wp_style_engine_get_styles( $shadow_block_styles ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } WP_Block_Supports::get_instance()->register( 'shadow', array( 'register_attribute' => 'wp_register_shadow_support', 'apply' => 'wp_apply_shadow_support', ) );
###require ABSPATH . WPINC . '/block-supports/background.php';
function wp_register_background_support( $block_type ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_background_support = block_has_support( $block_type, array( 'background' ), false ); if ( $has_background_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } function wp_render_background_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_background_image_support = block_has_support( $block_type, array( 'background', 'backgroundImage' ), false ); if ( ! $has_background_image_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundImage' ) || ! isset( $block_attributes['style']['background'] ) ) { return $block_content; } $background_styles = array(); $background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null; $background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null; $background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null; $background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null; $background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null; if ( ! empty( $background_styles['backgroundImage'] ) ) { $background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover'; if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) { $background_styles['backgroundPosition'] = '50% 50%'; } } $styles = wp_style_engine_get_styles( array( 'background' => $background_styles ) ); if ( ! empty( $styles['css'] ) ) { $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); if ( is_string( $existing_style ) && '' !== $existing_style ) { $separator = str_ends_with( $existing_style, ';' ) ? '' : ';'; $updated_style = "{$existing_style}{$separator}{$styles['css']}"; } else { $updated_style = $styles['css']; } $tags->set_attribute( 'style', $updated_style ); $tags->add_class( 'has-background' ); } return $tags->get_updated_html(); } return $block_content; } WP_Block_Supports::get_instance()->register( 'background', array( 'register_attribute' => 'wp_register_background_support', ) ); add_filter( 'render_block', 'wp_render_background_support', 10, 2 );
###require ABSPATH . WPINC . '/block-supports/block-style-variations.php';
function wp_get_block_style_variation_name_from_class( $class_string ) { if ( ! is_string( $class_string ) ) { return null; } preg_match_all( '/\bis-style-(?!default)(\S+)\b/', $class_string, $matches ); return $matches[1] ?? null; } function wp_resolve_block_style_variation_ref_values( &$variation_data, $theme_json ) { foreach ( $variation_data as $key => &$value ) { if ( is_array( $value ) ) { if ( array_key_exists( 'ref', $value ) ) { if ( empty( $value['ref'] ) || ! is_string( $value['ref'] ) ) { unset( $variation_data[ $key ] ); } $value_path = explode( '.', $value['ref'] ?? '' ); $ref_value = _wp_array_get( $theme_json, $value_path ); if ( null === $ref_value ) { unset( $variation_data[ $key ] ); } else { $value = $ref_value; } } else { wp_resolve_block_style_variation_ref_values( $value, $theme_json ); } } } } function wp_render_block_style_variation_support_styles( $parsed_block ) { $classes = $parsed_block['attrs']['className'] ?? null; $variations = wp_get_block_style_variation_name_from_class( $classes ); if ( ! $variations ) { return $parsed_block; } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $theme_json = $tree->get_raw_data(); $variation_data = array(); foreach ( $variations as $variation ) { $variation_data = $theme_json['styles']['blocks'][ $parsed_block['blockName'] ]['variations'][ $variation ] ?? array(); if ( ! empty( $variation_data ) ) { break; } } if ( empty( $variation_data ) ) { return $parsed_block; } wp_resolve_block_style_variation_ref_values( $variation_data, $theme_json ); $variation_instance = wp_unique_id( $variation . '--' ); $class_name = "is-style-$variation_instance"; $updated_class_name = $parsed_block['attrs']['className'] . " $class_name"; $elements_data = $variation_data['elements'] ?? array(); $blocks_data = $variation_data['blocks'] ?? array(); unset( $variation_data['elements'] ); unset( $variation_data['blocks'] ); _wp_array_set( $blocks_data, array( $parsed_block['blockName'], 'variations', $variation_instance ), $variation_data ); $config = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'styles' => array( 'elements' => $elements_data, 'blocks' => $blocks_data, ), ); if ( ! is_admin() ) { remove_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } $styles_registry = WP_Block_Styles_Registry::get_instance(); $styles_registry->register( $parsed_block['blockName'], array( 'name' => $variation_instance ) ); $variation_theme_json = new WP_Theme_JSON( $config, 'blocks' ); $variation_styles = $variation_theme_json->get_stylesheet( array( 'styles' ), array( 'custom' ), array( 'include_block_style_variations' => true, 'skip_root_layout_styles' => true, 'scope' => ".$class_name", ) ); $styles_registry->unregister( $parsed_block['blockName'], $variation_instance ); if ( ! is_admin() ) { add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } if ( empty( $variation_styles ) ) { return $parsed_block; } wp_register_style( 'block-style-variation-styles', false, array( 'wp-block-library', 'global-styles' ) ); wp_add_inline_style( 'block-style-variation-styles', $variation_styles ); _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); return $parsed_block; } function wp_render_block_style_variation_class_name( $block_content, $block ) { if ( ! $block_content || empty( $block['attrs']['className'] ) ) { return $block_content; } preg_match( '/\bis-style-(\S+?--\d+)\b/', $block['attrs']['className'], $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } function wp_enqueue_block_style_variation_styles() { wp_enqueue_style( 'block-style-variation-styles' ); } WP_Block_Supports::get_instance()->register( 'block-style-variation', array() ); add_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles', 10, 2 ); add_filter( 'render_block', 'wp_render_block_style_variation_class_name', 10, 2 ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles', 1 ); function wp_register_block_style_variations_from_theme_json_partials( $variations ) { if ( empty( $variations ) ) { return; } $registry = WP_Block_Styles_Registry::get_instance(); foreach ( $variations as $variation ) { if ( empty( $variation['blockTypes'] ) || empty( $variation['styles'] ) ) { continue; } $variation_name = $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ); $variation_label = $variation['title'] ?? $variation_name; foreach ( $variation['blockTypes'] as $block_type ) { $registered_styles = $registry->get_registered_styles_for_block( $block_type ); if ( ! array_key_exists( $variation_name, $registered_styles ) ) { register_block_style( $block_type, array( 'name' => $variation_name, 'label' => $variation_label, ) ); } } } }
###require ABSPATH . WPINC . '/block-supports/aria-label.php';
function wp_register_aria_label_support( $block_type ) { $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'ariaLabel', $block_type->attributes ) ) { $block_type->attributes['ariaLabel'] = array( 'type' => 'string', ); } } function wp_apply_aria_label_support( $block_type, $block_attributes ) { if ( ! $block_attributes ) { return array(); } $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support ) { return array(); } $has_aria_label = array_key_exists( 'ariaLabel', $block_attributes ); if ( ! $has_aria_label ) { return array(); } return array( 'aria-label' => $block_attributes['ariaLabel'] ); } WP_Block_Supports::get_instance()->register( 'aria-label', array( 'register_attribute' => 'wp_register_aria_label_support', 'apply' => 'wp_apply_aria_label_support', ) );
###require ABSPATH . WPINC . '/block-supports/block-visibility.php';
function wp_render_block_visibility_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! $block_type || ! block_has_support( $block_type, 'visibility', true ) ) { return $block_content; } if ( isset( $block['attrs']['metadata']['blockVisibility'] ) && false === $block['attrs']['metadata']['blockVisibility'] ) { return ''; } return $block_content; } add_filter( 'render_block', 'wp_render_block_visibility_support', 10, 2 );
###require ABSPATH . WPINC . '/style-engine.php';
function wp_style_engine_get_styles( $block_styles, $options = array() ) { $options = wp_parse_args( $options, array( 'selector' => null, 'context' => null, 'convert_vars_to_classnames' => false, ) ); $parsed_styles = WP_Style_Engine::parse_block_styles( $block_styles, $options ); $styles_output = array(); if ( ! empty( $parsed_styles['declarations'] ) ) { $styles_output['css'] = WP_Style_Engine::compile_css( $parsed_styles['declarations'], $options['selector'] ); $styles_output['declarations'] = $parsed_styles['declarations']; if ( ! empty( $options['context'] ) ) { WP_Style_Engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] ); } } if ( ! empty( $parsed_styles['classnames'] ) ) { $styles_output['classnames'] = implode( ' ', array_unique( $parsed_styles['classnames'] ) ); } return array_filter( $styles_output ); } function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = array() ) { if ( empty( $css_rules ) ) { return ''; } $options = wp_parse_args( $options, array( 'context' => null, ) ); $css_rule_objects = array(); foreach ( $css_rules as $css_rule ) { if ( empty( $css_rule['selector'] ) || empty( $css_rule['declarations'] ) || ! is_array( $css_rule['declarations'] ) ) { continue; } $rules_group = $css_rule['rules_group'] ?? null; if ( ! empty( $options['context'] ) ) { WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'], $rules_group ); } $css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'], $rules_group ); } if ( empty( $css_rule_objects ) ) { return ''; } return WP_Style_Engine::compile_stylesheet_from_css_rules( $css_rule_objects, $options ); } function wp_style_engine_get_stylesheet_from_context( $context, $options = array() ) { return WP_Style_Engine::compile_stylesheet_from_css_rules( WP_Style_Engine::get_store( $context )->get_all_rules(), $options ); }
###require ABSPATH . WPINC . '/style-engine/class-wp-style-engine.php';
final class WP_Style_Engine { const BLOCK_STYLE_DEFINITIONS_METADATA = array( 'background' => array( 'backgroundImage' => array( 'property_keys' => array( 'default' => 'background-image', ), 'value_func' => array( self::class, 'get_url_or_value_css_declaration' ), 'path' => array( 'background', 'backgroundImage' ), ), 'backgroundPosition' => array( 'property_keys' => array( 'default' => 'background-position', ), 'path' => array( 'background', 'backgroundPosition' ), ), 'backgroundRepeat' => array( 'property_keys' => array( 'default' => 'background-repeat', ), 'path' => array( 'background', 'backgroundRepeat' ), ), 'backgroundSize' => array( 'property_keys' => array( 'default' => 'background-size', ), 'path' => array( 'background', 'backgroundSize' ), ), 'backgroundAttachment' => array( 'property_keys' => array( 'default' => 'background-attachment', ), 'path' => array( 'background', 'backgroundAttachment' ), ), ), 'color' => array( 'text' => array( 'property_keys' => array( 'default' => 'color', ), 'path' => array( 'color', 'text' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), 'classnames' => array( 'has-text-color' => true, 'has-$slug-color' => 'color', ), ), 'background' => array( 'property_keys' => array( 'default' => 'background-color', ), 'path' => array( 'color', 'background' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), 'classnames' => array( 'has-background' => true, 'has-$slug-background-color' => 'color', ), ), 'gradient' => array( 'property_keys' => array( 'default' => 'background', ), 'path' => array( 'color', 'gradient' ), 'css_vars' => array( 'gradient' => '--wp--preset--gradient--$slug', ), 'classnames' => array( 'has-background' => true, 'has-$slug-gradient-background' => 'gradient', ), ), ), 'border' => array( 'color' => array( 'property_keys' => array( 'default' => 'border-color', 'individual' => 'border-%s-color', ), 'path' => array( 'border', 'color' ), 'classnames' => array( 'has-border-color' => true, 'has-$slug-border-color' => 'color', ), ), 'radius' => array( 'property_keys' => array( 'default' => 'border-radius', 'individual' => 'border-%s-radius', ), 'path' => array( 'border', 'radius' ), 'css_vars' => array( 'border-radius' => '--wp--preset--border-radius--$slug', ), ), 'style' => array( 'property_keys' => array( 'default' => 'border-style', 'individual' => 'border-%s-style', ), 'path' => array( 'border', 'style' ), ), 'width' => array( 'property_keys' => array( 'default' => 'border-width', 'individual' => 'border-%s-width', ), 'path' => array( 'border', 'width' ), ), 'top' => array( 'value_func' => array( self::class, 'get_individual_property_css_declarations' ), 'path' => array( 'border', 'top' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), ), 'right' => array( 'value_func' => array( self::class, 'get_individual_property_css_declarations' ), 'path' => array( 'border', 'right' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), ), 'bottom' => array( 'value_func' => array( self::class, 'get_individual_property_css_declarations' ), 'path' => array( 'border', 'bottom' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), ), 'left' => array( 'value_func' => array( self::class, 'get_individual_property_css_declarations' ), 'path' => array( 'border', 'left' ), 'css_vars' => array( 'color' => '--wp--preset--color--$slug', ), ), ), 'shadow' => array( 'shadow' => array( 'property_keys' => array( 'default' => 'box-shadow', ), 'path' => array( 'shadow' ), 'css_vars' => array( 'shadow' => '--wp--preset--shadow--$slug', ), ), ), 'dimensions' => array( 'aspectRatio' => array( 'property_keys' => array( 'default' => 'aspect-ratio', ), 'path' => array( 'dimensions', 'aspectRatio' ), 'classnames' => array( 'has-aspect-ratio' => true, ), ), 'minHeight' => array( 'property_keys' => array( 'default' => 'min-height', ), 'path' => array( 'dimensions', 'minHeight' ), 'css_vars' => array( 'spacing' => '--wp--preset--spacing--$slug', ), ), ), 'spacing' => array( 'padding' => array( 'property_keys' => array( 'default' => 'padding', 'individual' => 'padding-%s', ), 'path' => array( 'spacing', 'padding' ), 'css_vars' => array( 'spacing' => '--wp--preset--spacing--$slug', ), ), 'margin' => array( 'property_keys' => array( 'default' => 'margin', 'individual' => 'margin-%s', ), 'path' => array( 'spacing', 'margin' ), 'css_vars' => array( 'spacing' => '--wp--preset--spacing--$slug', ), ), ), 'typography' => array( 'fontSize' => array( 'property_keys' => array( 'default' => 'font-size', ), 'path' => array( 'typography', 'fontSize' ), 'css_vars' => array( 'font-size' => '--wp--preset--font-size--$slug', ), 'classnames' => array( 'has-$slug-font-size' => 'font-size', ), ), 'fontFamily' => array( 'property_keys' => array( 'default' => 'font-family', ), 'css_vars' => array( 'font-family' => '--wp--preset--font-family--$slug', ), 'path' => array( 'typography', 'fontFamily' ), 'classnames' => array( 'has-$slug-font-family' => 'font-family', ), ), 'fontStyle' => array( 'property_keys' => array( 'default' => 'font-style', ), 'path' => array( 'typography', 'fontStyle' ), ), 'fontWeight' => array( 'property_keys' => array( 'default' => 'font-weight', ), 'path' => array( 'typography', 'fontWeight' ), ), 'lineHeight' => array( 'property_keys' => array( 'default' => 'line-height', ), 'path' => array( 'typography', 'lineHeight' ), ), 'textColumns' => array( 'property_keys' => array( 'default' => 'column-count', ), 'path' => array( 'typography', 'textColumns' ), ), 'textDecoration' => array( 'property_keys' => array( 'default' => 'text-decoration', ), 'path' => array( 'typography', 'textDecoration' ), ), 'textTransform' => array( 'property_keys' => array( 'default' => 'text-transform', ), 'path' => array( 'typography', 'textTransform' ), ), 'letterSpacing' => array( 'property_keys' => array( 'default' => 'letter-spacing', ), 'path' => array( 'typography', 'letterSpacing' ), ), 'writingMode' => array( 'property_keys' => array( 'default' => 'writing-mode', ), 'path' => array( 'typography', 'writingMode' ), ), ), ); protected static function get_slug_from_preset_value( $style_value, $property_key ) { if ( is_string( $style_value ) && is_string( $property_key ) && str_contains( $style_value, "var:preset|{$property_key}|" ) ) { $index_to_splice = strrpos( $style_value, '|' ) + 1; return _wp_to_kebab_case( substr( $style_value, $index_to_splice ) ); } return ''; } protected static function get_css_var_value( $style_value, $css_vars ) { foreach ( $css_vars as $property_key => $css_var_pattern ) { $slug = static::get_slug_from_preset_value( $style_value, $property_key ); if ( static::is_valid_style_value( $slug ) ) { $var = strtr( $css_var_pattern, array( '$slug' => $slug ) ); return "var($var)"; } } return ''; } protected static function is_valid_style_value( $style_value ) { return '0' === $style_value || ! empty( $style_value ); } public static function store_css_rule( $store_name, $css_selector, $css_declarations, $rules_group = '' ) { if ( empty( $store_name ) || empty( $css_selector ) || empty( $css_declarations ) ) { return; } static::get_store( $store_name )->add_rule( $css_selector, $rules_group )->add_declarations( $css_declarations ); } public static function get_store( $store_name ) { return WP_Style_Engine_CSS_Rules_Store::get_store( $store_name ); } public static function parse_block_styles( $block_styles, $options ) { $parsed_styles = array( 'classnames' => array(), 'declarations' => array(), ); if ( empty( $block_styles ) || ! is_array( $block_styles ) ) { return $parsed_styles; } foreach ( static::BLOCK_STYLE_DEFINITIONS_METADATA as $definition_group_key => $definition_group_style ) { if ( empty( $block_styles[ $definition_group_key ] ) ) { continue; } foreach ( $definition_group_style as $style_definition ) { $style_value = _wp_array_get( $block_styles, $style_definition['path'], null ); if ( ! static::is_valid_style_value( $style_value ) ) { continue; } $classnames = static::get_classnames( $style_value, $style_definition ); if ( ! empty( $classnames ) ) { $parsed_styles['classnames'] = array_merge( $parsed_styles['classnames'], $classnames ); } $css_declarations = static::get_css_declarations( $style_value, $style_definition, $options ); if ( ! empty( $css_declarations ) ) { $parsed_styles['declarations'] = array_merge( $parsed_styles['declarations'], $css_declarations ); } } } return $parsed_styles; } protected static function get_classnames( $style_value, $style_definition ) { if ( empty( $style_value ) ) { return array(); } $classnames = array(); if ( ! empty( $style_definition['classnames'] ) ) { foreach ( $style_definition['classnames'] as $classname => $property_key ) { if ( true === $property_key ) { $classnames[] = $classname; continue; } $slug = static::get_slug_from_preset_value( $style_value, $property_key ); if ( $slug ) { $classnames[] = strtr( $classname, array( '$slug' => $slug ) ); } } } return $classnames; } protected static function get_css_declarations( $style_value, $style_definition, $options = array() ) { if ( isset( $style_definition['value_func'] ) && is_callable( $style_definition['value_func'] ) ) { return call_user_func( $style_definition['value_func'], $style_value, $style_definition, $options ); } $css_declarations = array(); $style_property_keys = $style_definition['property_keys']; $should_skip_css_vars = isset( $options['convert_vars_to_classnames'] ) && true === $options['convert_vars_to_classnames']; if ( is_string( $style_value ) && str_contains( $style_value, 'var:' ) ) { if ( ! $should_skip_css_vars && ! empty( $style_definition['css_vars'] ) ) { $css_var = static::get_css_var_value( $style_value, $style_definition['css_vars'] ); if ( static::is_valid_style_value( $css_var ) ) { $css_declarations[ $style_property_keys['default'] ] = $css_var; } } return $css_declarations; } if ( is_array( $style_value ) ) { if ( ! isset( $style_property_keys['individual'] ) ) { return $css_declarations; } foreach ( $style_value as $key => $value ) { if ( is_string( $value ) && str_contains( $value, 'var:' ) && ! $should_skip_css_vars && ! empty( $style_definition['css_vars'] ) ) { $value = static::get_css_var_value( $value, $style_definition['css_vars'] ); } $individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) ); if ( $individual_property && static::is_valid_style_value( $value ) ) { $css_declarations[ $individual_property ] = $value; } } return $css_declarations; } $css_declarations[ $style_property_keys['default'] ] = $style_value; return $css_declarations; } protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition, $options = array() ) { if ( ! is_array( $style_value ) || empty( $style_value ) || empty( $individual_property_definition['path'] ) ) { return array(); } $definition_group_key = $individual_property_definition['path'][0]; $individual_property_key = $individual_property_definition['path'][1]; $should_skip_css_vars = isset( $options['convert_vars_to_classnames'] ) && true === $options['convert_vars_to_classnames']; $css_declarations = array(); foreach ( $style_value as $css_property => $value ) { if ( empty( $value ) ) { continue; } $style_definition_path = array( $definition_group_key, $css_property ); $style_definition = _wp_array_get( static::BLOCK_STYLE_DEFINITIONS_METADATA, $style_definition_path, null ); if ( $style_definition && isset( $style_definition['property_keys']['individual'] ) ) { if ( is_string( $value ) && str_contains( $value, 'var:' ) && ! $should_skip_css_vars && ! empty( $individual_property_definition['css_vars'] ) ) { $value = static::get_css_var_value( $value, $individual_property_definition['css_vars'] ); } $individual_css_property = sprintf( $style_definition['property_keys']['individual'], $individual_property_key ); $css_declarations[ $individual_css_property ] = $value; } } return $css_declarations; } protected static function get_url_or_value_css_declaration( $style_value, $style_definition ) { if ( empty( $style_value ) ) { return array(); } $css_declarations = array(); if ( isset( $style_definition['property_keys']['default'] ) ) { $value = null; if ( ! empty( $style_value['url'] ) ) { $value = "url('" . $style_value['url'] . "')"; } elseif ( is_string( $style_value ) ) { $value = $style_value; } if ( null !== $value ) { $css_declarations[ $style_definition['property_keys']['default'] ] = $value; } } return $css_declarations; } public static function compile_css( $css_declarations, $css_selector ) { if ( empty( $css_declarations ) || ! is_array( $css_declarations ) ) { return ''; } if ( $css_selector ) { $css_rule = new WP_Style_Engine_CSS_Rule( $css_selector, $css_declarations ); return $css_rule->get_css(); } $css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations ); return $css_declarations->get_declarations_string(); } public static function compile_stylesheet_from_css_rules( $css_rules, $options = array() ) { $processor = new WP_Style_Engine_Processor(); $processor->add_rules( $css_rules ); return $processor->get_css( $options ); } }
###require ABSPATH . WPINC . '/style-engine/class-wp-style-engine-css-declarations.php';
class WP_Style_Engine_CSS_Declarations { protected $declarations = array(); public function __construct( $declarations = array() ) { $this->add_declarations( $declarations ); } public function add_declaration( $property, $value ) { $property = $this->sanitize_property( $property ); if ( empty( $property ) ) { return $this; } $value = trim( $value ); if ( '' === $value ) { return $this; } $this->declarations[ $property ] = $value; return $this; } public function remove_declaration( $property ) { unset( $this->declarations[ $property ] ); return $this; } public function add_declarations( $declarations ) { foreach ( $declarations as $property => $value ) { $this->add_declaration( $property, $value ); } return $this; } public function remove_declarations( $properties = array() ) { foreach ( $properties as $property ) { $this->remove_declaration( $property ); } return $this; } public function get_declarations() { return $this->declarations; } protected static function filter_declaration( $property, $value, $spacer = '' ) { $filtered_value = wp_strip_all_tags( $value, true ); if ( '' !== $filtered_value ) { return safecss_filter_attr( "{$property}:{$spacer}{$filtered_value}" ); } return ''; } public function get_declarations_string( $should_prettify = false, $indent_count = 0 ) { $declarations_array = $this->get_declarations(); $declarations_output = ''; $indent = $should_prettify ? str_repeat( "\t", $indent_count ) : ''; $suffix = $should_prettify ? ' ' : ''; $suffix = $should_prettify && $indent_count > 0 ? "\n" : $suffix; $spacer = $should_prettify ? ' ' : ''; foreach ( $declarations_array as $property => $value ) { $filtered_declaration = static::filter_declaration( $property, $value, $spacer ); if ( $filtered_declaration ) { $declarations_output .= "{$indent}{$filtered_declaration};$suffix"; } } return rtrim( $declarations_output ); } protected function sanitize_property( $property ) { return sanitize_key( $property ); } }
###require ABSPATH . WPINC . '/style-engine/class-wp-style-engine-css-rule.php';
class WP_Style_Engine_CSS_Rule { protected $selector; protected $declarations; protected $rules_group; public function __construct( $selector = '', $declarations = array(), $rules_group = '' ) { $this->set_selector( $selector ); $this->add_declarations( $declarations ); $this->set_rules_group( $rules_group ); } public function set_selector( $selector ) { $this->selector = $selector; return $this; } public function add_declarations( $declarations ) { $is_declarations_object = ! is_array( $declarations ); $declarations_array = $is_declarations_object ? $declarations->get_declarations() : $declarations; if ( null === $this->declarations ) { if ( $is_declarations_object ) { $this->declarations = $declarations; return $this; } $this->declarations = new WP_Style_Engine_CSS_Declarations( $declarations_array ); } $this->declarations->add_declarations( $declarations_array ); return $this; } public function set_rules_group( $rules_group ) { $this->rules_group = $rules_group; return $this; } public function get_rules_group() { return $this->rules_group; } public function get_declarations() { return $this->declarations; } public function get_selector() { return $this->selector; } public function get_css( $should_prettify = false, $indent_count = 0 ) { $rule_indent = $should_prettify ? str_repeat( "\t", $indent_count ) : ''; $nested_rule_indent = $should_prettify ? str_repeat( "\t", $indent_count + 1 ) : ''; $declarations_indent = $should_prettify ? $indent_count + 1 : 0; $nested_declarations_indent = $should_prettify ? $indent_count + 2 : 0; $suffix = $should_prettify ? "\n" : ''; $spacer = $should_prettify ? ' ' : ''; $selector = $should_prettify ? implode( ',', array_map( 'trim', explode( ',', $this->get_selector() ) ) ) : $this->get_selector(); $selector = $should_prettify ? str_replace( array( ',' ), ",\n", $selector ) : $selector; $rules_group = $this->get_rules_group(); $has_rules_group = ! empty( $rules_group ); $css_declarations = $this->declarations->get_declarations_string( $should_prettify, $has_rules_group ? $nested_declarations_indent : $declarations_indent ); if ( empty( $css_declarations ) ) { return ''; } if ( $has_rules_group ) { $selector = "{$rule_indent}{$rules_group}{$spacer}{{$suffix}{$nested_rule_indent}{$selector}{$spacer}{{$suffix}{$css_declarations}{$suffix}{$nested_rule_indent}}{$suffix}{$rule_indent}}"; return $selector; } return "{$rule_indent}{$selector}{$spacer}{{$suffix}{$css_declarations}{$suffix}{$rule_indent}}"; } }
###require ABSPATH . WPINC . '/style-engine/class-wp-style-engine-css-rules-store.php';
class WP_Style_Engine_CSS_Rules_Store { protected static $stores = array(); protected $name = ''; protected $rules = array(); public static function get_store( $store_name = 'default' ) { if ( ! is_string( $store_name ) || empty( $store_name ) ) { return; } if ( ! isset( static::$stores[ $store_name ] ) ) { static::$stores[ $store_name ] = new static(); static::$stores[ $store_name ]->set_name( $store_name ); } return static::$stores[ $store_name ]; } public static function get_stores() { return static::$stores; } public static function remove_all_stores() { static::$stores = array(); } public function set_name( $name ) { $this->name = $name; } public function get_name() { return $this->name; } public function get_all_rules() { return $this->rules; } public function add_rule( $selector, $rules_group = '' ) { $selector = $selector ? trim( $selector ) : ''; $rules_group = $rules_group ? trim( $rules_group ) : ''; if ( empty( $selector ) ) { return; } if ( ! empty( $rules_group ) ) { if ( empty( $this->rules[ "$rules_group $selector" ] ) ) { $this->rules[ "$rules_group $selector" ] = new WP_Style_Engine_CSS_Rule( $selector, array(), $rules_group ); } return $this->rules[ "$rules_group $selector" ]; } if ( empty( $this->rules[ $selector ] ) ) { $this->rules[ $selector ] = new WP_Style_Engine_CSS_Rule( $selector ); } return $this->rules[ $selector ]; } public function remove_rule( $selector ) { unset( $this->rules[ $selector ] ); } }
###require ABSPATH . WPINC . '/style-engine/class-wp-style-engine-processor.php';
class WP_Style_Engine_Processor { protected $stores = array(); protected $css_rules = array(); public function add_store( $store ) { if ( ! $store instanceof WP_Style_Engine_CSS_Rules_Store ) { _doing_it_wrong( __METHOD__, __( '$store must be an instance of WP_Style_Engine_CSS_Rules_Store' ), '6.1.0' ); return $this; } $this->stores[ $store->get_name() ] = $store; return $this; } public function add_rules( $css_rules ) { if ( ! is_array( $css_rules ) ) { $css_rules = array( $css_rules ); } foreach ( $css_rules as $rule ) { $selector = $rule->get_selector(); $rules_group = $rule->get_rules_group(); if ( ! empty( $rules_group ) ) { if ( isset( $this->css_rules[ "$rules_group $selector" ] ) ) { $this->css_rules[ "$rules_group $selector" ]->add_declarations( $rule->get_declarations() ); continue; } $this->css_rules[ "$rules_group $selector" ] = $rule; continue; } if ( isset( $this->css_rules[ $selector ] ) ) { $this->css_rules[ $selector ]->add_declarations( $rule->get_declarations() ); continue; } $this->css_rules[ $rule->get_selector() ] = $rule; } return $this; } public function get_css( $options = array() ) { $defaults = array( 'optimize' => false, 'prettify' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG, ); $options = wp_parse_args( $options, $defaults ); foreach ( $this->stores as $store ) { $this->add_rules( $store->get_all_rules() ); } if ( true === $options['optimize'] ) { $this->combine_rules_selectors(); } $css = ''; foreach ( $this->css_rules as $rule ) { $css .= $rule->get_css( $options['prettify'] ); $css .= $options['prettify'] ? "\n" : ''; } return $css; } private function combine_rules_selectors() { $selectors_json = array(); foreach ( $this->css_rules as $rule ) { $declarations = $rule->get_declarations()->get_declarations(); ksort( $declarations ); $selectors_json[ $rule->get_selector() ] = wp_json_encode( $declarations ); } foreach ( $selectors_json as $selector => $json ) { $duplicates = array_keys( $selectors_json, $json, true ); if ( 1 >= count( $duplicates ) ) { continue; } $declarations = $this->css_rules[ $selector ]->get_declarations(); foreach ( $duplicates as $key ) { unset( $selectors_json[ $key ] ); unset( $this->css_rules[ $key ] ); } $duplicate_selectors = implode( ',', $duplicates ); $this->css_rules[ $duplicate_selectors ] = new WP_Style_Engine_CSS_Rule( $duplicate_selectors, $declarations ); } } }
###require ABSPATH . WPINC . '/fonts/class-wp-font-face-resolver.php';
class WP_Font_Face_Resolver { public static function get_fonts_from_theme_json() { $settings = wp_get_global_settings(); if ( empty( $settings['typography']['fontFamilies'] ) ) { return array(); } return static::parse_settings( $settings ); } public static function get_fonts_from_style_variations() { $variations = WP_Theme_JSON_Resolver::get_style_variations(); $fonts = array(); if ( empty( $variations ) ) { return $fonts; } foreach ( $variations as $variation ) { if ( ! empty( $variation['settings']['typography']['fontFamilies']['theme'] ) ) { $fonts = array_merge( $fonts, $variation['settings']['typography']['fontFamilies']['theme'] ); } } $settings = array( 'typography' => array( 'fontFamilies' => array( 'theme' => $fonts, ), ), ); return static::parse_settings( $settings ); } private static function parse_settings( array $settings ) { $fonts = array(); foreach ( $settings['typography']['fontFamilies'] as $font_families ) { foreach ( $font_families as $definition ) { if ( empty( $definition['fontFace'] ) ) { continue; } if ( empty( $definition['fontFamily'] ) ) { continue; } $font_family_name = static::maybe_parse_name_from_comma_separated_list( $definition['fontFamily'] ); if ( empty( $font_family_name ) ) { continue; } $fonts[] = static::convert_font_face_properties( $definition['fontFace'], $font_family_name ); } } return $fonts; } private static function maybe_parse_name_from_comma_separated_list( $font_family ) { if ( str_contains( $font_family, ',' ) ) { $font_family = explode( ',', $font_family )[0]; } return trim( $font_family, "\"'" ); } private static function convert_font_face_properties( array $font_face_definition, $font_family_property ) { $converted_font_faces = array(); foreach ( $font_face_definition as $font_face ) { $font_face['font-family'] = $font_family_property; if ( ! empty( $font_face['src'] ) ) { $font_face['src'] = static::to_theme_file_uri( (array) $font_face['src'] ); } $font_face = static::to_kebab_case( $font_face ); $converted_font_faces[] = $font_face; } return $converted_font_faces; } private static function to_theme_file_uri( array $src ) { $placeholder = 'file:./'; foreach ( $src as $src_key => $src_url ) { if ( ! str_starts_with( $src_url, $placeholder ) ) { continue; } $src_file = str_replace( $placeholder, '', $src_url ); $src[ $src_key ] = get_theme_file_uri( $src_file ); } return $src; } private static function to_kebab_case( array $data ) { foreach ( $data as $key => $value ) { $kebab_case = _wp_to_kebab_case( $key ); $data[ $kebab_case ] = $value; if ( $kebab_case !== $key ) { unset( $data[ $key ] ); } } return $data; } }
###require ABSPATH . WPINC . '/fonts/class-wp-font-collection.php';
final class WP_Font_Collection { public $slug; private $data; private $src; public function __construct( string $slug, array $args ) { $this->slug = sanitize_title( $slug ); if ( $this->slug !== $slug ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Font collection slug "%s" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores.' ), $slug ), '6.5.0' ); } $required_properties = array( 'name', 'font_families' ); if ( isset( $args['font_families'] ) && is_string( $args['font_families'] ) ) { $this->src = $args['font_families']; unset( $args['font_families'] ); $required_properties = array( 'name' ); } $this->data = $this->sanitize_and_validate_data( $args, $required_properties ); } public function get_data() { if ( is_wp_error( $this->data ) ) { return $this->data; } if ( isset( $this->src ) ) { $this->data = $this->load_from_json( $this->src ); } if ( is_wp_error( $this->data ) ) { return $this->data; } $defaults = array( 'description' => '', 'categories' => array(), ); return wp_parse_args( $this->data, $defaults ); } private function load_from_json( $file_or_url ) { $url = wp_http_validate_url( $file_or_url ); $file = file_exists( $file_or_url ) ? wp_normalize_path( realpath( $file_or_url ) ) : false; if ( ! $url && ! $file ) { $message = __( 'Font collection JSON file is invalid or does not exist.' ); _doing_it_wrong( __METHOD__, $message, '6.5.0' ); return new WP_Error( 'font_collection_json_missing', $message ); } $data = $url ? $this->load_from_url( $url ) : $this->load_from_file( $file ); if ( is_wp_error( $data ) ) { return $data; } $data = array( 'name' => $this->data['name'], 'font_families' => $data['font_families'], ); if ( isset( $this->data['description'] ) ) { $data['description'] = $this->data['description']; } if ( isset( $this->data['categories'] ) ) { $data['categories'] = $this->data['categories']; } return $data; } private function load_from_file( $file ) { $data = wp_json_file_decode( $file, array( 'associative' => true ) ); if ( empty( $data ) ) { return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection JSON file contents.' ) ); } return $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); } private function load_from_url( $url ) { $transient_key = substr( 'wp_font_collection_url_' . $url, 0, 167 ); $data = get_site_transient( $transient_key ); if ( false === $data ) { $response = wp_safe_remote_get( $url ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { return new WP_Error( 'font_collection_request_error', sprintf( __( 'Error fetching the font collection data from "%s".' ), $url ) ); } $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( empty( $data ) ) { return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection data from the HTTP response JSON.' ) ); } $data = $this->sanitize_and_validate_data( $data, array( 'font_families' ) ); if ( is_wp_error( $data ) ) { return $data; } set_site_transient( $transient_key, $data, DAY_IN_SECONDS ); } return $data; } private function sanitize_and_validate_data( $data, $required_properties = array() ) { $schema = self::get_sanitization_schema(); $data = WP_Font_Utils::sanitize_from_schema( $data, $schema ); foreach ( $required_properties as $property ) { if ( empty( $data[ $property ] ) ) { $message = sprintf( __( 'Font collection "%1$s" has missing or empty property: "%2$s".' ), $this->slug, $property ); _doing_it_wrong( __METHOD__, $message, '6.5.0' ); return new WP_Error( 'font_collection_missing_property', $message ); } } return $data; } private static function get_sanitization_schema() { return array( 'name' => 'sanitize_text_field', 'description' => 'sanitize_text_field', 'font_families' => array( array( 'font_family_settings' => array( 'name' => 'sanitize_text_field', 'slug' => static function ( $value ) { return _wp_to_kebab_case( sanitize_title( $value ) ); }, 'fontFamily' => 'WP_Font_Utils::sanitize_font_family', 'preview' => 'sanitize_url', 'fontFace' => array( array( 'fontFamily' => 'sanitize_text_field', 'fontStyle' => 'sanitize_text_field', 'fontWeight' => 'sanitize_text_field', 'src' => static function ( $value ) { return is_array( $value ) ? array_map( 'sanitize_text_field', $value ) : sanitize_text_field( $value ); }, 'preview' => 'sanitize_url', 'fontDisplay' => 'sanitize_text_field', 'fontStretch' => 'sanitize_text_field', 'ascentOverride' => 'sanitize_text_field', 'descentOverride' => 'sanitize_text_field', 'fontVariant' => 'sanitize_text_field', 'fontFeatureSettings' => 'sanitize_text_field', 'fontVariationSettings' => 'sanitize_text_field', 'lineGapOverride' => 'sanitize_text_field', 'sizeAdjust' => 'sanitize_text_field', 'unicodeRange' => 'sanitize_text_field', ), ), ), 'categories' => array( 'sanitize_title' ), ), ), 'categories' => array( array( 'name' => 'sanitize_text_field', 'slug' => 'sanitize_title', ), ), ); } }
###require ABSPATH . WPINC . '/fonts/class-wp-font-face.php';
class WP_Font_Face { private $font_face_property_defaults = array( 'font-family' => '', 'font-style' => 'normal', 'font-weight' => '400', 'font-display' => 'fallback', ); private $valid_font_face_properties = array( 'ascent-override', 'descent-override', 'font-display', 'font-family', 'font-stretch', 'font-style', 'font-weight', 'font-variant', 'font-feature-settings', 'font-variation-settings', 'line-gap-override', 'size-adjust', 'src', 'unicode-range', ); private $valid_font_display = array( 'auto', 'block', 'fallback', 'swap', 'optional' ); private $style_tag_attrs = array(); public function __construct() { if ( function_exists( 'is_admin' ) && ! is_admin() && function_exists( 'current_theme_supports' ) && ! current_theme_supports( 'html5', 'style' ) ) { $this->style_tag_attrs = array( 'type' => 'text/css' ); } } public function generate_and_print( array $fonts ) { $fonts = $this->validate_fonts( $fonts ); if ( empty( $fonts ) ) { return; } $css = $this->get_css( $fonts ); $css = wp_strip_all_tags( $css ); if ( empty( $css ) ) { return; } printf( $this->get_style_element(), $css ); } private function validate_fonts( array $fonts ) { $validated_fonts = array(); foreach ( $fonts as $font_faces ) { foreach ( $font_faces as $font_face ) { $font_face = $this->validate_font_face_declarations( $font_face ); if ( false === $font_face ) { continue; } $validated_fonts[] = $font_face; } } return $validated_fonts; } private function validate_font_face_declarations( array $font_face ) { $font_face = wp_parse_args( $font_face, $this->font_face_property_defaults ); if ( empty( $font_face['font-family'] ) || ! is_string( $font_face['font-family'] ) ) { _doing_it_wrong( __METHOD__, __( 'Font font-family must be a non-empty string.' ), '6.4.0' ); return false; } if ( empty( $font_face['src'] ) || ( ! is_string( $font_face['src'] ) && ! is_array( $font_face['src'] ) ) ) { _doing_it_wrong( __METHOD__, __( 'Font src must be a non-empty string or an array of strings.' ), '6.4.0' ); return false; } foreach ( (array) $font_face['src'] as $src ) { if ( empty( $src ) || ! is_string( $src ) ) { _doing_it_wrong( __METHOD__, __( 'Each font src must be a non-empty string.' ), '6.4.0' ); return false; } } if ( ! is_string( $font_face['font-weight'] ) && ! is_int( $font_face['font-weight'] ) ) { _doing_it_wrong( __METHOD__, __( 'Font font-weight must be a properly formatted string or integer.' ), '6.4.0' ); return false; } if ( ! in_array( $font_face['font-display'], $this->valid_font_display, true ) ) { $font_face['font-display'] = $this->font_face_property_defaults['font-display']; } foreach ( $font_face as $property => $value ) { if ( ! in_array( $property, $this->valid_font_face_properties, true ) ) { unset( $font_face[ $property ] ); } } return $font_face; } private function get_style_element() { $attributes = $this->generate_style_element_attributes(); return "<style class='wp-fonts-local'{$attributes}>\n%s\n</style>\n"; } private function generate_style_element_attributes() { $attributes = ''; foreach ( $this->style_tag_attrs as $name => $value ) { $attributes .= " {$name}='{$value}'"; } return $attributes; } private function get_css( $font_faces ) { $css = ''; foreach ( $font_faces as $font_face ) { $font_face = $this->order_src( $font_face ); $css .= '@font-face{' . $this->build_font_face_css( $font_face ) . '}' . "\n"; } return rtrim( $css, "\n" ); } private function order_src( array $font_face ) { if ( ! is_array( $font_face['src'] ) ) { $font_face['src'] = (array) $font_face['src']; } $src = array(); $src_ordered = array(); foreach ( $font_face['src'] as $url ) { if ( str_starts_with( trim( $url ), 'data:' ) ) { $src_ordered[] = array( 'url' => $url, 'format' => 'data', ); continue; } $format = pathinfo( $url, PATHINFO_EXTENSION ); $src[ $format ] = $url; } if ( ! empty( $src['woff2'] ) ) { $src_ordered[] = array( 'url' => $src['woff2'], 'format' => 'woff2', ); } if ( ! empty( $src['woff'] ) ) { $src_ordered[] = array( 'url' => $src['woff'], 'format' => 'woff', ); } if ( ! empty( $src['ttf'] ) ) { $src_ordered[] = array( 'url' => $src['ttf'], 'format' => 'truetype', ); } if ( ! empty( $src['eot'] ) ) { $src_ordered[] = array( 'url' => $src['eot'], 'format' => 'embedded-opentype', ); } if ( ! empty( $src['otf'] ) ) { $src_ordered[] = array( 'url' => $src['otf'], 'format' => 'opentype', ); } $font_face['src'] = $src_ordered; return $font_face; } private function build_font_face_css( array $font_face ) { $css = ''; if ( str_contains( $font_face['font-family'], ' ' ) && ! str_contains( $font_face['font-family'], '"' ) && ! str_contains( $font_face['font-family'], "'" ) ) { $font_face['font-family'] = '"' . $font_face['font-family'] . '"'; } foreach ( $font_face as $key => $value ) { if ( 'src' === $key ) { $value = $this->compile_src( $value ); } if ( 'font-variation-settings' === $key && is_array( $value ) ) { $value = $this->compile_variations( $value ); } if ( ! empty( $value ) ) { $css .= "$key:$value;"; } } return $css; } private function compile_src( array $value ) { $src = ''; foreach ( $value as $item ) { $src .= ( 'data' === $item['format'] ) ? ", url({$item['url']})" : ", url('{$item['url']}') format('{$item['format']}')"; } $src = ltrim( $src, ', ' ); return $src; } private function compile_variations( array $font_variation_settings ) { $variations = ''; foreach ( $font_variation_settings as $key => $value ) { $variations .= "$key $value"; } return $variations; } }
###require ABSPATH . WPINC . '/fonts/class-wp-font-library.php';
class WP_Font_Library { private $collections = array(); private static $instance = null; public function register_font_collection( string $slug, array $args ) { $new_collection = new WP_Font_Collection( $slug, $args ); if ( $this->is_collection_registered( $new_collection->slug ) ) { $error_message = sprintf( __( 'Font collection with slug: "%s" is already registered.' ), $new_collection->slug ); _doing_it_wrong( __METHOD__, $error_message, '6.5.0' ); return new WP_Error( 'font_collection_registration_error', $error_message ); } $this->collections[ $new_collection->slug ] = $new_collection; return $new_collection; } public function unregister_font_collection( string $slug ) { if ( ! $this->is_collection_registered( $slug ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Font collection "%s" not found.' ), $slug ), '6.5.0' ); return false; } unset( $this->collections[ $slug ] ); return true; } private function is_collection_registered( string $slug ) { return array_key_exists( $slug, $this->collections ); } public function get_font_collections() { return $this->collections; } public function get_font_collection( string $slug ) { if ( $this->is_collection_registered( $slug ) ) { return $this->collections[ $slug ]; } return null; } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } }
###require ABSPATH . WPINC . '/fonts/class-wp-font-utils.php';
class WP_Font_Utils { private static function maybe_add_quotes( $item ) { $regex = '/^(?!generic\([a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/'; $item = trim( $item ); if ( preg_match( $regex, $item ) ) { $item = trim( $item, "\"'" ); return '"' . $item . '"'; } return $item; } public static function sanitize_font_family( $font_family ) { if ( ! $font_family ) { return ''; } $output = sanitize_text_field( $font_family ); $formatted_items = array(); if ( str_contains( $output, ',' ) ) { $items = explode( ',', $output ); foreach ( $items as $item ) { $formatted_item = self::maybe_add_quotes( $item ); if ( ! empty( $formatted_item ) ) { $formatted_items[] = $formatted_item; } } return implode( ', ', $formatted_items ); } return self::maybe_add_quotes( $output ); } public static function get_font_face_slug( $settings ) { $defaults = array( 'fontFamily' => '', 'fontStyle' => 'normal', 'fontWeight' => '400', 'fontStretch' => '100%', 'unicodeRange' => 'U+0-10FFFF', ); $settings = wp_parse_args( $settings, $defaults ); if ( function_exists( 'mb_strtolower' ) ) { $font_family = mb_strtolower( $settings['fontFamily'] ); } else { $font_family = strtolower( $settings['fontFamily'] ); } $font_style = strtolower( $settings['fontStyle'] ); $font_weight = strtolower( $settings['fontWeight'] ); $font_stretch = strtolower( $settings['fontStretch'] ); $unicode_range = strtoupper( $settings['unicodeRange'] ); $font_weight = str_replace( array( 'normal', 'bold' ), array( '400', '700' ), $font_weight ); $font_stretch_map = array( 'ultra-condensed' => '50%', 'extra-condensed' => '62.5%', 'condensed' => '75%', 'semi-condensed' => '87.5%', 'normal' => '100%', 'semi-expanded' => '112.5%', 'expanded' => '125%', 'extra-expanded' => '150%', 'ultra-expanded' => '200%', ); $font_stretch = str_replace( array_keys( $font_stretch_map ), array_values( $font_stretch_map ), $font_stretch ); $slug_elements = array( $font_family, $font_style, $font_weight, $font_stretch, $unicode_range ); $slug_elements = array_map( function ( $elem ) { $elem = trim( str_replace( array( '"', "'", ';' ), '', $elem ) ); return preg_replace( '/,\s+/', ',', $elem ); }, $slug_elements ); return sanitize_text_field( implode( ';', $slug_elements ) ); } public static function sanitize_from_schema( $tree, $schema ) { if ( ! is_array( $tree ) || ! is_array( $schema ) ) { return array(); } foreach ( $tree as $key => $value ) { if ( ! array_key_exists( $key, $schema ) ) { unset( $tree[ $key ] ); continue; } $is_value_array = is_array( $value ); $is_schema_array = is_array( $schema[ $key ] ) && ! is_callable( $schema[ $key ] ); if ( $is_value_array && $is_schema_array ) { if ( wp_is_numeric_array( $value ) ) { foreach ( $value as $item_key => $item_value ) { $tree[ $key ][ $item_key ] = isset( $schema[ $key ][0] ) && is_array( $schema[ $key ][0] ) ? self::sanitize_from_schema( $item_value, $schema[ $key ][0] ) : self::apply_sanitizer( $item_value, $schema[ $key ][0] ); } } else { $tree[ $key ] = self::sanitize_from_schema( $value, $schema[ $key ] ); } } elseif ( ! $is_value_array && $is_schema_array ) { unset( $tree[ $key ] ); } elseif ( ! $is_schema_array ) { $tree[ $key ] = self::apply_sanitizer( $value, $schema[ $key ] ); } if ( empty( $tree[ $key ] ) ) { unset( $tree[ $key ] ); } } return $tree; } private static function apply_sanitizer( $value, $sanitizer ) { if ( null === $sanitizer ) { return $value; } return call_user_func( $sanitizer, $value ); } public static function get_allowed_font_mime_types() { $php_7_ttf_mime_type = PHP_VERSION_ID >= 70300 ? 'application/font-sfnt' : 'application/x-font-ttf'; return array( 'otf' => 'application/vnd.ms-opentype', 'ttf' => PHP_VERSION_ID >= 70400 ? 'font/sfnt' : $php_7_ttf_mime_type, 'woff' => PHP_VERSION_ID >= 80112 ? 'font/woff' : 'application/font-woff', 'woff2' => PHP_VERSION_ID >= 80112 ? 'font/woff2' : 'application/font-woff2', ); } }
###require ABSPATH . WPINC . '/fonts.php';
function wp_print_font_faces( $fonts = array() ) { if ( empty( $fonts ) ) { $fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json(); } if ( empty( $fonts ) ) { return; } $wp_font_face = new WP_Font_Face(); $wp_font_face->generate_and_print( $fonts ); } function wp_print_font_faces_from_style_variations() { $fonts = WP_Font_Face_Resolver::get_fonts_from_style_variations(); if ( empty( $fonts ) ) { return; } wp_print_font_faces( $fonts ); } function wp_register_font_collection( string $slug, array $args ) { return WP_Font_Library::get_instance()->register_font_collection( $slug, $args ); } function wp_unregister_font_collection( string $slug ) { return WP_Font_Library::get_instance()->unregister_font_collection( $slug ); } function wp_get_font_dir() { return wp_font_dir( false ); } function wp_font_dir( $create_dir = true ) { add_filter( 'upload_dir', '_wp_filter_font_directory' ); $font_dir = wp_upload_dir( null, $create_dir, false ); remove_filter( 'upload_dir', '_wp_filter_font_directory' ); return $font_dir; } function _wp_filter_font_directory( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { return $font_dir; } $font_dir = array( 'path' => untrailingslashit( $font_dir['basedir'] ) . '/fonts', 'url' => untrailingslashit( $font_dir['baseurl'] ) . '/fonts', 'subdir' => '', 'basedir' => untrailingslashit( $font_dir['basedir'] ) . '/fonts', 'baseurl' => untrailingslashit( $font_dir['baseurl'] ) . '/fonts', 'error' => false, ); return apply_filters( 'font_dir', $font_dir ); } function _wp_after_delete_font_family( $post_id, $post ) { if ( 'wp_font_family' !== $post->post_type ) { return; } $font_faces_ids = get_children( array( 'post_parent' => $post_id, 'post_type' => 'wp_font_face', 'fields' => 'ids', ) ); foreach ( $font_faces_ids as $font_faces_id ) { wp_delete_post( $font_faces_id, true ); } } function _wp_before_delete_font_face( $post_id, $post ) { if ( 'wp_font_face' !== $post->post_type ) { return; } $font_files = get_post_meta( $post_id, '_wp_font_face_file', false ); $font_dir = untrailingslashit( wp_get_font_dir()['basedir'] ); foreach ( $font_files as $font_file ) { wp_delete_file( $font_dir . '/' . $font_file ); } } function _wp_register_default_font_collections() { wp_register_font_collection( 'google-fonts', array( 'name' => _x( 'Google Fonts', 'font collection name' ), 'description' => __( 'Install from Google Fonts. Fonts are copied to and served from your site.' ), 'font_families' => 'https://s.w.org/images/fonts/wp-6.9/collections/google-fonts-with-preview.json', 'categories' => array( array( 'name' => _x( 'Sans Serif', 'font category' ), 'slug' => 'sans-serif', ), array( 'name' => _x( 'Display', 'font category' ), 'slug' => 'display', ), array( 'name' => _x( 'Serif', 'font category' ), 'slug' => 'serif', ), array( 'name' => _x( 'Handwriting', 'font category' ), 'slug' => 'handwriting', ), array( 'name' => _x( 'Monospace', 'font category' ), 'slug' => 'monospace', ), ), ) ); }
###require ABSPATH . WPINC . '/class-wp-script-modules.php';
class WP_Script_Modules { private $registered = array(); private $queue = array(); private $done = array(); private $a11y_available = false; private $dependents_map = array(); private $priorities = array( 'low', 'auto', 'high', ); private $modules_with_missing_dependencies = array(); public function register( string $id, string $src, array $deps = array(), $version = false, array $args = array() ) { if ( '' === $id ) { _doing_it_wrong( __METHOD__, __( 'Non-empty string required for id.' ), '6.9.0' ); return; } if ( ! isset( $this->registered[ $id ] ) ) { $dependencies = array(); foreach ( $deps as $dependency ) { if ( is_array( $dependency ) ) { if ( ! isset( $dependency['id'] ) || ! is_string( $dependency['id'] ) ) { _doing_it_wrong( __METHOD__, __( 'Missing required id key in entry among dependencies array.' ), '6.5.0' ); continue; } $dependencies[] = array( 'id' => $dependency['id'], 'import' => isset( $dependency['import'] ) && 'dynamic' === $dependency['import'] ? 'dynamic' : 'static', ); } elseif ( is_string( $dependency ) ) { $dependencies[] = array( 'id' => $dependency, 'import' => 'static', ); } else { _doing_it_wrong( __METHOD__, __( 'Entries in dependencies array must be either strings or arrays with an id key.' ), '6.5.0' ); } } $in_footer = isset( $args['in_footer'] ) && (bool) $args['in_footer']; $fetchpriority = 'auto'; if ( isset( $args['fetchpriority'] ) ) { if ( $this->is_valid_fetchpriority( $args['fetchpriority'] ) ) { $fetchpriority = $args['fetchpriority']; } else { _doing_it_wrong( __METHOD__, sprintf( __( 'Invalid fetchpriority `%1$s` defined for `%2$s` during script registration.' ), is_string( $args['fetchpriority'] ) ? $args['fetchpriority'] : gettype( $args['fetchpriority'] ), $id ), '6.9.0' ); } } $this->registered[ $id ] = array( 'src' => $src, 'version' => $version, 'dependencies' => $dependencies, 'in_footer' => $in_footer, 'fetchpriority' => $fetchpriority, ); } } public function get_queue(): array { return $this->queue; } private function is_valid_fetchpriority( $priority ): bool { return in_array( $priority, $this->priorities, true ); } public function set_fetchpriority( string $id, string $priority ): bool { if ( ! isset( $this->registered[ $id ] ) ) { return false; } if ( '' === $priority ) { $priority = 'auto'; } if ( ! $this->is_valid_fetchpriority( $priority ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Invalid fetchpriority: %s' ), $priority ), '6.9.0' ); return false; } $this->registered[ $id ]['fetchpriority'] = $priority; return true; } public function set_in_footer( string $id, bool $in_footer ): bool { if ( ! isset( $this->registered[ $id ] ) ) { return false; } $this->registered[ $id ]['in_footer'] = $in_footer; return true; } public function enqueue( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) { if ( '' === $id ) { _doing_it_wrong( __METHOD__, __( 'Non-empty string required for id.' ), '6.9.0' ); return; } if ( ! in_array( $id, $this->queue, true ) ) { $this->queue[] = $id; } if ( ! isset( $this->registered[ $id ] ) && $src ) { $this->register( $id, $src, $deps, $version, $args ); } } public function dequeue( string $id ) { $this->queue = array_values( array_diff( $this->queue, array( $id ) ) ); } public function deregister( string $id ) { $this->dequeue( $id ); unset( $this->registered[ $id ] ); } public function add_hooks() { $is_block_theme = wp_is_block_theme(); $position = $is_block_theme ? 'wp_head' : 'wp_footer'; add_action( $position, array( $this, 'print_import_map' ) ); if ( $is_block_theme ) { add_action( 'wp_head', array( $this, 'print_head_enqueued_script_modules' ) ); } add_action( 'wp_footer', array( $this, 'print_enqueued_script_modules' ) ); add_action( $position, array( $this, 'print_script_module_preloads' ) ); add_action( 'admin_print_footer_scripts', array( $this, 'print_import_map' ) ); add_action( 'admin_print_footer_scripts', array( $this, 'print_enqueued_script_modules' ) ); add_action( 'admin_print_footer_scripts', array( $this, 'print_script_module_preloads' ) ); add_action( 'wp_footer', array( $this, 'print_script_module_data' ) ); add_action( 'admin_print_footer_scripts', array( $this, 'print_script_module_data' ) ); add_action( 'wp_footer', array( $this, 'print_a11y_script_module_html' ), 20 ); add_action( 'admin_print_footer_scripts', array( $this, 'print_a11y_script_module_html' ), 20 ); } private function get_highest_fetchpriority( array $ids ): string { static $high_priority_index = null; if ( null === $high_priority_index ) { $high_priority_index = count( $this->priorities ) - 1; } $highest_priority_index = 0; foreach ( $ids as $id ) { if ( isset( $this->registered[ $id ] ) ) { $highest_priority_index = (int) max( $highest_priority_index, (int) array_search( $this->registered[ $id ]['fetchpriority'], $this->priorities, true ) ); if ( $high_priority_index === $highest_priority_index ) { break; } } } return $this->priorities[ $highest_priority_index ]; } public function print_head_enqueued_script_modules() { foreach ( $this->get_sorted_dependencies( $this->queue ) as $id ) { if ( isset( $this->registered[ $id ] ) && ! $this->registered[ $id ]['in_footer'] ) { $dependencies = array_keys( $this->get_dependencies( array( $id ) ) ); foreach ( $dependencies as $dependency_id ) { if ( in_array( $dependency_id, $this->queue, true ) && isset( $this->registered[ $dependency_id ] ) && $this->registered[ $dependency_id ]['in_footer'] ) { continue 2; } } $this->print_script_module( $id ); } } } public function print_enqueued_script_modules() { foreach ( $this->get_sorted_dependencies( $this->queue ) as $id ) { $this->print_script_module( $id ); } } private function print_script_module( string $id ) { if ( in_array( $id, $this->done, true ) || ! in_array( $id, $this->queue, true ) ) { return; } $this->done[] = $id; $src = $this->get_src( $id ); if ( '' === $src ) { return; } $attributes = array( 'type' => 'module', 'src' => $src, 'id' => $id . '-js-module', ); $script_module = $this->registered[ $id ]; $queued_dependents = array_intersect( $this->queue, $this->get_recursive_dependents( $id ) ); $fetchpriority = $this->get_highest_fetchpriority( array_merge( array( $id ), $queued_dependents ) ); if ( 'auto' !== $fetchpriority ) { $attributes['fetchpriority'] = $fetchpriority; } if ( $fetchpriority !== $script_module['fetchpriority'] ) { $attributes['data-wp-fetchpriority'] = $script_module['fetchpriority']; } wp_print_script_tag( $attributes ); } public function print_script_module_preloads() { $dependency_ids = $this->get_sorted_dependencies( $this->queue, array( 'static' ) ); foreach ( $dependency_ids as $id ) { if ( in_array( $id, $this->queue, true ) ) { continue; } $src = $this->get_src( $id ); if ( '' === $src ) { continue; } $enqueued_dependents = array_intersect( $this->get_recursive_dependents( $id ), $this->queue ); $highest_fetchpriority = $this->get_highest_fetchpriority( $enqueued_dependents ); printf( '<link rel="modulepreload" href="%s" id="%s"', esc_url( $src ), esc_attr( $id . '-js-modulepreload' ) ); if ( 'auto' !== $highest_fetchpriority ) { printf( ' fetchpriority="%s"', esc_attr( $highest_fetchpriority ) ); } if ( $highest_fetchpriority !== $this->registered[ $id ]['fetchpriority'] && 'auto' !== $this->registered[ $id ]['fetchpriority'] ) { printf( ' data-wp-fetchpriority="%s"', esc_attr( $this->registered[ $id ]['fetchpriority'] ) ); } echo ">\n"; } } public function print_import_map() { $import_map = $this->get_import_map(); if ( ! empty( $import_map['imports'] ) ) { wp_print_inline_script_tag( (string) wp_json_encode( $import_map, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ), array( 'type' => 'importmap', 'id' => 'wp-importmap', ) ); } } private function get_import_map(): array { $imports = array(); foreach ( array_keys( $this->get_dependencies( $this->queue ) ) as $id ) { $src = $this->get_src( $id ); if ( '' !== $src ) { $imports[ $id ] = $src; } } return array( 'imports' => $imports ); } private function get_marked_for_enqueue(): array { return wp_array_slice_assoc( $this->registered, $this->queue ); } private function get_dependencies( array $ids, array $import_types = array( 'static', 'dynamic' ) ): array { $all_dependencies = array(); $id_queue = $ids; while ( ! empty( $id_queue ) ) { $id = array_shift( $id_queue ); if ( ! isset( $this->registered[ $id ] ) ) { continue; } foreach ( $this->registered[ $id ]['dependencies'] as $dependency ) { if ( ! isset( $all_dependencies[ $dependency['id'] ] ) && in_array( $dependency['import'], $import_types, true ) && isset( $this->registered[ $dependency['id'] ] ) ) { $all_dependencies[ $dependency['id'] ] = $this->registered[ $dependency['id'] ]; $id_queue[] = $dependency['id']; } } } return $all_dependencies; } private function get_dependents( string $id ): array { if ( isset( $this->dependents_map[ $id ] ) ) { return $this->dependents_map[ $id ]; } $dependents = array(); foreach ( $this->registered as $registered_id => $args ) { if ( in_array( $id, wp_list_pluck( $args['dependencies'], 'id' ), true ) ) { $dependents[] = $registered_id; } } $this->dependents_map[ $id ] = $dependents; return $dependents; } private function get_recursive_dependents( string $id ): array { $dependents = array(); $id_queue = array( $id ); $processed = array(); while ( ! empty( $id_queue ) ) { $current_id = array_shift( $id_queue ); if ( ! isset( $this->registered[ $current_id ] ) || isset( $processed[ $current_id ] ) ) { continue; } $processed[ $current_id ] = true; foreach ( $this->get_dependents( $current_id ) as $dependent_id ) { if ( ! isset( $dependents[ $dependent_id ] ) ) { $dependents[ $dependent_id ] = true; $id_queue[] = $dependent_id; } } } return array_keys( $dependents ); } private function get_sorted_dependencies( array $ids, array $import_types = array( 'static', 'dynamic' ) ): array { $sorted = array(); foreach ( $ids as $id ) { $this->sort_item_dependencies( $id, $import_types, $sorted ); } return array_unique( $sorted ); } private function sort_item_dependencies( string $id, array $import_types, array &$sorted ): bool { if ( in_array( $id, $sorted, true ) ) { return true; } if ( ! isset( $this->registered[ $id ] ) ) { return false; } $dependency_ids = array(); foreach ( $this->registered[ $id ]['dependencies'] as $dependency ) { if ( in_array( $dependency['import'], $import_types, true ) ) { $dependency_ids[] = $dependency['id']; } } $missing_dependencies = array_diff( $dependency_ids, array_keys( $this->registered ) ); if ( count( $missing_dependencies ) > 0 ) { if ( ! in_array( $id, $this->modules_with_missing_dependencies, true ) ) { _doing_it_wrong( get_class( $this ) . '::register', sprintf( __( 'The script module with the ID "%1$s" was enqueued with dependencies that are not registered: %2$s.' ), $id, implode( wp_get_list_item_separator(), $missing_dependencies ) ), '6.9.1' ); $this->modules_with_missing_dependencies[] = $id; } return false; } foreach ( $dependency_ids as $dependency_id ) { if ( ! $this->sort_item_dependencies( $dependency_id, $import_types, $sorted ) ) { return false; } } $sorted[] = $id; return true; } private function get_src( string $id ): string { if ( ! isset( $this->registered[ $id ] ) ) { return ''; } $script_module = $this->registered[ $id ]; $src = $script_module['src']; if ( '' !== $src ) { if ( false === $script_module['version'] ) { $src = add_query_arg( 'ver', get_bloginfo( 'version' ), $src ); } elseif ( null !== $script_module['version'] ) { $src = add_query_arg( 'ver', $script_module['version'], $src ); } } $src = apply_filters( 'script_module_loader_src', $src, $id ); if ( ! is_string( $src ) ) { $src = ''; } return $src; } public function print_script_module_data(): void { $modules = array(); foreach ( array_unique( $this->queue ) as $id ) { if ( '@wordpress/a11y' === $id ) { $this->a11y_available = true; } $modules[ $id ] = true; } foreach ( array_keys( $this->get_import_map()['imports'] ) as $id ) { if ( '@wordpress/a11y' === $id ) { $this->a11y_available = true; } $modules[ $id ] = true; } foreach ( array_keys( $modules ) as $module_id ) { $data = apply_filters( "script_module_data_{$module_id}", array() ); if ( is_array( $data ) && array() !== $data ) { $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS; if ( ! is_utf8_charset() ) { $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; } wp_print_inline_script_tag( (string) wp_json_encode( $data, $json_encode_flags ), array( 'type' => 'application/json', 'id' => "wp-script-module-data-{$module_id}", ) ); } } } public function print_a11y_script_module_html() { if ( ! $this->a11y_available ) { return; } echo '<div style="position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip-path:inset(50%);border:0;word-wrap:normal !important;">' . '<p id="a11y-speak-intro-text" class="a11y-speak-intro-text" hidden>' . esc_html__( 'Notifications' ) . '</p>' . '<div id="a11y-speak-assertive" class="a11y-speak-region" aria-live="assertive" aria-relevant="additions text" aria-atomic="true"></div>' . '<div id="a11y-speak-polite" class="a11y-speak-region" aria-live="polite" aria-relevant="additions text" aria-atomic="true"></div>' . '</div>'; } }
###require ABSPATH . WPINC . '/script-modules.php';
function wp_script_modules(): WP_Script_Modules { global $wp_script_modules; if ( ! ( $wp_script_modules instanceof WP_Script_Modules ) ) { $wp_script_modules = new WP_Script_Modules(); } return $wp_script_modules; } function wp_register_script_module( string $id, string $src, array $deps = array(), $version = false, array $args = array() ) { wp_script_modules()->register( $id, $src, $deps, $version, $args ); } function wp_enqueue_script_module( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) { wp_script_modules()->enqueue( $id, $src, $deps, $version, $args ); } function wp_dequeue_script_module( string $id ) { wp_script_modules()->dequeue( $id ); } function wp_deregister_script_module( string $id ) { wp_script_modules()->deregister( $id ); } function wp_default_script_modules() { $suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); $assets = include ABSPATH . WPINC . "/assets/script-modules-packages{$suffix}.php"; foreach ( $assets as $file_name => $script_module_data ) { $script_module_id = '@wordpress/' . preg_replace( '~(?:/index)?(?:\.min)?\.js$~D', '', $file_name, 1 ); switch ( $script_module_id ) { case '@wordpress/interactivity/debug': if ( ! SCRIPT_DEBUG ) { continue 2; } $script_module_id = '@wordpress/interactivity'; break; case '@wordpress/interactivity': if ( SCRIPT_DEBUG ) { continue 2; } break; } $args = array(); if ( str_starts_with( $script_module_id, '@wordpress/interactivity' ) || str_starts_with( $script_module_id, '@wordpress/block-library' ) || '@wordpress/a11y' === $script_module_id ) { $args['fetchpriority'] = 'low'; $args['in_footer'] = true; } if ( str_starts_with( $script_module_id, '@wordpress/block-library' ) ) { wp_interactivity()->add_client_navigation_support_to_script_module( $script_module_id ); } $path = includes_url( "js/dist/script-modules/{$file_name}" ); wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'], $args ); } }
###require ABSPATH . WPINC . '/interactivity-api/class-wp-interactivity-api.php';
final class WP_Interactivity_API { private static $directive_processors = array( 'data-wp-interactive' => 'data_wp_interactive_processor', 'data-wp-router-region' => 'data_wp_router_region_processor', 'data-wp-context' => 'data_wp_context_processor', 'data-wp-bind' => 'data_wp_bind_processor', 'data-wp-class' => 'data_wp_class_processor', 'data-wp-style' => 'data_wp_style_processor', 'data-wp-text' => 'data_wp_text_processor', 'data-wp-each' => 'data_wp_each_processor', ); private $state_data = array(); private $config_data = array(); private $derived_state_closures = array(); private $has_processed_router_region = false; private $script_modules_that_can_load_on_client_navigation = array(); private $namespace_stack = null; private $context_stack = null; private $current_element = null; public function state( ?string $store_namespace = null, ?array $state = null ): array { if ( ! $store_namespace ) { if ( $state ) { _doing_it_wrong( __METHOD__, __( 'The namespace is required when state data is passed.' ), '6.6.0' ); return array(); } if ( null !== $store_namespace ) { _doing_it_wrong( __METHOD__, __( 'The namespace should be a non-empty string.' ), '6.6.0' ); return array(); } if ( null === $this->namespace_stack ) { _doing_it_wrong( __METHOD__, __( 'The namespace can only be omitted during directive processing.' ), '6.6.0' ); return array(); } $store_namespace = end( $this->namespace_stack ); } if ( ! isset( $this->state_data[ $store_namespace ] ) ) { $this->state_data[ $store_namespace ] = array(); } if ( is_array( $state ) ) { $this->state_data[ $store_namespace ] = array_replace_recursive( $this->state_data[ $store_namespace ], $state ); } return $this->state_data[ $store_namespace ]; } public function config( string $store_namespace, array $config = array() ): array { if ( ! isset( $this->config_data[ $store_namespace ] ) ) { $this->config_data[ $store_namespace ] = array(); } if ( is_array( $config ) ) { $this->config_data[ $store_namespace ] = array_replace_recursive( $this->config_data[ $store_namespace ], $config ); } return $this->config_data[ $store_namespace ]; } public function print_client_interactivity_data() { _deprecated_function( __METHOD__, '6.7.0' ); } public function filter_script_module_interactivity_router_data( array $data ): array { if ( ! isset( $data['i18n'] ) ) { $data['i18n'] = array(); } $data['i18n']['loading'] = __( 'Loading page, please wait.' ); $data['i18n']['loaded'] = __( 'Page Loaded.' ); return $data; } public function filter_script_module_interactivity_data( array $data ): array { if ( empty( $this->state_data ) && empty( $this->config_data ) && empty( $this->derived_state_closures ) ) { return $data; } $config = array(); foreach ( $this->config_data as $key => $value ) { if ( ! empty( $value ) ) { $config[ $key ] = $value; } } if ( ! empty( $config ) ) { $data['config'] = $config; } $state = array(); foreach ( $this->state_data as $key => $value ) { if ( ! empty( $value ) ) { $state[ $key ] = $value; } } if ( ! empty( $state ) ) { $data['state'] = $state; } $derived_props = array(); foreach ( $this->derived_state_closures as $key => $value ) { if ( ! empty( $value ) ) { $derived_props[ $key ] = $value; } } if ( ! empty( $derived_props ) ) { $data['derivedStateClosures'] = $derived_props; } return $data; } public function get_context( ?string $store_namespace = null ): array { if ( null === $this->context_stack ) { _doing_it_wrong( __METHOD__, __( 'The context can only be read during directive processing.' ), '6.6.0' ); return array(); } if ( ! $store_namespace ) { if ( null !== $store_namespace ) { _doing_it_wrong( __METHOD__, __( 'The namespace should be a non-empty string.' ), '6.6.0' ); return array(); } $store_namespace = end( $this->namespace_stack ); } $context = end( $this->context_stack ); return ( $store_namespace && $context && isset( $context[ $store_namespace ] ) ) ? $context[ $store_namespace ] : array(); } public function get_element(): ?array { if ( null === $this->current_element ) { _doing_it_wrong( __METHOD__, __( 'The element can only be read during directive processing.' ), '6.7.0' ); } return $this->current_element; } public function register_script_modules() { _deprecated_function( __METHOD__, '6.7.0', 'wp_default_script_modules' ); } public function add_hooks() { add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) ); add_filter( 'script_module_data_@wordpress/interactivity-router', array( $this, 'filter_script_module_interactivity_router_data' ) ); add_filter( 'wp_script_attributes', array( $this, 'add_load_on_client_navigation_attribute_to_script_modules' ), 10, 1 ); } public function add_load_on_client_navigation_attribute_to_script_modules( $attributes ) { if ( is_array( $attributes ) && isset( $attributes['type'], $attributes['id'] ) && 'module' === $attributes['type'] && array_key_exists( preg_replace( '/-js-module$/', '', $attributes['id'] ), $this->script_modules_that_can_load_on_client_navigation ) ) { $attributes['data-wp-router-options'] = wp_json_encode( array( 'loadOnClientNavigation' => true ) ); } return $attributes; } public function add_client_navigation_support_to_script_module( string $script_module_id ) { $this->script_modules_that_can_load_on_client_navigation[ $script_module_id ] = true; } public function process_directives( string $html ): string { if ( ! str_contains( $html, 'data-wp-' ) ) { return $html; } $this->namespace_stack = array(); $this->context_stack = array(); $result = $this->_process_directives( $html ); $this->namespace_stack = null; $this->context_stack = null; return null === $result ? $html : $result; } private function _process_directives( string $html ) { $p = new WP_Interactivity_API_Directives_Processor( $html ); $tag_stack = array(); $unbalanced = false; $directive_processor_prefixes = array_keys( self::$directive_processors ); $directive_processor_prefixes_reversed = array_reverse( $directive_processor_prefixes ); $namespace_stack_size = count( $this->namespace_stack ); $context_stack_size = count( $this->context_stack ); while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { $tag_name = $p->get_tag(); if ( 'SVG' === $tag_name || 'MATH' === $tag_name ) { if ( $p->get_attribute_names_with_prefix( 'data-wp-' ) ) { $message = sprintf( __( 'Interactivity directives were detected on an incompatible %1$s tag when processing "%2$s". These directives will be ignored in the server side render.' ), $tag_name, end( $this->namespace_stack ) ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); } $p->skip_to_tag_closer(); continue; } if ( $p->is_tag_closer() ) { list( $opening_tag_name, $directives_prefixes ) = ! empty( $tag_stack ) ? end( $tag_stack ) : array( null, null ); if ( 0 === count( $tag_stack ) || $opening_tag_name !== $tag_name ) { $unbalanced = true; break; } else { array_pop( $tag_stack ); } } else { $each_child_attrs = $p->get_attribute_names_with_prefix( 'data-wp-each-child' ); if ( null === $each_child_attrs ) { continue; } if ( 0 !== count( $each_child_attrs ) ) { $p->next_balanced_tag_closer_tag(); continue; } else { $directives_prefixes = array(); foreach ( $p->get_attribute_names_with_prefix( 'data-wp-' ) as $attribute_name ) { $parsed_directive = $this->parse_directive_name( $attribute_name ); if ( empty( $parsed_directive ) ) { continue; } $directive_prefix = 'data-wp-' . $parsed_directive['prefix']; if ( array_key_exists( $directive_prefix, self::$directive_processors ) ) { $directives_prefixes[] = $directive_prefix; } } if ( $p->has_and_visits_its_closer_tag() ) { $tag_stack[] = array( $tag_name, $directives_prefixes ); } } } if ( 0 === count( $directives_prefixes ) ) { continue; } $modes = array( 'enter' => ! $p->is_tag_closer(), 'exit' => $p->is_tag_closer() || ! $p->has_and_visits_its_closer_tag(), ); $element_attrs = array(); $attr_names = $p->get_attribute_names_with_prefix( '' ) ?? array(); foreach ( $attr_names as $name ) { $element_attrs[ $name ] = $p->get_attribute( $name ); } $this->current_element = array( 'attributes' => $element_attrs, ); foreach ( $modes as $mode => $should_run ) { if ( ! $should_run ) { continue; } $existing_directives_prefixes = array_intersect( 'enter' === $mode ? $directive_processor_prefixes : $directive_processor_prefixes_reversed, $directives_prefixes ); foreach ( $existing_directives_prefixes as $directive_prefix ) { $func = is_array( self::$directive_processors[ $directive_prefix ] ) ? self::$directive_processors[ $directive_prefix ] : array( $this, self::$directive_processors[ $directive_prefix ] ); call_user_func_array( $func, array( $p, $mode, &$tag_stack ) ); } } $this->current_element = null; } if ( $unbalanced ) { array_splice( $this->namespace_stack, $namespace_stack_size ); array_splice( $this->context_stack, $context_stack_size ); } if ( $unbalanced || 0 < count( $tag_stack ) ) { return null; } return $p->get_updated_html(); } private function evaluate( $entry ) { $context = end( $this->context_stack ); ['namespace' => $ns, 'value' => $path] = $entry; if ( ! $ns || ! $path ) { $message = sprintf( __( 'Namespace or reference path cannot be empty. Directive value referenced: %s' ), json_encode( $entry ) ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); return null; } $store = array( 'state' => $this->state_data[ $ns ] ?? array(), 'context' => $context[ $ns ] ?? array(), ); $should_negate_value = '!' === $path[0]; $path = $should_negate_value ? substr( $path, 1 ) : $path; $path_segments = explode( '.', $path ); $current = $store; foreach ( $path_segments as $index => $path_segment ) { if ( 'length' === $path_segment ) { if ( is_array( $current ) && array_is_list( $current ) ) { $current = count( $current ); break; } if ( is_string( $current ) ) { $current = strlen( $current ); break; } } if ( ( is_array( $current ) || $current instanceof ArrayAccess ) && isset( $current[ $path_segment ] ) ) { $current = $current[ $path_segment ]; } elseif ( is_object( $current ) && isset( $current->$path_segment ) ) { $current = $current->$path_segment; } else { $current = null; break; } if ( $current instanceof Closure ) { array_push( $this->namespace_stack, $ns ); try { $current = $current(); $this->derived_state_closures[ $ns ] = $this->derived_state_closures[ $ns ] ?? array(); $current_path = implode( '.', array_slice( $path_segments, 0, $index + 1 ) ); if ( ! in_array( $current_path, $this->derived_state_closures[ $ns ], true ) ) { $this->derived_state_closures[ $ns ][] = $current_path; } } catch ( Throwable $e ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ), $path, $ns ), '6.6.0' ); return null; } finally { array_pop( $this->namespace_stack ); } } } return $should_negate_value ? ! $current : $current; } private function parse_directive_name( string $directive_name ): ?array { $name = substr( $directive_name, 8 ); if ( preg_match( '/[^a-z0-9\-_]/i', $name ) ) { return null; } $suffix_index = strpos( $name, '--' ); if ( false === $suffix_index ) { return array( 'prefix' => $name, 'suffix' => null, 'unique_id' => null, ); } $prefix = substr( $name, 0, $suffix_index ); $remaining = substr( $name, $suffix_index ); if ( '---' === substr( $remaining, 0, 3 ) && '-' !== ( $remaining[3] ?? '' ) ) { return array( 'prefix' => $prefix, 'suffix' => null, 'unique_id' => '---' !== $remaining ? substr( $remaining, 3 ) : null, ); } $suffix = substr( $remaining, 2 ); $unique_id_index = strpos( $suffix, '---' ); if ( false !== $unique_id_index && '-' !== ( $suffix[ $unique_id_index + 3 ] ?? '' ) ) { $unique_id = substr( $suffix, $unique_id_index + 3 ); $suffix = substr( $suffix, 0, $unique_id_index ); return array( 'prefix' => $prefix, 'suffix' => empty( $suffix ) ? null : $suffix, 'unique_id' => empty( $unique_id ) ? null : $unique_id, ); } return array( 'prefix' => $prefix, 'suffix' => empty( $suffix ) ? null : $suffix, 'unique_id' => null, ); } private function extract_directive_value( $directive_value, $default_namespace = null ): array { if ( empty( $directive_value ) || is_bool( $directive_value ) ) { return array( $default_namespace, null ); } if ( 1 === preg_match( '/^([\w\-_\/]+)::./', $directive_value ) ) { list($default_namespace, $directive_value) = explode( '::', $directive_value, 2 ); } $decoded_json = json_decode( $directive_value, true ); if ( null !== $decoded_json || 'null' === $directive_value ) { $directive_value = $decoded_json; } return array( $default_namespace, $directive_value ); } private function get_directive_entries( WP_Interactivity_API_Directives_Processor $p, string $prefix ) { $directive_attributes = $p->get_attribute_names_with_prefix( 'data-wp-' . $prefix ); $entries = array(); foreach ( $directive_attributes as $attribute_name ) { [ 'prefix' => $attr_prefix, 'suffix' => $suffix, 'unique_id' => $unique_id] = $this->parse_directive_name( $attribute_name ); if ( $prefix !== $attr_prefix ) { continue; } list( $namespace, $value ) = $this->extract_directive_value( $p->get_attribute( $attribute_name ), end( $this->namespace_stack ) ); $entries[] = array( 'namespace' => $namespace, 'value' => $value, 'suffix' => $suffix, 'unique_id' => $unique_id, ); } usort( $entries, function ( $a, $b ) { $a_suffix = $a['suffix'] ?? ''; $b_suffix = $b['suffix'] ?? ''; if ( $a_suffix !== $b_suffix ) { return $a_suffix < $b_suffix ? -1 : 1; } $a_id = $a['unique_id'] ?? ''; $b_id = $b['unique_id'] ?? ''; if ( $a_id === $b_id ) { return 0; } return $a_id > $b_id ? 1 : -1; } ); return $entries; } private function kebab_to_camel_case( string $str ): string { return lcfirst( preg_replace_callback( '/(-)([a-z])/', function ( $matches ) { return strtoupper( $matches[2] ); }, strtolower( rtrim( $str, '-' ) ) ) ); } private function data_wp_interactive_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'exit' === $mode ) { array_pop( $this->namespace_stack ); return; } $attribute_value = $p->get_attribute( 'data-wp-interactive' ); $new_namespace = null; if ( is_string( $attribute_value ) && ! empty( $attribute_value ) ) { $decoded_json = json_decode( $attribute_value, true ); if ( is_array( $decoded_json ) ) { $new_namespace = $decoded_json['namespace'] ?? null; } else { $new_namespace = $attribute_value; } } $this->namespace_stack[] = ( $new_namespace && 1 === preg_match( '/^([\w\-_\/]+)/', $new_namespace ) ) ? $new_namespace : end( $this->namespace_stack ); } private function data_wp_context_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'exit' === $mode ) { array_pop( $this->context_stack ); return; } $entries = $this->get_directive_entries( $p, 'context' ); $context = end( $this->context_stack ) !== false ? end( $this->context_stack ) : array(); foreach ( $entries as $entry ) { if ( null !== $entry['suffix'] ) { continue; } $context = array_replace_recursive( $context, array( $entry['namespace'] => is_array( $entry['value'] ) ? $entry['value'] : array() ) ); } $this->context_stack[] = $context; } private function data_wp_bind_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $entries = $this->get_directive_entries( $p, 'bind' ); foreach ( $entries as $entry ) { if ( empty( $entry['suffix'] ) || null !== $entry['unique_id'] ) { return; } if ( str_starts_with( $entry['suffix'], 'on' ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'Binding event handler attributes is not supported. Please use "%s" instead.' ), esc_attr( 'data-wp-on--' . substr( $entry['suffix'], 2 ) ) ), '6.9.2' ); continue; } $result = $this->evaluate( $entry ); if ( null !== $result && ( false !== $result || ( strlen( $entry['suffix'] ) > 5 && '-' === $entry['suffix'][4] ) ) ) { if ( is_bool( $result ) && ( strlen( $entry['suffix'] ) > 5 && '-' === $entry['suffix'][4] ) ) { $result = $result ? 'true' : 'false'; } $p->set_attribute( $entry['suffix'], $result ); } else { $p->remove_attribute( $entry['suffix'] ); } } } } private function data_wp_class_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $all_class_directives = $p->get_attribute_names_with_prefix( 'data-wp-class--' ); $entries = $this->get_directive_entries( $p, 'class' ); foreach ( $entries as $entry ) { if ( empty( $entry['suffix'] ) ) { continue; } $class_name = isset( $entry['unique_id'] ) && $entry['unique_id'] ? "{$entry['suffix']}---{$entry['unique_id']}" : $entry['suffix']; if ( empty( $class_name ) ) { return; } $result = $this->evaluate( $entry ); if ( $result ) { $p->add_class( $class_name ); } else { $p->remove_class( $class_name ); } } } } private function data_wp_style_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $entries = $this->get_directive_entries( $p, 'style' ); foreach ( $entries as $entry ) { $style_property = $entry['suffix']; if ( empty( $style_property ) || null !== $entry['unique_id'] ) { continue; } $style_property_value = $this->evaluate( $entry ); $style_attribute_value = $p->get_attribute( 'style' ); $style_attribute_value = ( $style_attribute_value && ! is_bool( $style_attribute_value ) ) ? $style_attribute_value : ''; if ( $style_property_value || $style_attribute_value ) { $style_attribute_value = $this->merge_style_property( $style_attribute_value, $style_property, $style_property_value ); if ( ! empty( $style_attribute_value ) ) { $p->set_attribute( 'style', $style_attribute_value ); } else { $p->remove_attribute( 'style' ); } } } } } private function merge_style_property( string $style_attribute_value, string $style_property_name, $style_property_value ): string { $style_assignments = explode( ';', $style_attribute_value ); $result = array(); $style_property_value = ! empty( $style_property_value ) ? rtrim( trim( $style_property_value ), ';' ) : null; $new_style_property = $style_property_value ? $style_property_name . ':' . $style_property_value . ';' : ''; foreach ( $style_assignments as $style_assignment ) { if ( empty( trim( $style_assignment ) ) ) { continue; } list( $name, $value ) = explode( ':', $style_assignment ); if ( trim( $name ) !== $style_property_name ) { $result[] = trim( $name ) . ':' . trim( $value ) . ';'; } } $result[] = $new_style_property; return implode( '', $result ); } private function data_wp_text_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $entries = $this->get_directive_entries( $p, 'text' ); $valid_entry = null; foreach ( $entries as $entry ) { if ( null === $entry['suffix'] && null === $entry['unique_id'] && ! empty( $entry['value'] ) ) { $valid_entry = $entry; break; } } if ( null === $valid_entry ) { return; } $result = $this->evaluate( $valid_entry ); if ( is_string( $result ) || is_numeric( $result ) ) { $p->set_content_between_balanced_tags( esc_html( $result ) ); } else { $p->set_content_between_balanced_tags( '' ); } } } private function get_router_animation_styles(): string { return <<<CSS
.wp-interactivity-router-loading-bar {
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
width: 100vw;
max-width: 100vw !important;
height: 4px;
background-color: #000;
opacity: 0
}
.wp-interactivity-router-loading-bar.start-animation {
animation: wp-interactivity-router-loading-bar-start-animation 30s cubic-bezier(0.03, 0.5, 0, 1) forwards
}
.wp-interactivity-router-loading-bar.finish-animation {
animation: wp-interactivity-router-loading-bar-finish-animation 300ms ease-in
}
@keyframes wp-interactivity-router-loading-bar-start-animation {
0% { transform: scaleX(0); transform-origin: 0 0; opacity: 1 }
100% { transform: scaleX(1); transform-origin: 0 0; opacity: 1 }
}
@keyframes wp-interactivity-router-loading-bar-finish-animation {
0% { opacity: 1 }
50% { opacity: 1 }
100% { opacity: 0 }
}
CSS;
} public function print_router_loading_and_screen_reader_markup() { _deprecated_function( __METHOD__, '6.7.0', 'WP_Interactivity_API::print_router_markup' ); $this->print_router_markup(); } public function print_router_markup() { echo <<<HTML
<div
class="wp-interactivity-router-loading-bar"
data-wp-interactive="core/router"
data-wp-class--start-animation="state.navigation.hasStarted"
data-wp-class--finish-animation="state.navigation.hasFinished"
></div>
HTML;
} private function data_wp_router_region_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode && ! $this->has_processed_router_region ) { $this->has_processed_router_region = true; wp_register_style( 'wp-interactivity-router-animations', false ); wp_add_inline_style( 'wp-interactivity-router-animations', $this->get_router_animation_styles() ); wp_enqueue_style( 'wp-interactivity-router-animations' ); add_action( 'wp_footer', array( $this, 'print_router_markup' ) ); } } private function data_wp_each_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$tag_stack ) { if ( 'enter' === $mode && 'TEMPLATE' === $p->get_tag() ) { $entries = $this->get_directive_entries( $p, 'each' ); if ( count( $entries ) > 1 || empty( $entries ) ) { return; } $entry = $entries[0]; if ( null !== $entry['unique_id'] ) { return; } $item_name = isset( $entry['suffix'] ) ? $this->kebab_to_camel_case( $entry['suffix'] ) : 'item'; $result = $this->evaluate( $entry ); $inner_content = $p->get_content_between_balanced_template_tags(); $template_end = 'data-wp-each: template end'; $p->set_bookmark( $template_end ); $p->next_tag(); $manual_sdp = $p->get_attribute( 'data-wp-each-child' ); $p->seek( $template_end ); $p->release_bookmark( $template_end ); if ( $manual_sdp || empty( $result ) || ! is_array( $result ) || ! array_is_list( $result ) || ! str_starts_with( trim( $inner_content ), '<' ) || ! str_ends_with( trim( $inner_content ), '>' ) ) { array_pop( $tag_stack ); return; } $processed_content = ''; foreach ( $result as $item ) { $this->context_stack[] = array_replace_recursive( end( $this->context_stack ) !== false ? end( $this->context_stack ) : array(), array( $entry['namespace'] => array( $item_name => $item ) ) ); $processed_item = $this->_process_directives( $inner_content ); if ( null === $processed_item ) { array_pop( $this->context_stack ); return; } $i = new WP_Interactivity_API_Directives_Processor( $processed_item ); while ( $i->next_tag() ) { $i->set_attribute( 'data-wp-each-child', $entry['namespace'] . '::' . $entry['value'] ); $i->next_balanced_tag_closer_tag(); } $processed_content .= $i->get_updated_html(); array_pop( $this->context_stack ); } $p->append_content_after_template_tag_closer( $processed_content ); array_pop( $tag_stack ); } } }
###require ABSPATH . WPINC . '/interactivity-api/class-wp-interactivity-api-directives-processor.php';
final class WP_Interactivity_API_Directives_Processor extends WP_HTML_Tag_Processor { const TAGS_THAT_DONT_VISIT_CLOSER_TAG = array( 'SCRIPT', 'IFRAME', 'NOEMBED', 'NOFRAMES', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP', ); public function get_content_between_balanced_template_tags() { if ( 'TEMPLATE' !== $this->get_tag() ) { return null; } $positions = $this->get_after_opener_tag_and_before_closer_tag_positions(); if ( ! $positions ) { return null; } list( $after_opener_tag, $before_closer_tag ) = $positions; return substr( $this->html, $after_opener_tag, $before_closer_tag - $after_opener_tag ); } public function set_content_between_balanced_tags( string $new_content ): bool { $positions = $this->get_after_opener_tag_and_before_closer_tag_positions( true ); if ( ! $positions ) { return false; } list( $after_opener_tag, $before_closer_tag ) = $positions; $this->lexical_updates[] = new WP_HTML_Text_Replacement( $after_opener_tag, $before_closer_tag - $after_opener_tag, esc_html( $new_content ) ); return true; } public function append_content_after_template_tag_closer( string $new_content ): bool { if ( empty( $new_content ) || 'TEMPLATE' !== $this->get_tag() || ! $this->is_tag_closer() ) { return false; } $this->get_updated_html(); $bookmark = 'append_content_after_template_tag_closer'; $this->set_bookmark( $bookmark ); $after_closing_tag = $this->bookmarks[ $bookmark ]->start + $this->bookmarks[ $bookmark ]->length; $this->release_bookmark( $bookmark ); $this->lexical_updates[] = new WP_HTML_Text_Replacement( $after_closing_tag, 0, $new_content ); return true; } private function get_after_opener_tag_and_before_closer_tag_positions( bool $rewind = false ) { $this->get_updated_html(); $bookmarks = $this->get_balanced_tag_bookmarks(); if ( ! $bookmarks ) { return null; } list( $opener_tag, $closer_tag ) = $bookmarks; $after_opener_tag = $this->bookmarks[ $opener_tag ]->start + $this->bookmarks[ $opener_tag ]->length; $before_closer_tag = $this->bookmarks[ $closer_tag ]->start; if ( $rewind ) { $this->seek( $opener_tag ); } $this->release_bookmark( $opener_tag ); $this->release_bookmark( $closer_tag ); return array( $after_opener_tag, $before_closer_tag ); } private function get_balanced_tag_bookmarks() { static $i = 0; $opener_tag = 'opener_tag_of_balanced_tag_' . ++$i; $this->set_bookmark( $opener_tag ); if ( ! $this->next_balanced_tag_closer_tag() ) { $this->release_bookmark( $opener_tag ); return null; } $closer_tag = 'closer_tag_of_balanced_tag_' . ++$i; $this->set_bookmark( $closer_tag ); return array( $opener_tag, $closer_tag ); } public function skip_to_tag_closer(): bool { $depth = 1; $tag_name = $this->get_tag(); while ( $depth > 0 && $this->next_tag( array( 'tag_closers' => 'visit' ) ) ) { if ( ! $this->is_tag_closer() && $this->get_attribute_names_with_prefix( 'data-wp-' ) ) { $message = sprintf( __( 'Interactivity directives were detected inside an incompatible %1$s tag. These directives will be ignored in the server side render.' ), $tag_name ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); } if ( $this->get_tag() === $tag_name ) { if ( $this->has_self_closing_flag() ) { continue; } $depth += $this->is_tag_closer() ? -1 : 1; } } return 0 === $depth; } public function next_balanced_tag_closer_tag(): bool { $depth = 0; $tag_name = $this->get_tag(); if ( ! $this->has_and_visits_its_closer_tag() ) { return false; } while ( $this->next_tag( array( 'tag_name' => $tag_name, 'tag_closers' => 'visit', ) ) ) { if ( ! $this->is_tag_closer() ) { ++$depth; continue; } if ( 0 === $depth ) { return true; } --$depth; } return false; } public function has_and_visits_its_closer_tag(): bool { $tag_name = $this->get_tag(); return null !== $tag_name && ( ! WP_HTML_Processor::is_void( $tag_name ) && ! in_array( $tag_name, self::TAGS_THAT_DONT_VISIT_CLOSER_TAG, true ) ); } }
###require ABSPATH . WPINC . '/interactivity-api/interactivity-api.php';
function wp_interactivity(): WP_Interactivity_API { global $wp_interactivity; if ( ! ( $wp_interactivity instanceof WP_Interactivity_API ) ) { $wp_interactivity = new WP_Interactivity_API(); } return $wp_interactivity; } function wp_interactivity_process_directives( string $html ): string { return wp_interactivity()->process_directives( $html ); } function wp_interactivity_state( ?string $store_namespace = null, array $state = array() ): array { return wp_interactivity()->state( $store_namespace, $state ); } function wp_interactivity_config( string $store_namespace, array $config = array() ): array { return wp_interactivity()->config( $store_namespace, $config ); } function wp_interactivity_data_wp_context( array $context, string $store_namespace = '' ): string { return 'data-wp-context=\'' . ( $store_namespace ? $store_namespace . '::' : '' ) . ( empty( $context ) ? '{}' : wp_json_encode( $context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ) . '\''; } function wp_interactivity_get_context( ?string $store_namespace = null ): array { return wp_interactivity()->get_context( $store_namespace ); } function wp_interactivity_get_element(): ?array { return wp_interactivity()->get_element(); }
###require ABSPATH . WPINC . '/class-wp-plugin-dependencies.php';
class WP_Plugin_Dependencies { protected static $plugins; protected static $plugin_dirnames; protected static $dependencies; protected static $dependency_slugs; protected static $dependent_slugs; protected static $dependency_api_data; protected static $dependency_filepaths; protected static $circular_dependencies_pairs; protected static $circular_dependencies_slugs; protected static $initialized = false; public static function initialize() { if ( false === self::$initialized ) { self::read_dependencies_from_plugin_headers(); self::get_dependency_api_data(); self::$initialized = true; } } public static function has_dependents( $plugin_file ) { return in_array( self::convert_to_slug( $plugin_file ), (array) self::$dependency_slugs, true ); } public static function has_dependencies( $plugin_file ) { return isset( self::$dependencies[ $plugin_file ] ); } public static function has_active_dependents( $plugin_file ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $dependents = self::get_dependents( self::convert_to_slug( $plugin_file ) ); foreach ( $dependents as $dependent ) { if ( is_plugin_active( $dependent ) ) { return true; } } return false; } public static function get_dependents( $slug ) { $dependents = array(); foreach ( (array) self::$dependencies as $dependent => $dependencies ) { if ( in_array( $slug, $dependencies, true ) ) { $dependents[] = $dependent; } } return $dependents; } public static function get_dependencies( $plugin_file ) { if ( isset( self::$dependencies[ $plugin_file ] ) ) { return self::$dependencies[ $plugin_file ]; } return array(); } public static function get_dependent_filepath( $slug ) { $filepath = array_search( $slug, self::$dependent_slugs, true ); return $filepath ? $filepath : false; } public static function has_unmet_dependencies( $plugin_file ) { if ( ! isset( self::$dependencies[ $plugin_file ] ) ) { return false; } require_once ABSPATH . 'wp-admin/includes/plugin.php'; foreach ( self::$dependencies[ $plugin_file ] as $dependency ) { $dependency_filepath = self::get_dependency_filepath( $dependency ); if ( false === $dependency_filepath || is_plugin_inactive( $dependency_filepath ) ) { return true; } } return false; } public static function has_circular_dependency( $plugin_file ) { if ( ! is_array( self::$circular_dependencies_slugs ) ) { self::get_circular_dependencies(); } if ( ! empty( self::$circular_dependencies_slugs ) ) { $slug = self::convert_to_slug( $plugin_file ); if ( in_array( $slug, self::$circular_dependencies_slugs, true ) ) { return true; } } return false; } public static function get_dependent_names( $plugin_file ) { $dependent_names = array(); $plugins = self::get_plugins(); $slug = self::convert_to_slug( $plugin_file ); foreach ( self::get_dependents( $slug ) as $dependent ) { $dependent_names[ $dependent ] = $plugins[ $dependent ]['Name']; } sort( $dependent_names ); return $dependent_names; } public static function get_dependency_names( $plugin_file ) { $dependency_api_data = self::get_dependency_api_data(); $dependencies = self::get_dependencies( $plugin_file ); $plugins = self::get_plugins(); $dependency_names = array(); foreach ( $dependencies as $dependency ) { if ( isset( $dependency_api_data[ $dependency ]['name'] ) ) { $name = $dependency_api_data[ $dependency ]['name']; } else { $dependency_filepath = self::get_dependency_filepath( $dependency ); if ( false !== $dependency_filepath ) { $name = $plugins[ $dependency_filepath ]['Name']; } else { $name = $dependency; } } $dependency_names[ $dependency ] = $name; } return $dependency_names; } public static function get_dependency_filepath( $slug ) { $dependency_filepaths = self::get_dependency_filepaths(); if ( ! isset( $dependency_filepaths[ $slug ] ) ) { return false; } return $dependency_filepaths[ $slug ]; } public static function get_dependency_data( $slug ) { $dependency_api_data = self::get_dependency_api_data(); if ( isset( $dependency_api_data[ $slug ] ) ) { return $dependency_api_data[ $slug ]; } return false; } public static function display_admin_notice_for_unmet_dependencies() { if ( in_array( false, self::get_dependency_filepaths(), true ) ) { $error_message = __( 'Some required plugins are missing or inactive.' ); if ( is_multisite() ) { if ( current_user_can( 'manage_network_plugins' ) ) { $error_message .= ' ' . sprintf( __( '<a href="%s">Manage plugins</a>.' ), esc_url( network_admin_url( 'plugins.php' ) ) ); } else { $error_message .= ' ' . __( 'Please contact your network administrator.' ); } } elseif ( 'plugins' !== get_current_screen()->base ) { $error_message .= ' ' . sprintf( __( '<a href="%s">Manage plugins</a>.' ), esc_url( admin_url( 'plugins.php' ) ) ); } wp_admin_notice( $error_message, array( 'type' => 'warning', ) ); } } public static function display_admin_notice_for_circular_dependencies() { $circular_dependencies = self::get_circular_dependencies(); if ( ! empty( $circular_dependencies ) && count( $circular_dependencies ) > 1 ) { $circular_dependencies = array_unique( $circular_dependencies, SORT_REGULAR ); $plugins = self::get_plugins(); $plugin_dirnames = self::get_plugin_dirnames(); $circular_dependency_lines = ''; foreach ( $circular_dependencies as $circular_dependency ) { $first_filepath = $plugin_dirnames[ $circular_dependency[0] ]; $second_filepath = $plugin_dirnames[ $circular_dependency[1] ]; $circular_dependency_lines .= sprintf( '<li>' . _x( '%1$s requires %2$s', 'The first plugin requires the second plugin.' ) . '</li>', '<strong>' . esc_html( $plugins[ $first_filepath ]['Name'] ) . '</strong>', '<strong>' . esc_html( $plugins[ $second_filepath ]['Name'] ) . '</strong>' ); } wp_admin_notice( sprintf( '<p>%1$s</p><ul>%2$s</ul><p>%3$s</p>', __( 'These plugins cannot be activated because their requirements are invalid.' ), $circular_dependency_lines, __( 'Please contact the plugin authors for more information.' ) ), array( 'type' => 'warning', 'paragraph_wrap' => false, ) ); } } public static function check_plugin_dependencies_during_ajax() { check_ajax_referer( 'updates' ); if ( empty( $_POST['slug'] ) ) { wp_send_json_error( array( 'slug' => '', 'pluginName' => '', 'errorCode' => 'no_plugin_specified', 'errorMessage' => __( 'No plugin specified.' ), ) ); } $slug = sanitize_key( wp_unslash( $_POST['slug'] ) ); $status = array( 'slug' => $slug ); self::get_plugins(); self::get_plugin_dirnames(); if ( ! isset( self::$plugin_dirnames[ $slug ] ) ) { $status['errorCode'] = 'plugin_not_installed'; $status['errorMessage'] = __( 'The plugin is not installed.' ); wp_send_json_error( $status ); } $plugin_file = self::$plugin_dirnames[ $slug ]; $status['pluginName'] = self::$plugins[ $plugin_file ]['Name']; $status['plugin'] = $plugin_file; if ( current_user_can( 'activate_plugin', $plugin_file ) && is_plugin_inactive( $plugin_file ) ) { $status['activateUrl'] = add_query_arg( array( '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $plugin_file ), 'action' => 'activate', 'plugin' => $plugin_file, ), is_multisite() ? network_admin_url( 'plugins.php' ) : admin_url( 'plugins.php' ) ); } if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) { $status['activateUrl'] = add_query_arg( array( 'networkwide' => 1 ), $status['activateUrl'] ); } self::initialize(); $dependencies = self::get_dependencies( $plugin_file ); if ( empty( $dependencies ) ) { $status['message'] = __( 'The plugin has no required plugins.' ); wp_send_json_success( $status ); } require_once ABSPATH . 'wp-admin/includes/plugin.php'; $inactive_dependencies = array(); foreach ( $dependencies as $dependency ) { if ( false === self::$plugin_dirnames[ $dependency ] || is_plugin_inactive( self::$plugin_dirnames[ $dependency ] ) ) { $inactive_dependencies[] = $dependency; } } if ( ! empty( $inactive_dependencies ) ) { $inactive_dependency_names = array_map( function ( $dependency ) { if ( isset( self::$dependency_api_data[ $dependency ]['Name'] ) ) { $inactive_dependency_name = self::$dependency_api_data[ $dependency ]['Name']; } else { $inactive_dependency_name = $dependency; } return $inactive_dependency_name; }, $inactive_dependencies ); $status['errorCode'] = 'inactive_dependencies'; $status['errorMessage'] = sprintf( __( 'The following plugins must be activated first: %s.' ), implode( ', ', $inactive_dependency_names ) ); $status['errorData'] = array_combine( $inactive_dependencies, $inactive_dependency_names ); wp_send_json_error( $status ); } $status['message'] = __( 'All required plugins are installed and activated.' ); wp_send_json_success( $status ); } protected static function get_plugins() { if ( is_array( self::$plugins ) ) { return self::$plugins; } require_once ABSPATH . 'wp-admin/includes/plugin.php'; self::$plugins = get_plugins(); return self::$plugins; } protected static function read_dependencies_from_plugin_headers() { self::$dependencies = array(); self::$dependency_slugs = array(); self::$dependent_slugs = array(); $plugins = self::get_plugins(); foreach ( $plugins as $plugin => $header ) { if ( '' === $header['RequiresPlugins'] ) { continue; } $dependency_slugs = self::sanitize_dependency_slugs( $header['RequiresPlugins'] ); self::$dependencies[ $plugin ] = $dependency_slugs; self::$dependency_slugs = array_merge( self::$dependency_slugs, $dependency_slugs ); $dependent_slug = self::convert_to_slug( $plugin ); self::$dependent_slugs[ $plugin ] = $dependent_slug; } self::$dependency_slugs = array_unique( self::$dependency_slugs ); } protected static function sanitize_dependency_slugs( $slugs ) { $sanitized_slugs = array(); $slugs = explode( ',', $slugs ); foreach ( $slugs as $slug ) { $slug = trim( $slug ); $slug = apply_filters( 'wp_plugin_dependencies_slug', $slug ); if ( preg_match( '/^[a-z0-9]+(-[a-z0-9]+)*$/mu', $slug ) ) { $sanitized_slugs[] = $slug; } } $sanitized_slugs = array_unique( $sanitized_slugs ); sort( $sanitized_slugs ); return $sanitized_slugs; } protected static function get_dependency_filepaths() { if ( is_array( self::$dependency_filepaths ) ) { return self::$dependency_filepaths; } if ( null === self::$dependency_slugs ) { return array(); } self::$dependency_filepaths = array(); $plugin_dirnames = self::get_plugin_dirnames(); foreach ( self::$dependency_slugs as $slug ) { if ( isset( $plugin_dirnames[ $slug ] ) ) { self::$dependency_filepaths[ $slug ] = $plugin_dirnames[ $slug ]; continue; } self::$dependency_filepaths[ $slug ] = false; } return self::$dependency_filepaths; } protected static function get_dependency_api_data() { global $pagenow; if ( ! is_admin() || ( 'plugins.php' !== $pagenow && 'plugin-install.php' !== $pagenow ) ) { return; } if ( is_array( self::$dependency_api_data ) ) { return self::$dependency_api_data; } $plugins = self::get_plugins(); self::$dependency_api_data = (array) get_site_transient( 'wp_plugin_dependencies_plugin_data' ); foreach ( self::$dependency_slugs as $slug ) { if ( ! get_site_transient( "wp_plugin_dependencies_plugin_timeout_{$slug}" ) ) { unset( self::$dependency_api_data[ $slug ] ); set_site_transient( "wp_plugin_dependencies_plugin_timeout_{$slug}", true, 12 * HOUR_IN_SECONDS ); } if ( isset( self::$dependency_api_data[ $slug ] ) ) { if ( false === self::$dependency_api_data[ $slug ] ) { $dependency_file = self::get_dependency_filepath( $slug ); if ( false === $dependency_file ) { self::$dependency_api_data[ $slug ] = array( 'Name' => $slug ); } else { self::$dependency_api_data[ $slug ] = array( 'Name' => $plugins[ $dependency_file ]['Name'] ); } continue; } if ( ! empty( self::$dependency_api_data[ $slug ]['last_updated'] ) ) { continue; } } if ( ! function_exists( 'plugins_api' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } $information = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'short_description' => true, 'icons' => true, ), ) ); if ( is_wp_error( $information ) ) { continue; } self::$dependency_api_data[ $slug ] = (array) $information; self::$dependency_api_data[ $slug ]['Name'] = self::$dependency_api_data[ $slug ]['name']; set_site_transient( 'wp_plugin_dependencies_plugin_data', self::$dependency_api_data, 0 ); } $differences = array_diff( array_keys( self::$dependency_api_data ), self::$dependency_slugs ); foreach ( $differences as $difference ) { unset( self::$dependency_api_data[ $difference ] ); } ksort( self::$dependency_api_data ); self::$dependency_api_data = array_filter( self::$dependency_api_data ); set_site_transient( 'wp_plugin_dependencies_plugin_data', self::$dependency_api_data, 0 ); return self::$dependency_api_data; } protected static function get_plugin_dirnames() { if ( is_array( self::$plugin_dirnames ) ) { return self::$plugin_dirnames; } self::$plugin_dirnames = array(); $plugin_files = array_keys( self::get_plugins() ); foreach ( $plugin_files as $plugin_file ) { $slug = self::convert_to_slug( $plugin_file ); self::$plugin_dirnames[ $slug ] = $plugin_file; } return self::$plugin_dirnames; } protected static function get_circular_dependencies() { if ( is_array( self::$circular_dependencies_pairs ) ) { return self::$circular_dependencies_pairs; } if ( null === self::$dependencies ) { return array(); } self::$circular_dependencies_slugs = array(); self::$circular_dependencies_pairs = array(); foreach ( self::$dependencies as $dependent => $dependencies ) { $dependent_slug = self::convert_to_slug( $dependent ); self::$circular_dependencies_pairs = array_merge( self::$circular_dependencies_pairs, self::check_for_circular_dependencies( array( $dependent_slug ), $dependencies ) ); } return self::$circular_dependencies_pairs; } protected static function check_for_circular_dependencies( $dependents, $dependencies ) { $circular_dependencies_pairs = array(); $dependents_location_in_its_own_dependencies = array_intersect( $dependents, $dependencies ); if ( ! empty( $dependents_location_in_its_own_dependencies ) ) { foreach ( $dependents_location_in_its_own_dependencies as $self_dependency ) { self::$circular_dependencies_slugs[] = $self_dependency; $circular_dependencies_pairs[] = array( $self_dependency, $self_dependency ); unset( $dependencies[ array_search( $self_dependency, $dependencies, true ) ] ); } } foreach ( $dependencies as $dependency ) { $dependency_location_in_dependents = array_search( $dependency, self::$dependent_slugs, true ); if ( false !== $dependency_location_in_dependents ) { $dependencies_of_the_dependency = self::$dependencies[ $dependency_location_in_dependents ]; foreach ( $dependents as $dependent ) { $dependent_location_in_dependency_dependencies = array_search( $dependent, $dependencies_of_the_dependency, true ); if ( false !== $dependent_location_in_dependency_dependencies ) { self::$circular_dependencies_slugs[] = $dependent; self::$circular_dependencies_slugs[] = $dependency; $circular_dependencies_pairs[] = array( $dependent, $dependency ); unset( $dependencies_of_the_dependency[ $dependent_location_in_dependency_dependencies ] ); } } $dependents[] = $dependency; $circular_dependencies_pairs = array_merge( $circular_dependencies_pairs, self::check_for_circular_dependencies( $dependents, array_unique( $dependencies_of_the_dependency ) ) ); } } return $circular_dependencies_pairs; } protected static function convert_to_slug( $plugin_file ) { if ( 'hello.php' === $plugin_file ) { return 'hello-dolly'; } return str_contains( $plugin_file, '/' ) ? dirname( $plugin_file ) : str_replace( '.php', '', $plugin_file ); } }
###require ABSPATH . WPINC . '/class-wp-url-pattern-prefixer.php';
class WP_URL_Pattern_Prefixer { private $contexts; public function __construct( array $contexts = array() ) { if ( count( $contexts ) > 0 ) { $this->contexts = array_map( static function ( string $str ): string { return self::escape_pattern_string( trailingslashit( $str ) ); }, $contexts ); } else { $this->contexts = self::get_default_contexts(); } } public function prefix_path_pattern( string $path_pattern, string $context = 'home' ): string { if ( ! isset( $this->contexts[ $context ] ) ) { _doing_it_wrong( __FUNCTION__, esc_html( sprintf( __( 'Invalid URL pattern context %s.' ), $context ) ), '6.8.0' ); return $path_pattern; } $context_path = $this->contexts[ $context ]; $escaped_context_path = $context_path; if ( strcspn( $context_path, ':?#' ) !== strlen( $context_path ) ) { $escaped_context_path = '{' . substr( $context_path, 0, -1 ) . '}/'; } if ( str_starts_with( $path_pattern, $context_path ) ) { $path_pattern = substr( $path_pattern, strlen( $context_path ) ); } return $escaped_context_path . ltrim( $path_pattern, '/' ); } public static function get_default_contexts(): array { return array( 'home' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( home_url( '/' ), PHP_URL_PATH ) ) ), 'site' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( site_url( '/' ), PHP_URL_PATH ) ) ), 'uploads' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( wp_upload_dir( null, false )['baseurl'], PHP_URL_PATH ) ) ), 'content' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( content_url(), PHP_URL_PATH ) ) ), 'plugins' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( plugins_url(), PHP_URL_PATH ) ) ), 'template' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( get_stylesheet_directory_uri(), PHP_URL_PATH ) ) ), 'stylesheet' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( get_template_directory_uri(), PHP_URL_PATH ) ) ), ); } private static function escape_pattern_string( string $str ): string { return addcslashes( $str, '+*?:{}()\\' ); } }
###require ABSPATH . WPINC . '/class-wp-speculation-rules.php';
final class WP_Speculation_Rules implements JsonSerializable { private $rules_by_mode = array(); private static $mode_allowlist = array( 'prefetch' => true, 'prerender' => true, ); private static $eagerness_allowlist = array( 'immediate' => true, 'eager' => true, 'moderate' => true, 'conservative' => true, ); private static $source_allowlist = array( 'list' => true, 'document' => true, ); public function add_rule( string $mode, string $id, array $rule ): bool { if ( ! self::is_valid_mode( $mode ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The value "%s" is not a valid speculation rules mode.' ), esc_html( $mode ) ), '6.8.0' ); return false; } if ( ! $this->is_valid_id( $id ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The value "%s" is not a valid ID for a speculation rule.' ), esc_html( $id ) ), '6.8.0' ); return false; } if ( $this->has_rule( $mode, $id ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'A speculation rule with ID "%s" already exists.' ), esc_html( $id ) ), '6.8.0' ); return false; } if ( ( ! isset( $rule['where'] ) && ! isset( $rule['urls'] ) ) || ( isset( $rule['where'] ) && isset( $rule['urls'] ) ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'A speculation rule must include either a "%1$s" key or a "%2$s" key, but not both.' ), 'where', 'urls' ), '6.8.0' ); return false; } if ( isset( $rule['source'] ) ) { if ( ! self::is_valid_source( $rule['source'] ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The value "%s" is not a valid source for a speculation rule.' ), esc_html( $rule['source'] ) ), '6.8.0' ); return false; } if ( 'list' === $rule['source'] && isset( $rule['where'] ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ), 'list', 'where' ), '6.8.0' ); return false; } if ( 'document' === $rule['source'] && isset( $rule['urls'] ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ), 'document', 'urls' ), '6.8.0' ); return false; } } if ( isset( $rule['eagerness'] ) ) { if ( ! self::is_valid_eagerness( $rule['eagerness'] ) ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The value "%s" is not a valid eagerness for a speculation rule.' ), esc_html( $rule['eagerness'] ) ), '6.8.0' ); return false; } if ( isset( $rule['where'] ) && 'immediate' === $rule['eagerness'] ) { _doing_it_wrong( __METHOD__, sprintf( __( 'The eagerness value "%s" is forbidden for document-level speculation rules.' ), 'immediate' ), '6.8.0' ); return false; } } if ( ! isset( $this->rules_by_mode[ $mode ] ) ) { $this->rules_by_mode[ $mode ] = array(); } $this->rules_by_mode[ $mode ][ $id ] = $rule; return true; } public function has_rule( string $mode, string $id ): bool { return isset( $this->rules_by_mode[ $mode ][ $id ] ); } public function jsonSerialize() { return array_map( static function ( array $rules ) { return array_values( $rules ); }, array_filter( $this->rules_by_mode ) ); } private function is_valid_id( string $id ): bool { return (bool) preg_match( '/^[a-z][a-z0-9_-]+$/', $id ); } public static function is_valid_mode( string $mode ): bool { return isset( self::$mode_allowlist[ $mode ] ); } public static function is_valid_eagerness( string $eagerness ): bool { return isset( self::$eagerness_allowlist[ $eagerness ] ); } public static function is_valid_source( string $source ): bool { return isset( self::$source_allowlist[ $source ] ); } }
###require ABSPATH . WPINC . '/speculative-loading.php';
function wp_get_speculation_rules_configuration(): ?array { if ( ! is_user_logged_in() && get_option( 'permalink_structure' ) ) { $config = array( 'mode' => 'auto', 'eagerness' => 'auto', ); } else { $config = null; } $config = apply_filters( 'wp_speculation_rules_configuration', $config ); if ( null === $config ) { return null; } $default_mode = 'prefetch'; $default_eagerness = 'conservative'; if ( ! is_array( $config ) ) { return array( 'mode' => $default_mode, 'eagerness' => $default_eagerness, ); } if ( ! isset( $config['mode'] ) || 'auto' === $config['mode'] || ! WP_Speculation_Rules::is_valid_mode( $config['mode'] ) ) { $config['mode'] = $default_mode; } if ( ! isset( $config['eagerness'] ) || 'auto' === $config['eagerness'] || ! WP_Speculation_Rules::is_valid_eagerness( $config['eagerness'] ) || 'immediate' === $config['eagerness'] ) { $config['eagerness'] = $default_eagerness; } return array( 'mode' => $config['mode'], 'eagerness' => $config['eagerness'], ); } function wp_get_speculation_rules(): ?WP_Speculation_Rules { $configuration = wp_get_speculation_rules_configuration(); if ( null === $configuration ) { return null; } $mode = $configuration['mode']; $eagerness = $configuration['eagerness']; $prefixer = new WP_URL_Pattern_Prefixer(); $base_href_exclude_paths = array( $prefixer->prefix_path_pattern( '/wp-*.php', 'site' ), $prefixer->prefix_path_pattern( '/wp-admin/*', 'site' ), $prefixer->prefix_path_pattern( '/*', 'uploads' ), $prefixer->prefix_path_pattern( '/*', 'content' ), $prefixer->prefix_path_pattern( '/*', 'plugins' ), $prefixer->prefix_path_pattern( '/*', 'template' ), $prefixer->prefix_path_pattern( '/*', 'stylesheet' ), ); if ( get_option( 'permalink_structure' ) ) { $base_href_exclude_paths[] = $prefixer->prefix_path_pattern( '/*\\?(.+)', 'home' ); } else { $base_href_exclude_paths[] = $prefixer->prefix_path_pattern( '/*\\?*(^|&)*nonce*=*', 'home' ); } $href_exclude_paths = (array) apply_filters( 'wp_speculation_rules_href_exclude_paths', array(), $mode ); $href_exclude_paths = array_values( array_unique( array_merge( $base_href_exclude_paths, array_map( static function ( string $href_exclude_path ) use ( $prefixer ): string { return $prefixer->prefix_path_pattern( $href_exclude_path ); }, $href_exclude_paths ) ) ) ); $speculation_rules = new WP_Speculation_Rules(); $main_rule_conditions = array( array( 'href_matches' => $prefixer->prefix_path_pattern( '/*' ), ), array( 'not' => array( 'href_matches' => $href_exclude_paths, ), ), array( 'not' => array( 'selector_matches' => 'a[rel~="nofollow"]', ), ), array( 'not' => array( 'selector_matches' => ".no-{$mode}, .no-{$mode} a", ), ), ); if ( 'prerender' === $mode ) { $main_rule_conditions[] = array( 'not' => array( 'selector_matches' => '.no-prefetch, .no-prefetch a', ), ); } $speculation_rules->add_rule( $mode, 'main', array( 'source' => 'document', 'where' => array( 'and' => $main_rule_conditions, ), 'eagerness' => $eagerness, ) ); do_action( 'wp_load_speculation_rules', $speculation_rules ); return $speculation_rules; } function wp_print_speculation_rules(): void { $speculation_rules = wp_get_speculation_rules(); if ( null === $speculation_rules ) { return; } wp_print_inline_script_tag( (string) wp_json_encode( $speculation_rules, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ), array( 'type' => 'speculationrules' ) ); }
add_action( 'after_setup_theme', array( wp_script_modules(), 'add_hooks' ) );
add_action( 'after_setup_theme', array( wp_interactivity(), 'add_hooks' ) );
$GLOBALS['wp_embed'] = new WP_Embed();
$GLOBALS['wp_textdomain_registry'] = new WP_Textdomain_Registry();
$GLOBALS['wp_textdomain_registry']->init();
if ( is_multisite() ) {
### require ABSPATH . WPINC . '/ms-functions.php';
function get_sitestats() { $stats = array( 'blogs' => get_blog_count(), 'users' => get_user_count(), ); return $stats; } function get_active_blog_for_user( $user_id ) { $blogs = get_blogs_of_user( $user_id ); if ( empty( $blogs ) ) { return; } if ( ! is_multisite() ) { return $blogs[ get_current_blog_id() ]; } $primary_blog = get_user_meta( $user_id, 'primary_blog', true ); $first_blog = current( $blogs ); if ( false !== $primary_blog ) { if ( ! isset( $blogs[ $primary_blog ] ) ) { update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id ); $primary = get_site( $first_blog->userblog_id ); } else { $primary = get_site( $primary_blog ); } } else { $result = add_user_to_blog( $first_blog->userblog_id, $user_id, 'subscriber' ); if ( ! is_wp_error( $result ) ) { update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id ); $primary = $first_blog; } } if ( ( ! is_object( $primary ) ) || ( '1' === $primary->archived || '1' === $primary->spam || '1' === $primary->deleted ) ) { $blogs = get_blogs_of_user( $user_id, true ); $ret = false; if ( is_array( $blogs ) && count( $blogs ) > 0 ) { $current_network_id = get_current_network_id(); foreach ( (array) $blogs as $blog_id => $blog ) { if ( $blog->site_id !== $current_network_id ) { continue; } $details = get_site( $blog_id ); if ( is_object( $details ) && '0' === $details->archived && '0' === $details->spam && '0' === $details->deleted ) { $ret = $details; if ( (int) get_user_meta( $user_id, 'primary_blog', true ) !== $blog_id ) { update_user_meta( $user_id, 'primary_blog', $blog_id ); } if ( ! get_user_meta( $user_id, 'source_domain', true ) ) { update_user_meta( $user_id, 'source_domain', $details->domain ); } break; } } } else { return; } return $ret; } else { return $primary; } } function get_blog_count( $network_id = null ) { return get_network_option( $network_id, 'blog_count' ); } function get_blog_post( $blog_id, $post_id ) { switch_to_blog( $blog_id ); $post = get_post( $post_id ); restore_current_blog(); return $post; } function add_user_to_blog( $blog_id, $user_id, $role ) { switch_to_blog( $blog_id ); $user = get_userdata( $user_id ); if ( ! $user ) { restore_current_blog(); return new WP_Error( 'user_does_not_exist', __( 'The requested user does not exist.' ) ); } $can_add_user = apply_filters( 'can_add_user_to_blog', true, $user_id, $role, $blog_id ); if ( true !== $can_add_user ) { restore_current_blog(); if ( is_wp_error( $can_add_user ) ) { return $can_add_user; } return new WP_Error( 'user_cannot_be_added', __( 'User cannot be added to this site.' ) ); } if ( ! get_user_meta( $user_id, 'primary_blog', true ) ) { update_user_meta( $user_id, 'primary_blog', $blog_id ); $site = get_site( $blog_id ); update_user_meta( $user_id, 'source_domain', $site->domain ); } $user->set_role( $role ); do_action( 'add_user_to_blog', $user_id, $role, $blog_id ); clean_user_cache( $user_id ); wp_cache_delete( $blog_id . '_user_count', 'blog-details' ); restore_current_blog(); return true; } function remove_user_from_blog( $user_id, $blog_id = 0, $reassign = 0 ) { global $wpdb; $user_id = (int) $user_id; $blog_id = (int) $blog_id; switch_to_blog( $blog_id ); do_action( 'remove_user_from_blog', $user_id, $blog_id, $reassign ); $primary_blog = (int) get_user_meta( $user_id, 'primary_blog', true ); if ( $primary_blog === $blog_id ) { $new_id = ''; $new_domain = ''; $blogs = get_blogs_of_user( $user_id ); foreach ( (array) $blogs as $blog ) { if ( $blog->userblog_id === $blog_id ) { continue; } $new_id = $blog->userblog_id; $new_domain = $blog->domain; break; } update_user_meta( $user_id, 'primary_blog', $new_id ); update_user_meta( $user_id, 'source_domain', $new_domain ); } $user = get_userdata( $user_id ); if ( ! $user ) { restore_current_blog(); return new WP_Error( 'user_does_not_exist', __( 'That user does not exist.' ) ); } $user->remove_all_caps(); $blogs = get_blogs_of_user( $user_id ); if ( count( $blogs ) === 0 ) { update_user_meta( $user_id, 'primary_blog', '' ); update_user_meta( $user_id, 'source_domain', '' ); } if ( $reassign ) { $reassign = (int) $reassign; $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $user_id ) ); $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $user_id ) ); if ( ! empty( $post_ids ) ) { $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_author = %d WHERE post_author = %d", $reassign, $user_id ) ); array_walk( $post_ids, 'clean_post_cache' ); } if ( ! empty( $link_ids ) ) { $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->links SET link_owner = %d WHERE link_owner = %d", $reassign, $user_id ) ); array_walk( $link_ids, 'clean_bookmark_cache' ); } } clean_user_cache( $user_id ); restore_current_blog(); return true; } function get_blog_permalink( $blog_id, $post_id ) { switch_to_blog( $blog_id ); $link = get_permalink( $post_id ); restore_current_blog(); return $link; } function get_blog_id_from_url( $domain, $path = '/' ) { $domain = strtolower( $domain ); $path = strtolower( $path ); $id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' ); if ( -1 === $id ) { return 0; } elseif ( $id ) { return (int) $id; } $args = array( 'domain' => $domain, 'path' => $path, 'fields' => 'ids', 'number' => 1, 'update_site_meta_cache' => false, ); $result = get_sites( $args ); $id = array_shift( $result ); if ( ! $id ) { wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' ); return 0; } wp_cache_set( md5( $domain . $path ), $id, 'blog-id-cache' ); return $id; } function is_email_address_unsafe( $user_email ) { $banned_names = get_site_option( 'banned_email_domains' ); if ( $banned_names && ! is_array( $banned_names ) ) { $banned_names = explode( "\n", $banned_names ); } $is_email_address_unsafe = false; if ( $banned_names && is_array( $banned_names ) && false !== strpos( $user_email, '@', 1 ) ) { $banned_names = array_map( 'strtolower', $banned_names ); $normalized_email = strtolower( $user_email ); list( $email_local_part, $email_domain ) = explode( '@', $normalized_email ); foreach ( $banned_names as $banned_domain ) { if ( ! $banned_domain ) { continue; } if ( $email_domain === $banned_domain ) { $is_email_address_unsafe = true; break; } if ( str_ends_with( $normalized_email, ".$banned_domain" ) ) { $is_email_address_unsafe = true; break; } } } return apply_filters( 'is_email_address_unsafe', $is_email_address_unsafe, $user_email ); } function wpmu_validate_user_signup( $user_name, $user_email ) { global $wpdb; $errors = new WP_Error(); $orig_username = $user_name; $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) ); if ( $user_name !== $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) { $errors->add( 'user_name', __( 'Usernames can only contain lowercase letters (a-z) and numbers.' ) ); $user_name = $orig_username; } $user_email = sanitize_email( $user_email ); if ( empty( $user_name ) ) { $errors->add( 'user_name', __( 'Please enter a username.' ) ); } $illegal_names = get_site_option( 'illegal_names' ); if ( ! is_array( $illegal_names ) ) { $illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' ); add_site_option( 'illegal_names', $illegal_names ); } if ( in_array( $user_name, $illegal_names, true ) ) { $errors->add( 'user_name', __( 'Sorry, that username is not allowed.' ) ); } $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $user_name ), array_map( 'strtolower', $illegal_logins ), true ) ) { $errors->add( 'user_name', __( 'Sorry, that username is not allowed.' ) ); } if ( ! is_email( $user_email ) ) { $errors->add( 'user_email', __( 'Please enter a valid email address.' ) ); } elseif ( is_email_address_unsafe( $user_email ) ) { $errors->add( 'user_email', __( 'You cannot use that email address to signup. There are problems with them blocking some emails from WordPress. Please use another email provider.' ) ); } if ( strlen( $user_name ) < 4 ) { $errors->add( 'user_name', __( 'Username must be at least 4 characters.' ) ); } if ( strlen( $user_name ) > 60 ) { $errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) ); } if ( preg_match( '/^[0-9]*$/', $user_name ) ) { $errors->add( 'user_name', __( 'Sorry, usernames must have letters too!' ) ); } $limited_email_domains = get_site_option( 'limited_email_domains' ); if ( is_array( $limited_email_domains ) && ! empty( $limited_email_domains ) ) { $limited_email_domains = array_map( 'strtolower', $limited_email_domains ); $email_domain = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) ); if ( ! in_array( $email_domain, $limited_email_domains, true ) ) { $errors->add( 'user_email', __( 'Sorry, that email address is not allowed!' ) ); } } if ( username_exists( $user_name ) ) { $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) ); } if ( email_exists( $user_email ) ) { $errors->add( 'user_email', sprintf( __( '<strong>Error:</strong> This email address is already registered. <a href="%s">Log in</a> with this address or choose another one.' ), wp_login_url() ) ); } $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name ) ); if ( $signup instanceof stdClass ) { $registered_at = mysql2date( 'U', $signup->registered ); $now = time(); $diff = $now - $registered_at; if ( $diff > 2 * DAY_IN_SECONDS ) { $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_name ) ); } else { $errors->add( 'user_name', __( 'That username is currently reserved but may be available in a couple of days.' ) ); } } $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email ) ); if ( $signup instanceof stdClass ) { $diff = time() - mysql2date( 'U', $signup->registered ); if ( $diff > 2 * DAY_IN_SECONDS ) { $wpdb->delete( $wpdb->signups, array( 'user_email' => $user_email ) ); } else { $errors->add( 'user_email', __( 'That email address is pending activation and is not available for new registration. If you made a previous attempt with this email address, please check your inbox for an activation email. If left unconfirmed, it will become available in a couple of days.' ) ); } } $result = array( 'user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors, ); return apply_filters( 'wpmu_validate_user_signup', $result ); } function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) { global $wpdb, $domain; $current_network = get_network(); $base = $current_network->path; $blog_title = strip_tags( $blog_title ); $errors = new WP_Error(); $illegal_names = get_site_option( 'illegal_names' ); if ( ! is_array( $illegal_names ) ) { $illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' ); add_site_option( 'illegal_names', $illegal_names ); } if ( ! is_subdomain_install() ) { $illegal_names = array_merge( $illegal_names, get_subdirectory_reserved_names() ); } if ( empty( $blogname ) ) { $errors->add( 'blogname', __( 'Please enter a site name.' ) ); } if ( preg_match( '/[^a-z0-9]+/', $blogname ) ) { $errors->add( 'blogname', __( 'Site names can only contain lowercase letters (a-z) and numbers.' ) ); } if ( in_array( $blogname, $illegal_names, true ) ) { $errors->add( 'blogname', __( 'That name is not allowed.' ) ); } $minimum_site_name_length = apply_filters( 'minimum_site_name_length', 4 ); if ( strlen( $blogname ) < $minimum_site_name_length ) { $errors->add( 'blogname', sprintf( _n( 'Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length ), number_format_i18n( $minimum_site_name_length ) ) ); } if ( ! is_subdomain_install() && $wpdb->get_var( $wpdb->prepare( 'SELECT post_name FROM ' . $wpdb->get_blog_prefix( $current_network->site_id ) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname ) ) ) { $errors->add( 'blogname', __( 'Sorry, you may not use that site name.' ) ); } if ( preg_match( '/^[0-9]*$/', $blogname ) ) { $errors->add( 'blogname', __( 'Sorry, site names must have letters too!' ) ); } $blogname = apply_filters( 'newblogname', $blogname ); $blog_title = wp_unslash( $blog_title ); if ( empty( $blog_title ) ) { $errors->add( 'blog_title', __( 'Please enter a site title.' ) ); } if ( is_subdomain_install() ) { $mydomain = $blogname . '.' . preg_replace( '|^www\.|', '', $domain ); $path = $base; } else { $mydomain = $domain; $path = $base . $blogname . '/'; } if ( domain_exists( $mydomain, $path, $current_network->id ) ) { $errors->add( 'blogname', __( 'Sorry, that site already exists!' ) ); } if ( username_exists( $blogname ) ) { if ( ! $user instanceof WP_User || $user->user_login !== $blogname ) { $errors->add( 'blogname', __( 'Sorry, that site is reserved!' ) ); } } $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path ) ); if ( $signup instanceof stdClass ) { $diff = time() - mysql2date( 'U', $signup->registered ); if ( $diff > 2 * DAY_IN_SECONDS ) { $wpdb->delete( $wpdb->signups, array( 'domain' => $mydomain, 'path' => $path, ) ); } else { $errors->add( 'blogname', __( 'That site is currently reserved but may be available in a couple days.' ) ); } } $result = array( 'domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors, ); return apply_filters( 'wpmu_validate_blog_signup', $result ); } function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() ) { global $wpdb; $key = substr( md5( time() . wp_rand() . $domain ), 0, 16 ); $meta = apply_filters( 'signup_site_meta', $meta, $domain, $path, $title, $user, $user_email, $key ); $wpdb->insert( $wpdb->signups, array( 'domain' => $domain, 'path' => $path, 'title' => $title, 'user_login' => $user, 'user_email' => $user_email, 'registered' => current_time( 'mysql', true ), 'activation_key' => $key, 'meta' => serialize( $meta ), ) ); do_action( 'after_signup_site', $domain, $path, $title, $user, $user_email, $key, $meta ); } function wpmu_signup_user( $user, $user_email, $meta = array() ) { global $wpdb; $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) ); $user_email = sanitize_email( $user_email ); $key = substr( md5( time() . wp_rand() . $user_email ), 0, 16 ); $meta = apply_filters( 'signup_user_meta', $meta, $user, $user_email, $key ); $wpdb->insert( $wpdb->signups, array( 'domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => current_time( 'mysql', true ), 'activation_key' => $key, 'meta' => serialize( $meta ), ) ); do_action( 'after_signup_user', $user, $user_email, $key, $meta ); } function wpmu_signup_blog_notification( $domain, $path, $title, $user_login, $user_email, $key, $meta = array() ) { if ( ! apply_filters( 'wpmu_signup_blog_notification', $domain, $path, $title, $user_login, $user_email, $key, $meta ) ) { return false; } if ( ! is_subdomain_install() || get_current_network_id() !== 1 ) { $activate_url = network_site_url( "wp-activate.php?key=$key" ); } else { $activate_url = "http://{$domain}{$path}wp-activate.php?key=$key"; } $activate_url = esc_url( $activate_url ); $admin_email = get_site_option( 'admin_email' ); if ( '' === $admin_email ) { $admin_email = 'support@' . wp_parse_url( network_home_url(), PHP_URL_HOST ); } $from_name = ( '' !== get_site_option( 'site_name' ) ) ? esc_html( get_site_option( 'site_name' ) ) : 'WordPress'; $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . "\"\n"; $user = get_user_by( 'login', $user_login ); $switched_locale = $user && switch_to_user_locale( $user->ID ); $message = sprintf( apply_filters( 'wpmu_signup_blog_notification_email', __( "To activate your site, please click the following link:\n\n%1\$s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your site here:\n\n%2\$s" ), $domain, $path, $title, $user_login, $user_email, $key, $meta ), $activate_url, esc_url( "http://{$domain}{$path}" ), $key ); $subject = sprintf( apply_filters( 'wpmu_signup_blog_notification_subject', _x( '[%1$s] Activate %2$s', 'New site notification email subject' ), $domain, $path, $title, $user_login, $user_email, $key, $meta ), $from_name, esc_url( 'http://' . $domain . $path ) ); wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers ); if ( $switched_locale ) { restore_previous_locale(); } return true; } function wpmu_signup_user_notification( $user_login, $user_email, $key, $meta = array() ) { if ( ! apply_filters( 'wpmu_signup_user_notification', $user_login, $user_email, $key, $meta ) ) { return false; } $user = get_user_by( 'login', $user_login ); $switched_locale = $user && switch_to_user_locale( $user->ID ); $admin_email = get_site_option( 'admin_email' ); if ( '' === $admin_email ) { $admin_email = 'support@' . wp_parse_url( network_home_url(), PHP_URL_HOST ); } $from_name = ( '' !== get_site_option( 'site_name' ) ) ? esc_html( get_site_option( 'site_name' ) ) : 'WordPress'; $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . "\"\n"; $message = sprintf( apply_filters( 'wpmu_signup_user_notification_email', __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login." ), $user_login, $user_email, $key, $meta ), site_url( "wp-activate.php?key=$key" ) ); $subject = sprintf( apply_filters( 'wpmu_signup_user_notification_subject', _x( '[%1$s] Activate %2$s', 'New user notification email subject' ), $user_login, $user_email, $key, $meta ), $from_name, $user_login ); wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers ); if ( $switched_locale ) { restore_previous_locale(); } return true; } function wpmu_activate_signup( $key ) { global $wpdb; $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key ) ); if ( empty( $signup ) ) { return new WP_Error( 'invalid_key', __( 'Invalid activation key.' ) ); } if ( $signup->active ) { if ( empty( $signup->domain ) ) { return new WP_Error( 'already_active', __( 'The user is already active.' ), $signup ); } else { return new WP_Error( 'already_active', __( 'The site is already active.' ), $signup ); } } $meta = maybe_unserialize( $signup->meta ); $password = wp_generate_password( 12, false ); $user_id = username_exists( $signup->user_login ); if ( ! $user_id ) { $user_id = wpmu_create_user( $signup->user_login, $password, $signup->user_email ); } else { $user_already_exists = true; } if ( ! $user_id ) { return new WP_Error( 'create_user', __( 'Could not create user' ), $signup ); } $now = current_time( 'mysql', true ); if ( empty( $signup->domain ) ) { $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => $now, ), array( 'activation_key' => $key ) ); if ( isset( $user_already_exists ) ) { return new WP_Error( 'user_already_exists', __( 'That username is already activated.' ), $signup ); } do_action( 'wpmu_activate_user', $user_id, $password, $meta ); return array( 'user_id' => $user_id, 'password' => $password, 'meta' => $meta, ); } $blog_id = wpmu_create_blog( $signup->domain, $signup->path, $signup->title, $user_id, $meta, get_current_network_id() ); if ( is_wp_error( $blog_id ) ) { if ( 'blog_taken' === $blog_id->get_error_code() ) { $blog_id->add_data( $signup ); $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => $now, ), array( 'activation_key' => $key ) ); } return $blog_id; } $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => $now, ), array( 'activation_key' => $key ) ); do_action( 'wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta ); return array( 'blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta, ); } function wp_delete_signup_on_user_delete( $id, $reassign, $user ) { global $wpdb; $wpdb->delete( $wpdb->signups, array( 'user_login' => $user->user_login ) ); } function wpmu_create_user( $user_name, $password, $email ) { $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) ); $user_id = wp_create_user( $user_name, $password, $email ); if ( is_wp_error( $user_id ) ) { return false; } delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'user_level' ); do_action( 'wpmu_new_user', $user_id ); return $user_id; } function wpmu_create_blog( $domain, $path, $title, $user_id, $options = array(), $network_id = 1 ) { $defaults = array( 'public' => 0, ); $options = wp_parse_args( $options, $defaults ); $title = strip_tags( $title ); $user_id = (int) $user_id; if ( domain_exists( $domain, $path, $network_id ) ) { return new WP_Error( 'blog_taken', __( 'Sorry, that site already exists!' ) ); } if ( ! wp_installing() ) { wp_installing( true ); } $allowed_data_fields = array( 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); $site_data = array_merge( array( 'domain' => $domain, 'path' => $path, 'network_id' => $network_id, ), array_intersect_key( $options, array_flip( $allowed_data_fields ) ) ); $site_initialization_data = array( 'title' => $title, 'user_id' => $user_id, 'options' => array_diff_key( $options, array_flip( $allowed_data_fields ) ), ); $blog_id = wp_insert_site( array_merge( $site_data, $site_initialization_data ) ); if ( is_wp_error( $blog_id ) ) { return $blog_id; } wp_cache_set_sites_last_changed(); return $blog_id; } function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) { if ( is_object( $blog_id ) ) { $blog_id = $blog_id->blog_id; } if ( 'yes' !== get_site_option( 'registrationnotification' ) ) { return false; } $email = get_site_option( 'admin_email' ); if ( ! is_email( $email ) ) { return false; } $options_site_url = esc_url( network_admin_url( 'settings.php' ) ); switch_to_blog( $blog_id ); $blogname = get_option( 'blogname' ); $siteurl = site_url(); restore_current_blog(); $msg = sprintf( __( 'New Site: %1$s
URL: %2$s
Remote IP address: %3$s
Disable these notifications: %4$s' ), $blogname, $siteurl, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url ); $msg = apply_filters( 'newblog_notify_siteadmin', $msg, $blog_id ); wp_mail( $email, sprintf( __( 'New Site Registration: %s' ), $siteurl ), $msg ); return true; } function newuser_notify_siteadmin( $user_id ) { if ( 'yes' !== get_site_option( 'registrationnotification' ) ) { return false; } $email = get_site_option( 'admin_email' ); if ( ! is_email( $email ) ) { return false; } $user = get_userdata( $user_id ); $options_site_url = esc_url( network_admin_url( 'settings.php' ) ); $msg = sprintf( __( 'New User: %1$s
Remote IP address: %2$s
Disable these notifications: %3$s' ), $user->user_login, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url ); $msg = apply_filters( 'newuser_notify_siteadmin', $msg, $user ); wp_mail( $email, sprintf( __( 'New User Registration: %s' ), $user->user_login ), $msg ); return true; } function domain_exists( $domain, $path, $network_id = 1 ) { $path = trailingslashit( $path ); $args = array( 'network_id' => $network_id, 'domain' => $domain, 'path' => $path, 'fields' => 'ids', 'number' => 1, 'update_site_meta_cache' => false, ); $result = get_sites( $args ); $result = array_shift( $result ); return apply_filters( 'domain_exists', $result, $domain, $path, $network_id ); } function wpmu_welcome_notification( $blog_id, $user_id, $password, $title, $meta = array() ) { $current_network = get_network(); if ( ! apply_filters( 'wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta ) ) { return false; } $user = get_userdata( $user_id ); $switched_locale = switch_to_user_locale( $user_id ); $welcome_email = get_site_option( 'welcome_email' ); if ( ! $welcome_email ) { $welcome_email = __( 'Howdy USERNAME,
Your new SITE_NAME site has been successfully set up at:
BLOG_URL
You can log in to the administrator account with the following information:
Username: USERNAME
Password: PASSWORD
Log in here: BLOG_URLwp-login.php
We hope you enjoy your new site. Thanks!
--The Team @ SITE_NAME' ); } $url = get_blogaddress_by_id( $blog_id ); $welcome_email = str_replace( 'SITE_NAME', $current_network->site_name, $welcome_email ); $welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email ); $welcome_email = str_replace( 'BLOG_URL', $url, $welcome_email ); $welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email ); $welcome_email = str_replace( 'PASSWORD', $password, $welcome_email ); $welcome_email = apply_filters( 'update_welcome_email', $welcome_email, $blog_id, $user_id, $password, $title, $meta ); $admin_email = get_site_option( 'admin_email' ); if ( '' === $admin_email ) { $admin_email = 'support@' . wp_parse_url( network_home_url(), PHP_URL_HOST ); } $from_name = ( '' !== get_site_option( 'site_name' ) ) ? esc_html( get_site_option( 'site_name' ) ) : 'WordPress'; $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . "\"\n"; $message = $welcome_email; if ( empty( $current_network->site_name ) ) { $current_network->site_name = 'WordPress'; } $subject = __( 'New %1$s Site: %2$s' ); $subject = apply_filters( 'update_welcome_subject', sprintf( $subject, $current_network->site_name, wp_unslash( $title ) ) ); wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers ); if ( $switched_locale ) { restore_previous_locale(); } return true; } function wpmu_new_site_admin_notification( $site_id, $user_id ) { $site = get_site( $site_id ); $user = get_userdata( $user_id ); $email = get_site_option( 'admin_email' ); if ( ! $site || ! $user || ! $email ) { return false; } if ( ! apply_filters( 'send_new_site_email', true, $site, $user ) ) { return false; } $switched_locale = false; $network_admin = get_user_by( 'email', $email ); if ( $network_admin ) { $switched_locale = switch_to_user_locale( $network_admin->ID ); } else { $switched_locale = switch_to_locale( get_locale() ); } $subject = sprintf( __( '[%s] New Site Created' ), get_network()->site_name ); $message = sprintf( __( 'New site created by %1$s
Address: %2$s
Name: %3$s' ), $user->user_login, get_site_url( $site->id ), get_blog_option( $site->id, 'blogname' ) ); $header = sprintf( 'From: "%1$s" <%2$s>', _x( 'Site Admin', 'email "From" field' ), $email ); $new_site_email = array( 'to' => $email, 'subject' => $subject, 'message' => $message, 'headers' => $header, ); $new_site_email = apply_filters( 'new_site_email', $new_site_email, $site, $user ); wp_mail( $new_site_email['to'], wp_specialchars_decode( $new_site_email['subject'] ), $new_site_email['message'], $new_site_email['headers'] ); if ( $switched_locale ) { restore_previous_locale(); } return true; } function wpmu_welcome_user_notification( $user_id, $password, $meta = array() ) { $current_network = get_network(); if ( ! apply_filters( 'wpmu_welcome_user_notification', $user_id, $password, $meta ) ) { return false; } $welcome_email = get_site_option( 'welcome_user_email' ); $user = get_userdata( $user_id ); $switched_locale = switch_to_user_locale( $user_id ); $welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta ); $welcome_email = str_replace( 'SITE_NAME', $current_network->site_name, $welcome_email ); $welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email ); $welcome_email = str_replace( 'PASSWORD', $password, $welcome_email ); $welcome_email = str_replace( 'LOGINLINK', wp_login_url(), $welcome_email ); $admin_email = get_site_option( 'admin_email' ); if ( '' === $admin_email ) { $admin_email = 'support@' . wp_parse_url( network_home_url(), PHP_URL_HOST ); } $from_name = ( '' !== get_site_option( 'site_name' ) ) ? esc_html( get_site_option( 'site_name' ) ) : 'WordPress'; $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . "\"\n"; $message = $welcome_email; if ( empty( $current_network->site_name ) ) { $current_network->site_name = 'WordPress'; } $subject = __( 'New %1$s User: %2$s' ); $subject = apply_filters( 'update_welcome_user_subject', sprintf( $subject, $current_network->site_name, $user->user_login ) ); wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers ); if ( $switched_locale ) { restore_previous_locale(); } return true; } function get_current_site() { global $current_site; return $current_site; } function get_most_recent_post_of_user( $user_id ) { global $wpdb; $user_blogs = get_blogs_of_user( (int) $user_id ); $most_recent_post = array(); foreach ( (array) $user_blogs as $blog ) { $prefix = $wpdb->get_blog_prefix( $blog->userblog_id ); $recent_post = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_date_gmt FROM {$prefix}posts WHERE post_author = %d AND post_type = 'post' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1", $user_id ), ARRAY_A ); if ( isset( $recent_post['ID'] ) ) { $post_gmt_ts = strtotime( $recent_post['post_date_gmt'] ); if ( ! isset( $most_recent_post['post_gmt_ts'] ) || ( $post_gmt_ts > $most_recent_post['post_gmt_ts'] ) ) { $most_recent_post = array( 'blog_id' => $blog->userblog_id, 'post_id' => $recent_post['ID'], 'post_date_gmt' => $recent_post['post_date_gmt'], 'post_gmt_ts' => $post_gmt_ts, ); } } } return $most_recent_post; } function check_upload_mimes( $mimes ) { $site_exts = explode( ' ', get_site_option( 'upload_filetypes', 'jpg jpeg png gif' ) ); $site_mimes = array(); foreach ( $site_exts as $ext ) { foreach ( $mimes as $ext_pattern => $mime ) { if ( '' !== $ext && str_contains( $ext_pattern, $ext ) ) { $site_mimes[ $ext_pattern ] = $mime; } } } return $site_mimes; } function update_posts_count( $deprecated = '' ) { global $wpdb; update_option( 'post_count', (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ), true ); } function wpmu_log_new_registrations( $blog_id, $user_id ) { global $wpdb; if ( is_object( $blog_id ) ) { $blog_id = $blog_id->blog_id; } if ( is_array( $user_id ) ) { $user_id = ! empty( $user_id['user_id'] ) ? $user_id['user_id'] : 0; } $user = get_userdata( (int) $user_id ); if ( $user ) { $wpdb->insert( $wpdb->registration_log, array( 'email' => $user->user_email, 'IP' => preg_replace( '/[^0-9., ]/', '', wp_unslash( $_SERVER['REMOTE_ADDR'] ) ), 'blog_id' => $blog_id, 'date_registered' => current_time( 'mysql' ), ) ); } } function redirect_this_site( $deprecated = '' ) { return array( get_network()->domain ); } function upload_is_file_too_big( $upload ) { if ( ! is_array( $upload ) || defined( 'WP_IMPORTING' ) || get_site_option( 'upload_space_check_disabled' ) ) { return $upload; } if ( strlen( $upload['bits'] ) > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) { return sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ) . '<br />', get_site_option( 'fileupload_maxk', 1500 ) ); } return $upload; } function signup_nonce_fields() { $id = mt_rand(); echo "<input type='hidden' name='signup_form_id' value='{$id}' />"; wp_nonce_field( 'signup_form_' . $id, '_signup_form', false ); } function signup_nonce_check( $result ) { if ( ! strpos( $_SERVER['PHP_SELF'], 'wp-signup.php' ) ) { return $result; } if ( ! wp_verify_nonce( $_POST['_signup_form'], 'signup_form_' . $_POST['signup_form_id'] ) ) { $result['errors']->add( 'invalid_nonce', __( 'Unable to submit this form, please try again.' ) ); } return $result; } function maybe_redirect_404() { if ( is_main_site() && is_404() && defined( 'NOBLOGREDIRECT' ) ) { $destination = apply_filters( 'blog_redirect_404', NOBLOGREDIRECT ); if ( $destination ) { if ( '%siteurl%' === $destination ) { $destination = network_home_url(); } wp_redirect( $destination ); exit; } } } function maybe_add_existing_user_to_blog() { if ( ! str_contains( $_SERVER['REQUEST_URI'], '/newbloguser/' ) ) { return; } $parts = explode( '/', $_SERVER['REQUEST_URI'] ); $key = array_pop( $parts ); if ( '' === $key ) { $key = array_pop( $parts ); } $details = get_option( 'new_user_' . $key ); if ( ! empty( $details ) ) { delete_option( 'new_user_' . $key ); } if ( empty( $details ) || is_wp_error( add_existing_user_to_blog( $details ) ) ) { wp_die( sprintf( __( 'An error occurred adding you to this site. Go to the <a href="%s">homepage</a>.' ), home_url() ) ); } wp_die( sprintf( __( 'You have been added to this site. Please visit the <a href="%1$s">homepage</a> or <a href="%2$s">log in</a> using your username and password.' ), home_url(), admin_url() ), __( 'WordPress › Success' ), array( 'response' => 200 ) ); } function add_existing_user_to_blog( $details = false ) { if ( is_array( $details ) ) { $blog_id = get_current_blog_id(); $result = add_user_to_blog( $blog_id, $details['user_id'], $details['role'] ); do_action( 'added_existing_user', $details['user_id'], $result ); return $result; } } function add_new_user_to_blog( $user_id, $password, $meta ) { if ( ! empty( $meta['add_to_blog'] ) ) { $blog_id = $meta['add_to_blog']; $role = $meta['new_role']; remove_user_from_blog( $user_id, get_network()->site_id ); $result = add_user_to_blog( $blog_id, $user_id, $role ); if ( ! is_wp_error( $result ) ) { update_user_meta( $user_id, 'primary_blog', $blog_id ); } } } function fix_phpmailer_messageid( $phpmailer ) { $phpmailer->Hostname = get_network()->domain; } function is_user_spammy( $user = null ) { if ( ! ( $user instanceof WP_User ) ) { if ( $user ) { $user = get_user_by( 'login', $user ); } else { $user = wp_get_current_user(); } } return $user && isset( $user->spam ) && '1' === $user->spam; } function update_blog_public( $old_value, $value ) { update_blog_status( get_current_blog_id(), 'public', (int) $value ); } function users_can_register_signup_filter() { $registration = get_site_option( 'registration' ); return ( 'all' === $registration || 'user' === $registration ); } function welcome_user_msg_filter( $text ) { if ( ! $text ) { remove_filter( 'site_option_welcome_user_email', 'welcome_user_msg_filter' ); $text = __( 'Howdy USERNAME,
Your new account is set up.
You can log in with the following information:
Username: USERNAME
Password: PASSWORD
LOGINLINK
Thanks!
--The Team @ SITE_NAME' ); update_site_option( 'welcome_user_email', $text ); } return $text; } function force_ssl_content( $force = null ) { static $forced_content = false; if ( ! is_null( $force ) ) { $old_forced = $forced_content; $forced_content = (bool) $force; return $old_forced; } return $forced_content; } function filter_SSL( $url ) { if ( ! is_string( $url ) ) { return get_bloginfo( 'url' ); } if ( force_ssl_content() && is_ssl() ) { $url = set_url_scheme( $url, 'https' ); } return $url; } function wp_schedule_update_network_counts() { if ( ! is_main_site() ) { return; } if ( ! wp_next_scheduled( 'update_network_counts' ) && ! wp_installing() ) { wp_schedule_event( time(), 'twicedaily', 'update_network_counts' ); } } function wp_update_network_counts( $network_id = null ) { wp_update_network_user_counts( $network_id ); wp_update_network_site_counts( $network_id ); } function wp_maybe_update_network_site_counts( $network_id = null ) { $is_small_network = ! wp_is_large_network( 'sites', $network_id ); if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'sites' ) ) { return; } wp_update_network_site_counts( $network_id ); } function wp_maybe_update_network_user_counts( $network_id = null ) { $is_small_network = ! wp_is_large_network( 'users', $network_id ); if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) ) { return; } wp_update_network_user_counts( $network_id ); } function wp_update_network_site_counts( $network_id = null ) { $network_id = (int) $network_id; if ( ! $network_id ) { $network_id = get_current_network_id(); } $count = get_sites( array( 'network_id' => $network_id, 'spam' => 0, 'deleted' => 0, 'archived' => 0, 'count' => true, 'update_site_meta_cache' => false, ) ); update_network_option( $network_id, 'blog_count', $count ); } function wp_update_network_user_counts( $network_id = null ) { wp_update_user_counts( $network_id ); } function get_space_used() { $space_used = apply_filters( 'pre_get_space_used', false ); if ( false === $space_used ) { $upload_dir = wp_upload_dir(); $space_used = get_dirsize( $upload_dir['basedir'] ) / MB_IN_BYTES; } return $space_used; } function get_space_allowed() { $space_allowed = get_option( 'blog_upload_space' ); if ( ! is_numeric( $space_allowed ) ) { $space_allowed = get_site_option( 'blog_upload_space' ); } if ( ! is_numeric( $space_allowed ) ) { $space_allowed = 100; } return apply_filters( 'get_space_allowed', $space_allowed ); } function get_upload_space_available() { $allowed = get_space_allowed(); if ( $allowed < 0 ) { $allowed = 0; } $space_allowed = $allowed * MB_IN_BYTES; if ( get_site_option( 'upload_space_check_disabled' ) ) { return $space_allowed; } $space_used = get_space_used() * MB_IN_BYTES; if ( ( $space_allowed - $space_used ) <= 0 ) { return 0; } return $space_allowed - $space_used; } function is_upload_space_available() { if ( get_site_option( 'upload_space_check_disabled' ) ) { return true; } return (bool) get_upload_space_available(); } function upload_size_limit_filter( $size ) { $fileupload_maxk = (int) get_site_option( 'fileupload_maxk', 1500 ); $max_fileupload_in_bytes = KB_IN_BYTES * $fileupload_maxk; if ( get_site_option( 'upload_space_check_disabled' ) ) { return min( $size, $max_fileupload_in_bytes ); } return min( $size, $max_fileupload_in_bytes, get_upload_space_available() ); } function wp_is_large_network( $using = 'sites', $network_id = null ) { $network_id = (int) $network_id; if ( ! $network_id ) { $network_id = get_current_network_id(); } if ( 'users' === $using ) { $count = get_user_count( $network_id ); $is_large_network = wp_is_large_user_count( $network_id ); return apply_filters( 'wp_is_large_network', $is_large_network, 'users', $count, $network_id ); } $count = get_blog_count( $network_id ); return apply_filters( 'wp_is_large_network', $count > 10000, 'sites', $count, $network_id ); } function get_subdirectory_reserved_names() { $names = array( 'page', 'comments', 'blog', 'files', 'feed', 'wp-admin', 'wp-content', 'wp-includes', 'wp-json', 'embed', ); return apply_filters( 'subdirectory_reserved_names', $names ); } function update_network_option_new_admin_email( $old_value, $value ) { if ( get_site_option( 'admin_email' ) === $value || ! is_email( $value ) ) { return; } $hash = md5( $value . time() . mt_rand() ); $new_admin_email = array( 'hash' => $hash, 'newemail' => $value, ); update_site_option( 'network_admin_hash', $new_admin_email ); $switched_locale = switch_to_user_locale( get_current_user_id() ); $email_text = __( 'Howdy ###USERNAME###,
You recently requested to have the network admin email address on
your network changed.
If this is correct, please click on the following link to change it:
###ADMIN_URL###
You can safely ignore and delete this email if you do not want to
take this action.
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $content = apply_filters( 'new_network_admin_email_content', $email_text, $new_admin_email ); $current_user = wp_get_current_user(); $content = str_replace( '###USERNAME###', $current_user->user_login, $content ); $content = str_replace( '###ADMIN_URL###', esc_url( network_admin_url( 'settings.php?network_admin_hash=' . $hash ) ), $content ); $content = str_replace( '###EMAIL###', $value, $content ); $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content ); $content = str_replace( '###SITEURL###', network_home_url(), $content ); wp_mail( $value, sprintf( __( '[%s] Network Admin Email Change Request' ), wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ) ), $content ); if ( $switched_locale ) { restore_previous_locale(); } } function wp_network_admin_email_change_notification( $option_name, $new_email, $old_email, $network_id ) { $send = true; if ( empty( $old_email ) || 'you@example.com' === $old_email ) { $send = false; } $send = apply_filters( 'send_network_admin_email_change_email', $send, $old_email, $new_email, $network_id ); if ( ! $send ) { return; } $email_change_text = __( 'Hi,
This notice confirms that the network admin email address was changed on ###SITENAME###.
The new network admin email address is ###NEW_EMAIL###.
This email has been sent to ###OLD_EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###' ); $email_change_email = array( 'to' => $old_email, 'subject' => __( '[%s] Network Admin Email Changed' ), 'message' => $email_change_text, 'headers' => '', ); $network_name = wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ); $email_change_email = apply_filters( 'network_admin_email_change_email', $email_change_email, $old_email, $new_email, $network_id ); $email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITENAME###', $network_name, $email_change_email['message'] ); $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] ); wp_mail( $email_change_email['to'], sprintf( $email_change_email['subject'], $network_name ), $email_change_email['message'], $email_change_email['headers'] ); }
### require ABSPATH . WPINC . '/ms-default-filters.php';
add_action( 'init', 'ms_subdomain_constants' ); add_action( 'update_option_blog_public', 'update_blog_public', 10, 2 ); add_filter( 'option_users_can_register', 'users_can_register_signup_filter' ); add_filter( 'site_option_welcome_user_email', 'welcome_user_msg_filter' ); add_filter( 'wpmu_validate_user_signup', 'signup_nonce_check' ); add_action( 'init', 'maybe_add_existing_user_to_blog' ); add_action( 'wpmu_new_user', 'newuser_notify_siteadmin' ); add_action( 'wpmu_activate_user', 'add_new_user_to_blog', 10, 3 ); add_action( 'wpmu_activate_user', 'wpmu_welcome_user_notification', 10, 3 ); add_action( 'after_signup_user', 'wpmu_signup_user_notification', 10, 4 ); add_action( 'network_site_new_created_user', 'wp_send_new_user_notifications' ); add_action( 'network_site_users_created_user', 'wp_send_new_user_notifications' ); add_action( 'network_user_new_created_user', 'wp_send_new_user_notifications' ); add_filter( 'sanitize_user', 'strtolower' ); add_action( 'deleted_user', 'wp_delete_signup_on_user_delete', 10, 3 ); add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 ); add_filter( 'wpmu_validate_blog_signup', 'signup_nonce_check' ); add_action( 'wpmu_activate_blog', 'wpmu_welcome_notification', 10, 5 ); add_action( 'after_signup_site', 'wpmu_signup_blog_notification', 10, 7 ); add_filter( 'wp_normalize_site_data', 'wp_normalize_site_data', 10, 1 ); add_action( 'wp_validate_site_data', 'wp_validate_site_data', 10, 3 ); add_action( 'wp_insert_site', 'wp_maybe_update_network_site_counts_on_update', 10, 1 ); add_action( 'wp_update_site', 'wp_maybe_update_network_site_counts_on_update', 10, 2 ); add_action( 'wp_delete_site', 'wp_maybe_update_network_site_counts_on_update', 10, 1 ); add_action( 'wp_insert_site', 'wp_maybe_transition_site_statuses_on_update', 10, 1 ); add_action( 'wp_update_site', 'wp_maybe_transition_site_statuses_on_update', 10, 2 ); add_action( 'wp_update_site', 'wp_maybe_clean_new_site_cache_on_update', 10, 2 ); add_action( 'wp_initialize_site', 'wp_initialize_site', 10, 2 ); add_action( 'wp_initialize_site', 'wpmu_log_new_registrations', 100, 2 ); add_action( 'wp_initialize_site', 'newblog_notify_siteadmin', 100, 1 ); add_action( 'wp_uninitialize_site', 'wp_uninitialize_site', 10, 1 ); add_action( 'update_blog_public', 'wp_update_blog_public_option_on_site_update', 1, 2 ); add_action( 'added_blog_meta', 'wp_cache_set_sites_last_changed' ); add_action( 'updated_blog_meta', 'wp_cache_set_sites_last_changed' ); add_action( 'deleted_blog_meta', 'wp_cache_set_sites_last_changed' ); add_filter( 'get_blog_metadata', 'wp_check_site_meta_support_prefilter' ); add_filter( 'add_blog_metadata', 'wp_check_site_meta_support_prefilter' ); add_filter( 'update_blog_metadata', 'wp_check_site_meta_support_prefilter' ); add_filter( 'delete_blog_metadata', 'wp_check_site_meta_support_prefilter' ); add_filter( 'get_blog_metadata_by_mid', 'wp_check_site_meta_support_prefilter' ); add_filter( 'update_blog_metadata_by_mid', 'wp_check_site_meta_support_prefilter' ); add_filter( 'delete_blog_metadata_by_mid', 'wp_check_site_meta_support_prefilter' ); add_filter( 'update_blog_metadata_cache', 'wp_check_site_meta_support_prefilter' ); add_action( 'signup_hidden_fields', 'signup_nonce_fields' ); add_action( 'template_redirect', 'maybe_redirect_404' ); add_filter( 'allowed_redirect_hosts', 'redirect_this_site' ); add_action( 'after_delete_post', '_update_posts_count_on_delete', 10, 2 ); add_action( 'delete_post', '_update_blog_date_on_post_delete' ); add_action( 'transition_post_status', '_update_blog_date_on_post_publish', 10, 3 ); add_action( 'transition_post_status', '_update_posts_count_on_transition_post_status', 10, 3 ); add_action( 'admin_init', 'wp_schedule_update_network_counts' ); add_action( 'update_network_counts', 'wp_update_network_counts', 10, 0 ); foreach ( array( 'wpmu_new_user', 'make_spam_user', 'make_ham_user' ) as $action ) { add_action( $action, 'wp_maybe_update_network_user_counts', 10, 0 ); } remove_action( 'admin_init', 'wp_schedule_update_user_counts' ); remove_action( 'wp_update_user_counts', 'wp_schedule_update_user_counts' ); foreach ( array( 'make_spam_blog', 'make_ham_blog', 'archive_blog', 'unarchive_blog', 'make_delete_blog', 'make_undelete_blog' ) as $action ) { add_action( $action, 'wp_maybe_update_network_site_counts', 10, 0 ); } unset( $action ); add_filter( 'wp_upload_bits', 'upload_is_file_too_big' ); add_filter( 'import_upload_size_limit', 'fix_import_form_size' ); add_filter( 'upload_mimes', 'check_upload_mimes' ); add_filter( 'upload_size_limit', 'upload_size_limit_filter' ); add_action( 'upload_ui_over_quota', 'multisite_over_quota_message' ); add_action( 'phpmailer_init', 'fix_phpmailer_messageid' ); add_filter( 'enable_update_services_configuration', '__return_false' ); if ( ! defined( 'POST_BY_EMAIL' ) || ! POST_BY_EMAIL ) { add_filter( 'enable_post_by_email_configuration', '__return_false' ); } if ( ! defined( 'EDIT_ANY_USER' ) || ! EDIT_ANY_USER ) { add_filter( 'enable_edit_any_user_configuration', '__return_false' ); } add_filter( 'force_filtered_html_on_import', '__return_true' ); remove_filter( 'option_siteurl', '_config_wp_siteurl' ); remove_filter( 'option_home', '_config_wp_home' ); add_action( 'update_option_blogname', 'clean_site_details_cache', 10, 0 ); add_action( 'update_option_siteurl', 'clean_site_details_cache', 10, 0 ); add_action( 'update_option_post_count', 'clean_site_details_cache', 10, 0 ); add_action( 'update_option_home', 'clean_site_details_cache', 10, 0 ); add_filter( 'default_site_option_ms_files_rewriting', '__return_true' ); add_filter( 'http_request_host_is_external', 'ms_allowed_http_request_hosts', 20, 2 );
### require ABSPATH . WPINC . '/ms-deprecated.php';
function get_dashboard_blog() { _deprecated_function( __FUNCTION__, '3.1.0', 'get_site()' ); if ( $blog = get_site_option( 'dashboard_blog' ) ) { return get_site( $blog ); } return get_site( get_network()->site_id ); } function generate_random_password( $len = 8 ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_generate_password()' ); return wp_generate_password( $len ); } function is_site_admin( $user_login = '' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'is_super_admin()' ); if ( empty( $user_login ) ) { $user_id = get_current_user_id(); if ( !$user_id ) return false; } else { $user = get_user_by( 'login', $user_login ); if ( ! $user->exists() ) return false; $user_id = $user->ID; } return is_super_admin( $user_id ); } if ( !function_exists( 'graceful_fail' ) ) : function graceful_fail( $message ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_die()' ); $message = apply_filters( 'graceful_fail', $message ); $message_template = apply_filters( 'graceful_fail_template', '<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Error!</title>
<style type="text/css">
img {
border: 0;
}
body {
line-height: 1.6em; font-family: Georgia, serif; width: 390px; margin: auto;
text-align: center;
}
.message {
font-size: 22px;
width: 350px;
margin: auto;
}
</style>
</head>
<body>
<p class="message">%s</p>
</body>
</html>' ); die( sprintf( $message_template, $message ) ); } endif; function get_user_details( $username ) { _deprecated_function( __FUNCTION__, '3.0.0', 'get_user_by()' ); return get_user_by('login', $username); } function clear_global_post_cache( $post_id ) { _deprecated_function( __FUNCTION__, '3.0.0', 'clean_post_cache()' ); } function is_main_blog() { _deprecated_function( __FUNCTION__, '3.0.0', 'is_main_site()' ); return is_main_site(); } function validate_email( $email, $check_domain = true) { _deprecated_function( __FUNCTION__, '3.0.0', 'is_email()' ); return is_email( $email, $check_domain ); } function get_blog_list( $start = 0, $num = 10, $deprecated = '' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_sites()' ); global $wpdb; $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", get_current_network_id() ), ARRAY_A ); $blog_list = array(); foreach ( (array) $blogs as $details ) { $blog_list[ $details['blog_id'] ] = $details; $blog_list[ $details['blog_id'] ]['postcount'] = $wpdb->get_var( "SELECT COUNT(ID) FROM " . $wpdb->get_blog_prefix( $details['blog_id'] ). "posts WHERE post_status='publish' AND post_type='post'" ); } if ( ! $blog_list ) { return array(); } if ( 'all' === $num ) { return array_slice( $blog_list, $start, count( $blog_list ) ); } else { return array_slice( $blog_list, $start, $num ); } } function get_most_active_blogs( $num = 10, $display = true ) { _deprecated_function( __FUNCTION__, '3.0.0' ); $blogs = get_blog_list( 0, 'all', false ); if ( is_array( $blogs ) ) { reset( $blogs ); $most_active = array(); $blog_list = array(); foreach ( (array) $blogs as $key => $details ) { $most_active[ $details['blog_id'] ] = $details['postcount']; $blog_list[ $details['blog_id'] ] = $details; } arsort( $most_active ); reset( $most_active ); $t = array(); foreach ( (array) $most_active as $key => $details ) { $t[ $key ] = $blog_list[ $key ]; } unset( $most_active ); $most_active = $t; } if ( $display ) { if ( is_array( $most_active ) ) { reset( $most_active ); foreach ( (array) $most_active as $key => $details ) { $url = esc_url('http://' . $details['domain'] . $details['path']); echo '<li>' . $details['postcount'] . " <a href='$url'>$url</a></li>"; } } } return array_slice( $most_active, 0, $num ); } function wpmu_admin_do_redirect( $url = '' ) { _deprecated_function( __FUNCTION__, '3.3.0', 'wp_redirect()' ); $ref = ''; if ( isset( $_GET['ref'] ) && isset( $_POST['ref'] ) && $_GET['ref'] !== $_POST['ref'] ) { wp_die( __( 'A variable mismatch has been detected.' ), __( 'Sorry, you are not allowed to view this item.' ), 400 ); } elseif ( isset( $_POST['ref'] ) ) { $ref = $_POST['ref']; } elseif ( isset( $_GET['ref'] ) ) { $ref = $_GET['ref']; } if ( $ref ) { $ref = wpmu_admin_redirect_add_updated_param( $ref ); wp_redirect( $ref ); exit; } if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { wp_redirect( $_SERVER['HTTP_REFERER'] ); exit; } $url = wpmu_admin_redirect_add_updated_param( $url ); if ( isset( $_GET['redirect'] ) && isset( $_POST['redirect'] ) && $_GET['redirect'] !== $_POST['redirect'] ) { wp_die( __( 'A variable mismatch has been detected.' ), __( 'Sorry, you are not allowed to view this item.' ), 400 ); } elseif ( isset( $_GET['redirect'] ) ) { if ( str_starts_with( $_GET['redirect'], 's_' ) ) $url .= '&action=blogs&s='. esc_html( substr( $_GET['redirect'], 2 ) ); } elseif ( isset( $_POST['redirect'] ) ) { $url = wpmu_admin_redirect_add_updated_param( $_POST['redirect'] ); } wp_redirect( $url ); exit; } function wpmu_admin_redirect_add_updated_param( $url = '' ) { _deprecated_function( __FUNCTION__, '3.3.0', 'add_query_arg()' ); if ( ! str_contains( $url, 'updated=true' ) ) { if ( ! str_contains( $url, '?' ) ) return $url . '?updated=true'; else return $url . '&updated=true'; } return $url; } function get_user_id_from_string( $email_or_login ) { _deprecated_function( __FUNCTION__, '3.6.0', 'get_user_by()' ); if ( is_email( $email_or_login ) ) $user = get_user_by( 'email', $email_or_login ); elseif ( is_numeric( $email_or_login ) ) return $email_or_login; else $user = get_user_by( 'login', $email_or_login ); if ( $user ) return $user->ID; return 0; } function get_blogaddress_by_domain( $domain, $path ) { _deprecated_function( __FUNCTION__, '3.7.0' ); if ( is_subdomain_install() ) { $url = "http://" . $domain.$path; } else { if ( $domain != $_SERVER['HTTP_HOST'] ) { $blogname = substr( $domain, 0, strpos( $domain, '.' ) ); $url = 'http://' . substr( $domain, strpos( $domain, '.' ) + 1 ) . $path; if ( 'www.' !== $blogname ) $url .= $blogname . '/'; } else { $url = 'http://' . $domain . $path; } } return sanitize_url( $url ); } function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) { _deprecated_function( __FUNCTION__, '4.4.0' ); if ( empty($path) ) $path = '/'; if ( domain_exists($domain, $path, $site_id) ) return __( '<strong>Error:</strong> Site URL you’ve entered is already taken.' ); if ( ! $blog_id = insert_blog($domain, $path, $site_id) ) return __( '<strong>Error:</strong> There was a problem creating site entry.' ); switch_to_blog($blog_id); install_blog($blog_id); restore_current_blog(); return $blog_id; } function get_admin_users_for_domain( $domain = '', $path = '' ) { _deprecated_function( __FUNCTION__, '4.4.0' ); global $wpdb; if ( ! $domain ) { $network_id = get_current_network_id(); } else { $_networks = get_networks( array( 'fields' => 'ids', 'number' => 1, 'domain' => $domain, 'path' => $path, ) ); $network_id = ! empty( $_networks ) ? array_shift( $_networks ) : 0; } if ( $network_id ) return $wpdb->get_results( $wpdb->prepare( "SELECT u.ID, u.user_login, u.user_pass FROM $wpdb->users AS u, $wpdb->sitemeta AS sm WHERE sm.meta_key = 'admin_user_id' AND u.ID = sm.meta_value AND sm.site_id = %d", $network_id ), ARRAY_A ); return false; } function wp_get_sites( $args = array() ) { _deprecated_function( __FUNCTION__, '4.6.0', 'get_sites()' ); if ( wp_is_large_network() ) return array(); $defaults = array( 'network_id' => get_current_network_id(), 'public' => null, 'archived' => null, 'mature' => null, 'spam' => null, 'deleted' => null, 'limit' => 100, 'offset' => 0, ); $args = wp_parse_args( $args, $defaults ); if( is_array( $args['network_id'] ) ){ $args['network__in'] = $args['network_id']; $args['network_id'] = null; } if( is_numeric( $args['limit'] ) ){ $args['number'] = $args['limit']; $args['limit'] = null; } elseif ( ! $args['limit'] ) { $args['number'] = 0; $args['limit'] = null; } $args['count'] = false; $_sites = get_sites( $args ); $results = array(); foreach ( $_sites as $_site ) { $_site = get_site( $_site ); $results[] = $_site->to_array(); } return $results; } function is_user_option_local( $key, $user_id = 0, $blog_id = 0 ) { global $wpdb; _deprecated_function( __FUNCTION__, '4.9.0' ); $current_user = wp_get_current_user(); if ( $blog_id == 0 ) { $blog_id = get_current_blog_id(); } $local_key = $wpdb->get_blog_prefix( $blog_id ) . $key; return isset( $current_user->$local_key ); } function insert_blog($domain, $path, $site_id) { _deprecated_function( __FUNCTION__, '5.1.0', 'wp_insert_site()' ); $data = array( 'domain' => $domain, 'path' => $path, 'site_id' => $site_id, ); $site_id = wp_insert_site( $data ); if ( is_wp_error( $site_id ) ) { return false; } clean_blog_cache( $site_id ); return $site_id; } function install_blog( $blog_id, $blog_title = '' ) { global $wpdb, $wp_roles; _deprecated_function( __FUNCTION__, '5.1.0' ); $blog_id = (int) $blog_id; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $suppress = $wpdb->suppress_errors(); if ( $wpdb->get_results( "DESCRIBE {$wpdb->posts}" ) ) { die( '<h1>' . __( 'Already Installed' ) . '</h1><p>' . __( 'You appear to have already installed WordPress. To reinstall please clear your old database tables first.' ) . '</p></body></html>' ); } $wpdb->suppress_errors( $suppress ); $url = get_blogaddress_by_id( $blog_id ); make_db_current_silent( 'blog' ); populate_options(); populate_roles(); $wp_roles = new WP_Roles(); $siteurl = $home = untrailingslashit( $url ); if ( ! is_subdomain_install() ) { if ( 'https' === parse_url( get_site_option( 'siteurl' ), PHP_URL_SCHEME ) ) { $siteurl = set_url_scheme( $siteurl, 'https' ); } if ( 'https' === parse_url( get_home_url( get_network()->site_id ), PHP_URL_SCHEME ) ) { $home = set_url_scheme( $home, 'https' ); } } update_option( 'siteurl', $siteurl ); update_option( 'home', $home ); if ( get_site_option( 'ms_files_rewriting' ) ) { update_option( 'upload_path', UPLOADBLOGSDIR . "/$blog_id/files" ); } else { update_option( 'upload_path', get_blog_option( get_network()->site_id, 'upload_path' ) ); } update_option( 'blogname', wp_unslash( $blog_title ) ); update_option( 'admin_email', '' ); $table_prefix = $wpdb->get_blog_prefix(); delete_metadata( 'user', 0, $table_prefix . 'user_level', null, true ); delete_metadata( 'user', 0, $table_prefix . 'capabilities', null, true ); } function install_blog_defaults( $blog_id, $user_id ) { global $wpdb; _deprecated_function( __FUNCTION__, 'MU' ); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $suppress = $wpdb->suppress_errors(); wp_install_defaults( $user_id ); $wpdb->suppress_errors( $suppress ); } function update_user_status( $id, $pref, $value, $deprecated = null ) { global $wpdb; _deprecated_function( __FUNCTION__, '5.3.0', 'wp_update_user()' ); if ( null !== $deprecated ) { _deprecated_argument( __FUNCTION__, '3.0.2' ); } $wpdb->update( $wpdb->users, array( sanitize_key( $pref ) => $value ), array( 'ID' => $id ) ); $user = new WP_User( $id ); clean_user_cache( $user ); if ( 'spam' === $pref ) { if ( $value == 1 ) { do_action( 'make_spam_user', $id ); } else { do_action( 'make_ham_user', $id ); } } return $value; } function global_terms( $term_id, $deprecated = '' ) { _deprecated_function( __FUNCTION__, '6.1.0' ); return $term_id; }
}
wp_plugin_directory_constants();
$GLOBALS['wp_plugin_paths'] = array();
foreach ( wp_get_mu_plugins() as $mu_plugin ) {
$_wp_plugin_file = $mu_plugin;
include_once $mu_plugin;
$mu_plugin = $_wp_plugin_file; // Avoid stomping of the $mu_plugin variable in a plugin.
do_action( 'mu_plugin_loaded', $mu_plugin );
}
unset( $mu_plugin, $_wp_plugin_file );
if ( is_multisite() ) {
foreach ( wp_get_active_network_plugins() as $network_plugin ) {
wp_register_plugin_realpath( $network_plugin );
$_wp_plugin_file = $network_plugin;
include_once $network_plugin;
$network_plugin = $_wp_plugin_file; // Avoid stomping of the $network_plugin variable in a plugin.
do_action( 'network_plugin_loaded', $network_plugin );
}
unset( $network_plugin, $_wp_plugin_file );
}
do_action( 'muplugins_loaded' );
if ( is_multisite() ) {
ms_cookie_constants();
}
wp_cookie_constants();
wp_ssl_constants();
###require ABSPATH . WPINC . '/vars.php';
if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } global $pagenow, $is_lynx, $is_gecko, $is_winIE, $is_macIE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone, $is_IE, $is_edge, $is_apache, $is_IIS, $is_iis7, $is_nginx, $is_caddy; if ( is_admin() ) { if ( is_network_admin() ) { preg_match( '#/wp-admin/network/?(.*?)$#i', $_SERVER['PHP_SELF'], $self_matches ); } elseif ( is_user_admin() ) { preg_match( '#/wp-admin/user/?(.*?)$#i', $_SERVER['PHP_SELF'], $self_matches ); } else { preg_match( '#/wp-admin/?(.*?)$#i', $_SERVER['PHP_SELF'], $self_matches ); } $pagenow = ! empty( $self_matches[1] ) ? $self_matches[1] : ''; $pagenow = trim( $pagenow, '/' ); $pagenow = preg_replace( '#\?.*?$#', '', $pagenow ); if ( '' === $pagenow || 'index' === $pagenow || 'index.php' === $pagenow ) { $pagenow = 'index.php'; } else { preg_match( '#(.*?)(/|$)#', $pagenow, $self_matches ); $pagenow = strtolower( $self_matches[1] ); if ( ! str_ends_with( $pagenow, '.php' ) ) { $pagenow .= '.php'; } } } else { if ( preg_match( '#([^/]+\.php)([?/].*?)?$#i', $_SERVER['PHP_SELF'], $self_matches ) ) { $pagenow = strtolower( $self_matches[1] ); } else { $pagenow = 'index.php'; } } unset( $self_matches ); $is_lynx = false; $is_gecko = false; $is_winIE = false; $is_macIE = false; $is_opera = false; $is_NS4 = false; $is_safari = false; $is_chrome = false; $is_iphone = false; $is_edge = false; if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { if ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Lynx' ) ) { $is_lynx = true; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Edg' ) ) { $is_edge = true; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'OPR/' ) ) { $is_opera = true; } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chrome' ) !== false ) { if ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chromeframe' ) !== false ) { $is_admin = is_admin(); $is_chrome = apply_filters( 'use_google_chrome_frame', $is_admin ); if ( $is_chrome ) { header( 'X-UA-Compatible: chrome=1' ); } $is_winIE = ! $is_chrome; } else { $is_chrome = true; } } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'safari' ) !== false ) { $is_safari = true; } elseif ( ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Trident' ) ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Win' ) ) { $is_winIE = true; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mac' ) ) { $is_macIE = true; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Gecko' ) ) { $is_gecko = true; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Nav' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mozilla/4.' ) ) { $is_NS4 = true; } } if ( $is_safari && stripos( $_SERVER['HTTP_USER_AGENT'], 'mobile' ) !== false ) { $is_iphone = true; } $is_IE = ( $is_macIE || $is_winIE ); $is_apache = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) ); $is_nginx = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) ); $is_caddy = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Caddy' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'FrankenPHP' ) ); $is_IIS = ! $is_apache && ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer' ) ); $is_iis7 = $is_IIS && (int) substr( $_SERVER['SERVER_SOFTWARE'], strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/' ) + 14 ) >= 7; function wp_is_mobile() { if ( isset( $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ) ) { $is_mobile = ( '?1' === $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ); } elseif ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) { $is_mobile = false; } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mobile' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Android' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Silk/' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Kindle' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'BlackBerry' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mini' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mobi' ) ) { $is_mobile = true; } else { $is_mobile = false; } return apply_filters( 'wp_is_mobile', $is_mobile ); }
create_initial_taxonomies();
create_initial_post_types();
wp_start_scraping_edited_file_errors();
register_theme_directory( get_theme_root() );
if ( ! is_multisite() && wp_is_fatal_error_handler_enabled() ) {
wp_recovery_mode()->initialize();
}
require_once ABSPATH . 'wp-admin/includes/plugin.php';
foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
wp_register_plugin_realpath( $plugin );
$plugin_data = get_plugin_data( $plugin, false, false );
$textdomain = $plugin_data['TextDomain'];
if ( $textdomain ) {
if ( $plugin_data['DomainPath'] ) {
$GLOBALS['wp_textdomain_registry']->set_custom_path( $textdomain, dirname( $plugin ) . $plugin_data['DomainPath'] );
} else {
$GLOBALS['wp_textdomain_registry']->set_custom_path( $textdomain, dirname( $plugin ) );
}
}
$_wp_plugin_file = $plugin;
include_once $plugin;
$plugin = $_wp_plugin_file; // Avoid stomping of the $plugin variable in a plugin.
do_action( 'plugin_loaded', $plugin );
}
unset( $plugin, $_wp_plugin_file, $plugin_data, $textdomain );
require ABSPATH . WPINC . '/pluggable.php';
###require ABSPATH . WPINC . '/pluggable-deprecated.php';
if ( !function_exists('set_current_user') ) : function set_current_user($id, $name = '') { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_set_current_user()' ); return wp_set_current_user($id, $name); } endif; if ( !function_exists('get_currentuserinfo') ) : function get_currentuserinfo() { _deprecated_function( __FUNCTION__, '4.5.0', 'wp_get_current_user()' ); return _wp_get_current_user(); } endif; if ( !function_exists('get_userdatabylogin') ) : function get_userdatabylogin($user_login) { _deprecated_function( __FUNCTION__, '3.3.0', "get_user_by('login')" ); return get_user_by('login', $user_login); } endif; if ( !function_exists('get_user_by_email') ) : function get_user_by_email($email) { _deprecated_function( __FUNCTION__, '3.3.0', "get_user_by('email')" ); return get_user_by('email', $email); } endif; if ( !function_exists('wp_setcookie') ) : function wp_setcookie( $username, $password = '', $already_md5 = false, $home = '', $siteurl = '', $remember = false ) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_set_auth_cookie()' ); $user = get_user_by('login', $username); wp_set_auth_cookie($user->ID, $remember); } else : _deprecated_function( 'wp_setcookie', '2.5.0', 'wp_set_auth_cookie()' ); endif; if ( !function_exists('wp_clearcookie') ) : function wp_clearcookie() { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_clear_auth_cookie()' ); wp_clear_auth_cookie(); } else : _deprecated_function( 'wp_clearcookie', '2.5.0', 'wp_clear_auth_cookie()' ); endif; if ( !function_exists('wp_get_cookie_login') ): function wp_get_cookie_login() { _deprecated_function( __FUNCTION__, '2.5.0' ); return false; } else : _deprecated_function( 'wp_get_cookie_login', '2.5.0' ); endif; if ( !function_exists('wp_login') ) : function wp_login( $username, $password, $deprecated = '' ) { _deprecated_function( __FUNCTION__, '2.5.0', 'wp_signon()' ); global $error; $user = wp_authenticate($username, $password); if ( ! is_wp_error($user) ) return true; $error = $user->get_error_message(); return false; } else : _deprecated_function( 'wp_login', '2.5.0', 'wp_signon()' ); endif; if ( ! class_exists( 'wp_atom_server', false ) ) { class wp_atom_server { public function __call( $name, $arguments ) { _deprecated_function( __CLASS__ . '::' . $name, '3.5.0', 'the Atom Publishing Protocol plugin' ); } public static function __callStatic( $name, $arguments ) { _deprecated_function( __CLASS__ . '::' . $name, '3.5.0', 'the Atom Publishing Protocol plugin' ); } } }
wp_set_internal_encoding();
if ( WP_CACHE && function_exists( 'wp_cache_postload' ) ) {
wp_cache_postload();
}
do_action( 'plugins_loaded' );
wp_functionality_constants();
wp_magic_quotes();
do_action( 'sanitize_comment_cookies' );
$GLOBALS['wp_the_query'] = new WP_Query();
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
$GLOBALS['wp_rewrite'] = new WP_Rewrite();
$GLOBALS['wp'] = new WP();
$GLOBALS['wp_widget_factory'] = new WP_Widget_Factory();
$GLOBALS['wp_roles'] = new WP_Roles();
do_action( 'setup_theme' );
wp_templating_constants();
wp_set_template_globals();
load_default_textdomain();
$locale = get_locale();
$locale_file = WP_LANG_DIR . "/$locale.php";
if ( ( 0 === validate_file( $locale ) ) && is_readable( $locale_file ) ) {
require $locale_file;
}
unset( $locale_file );
$GLOBALS['wp_locale'] = new WP_Locale();
$GLOBALS['wp_locale_switcher'] = new WP_Locale_Switcher();
$GLOBALS['wp_locale_switcher']->init();
foreach ( wp_get_active_and_valid_themes() as $theme ) {
$wp_theme = wp_get_theme( basename( $theme ) );
$wp_theme->load_textdomain();
if ( file_exists( $theme . '/functions.php' ) ) {
include $theme . '/functions.php';
}
}
unset( $theme, $wp_theme );
do_action( 'after_setup_theme' );
if ( ! class_exists( 'WP_Site_Health' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
}
WP_Site_Health::get_instance();
$GLOBALS['wp']->init();
do_action( 'init' );
if ( is_multisite() ) {
$file = ms_site_check();
if ( true !== $file ) {
require $file;
die();
}
unset( $file );
}
do_action( 'wp_loaded' );