Submit
Path:
~
/
home
/
contenidosenred
/
www
/
OD
/
wp-admin
/
includes
/
219846
/
File Content:
theme.php.tar
home/contenidosenred/public_html/OD/wp-admin/includes/theme.php 0000644 00000135176 15105340140 0020626 0 ustar 00 <?php /** * WordPress Theme Administration API * * @package WordPress * @subpackage Administration */ /** * Removes a theme. * * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param string $stylesheet Stylesheet of the theme to delete. * @param string $redirect Redirect to page when complete. * @return bool|null|WP_Error True on success, false if `$stylesheet` is empty, WP_Error on failure. * Null if filesystem credentials are required to proceed. */ function delete_theme( $stylesheet, $redirect = '' ) { global $wp_filesystem; if ( empty( $stylesheet ) ) { return false; } if ( empty( $redirect ) ) { $redirect = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet ); } ob_start(); $credentials = request_filesystem_credentials( $redirect ); $data = ob_get_clean(); if ( false === $credentials ) { if ( ! empty( $data ) ) { require_once ABSPATH . 'wp-admin/admin-header.php'; echo $data; require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } return; } if ( ! WP_Filesystem( $credentials ) ) { ob_start(); // Failed to connect. Error and request again. request_filesystem_credentials( $redirect, '', true ); $data = ob_get_clean(); if ( ! empty( $data ) ) { require_once ABSPATH . 'wp-admin/admin-header.php'; echo $data; require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } return; } if ( ! is_object( $wp_filesystem ) ) { return new WP_Error( 'fs_unavailable', __( 'Could not access filesystem.' ) ); } if ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { return new WP_Error( 'fs_error', __( 'Filesystem error.' ), $wp_filesystem->errors ); } // Get the base theme folder. $themes_dir = $wp_filesystem->wp_themes_dir(); if ( empty( $themes_dir ) ) { return new WP_Error( 'fs_no_themes_dir', __( 'Unable to locate WordPress theme directory.' ) ); } /** * Fires immediately before a theme deletion attempt. * * @since 5.8.0 * * @param string $stylesheet Stylesheet of the theme to delete. */ do_action( 'delete_theme', $stylesheet ); $theme = wp_get_theme( $stylesheet ); $themes_dir = trailingslashit( $themes_dir ); $theme_dir = trailingslashit( $themes_dir . $stylesheet ); $deleted = $wp_filesystem->delete( $theme_dir, true ); /** * Fires immediately after a theme deletion attempt. * * @since 5.8.0 * * @param string $stylesheet Stylesheet of the theme to delete. * @param bool $deleted Whether the theme deletion was successful. */ do_action( 'deleted_theme', $stylesheet, $deleted ); if ( ! $deleted ) { return new WP_Error( 'could_not_remove_theme', /* translators: %s: Theme name. */ sprintf( __( 'Could not fully remove the theme %s.' ), $stylesheet ) ); } $theme_translations = wp_get_installed_translations( 'themes' ); // Remove language files, silently. if ( ! empty( $theme_translations[ $stylesheet ] ) ) { $translations = $theme_translations[ $stylesheet ]; foreach ( $translations as $translation => $data ) { $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.po' ); $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.mo' ); $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.l10n.php' ); $json_translation_files = glob( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '-*.json' ); if ( $json_translation_files ) { array_map( array( $wp_filesystem, 'delete' ), $json_translation_files ); } } } // Remove the theme from allowed themes on the network. if ( is_multisite() ) { WP_Theme::network_disable_theme( $stylesheet ); } // Clear theme caches. $theme->cache_delete(); // Force refresh of theme update information. delete_site_transient( 'update_themes' ); return true; } /** * Gets the page templates available in this theme. * * @since 1.5.0 * @since 4.7.0 Added the `$post_type` parameter. * * @param WP_Post|null $post Optional. The post being edited, provided for context. * @param string $post_type Optional. Post type to get the templates for. Default 'page'. * @return string[] Array of template file names keyed by the template header name. */ function get_page_templates( $post = null, $post_type = 'page' ) { return array_flip( wp_get_theme()->get_page_templates( $post, $post_type ) ); } /** * Tidies a filename for url display by the theme file editor. * * @since 2.9.0 * @access private * * @param string $fullpath Full path to the theme file * @param string $containingfolder Path of the theme parent folder * @return string */ function _get_template_edit_filename( $fullpath, $containingfolder ) { return str_replace( dirname( $containingfolder, 2 ), '', $fullpath ); } /** * Check if there is an update for a theme available. * * Will display link, if there is an update available. * * @since 2.7.0 * * @see get_theme_update_available() * * @param WP_Theme $theme Theme data object. */ function theme_update_available( $theme ) { echo get_theme_update_available( $theme ); } /** * Retrieves the update link if there is a theme update available. * * Will return a link if there is an update available. * * @since 3.8.0 * * @param WP_Theme $theme WP_Theme object. * @return string|false HTML for the update link, or false if invalid info was passed. */ function get_theme_update_available( $theme ) { static $themes_update = null; if ( ! current_user_can( 'update_themes' ) ) { return false; } if ( ! isset( $themes_update ) ) { $themes_update = get_site_transient( 'update_themes' ); } if ( ! ( $theme instanceof WP_Theme ) ) { return false; } $stylesheet = $theme->get_stylesheet(); $html = ''; if ( isset( $themes_update->response[ $stylesheet ] ) ) { $update = $themes_update->response[ $stylesheet ]; $theme_name = $theme->display( 'Name' ); $details_url = add_query_arg( array( 'TB_iframe' => 'true', 'width' => 1024, 'height' => 800, ), $update['url'] ); // Theme browser inside WP? Replace this. Also, theme preview JS will override this on the available list. $update_url = wp_nonce_url( admin_url( 'update.php?action=upgrade-theme&theme=' . urlencode( $stylesheet ) ), 'upgrade-theme_' . $stylesheet ); if ( ! is_multisite() ) { if ( ! current_user_can( 'update_themes' ) ) { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'] ); } elseif ( empty( $update['package'] ) ) { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'] ); } else { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'], $update_url, sprintf( 'aria-label="%s" id="update-theme" data-slug="%s"', /* translators: %s: Theme name. */ esc_attr( sprintf( _x( 'Update %s now', 'theme' ), $theme_name ) ), $stylesheet ) ); } } } return $html; } /** * Retrieves list of WordPress theme features (aka theme tags). * * @since 3.1.0 * @since 3.2.0 Added 'Gray' color and 'Featured Image Header', 'Featured Images', * 'Full Width Template', and 'Post Formats' features. * @since 3.5.0 Added 'Flexible Header' feature. * @since 3.8.0 Renamed 'Width' filter to 'Layout'. * @since 3.8.0 Renamed 'Fixed Width' and 'Flexible Width' options * to 'Fixed Layout' and 'Fluid Layout'. * @since 3.8.0 Added 'Accessibility Ready' feature and 'Responsive Layout' option. * @since 3.9.0 Combined 'Layout' and 'Columns' filters. * @since 4.6.0 Removed 'Colors' filter. * @since 4.6.0 Added 'Grid Layout' option. * Removed 'Fixed Layout', 'Fluid Layout', and 'Responsive Layout' options. * @since 4.6.0 Added 'Custom Logo' and 'Footer Widgets' features. * Removed 'Blavatar' feature. * @since 4.6.0 Added 'Blog', 'E-Commerce', 'Education', 'Entertainment', 'Food & Drink', * 'Holiday', 'News', 'Photography', and 'Portfolio' subjects. * Removed 'Photoblogging' and 'Seasonal' subjects. * @since 4.9.0 Reordered the filters from 'Layout', 'Features', 'Subject' * to 'Subject', 'Features', 'Layout'. * @since 4.9.0 Removed 'BuddyPress', 'Custom Menu', 'Flexible Header', * 'Front Page Posting', 'Microformats', 'RTL Language Support', * 'Threaded Comments', and 'Translation Ready' features. * @since 5.5.0 Added 'Block Editor Patterns', 'Block Editor Styles', * and 'Full Site Editing' features. * @since 5.5.0 Added 'Wide Blocks' layout option. * @since 5.8.1 Added 'Template Editing' feature. * @since 6.1.1 Replaced 'Full Site Editing' feature name with 'Site Editor'. * @since 6.2.0 Added 'Style Variations' feature. * * @param bool $api Optional. Whether try to fetch tags from the WordPress.org API. Defaults to true. * @return array Array of features keyed by category with translations keyed by slug. */ function get_theme_feature_list( $api = true ) { // Hard-coded list is used if API is not accessible. $features = array( __( 'Subject' ) => array( 'blog' => __( 'Blog' ), 'e-commerce' => __( 'E-Commerce' ), 'education' => __( 'Education' ), 'entertainment' => __( 'Entertainment' ), 'food-and-drink' => __( 'Food & Drink' ), 'holiday' => __( 'Holiday' ), 'news' => __( 'News' ), 'photography' => __( 'Photography' ), 'portfolio' => __( 'Portfolio' ), ), __( 'Features' ) => array( 'accessibility-ready' => __( 'Accessibility Ready' ), 'block-patterns' => __( 'Block Editor Patterns' ), 'block-styles' => __( 'Block Editor Styles' ), 'custom-background' => __( 'Custom Background' ), 'custom-colors' => __( 'Custom Colors' ), 'custom-header' => __( 'Custom Header' ), 'custom-logo' => __( 'Custom Logo' ), 'editor-style' => __( 'Editor Style' ), 'featured-image-header' => __( 'Featured Image Header' ), 'featured-images' => __( 'Featured Images' ), 'footer-widgets' => __( 'Footer Widgets' ), 'full-site-editing' => __( 'Site Editor' ), 'full-width-template' => __( 'Full Width Template' ), 'post-formats' => __( 'Post Formats' ), 'sticky-post' => __( 'Sticky Post' ), 'style-variations' => __( 'Style Variations' ), 'template-editing' => __( 'Template Editing' ), 'theme-options' => __( 'Theme Options' ), ), __( 'Layout' ) => array( 'grid-layout' => __( 'Grid Layout' ), 'one-column' => __( 'One Column' ), 'two-columns' => __( 'Two Columns' ), 'three-columns' => __( 'Three Columns' ), 'four-columns' => __( 'Four Columns' ), 'left-sidebar' => __( 'Left Sidebar' ), 'right-sidebar' => __( 'Right Sidebar' ), 'wide-blocks' => __( 'Wide Blocks' ), ), ); if ( ! $api || ! current_user_can( 'install_themes' ) ) { return $features; } $feature_list = get_site_transient( 'wporg_theme_feature_list' ); if ( ! $feature_list ) { set_site_transient( 'wporg_theme_feature_list', array(), 3 * HOUR_IN_SECONDS ); } if ( ! $feature_list ) { $feature_list = themes_api( 'feature_list', array() ); if ( is_wp_error( $feature_list ) ) { return $features; } } if ( ! $feature_list ) { return $features; } set_site_transient( 'wporg_theme_feature_list', $feature_list, 3 * HOUR_IN_SECONDS ); $category_translations = array( 'Layout' => __( 'Layout' ), 'Features' => __( 'Features' ), 'Subject' => __( 'Subject' ), ); $wporg_features = array(); // Loop over the wp.org canonical list and apply translations. foreach ( (array) $feature_list as $feature_category => $feature_items ) { if ( isset( $category_translations[ $feature_category ] ) ) { $feature_category = $category_translations[ $feature_category ]; } $wporg_features[ $feature_category ] = array(); foreach ( $feature_items as $feature ) { if ( isset( $features[ $feature_category ][ $feature ] ) ) { $wporg_features[ $feature_category ][ $feature ] = $features[ $feature_category ][ $feature ]; } else { $wporg_features[ $feature_category ][ $feature ] = $feature; } } } return $wporg_features; } /** * Retrieves theme installer pages from the WordPress.org Themes API. * * It is possible for a theme to override the Themes API result with three * filters. Assume this is for themes, which can extend on the Theme Info to * offer more choices. This is very powerful and must be used with care, when * overriding the filters. * * The first filter, {@see 'themes_api_args'}, is for the args and gives the action * as the second parameter. The hook for {@see 'themes_api_args'} must ensure that * an object is returned. * * The second filter, {@see 'themes_api'}, allows a plugin to override the WordPress.org * Theme API entirely. If `$action` is 'query_themes', 'theme_information', or 'feature_list', * an object MUST be passed. If `$action` is 'hot_tags', an array should be passed. * * Finally, the third filter, {@see 'themes_api_result'}, makes it possible to filter the * response object or array, depending on the `$action` type. * * Supported arguments per action: * * | Argument Name | 'query_themes' | 'theme_information' | 'hot_tags' | 'feature_list' | * | -------------------| :------------: | :-----------------: | :--------: | :--------------: | * | `$slug` | No | Yes | No | No | * | `$per_page` | Yes | No | No | No | * | `$page` | Yes | No | No | No | * | `$number` | No | No | Yes | No | * | `$search` | Yes | No | No | No | * | `$tag` | Yes | No | No | No | * | `$author` | Yes | No | No | No | * | `$user` | Yes | No | No | No | * | `$browse` | Yes | No | No | No | * | `$locale` | Yes | Yes | No | No | * | `$fields` | Yes | Yes | No | No | * * @since 2.8.0 * * @param string $action API action to perform: Accepts 'query_themes', 'theme_information', * 'hot_tags' or 'feature_list'. * @param array|object $args { * Optional. Array or object of arguments to serialize for the Themes API. Default empty array. * * @type string $slug The theme slug. Default empty. * @type int $per_page Number of themes per page. Default 24. * @type int $page Number of current page. Default 1. * @type int $number Number of tags to be queried. * @type string $search A search term. Default empty. * @type string $tag Tag to filter themes. Default empty. * @type string $author Username of an author to filter themes. Default empty. * @type string $user Username to query for their favorites. Default empty. * @type string $browse Browse view: 'featured', 'popular', 'updated', 'favorites'. * @type string $locale Locale to provide context-sensitive results. Default is the value of get_locale(). * @type array $fields { * Array of fields which should or should not be returned. * * @type bool $description Whether to return the theme full description. Default false. * @type bool $sections Whether to return the theme readme sections: description, installation, * FAQ, screenshots, other notes, and changelog. Default false. * @type bool $rating Whether to return the rating in percent and total number of ratings. * Default false. * @type bool $ratings Whether to return the number of rating for each star (1-5). Default false. * @type bool $downloaded Whether to return the download count. Default false. * @type bool $downloadlink Whether to return the download link for the package. Default false. * @type bool $last_updated Whether to return the date of the last update. Default false. * @type bool $tags Whether to return the assigned tags. Default false. * @type bool $homepage Whether to return the theme homepage link. Default false. * @type bool $screenshots Whether to return the screenshots. Default false. * @type int $screenshot_count Number of screenshots to return. Default 1. * @type bool $screenshot_url Whether to return the URL of the first screenshot. Default false. * @type bool $photon_screenshots Whether to return the screenshots via Photon. Default false. * @type bool $template Whether to return the slug of the parent theme. Default false. * @type bool $parent Whether to return the slug, name and homepage of the parent theme. Default false. * @type bool $versions Whether to return the list of all available versions. Default false. * @type bool $theme_url Whether to return theme's URL. Default false. * @type bool $extended_author Whether to return nicename or nicename and display name. Default false. * } * } * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the * {@link https://developer.wordpress.org/reference/functions/themes_api/ function reference article} * for more information on the make-up of possible return objects depending on the value of `$action`. */ function themes_api( $action, $args = array() ) { if ( is_array( $args ) ) { $args = (object) $args; } if ( 'query_themes' === $action ) { if ( ! isset( $args->per_page ) ) { $args->per_page = 24; } } if ( ! isset( $args->locale ) ) { $args->locale = get_user_locale(); } if ( ! isset( $args->wp_version ) ) { $args->wp_version = substr( wp_get_wp_version(), 0, 3 ); // x.y } /** * Filters arguments used to query for installer pages from the WordPress.org Themes API. * * Important: An object MUST be returned to this filter. * * @since 2.8.0 * * @param object $args Arguments used to query for installer pages from the WordPress.org Themes API. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. */ $args = apply_filters( 'themes_api_args', $args, $action ); /** * Filters whether to override the WordPress.org Themes API. * * Returning a non-false value will effectively short-circuit the WordPress.org API request. * * If `$action` is 'query_themes', 'theme_information', or 'feature_list', an object MUST * be passed. If `$action` is 'hot_tags', an array should be passed. * * @since 2.8.0 * * @param false|object|array $override Whether to override the WordPress.org Themes API. Default false. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param object $args Arguments used to query for installer pages from the Themes API. */ $res = apply_filters( 'themes_api', false, $action, $args ); if ( ! $res ) { $url = 'http://api.wordpress.org/themes/info/1.2/'; $url = add_query_arg( array( 'action' => $action, 'request' => $args, ), $url ); $http_url = $url; $ssl = wp_http_supports( array( 'ssl' ) ); if ( $ssl ) { $url = set_url_scheme( $url, 'https' ); } $http_args = array( 'timeout' => 15, 'user-agent' => 'WordPress/' . wp_get_wp_version() . '; ' . home_url( '/' ), ); $request = wp_remote_get( $url, $http_args ); if ( $ssl && is_wp_error( $request ) ) { if ( ! wp_doing_ajax() ) { wp_trigger_error( __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); } $request = wp_remote_get( $http_url, $http_args ); } if ( is_wp_error( $request ) ) { $res = new WP_Error( 'themes_api_failed', sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ), $request->get_error_message() ); } else { $res = json_decode( wp_remote_retrieve_body( $request ), true ); if ( is_array( $res ) ) { // Object casting is required in order to match the info/1.0 format. $res = (object) $res; } elseif ( null === $res ) { $res = new WP_Error( 'themes_api_failed', sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ), wp_remote_retrieve_body( $request ) ); } if ( isset( $res->error ) ) { $res = new WP_Error( 'themes_api_failed', $res->error ); } } if ( ! is_wp_error( $res ) ) { // Back-compat for info/1.2 API, upgrade the theme objects in query_themes to objects. if ( 'query_themes' === $action ) { foreach ( $res->themes as $i => $theme ) { $res->themes[ $i ] = (object) $theme; } } // Back-compat for info/1.2 API, downgrade the feature_list result back to an array. if ( 'feature_list' === $action ) { $res = (array) $res; } } } /** * Filters the returned WordPress.org Themes API response. * * @since 2.8.0 * * @param array|stdClass|WP_Error $res WordPress.org Themes API response. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param stdClass $args Arguments used to query for installer pages from the WordPress.org Themes API. */ return apply_filters( 'themes_api_result', $res, $action, $args ); } /** * Prepares themes for JavaScript. * * @since 3.8.0 * * @param WP_Theme[] $themes Optional. Array of theme objects to prepare. * Defaults to all allowed themes. * * @return array An associative array of theme data, sorted by name. */ function wp_prepare_themes_for_js( $themes = null ) { $current_theme = get_stylesheet(); /** * Filters theme data before it is prepared for JavaScript. * * Passing a non-empty array will result in wp_prepare_themes_for_js() returning * early with that value instead. * * @since 4.2.0 * * @param array $prepared_themes An associative array of theme data. Default empty array. * @param WP_Theme[]|null $themes An array of theme objects to prepare, if any. * @param string $current_theme The active theme slug. */ $prepared_themes = (array) apply_filters( 'pre_prepare_themes_for_js', array(), $themes, $current_theme ); if ( ! empty( $prepared_themes ) ) { return $prepared_themes; } // Make sure the active theme is listed first. $prepared_themes[ $current_theme ] = array(); if ( null === $themes ) { $themes = wp_get_themes( array( 'allowed' => true ) ); if ( ! isset( $themes[ $current_theme ] ) ) { $themes[ $current_theme ] = wp_get_theme(); } } $updates = array(); $no_updates = array(); if ( ! is_multisite() && current_user_can( 'update_themes' ) ) { $updates_transient = get_site_transient( 'update_themes' ); if ( isset( $updates_transient->response ) ) { $updates = $updates_transient->response; } if ( isset( $updates_transient->no_update ) ) { $no_updates = $updates_transient->no_update; } } WP_Theme::sort_by_name( $themes ); $parents = array(); $auto_updates = (array) get_site_option( 'auto_update_themes', array() ); foreach ( $themes as $theme ) { $slug = $theme->get_stylesheet(); $encoded_slug = urlencode( $slug ); $parent = false; if ( $theme->parent() ) { $parent = $theme->parent(); $parents[ $slug ] = $parent->get_stylesheet(); $parent = $parent->display( 'Name' ); } $customize_action = null; $can_edit_theme_options = current_user_can( 'edit_theme_options' ); $can_customize = current_user_can( 'customize' ); $is_block_theme = $theme->is_block_theme(); if ( $is_block_theme && $can_edit_theme_options ) { $customize_action = admin_url( 'site-editor.php' ); if ( $current_theme !== $slug ) { $customize_action = add_query_arg( 'wp_theme_preview', $slug, $customize_action ); } } elseif ( ! $is_block_theme && $can_customize && $can_edit_theme_options ) { $customize_action = wp_customize_url( $slug ); } if ( null !== $customize_action ) { $customize_action = add_query_arg( array( 'return' => urlencode( sanitize_url( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ), ), $customize_action ); $customize_action = esc_url( $customize_action ); } $update_requires_wp = isset( $updates[ $slug ]['requires'] ) ? $updates[ $slug ]['requires'] : null; $update_requires_php = isset( $updates[ $slug ]['requires_php'] ) ? $updates[ $slug ]['requires_php'] : null; $auto_update = in_array( $slug, $auto_updates, true ); $auto_update_action = $auto_update ? 'disable-auto-update' : 'enable-auto-update'; if ( isset( $updates[ $slug ] ) ) { $auto_update_supported = true; $auto_update_filter_payload = (object) $updates[ $slug ]; } elseif ( isset( $no_updates[ $slug ] ) ) { $auto_update_supported = true; $auto_update_filter_payload = (object) $no_updates[ $slug ]; } else { $auto_update_supported = false; /* * Create the expected payload for the auto_update_theme filter, this is the same data * as contained within $updates or $no_updates but used when the Theme is not known. */ $auto_update_filter_payload = (object) array( 'theme' => $slug, 'new_version' => $theme->get( 'Version' ), 'url' => '', 'package' => '', 'requires' => $theme->get( 'RequiresWP' ), 'requires_php' => $theme->get( 'RequiresPHP' ), ); } $auto_update_forced = wp_is_auto_update_forced_for_item( 'theme', null, $auto_update_filter_payload ); $prepared_themes[ $slug ] = array( 'id' => $slug, 'name' => $theme->display( 'Name' ), 'screenshot' => array( $theme->get_screenshot() ), // @todo Multiple screenshots. 'description' => $theme->display( 'Description' ), 'author' => $theme->display( 'Author', false, true ), 'authorAndUri' => $theme->display( 'Author' ), 'tags' => $theme->display( 'Tags' ), 'version' => $theme->get( 'Version' ), 'compatibleWP' => is_wp_version_compatible( $theme->get( 'RequiresWP' ) ), 'compatiblePHP' => is_php_version_compatible( $theme->get( 'RequiresPHP' ) ), 'updateResponse' => array( 'compatibleWP' => is_wp_version_compatible( $update_requires_wp ), 'compatiblePHP' => is_php_version_compatible( $update_requires_php ), ), 'parent' => $parent, 'active' => $slug === $current_theme, 'hasUpdate' => isset( $updates[ $slug ] ), 'hasPackage' => isset( $updates[ $slug ] ) && ! empty( $updates[ $slug ]['package'] ), 'update' => get_theme_update_available( $theme ), 'autoupdate' => array( 'enabled' => $auto_update || $auto_update_forced, 'supported' => $auto_update_supported, 'forced' => $auto_update_forced, ), 'actions' => array( 'activate' => current_user_can( 'switch_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=activate&stylesheet=' . $encoded_slug ), 'switch-theme_' . $slug ) : null, 'customize' => $customize_action, 'delete' => ( ! is_multisite() && current_user_can( 'delete_themes' ) ) ? wp_nonce_url( admin_url( 'themes.php?action=delete&stylesheet=' . $encoded_slug ), 'delete-theme_' . $slug ) : null, 'autoupdate' => wp_is_auto_update_enabled_for_type( 'theme' ) && ! is_multisite() && current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=' . $auto_update_action . '&stylesheet=' . $encoded_slug ), 'updates' ) : null, ), 'blockTheme' => $theme->is_block_theme(), ); } // Remove 'delete' action if theme has an active child. if ( ! empty( $parents ) && array_key_exists( $current_theme, $parents ) ) { unset( $prepared_themes[ $parents[ $current_theme ] ]['actions']['delete'] ); } /** * Filters the themes prepared for JavaScript, for themes.php. * * Could be useful for changing the order, which is by name by default. * * @since 3.8.0 * * @param array $prepared_themes Array of theme data. */ $prepared_themes = apply_filters( 'wp_prepare_themes_for_js', $prepared_themes ); $prepared_themes = array_values( $prepared_themes ); return array_filter( $prepared_themes ); } /** * Prints JS templates for the theme-browsing UI in the Customizer. * * @since 4.2.0 */ function customize_themes_print_templates() { ?> <script type="text/html" id="tmpl-customize-themes-details-view"> <div class="theme-backdrop"></div> <div class="theme-wrap wp-clearfix" role="document"> <div class="theme-header"> <button type="button" class="left dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Show previous theme' ); ?> </span></button> <button type="button" class="right dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Show next theme' ); ?> </span></button> <button type="button" class="close dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Close details dialog' ); ?> </span></button> </div> <div class="theme-about wp-clearfix"> <div class="theme-screenshots"> <# if ( data.screenshot && data.screenshot[0] ) { #> <div class="screenshot"><img src="{{ data.screenshot[0] }}?ver={{ data.version }}" alt="" /></div> <# } else { #> <div class="screenshot blank"></div> <# } #> </div> <div class="theme-info"> <# if ( data.active ) { #> <span class="current-label"><?php _e( 'Active Theme' ); ?></span> <# } #> <h2 class="theme-name">{{{ data.name }}}<span class="theme-version"> <?php /* translators: %s: Theme version. */ printf( __( 'Version: %s' ), '{{ data.version }}' ); ?> </span></h2> <h3 class="theme-author"> <?php /* translators: %s: Theme author link. */ printf( __( 'By %s' ), '{{{ data.authorAndUri }}}' ); ?> </h3> <# if ( data.stars && 0 != data.num_ratings ) { #> <div class="theme-rating"> {{{ data.stars }}} <a class="num-ratings" target="_blank" href="{{ data.reviews_url }}"> <?php printf( '%1$s <span class="screen-reader-text">%2$s</span>', /* translators: %s: Number of ratings. */ sprintf( __( '(%s ratings)' ), '{{ data.num_ratings }}' ), /* translators: Hidden accessibility text. */ __( '(opens in a new tab)' ) ); ?> </a> </div> <# } #> <# if ( data.hasUpdate ) { #> <# if ( data.updateResponse.compatibleWP && data.updateResponse.compatiblePHP ) { #> <div class="notice notice-warning notice-alt notice-large" data-slug="{{ data.id }}"> <h3 class="notice-title"><?php _e( 'Update Available' ); ?></h3> {{{ data.update }}} </div> <# } else { #> <div class="notice notice-error notice-alt notice-large" data-slug="{{ data.id }}"> <h3 class="notice-title"><?php _e( 'Update Incompatible' ); ?></h3> <p> <# if ( ! data.updateResponse.compatibleWP && ! data.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your versions of WordPress and PHP.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.updateResponse.compatibleWP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of WordPress.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of PHP.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p> </div> <# } #> <# } #> <# if ( data.parent ) { #> <p class="parent-theme"> <?php printf( /* translators: %s: Theme name. */ __( 'This is a child theme of %s.' ), '<strong>{{{ data.parent }}}</strong>' ); ?> </p> <# } #> <# if ( ! data.compatibleWP || ! data.compatiblePHP ) { #> <div class="notice notice-error notice-alt notice-large"><p> <# if ( ! data.compatibleWP && ! data.compatiblePHP ) { #> <?php _e( 'This theme does not work with your versions of WordPress and PHP.' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.compatibleWP ) { #> <?php _e( 'This theme does not work with your version of WordPress.' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.compatiblePHP ) { #> <?php _e( 'This theme does not work with your version of PHP.' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p></div> <# } else if ( ! data.active && data.blockTheme ) { #> <div class="notice notice-error notice-alt notice-large"><p> <?php _e( 'This theme doesn\'t support Customizer.' ); ?> <# if ( data.actions.activate ) { #> <?php printf( /* translators: %s: URL to the themes page (also it activates the theme). */ ' ' . __( 'However, you can still <a href="%s">activate this theme</a>, and use the Site Editor to customize it.' ), '{{{ data.actions.activate }}}' ); ?> <# } #> </p></div> <# } #> <p class="theme-description">{{{ data.description }}}</p> <# if ( data.tags ) { #> <p class="theme-tags"><span><?php _e( 'Tags:' ); ?></span> {{{ data.tags }}}</p> <# } #> </div> </div> <div class="theme-actions"> <# if ( data.active ) { #> <button type="button" class="button button-primary customize-theme"><?php _e( 'Customize' ); ?></button> <# } else if ( 'installed' === data.type ) { #> <div class="theme-inactive-actions"> <# if ( data.blockTheme ) { #> <?php /* translators: %s: Theme name. */ $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' ); ?> <# if ( data.compatibleWP && data.compatiblePHP && data.actions.activate ) { #> <a href="{{{ data.actions.activate }}}" class="button button-primary activate" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a> <# } #> <# } else { #> <# if ( data.compatibleWP && data.compatiblePHP ) { #> <button type="button" class="button button-primary preview-theme" data-slug="{{ data.id }}"><?php _e( 'Live Preview' ); ?></button> <# } else { #> <button class="button button-primary disabled"><?php _e( 'Live Preview' ); ?></button> <# } #> <# } #> </div> <?php if ( current_user_can( 'delete_themes' ) ) { ?> <# if ( data.actions && data.actions['delete'] ) { #> <a href="{{{ data.actions['delete'] }}}" data-slug="{{ data.id }}" class="button button-secondary delete-theme"><?php _e( 'Delete' ); ?></a> <# } #> <?php } ?> <# } else { #> <# if ( data.compatibleWP && data.compatiblePHP ) { #> <button type="button" class="button theme-install" data-slug="{{ data.id }}"><?php _e( 'Install' ); ?></button> <button type="button" class="button button-primary theme-install preview" data-slug="{{ data.id }}"><?php _e( 'Install & Preview' ); ?></button> <# } else { #> <button type="button" class="button disabled"><?php _ex( 'Cannot Install', 'theme' ); ?></button> <button type="button" class="button button-primary disabled"><?php _e( 'Install & Preview' ); ?></button> <# } #> <# } #> </div> </div> </script> <?php } /** * Determines whether a theme is technically active but was paused while * loading. * * For more information on this and similar theme functions, check out * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ * Conditional Tags} article in the Theme Developer Handbook. * * @since 5.2.0 * * @global WP_Paused_Extensions_Storage $_paused_themes * * @param string $theme Path to the theme directory relative to the themes directory. * @return bool True, if in the list of paused themes. False, not in the list. */ function is_theme_paused( $theme ) { if ( ! isset( $GLOBALS['_paused_themes'] ) ) { return false; } if ( get_stylesheet() !== $theme && get_template() !== $theme ) { return false; } return array_key_exists( $theme, $GLOBALS['_paused_themes'] ); } /** * Gets the error that was recorded for a paused theme. * * @since 5.2.0 * * @global WP_Paused_Extensions_Storage $_paused_themes * * @param string $theme Path to the theme directory relative to the themes * directory. * @return array|false Array of error information as it was returned by * `error_get_last()`, or false if none was recorded. */ function wp_get_theme_error( $theme ) { if ( ! isset( $GLOBALS['_paused_themes'] ) ) { return false; } if ( ! array_key_exists( $theme, $GLOBALS['_paused_themes'] ) ) { return false; } return $GLOBALS['_paused_themes'][ $theme ]; } /** * Tries to resume a single theme. * * If a redirect was provided and a functions.php file was found, we first ensure that * functions.php file does not throw fatal errors anymore. * * The way it works is by setting the redirection to the error before trying to * include the file. If the theme fails, then the redirection will not be overwritten * with the success message and the theme will not be resumed. * * @since 5.2.0 * * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. * @global string $wp_template_path Path to current theme's template directory. * * @param string $theme Single theme to resume. * @param string $redirect Optional. URL to redirect to. Default empty string. * @return bool|WP_Error True on success, false if `$theme` was not paused, * `WP_Error` on failure. */ function resume_theme( $theme, $redirect = '' ) { global $wp_stylesheet_path, $wp_template_path; list( $extension ) = explode( '/', $theme ); /* * We'll override this later if the theme could be resumed without * creating a fatal error. */ if ( ! empty( $redirect ) ) { $functions_path = ''; if ( str_contains( $wp_stylesheet_path, $extension ) ) { $functions_path = $wp_stylesheet_path . '/functions.php'; } elseif ( str_contains( $wp_template_path, $extension ) ) { $functions_path = $wp_template_path . '/functions.php'; } if ( ! empty( $functions_path ) ) { wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'theme-resume-error_' . $theme ), $redirect ) ); // Load the theme's functions.php to test whether it throws a fatal error. ob_start(); if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) { define( 'WP_SANDBOX_SCRAPING', true ); } include $functions_path; ob_clean(); } } $result = wp_paused_themes()->delete( $extension ); if ( ! $result ) { return new WP_Error( 'could_not_resume_theme', __( 'Could not resume the theme.' ) ); } return true; } /** * Renders an admin notice in case some themes have been paused due to errors. * * @since 5.2.0 * * @global string $pagenow The filename of the current screen. * @global WP_Paused_Extensions_Storage $_paused_themes */ function paused_themes_notice() { if ( 'themes.php' === $GLOBALS['pagenow'] ) { return; } if ( ! current_user_can( 'resume_themes' ) ) { return; } if ( ! isset( $GLOBALS['_paused_themes'] ) || empty( $GLOBALS['_paused_themes'] ) ) { return; } $message = sprintf( '<p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p>', __( 'One or more themes failed to load properly.' ), __( 'You can find more details and make changes on the Themes screen.' ), esc_url( admin_url( 'themes.php' ) ), __( 'Go to the Themes screen' ) ); wp_admin_notice( $message, array( 'type' => 'error', 'paragraph_wrap' => false, ) ); } home/contenidosenred/public_html/OD/wp-includes/theme.php 0000644 00000406237 15105405313 0017541 0 ustar 00 <?php /** * Theme, template, and stylesheet functions. * * @package WordPress * @subpackage Theme */ /** * Returns an array of WP_Theme objects based on the arguments. * * Despite advances over get_themes(), this function is quite expensive, and grows * linearly with additional themes. Stick to wp_get_theme() if possible. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param array $args { * Optional. The search arguments. * * @type mixed $errors True to return themes with errors, false to return * themes without errors, null to return all themes. * Default false. * @type mixed $allowed (Multisite) True to return only allowed themes for a site. * False to return only disallowed themes for a site. * 'site' to return only site-allowed themes. * 'network' to return only network-allowed themes. * Null to return all themes. Default null. * @type int $blog_id (Multisite) The blog ID used to calculate which themes * are allowed. Default 0, synonymous for the current blog. * } * @return WP_Theme[] Array of WP_Theme objects. */ 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 ) { /* * Make sure the active theme wins out, in case search_theme_directories() picks the wrong * one in the case of a conflict. (Normally, last registered theme root wins.) */ $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; } /** * Gets a WP_Theme object for a theme. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet Optional. Directory name for the theme. Defaults to active theme. * @param string $theme_root Optional. Absolute path of the theme root to look in. * If not specified, get_raw_theme_root() is used to calculate * the theme root for the $stylesheet provided (or active theme). * @return WP_Theme Theme object. Be sure to check the object's exists() method * if you need to confirm the theme's existence. */ 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 ); } /** * Clears the cache held by get_theme_roots() and WP_Theme. * * @since 3.5.0 * @param bool $clear_update_cache Whether to clear the theme updates cache. */ 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(); } } /** * Whether a child theme is in use. * * @since 3.0.0 * @since 6.5.0 Makes use of global template variables. * * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. * @global string $wp_template_path Path to current theme's template directory. * * @return bool True if a child theme is in use, false otherwise. */ function is_child_theme() { global $wp_stylesheet_path, $wp_template_path; return $wp_stylesheet_path !== $wp_template_path; } /** * Retrieves name of the current stylesheet. * * The theme name that is currently set as the front end theme. * * For all intents and purposes, the template name and the stylesheet name * are going to be the same for most cases. * * @since 1.5.0 * * @return string Stylesheet name. */ function get_stylesheet() { /** * Filters the name of current stylesheet. * * @since 1.5.0 * * @param string $stylesheet Name of the current stylesheet. */ return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); } /** * Retrieves stylesheet directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.2 Memoization removed. * * @return string Path to active theme's stylesheet directory. */ function get_stylesheet_directory() { $stylesheet = get_stylesheet(); $theme_root = get_theme_root( $stylesheet ); $stylesheet_dir = "$theme_root/$stylesheet"; /** * Filters the stylesheet directory path for the active theme. * * @since 1.5.0 * * @param string $stylesheet_dir Absolute path to the active theme. * @param string $stylesheet Directory name of the active theme. * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); } /** * Retrieves stylesheet directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's stylesheet directory. */ 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"; /** * Filters the stylesheet directory URI. * * @since 1.5.0 * * @param string $stylesheet_dir_uri Stylesheet directory URI. * @param string $stylesheet Name of the activated theme's directory. * @param string $theme_root_uri Themes root URI. */ return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); } /** * Retrieves stylesheet URI for the active theme. * * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path. * See get_stylesheet_directory_uri(). * * @since 1.5.0 * * @return string URI to active theme's stylesheet. */ function get_stylesheet_uri() { $stylesheet_dir_uri = get_stylesheet_directory_uri(); $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; /** * Filters the URI of the active theme stylesheet. * * @since 1.5.0 * * @param string $stylesheet_uri Stylesheet URI for the active theme/child theme. * @param string $stylesheet_dir_uri Stylesheet directory URI for the active theme/child theme. */ return apply_filters( 'stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves the localized stylesheet URI. * * The stylesheet directory for the localized stylesheet files are located, by * default, in the base theme directory. The name of the locale file will be the * locale followed by '.css'. If that does not exist, then the text direction * stylesheet will be checked for existence, for example 'ltr.css'. * * The theme may change the location of the stylesheet directory by either using * the {@see 'stylesheet_directory_uri'} or {@see 'locale_stylesheet_uri'} filters. * * If you want to change the location of the stylesheet files for the entire * WordPress workflow, then change the former. If you just have the locale in a * separate folder, then change the latter. * * @since 2.1.0 * * @global WP_Locale $wp_locale WordPress date and time locale object. * * @return string URI to active theme's localized stylesheet. */ 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 = ''; } /** * Filters the localized stylesheet URI. * * @since 2.1.0 * * @param string $stylesheet_uri Localized stylesheet URI. * @param string $stylesheet_dir_uri Stylesheet directory URI. */ return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves name of the active theme. * * @since 1.5.0 * * @return string Template name. */ function get_template() { /** * Filters the name of the active theme. * * @since 1.5.0 * * @param string $template active theme's directory name. */ return apply_filters( 'template', get_option( 'template' ) ); } /** * Retrieves template directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.1 Memoization removed. * * @return string Path to active theme's template directory. */ function get_template_directory() { $template = get_template(); $theme_root = get_theme_root( $template ); $template_dir = "$theme_root/$template"; /** * Filters the active theme directory path. * * @since 1.5.0 * * @param string $template_dir The path of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root Absolute path to the themes directory. */ return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); } /** * Retrieves template directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's template directory. */ 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"; /** * Filters the active theme directory URI. * * @since 1.5.0 * * @param string $template_dir_uri The URI of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root_uri The themes root URI. */ return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); } /** * Retrieves theme roots. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @return array|string An array of theme roots keyed by template/stylesheet * or a single theme root if all themes have the same root. */ 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 ); // Regenerate the transient. $theme_roots = get_site_transient( 'theme_roots' ); } return $theme_roots; } /** * Registers a directory that contains themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param string $directory Either the full filesystem path to a theme folder * or a folder within WP_CONTENT_DIR. * @return bool True if successfully registered a directory that contains themes, * false if the directory does not exist. */ function register_theme_directory( $directory ) { global $wp_theme_directories; if ( ! file_exists( $directory ) ) { // Try prepending as the theme directory could be relative to the content directory. $directory = WP_CONTENT_DIR . '/' . $directory; // If this directory does not exist, return and do not register. 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; } /** * Searches all registered theme directories for complete and valid themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param bool $force Optional. Whether to force a new directory scan. Default false. * @return array|false Valid themes found on success, false on failure. */ 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(); /* * Set up maybe-relative, maybe-absolute array of theme directories. * We always want to return absolute, but we need to cache relative * to use in get_theme_root(). */ 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; } } /** * Filters whether to get the cache of the registered theme directories. * * @since 3.4.0 * * @param bool $cache_expiration Whether to get the cache of the theme directories. Default false. * @param string $context The class or function name calling the filter. */ $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 ) { // A cached theme root is no longer around, so skip it. 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 ], // Convert relative to absolute. ); } return $found_themes; } if ( ! is_int( $cache_expiration ) ) { $cache_expiration = 30 * MINUTE_IN_SECONDS; } } else { $cache_expiration = 30 * MINUTE_IN_SECONDS; } /* Loop the registered theme directories and extract all themes */ foreach ( $wp_theme_directories as $theme_root ) { // Start with directories in the root of the active theme directory. $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' ) ) { /* * wp-content/themes/a-single-theme * wp-content/themes is $theme_root, a-single-theme is $dir. */ $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } else { $found_theme = false; /* * wp-content/themes/a-folder-of-themes/* * wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs. */ $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; } /* * Never mind the above, it's just a theme missing a style.css. * Return it; WP_Theme will catch the error. */ 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'] ]; // Convert absolute to relative. } if ( get_site_transient( 'theme_roots' ) !== $theme_roots ) { set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); } return $found_themes; } /** * Retrieves path to themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @return string Themes directory path. */ 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 ) { /* * Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. * This gives relative theme roots the benefit of the doubt when things go haywire. */ 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'; } /** * Filters the absolute path to the themes directory. * * @since 1.5.0 * * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'theme_root', $theme_root ); } /** * Retrieves URI for themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @param string $theme_root Optional. The theme root for which calculations will be based, * preventing the need for a get_raw_theme_root() call. Default empty. * @return string Themes directory URI. */ 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 ) ) { // Absolute path. Make an educated guess. YMMV -- but note the filter below. 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' ); } /** * Filters the URI for themes directory. * * @since 1.5.0 * * @param string $theme_root_uri The URI for themes directory. * @param string $siteurl WordPress web address which is set in General Options. * @param string $stylesheet_or_template The stylesheet or template name of the theme. */ return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); } /** * Gets the raw theme root relative to the content directory with no filters applied. * * @since 3.1.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template The stylesheet or template name of the theme. * @param bool $skip_cache Optional. Whether to skip the cache. * Defaults to false, meaning the cache is used. * @return string Theme root. */ 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 requesting the root for the active theme, consult options to avoid calling get_theme_roots(). 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; } /** * Displays localized stylesheet link element. * * @since 2.1.0 */ 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 ); } /** * Switches the theme. * * Accepts one argument: $stylesheet of the theme. It also accepts an additional function signature * of two arguments: $template then $stylesheet. This is for backward compatibility. * * @since 2.5.0 * * @global string[] $wp_theme_directories * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * @global array $wp_registered_sidebars * * @param string $stylesheet Stylesheet name. */ 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 ); // Migrate from the old mods_{name} option to theme_mods_{slug}. 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 { /* * Since retrieve_widgets() is called when initializing a theme in the Customizer, * we need to remove the theme mods to avoid overwriting changes made via * the Customizer when accessing wp-admin/widgets.php. */ if ( 'wp_ajax_customize_save' === current_action() ) { remove_theme_mod( 'sidebars_widgets' ); } } // Stores classic sidebars for later use by block themes. if ( $new_theme->is_block_theme() ) { set_theme_mod( 'wp_classic_sidebars', $wp_registered_sidebars ); } update_option( 'theme_switched', $old_theme->get_stylesheet() ); /* * Reset template globals when switching themes outside of a switched blog * context to ensure templates will be loaded from the new theme. */ if ( ! is_multisite() || ! ms_is_switched() ) { wp_set_template_globals(); } // Clear pattern caches. if ( ! is_multisite() ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); } // Set autoload=no for the old theme, autoload=yes for the switched theme. $theme_mods_options = array( 'theme_mods_' . $stylesheet => 'yes', 'theme_mods_' . $old_theme->get_stylesheet() => 'no', ); wp_set_option_autoload_values( $theme_mods_options ); /** * Fires after the theme is switched. * * See {@see 'after_switch_theme'}. * * @since 1.5.0 * @since 4.5.0 Introduced the `$old_theme` parameter. * * @param string $new_name Name of the new theme. * @param WP_Theme $new_theme WP_Theme instance of the new theme. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } /** * Checks that the active theme has the required files. * * Standalone themes need to have a `templates/index.html` or `index.php` template file. * Child themes need to have a `Template` header in the `style.css` stylesheet. * * Does not initially check the default theme, which is the fallback and should always exist. * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. * Will switch theme to the fallback theme if active theme does not validate. * * You can use the {@see 'validate_current_theme'} filter to return false to disable * this functionality. * * @since 1.5.0 * @since 6.0.0 Removed the requirement for block themes to have an `index.php` template. * * @see WP_DEFAULT_THEME * * @return bool */ function validate_current_theme() { /** * Filters whether to validate the active theme. * * @since 2.7.0 * * @param bool $validate Whether to validate the active theme. Default true. */ 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' ) // Deprecated path support since 5.9.0. && ! file_exists( get_template_directory() . '/index.php' ) ) { // Invalid. } elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) { // Invalid. } elseif ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { // Invalid. } else { // Valid. return true; } $default = wp_get_theme( WP_DEFAULT_THEME ); if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } /** * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, * switch to the latest core default theme that's installed. * * If it turns out that this latest core default theme is our current * theme, then there's nothing we can do about that, so we have to bail, * rather than going into an infinite loop. (This is why there are * checks against WP_DEFAULT_THEME above, also.) We also can't do anything * if it turns out there is no default theme installed. (That's `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; } /** * Validates the theme requirements for WordPress version and PHP version. * * Uses the information from `Requires at least` and `Requires PHP` headers * defined in the theme's `style.css` file. * * @since 5.5.0 * @since 5.8.0 Removed support for using `readme.txt` as a fallback. * * @param string $stylesheet Directory name for the theme. * @return true|WP_Error True if requirements are met, WP_Error on failure. */ 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( /* translators: %s: Theme name. */ _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( /* translators: %s: Theme name. */ _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( /* translators: %s: Theme name. */ _x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } return true; } /** * Retrieves all theme modifications. * * @since 3.1.0 * @since 5.9.0 The return value is always an array. * * @return array Theme modifications. */ 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" ); // Deprecated location. 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; } /** * Retrieves theme modification value for the active theme. * * If the modification name does not exist and `$default_value` is a string, then the * default will be passed through the {@link https://www.php.net/sprintf sprintf()} * PHP function with the template directory URI as the first value and the * stylesheet directory URI as the second value. * * @since 2.1.0 * * @param string $name Theme modification name. * @param mixed $default_value Optional. Theme modification default value. Default false. * @return mixed Theme modification value. */ function get_theme_mod( $name, $default_value = false ) { $mods = get_theme_mods(); if ( isset( $mods[ $name ] ) ) { /** * Filters the theme modification, or 'theme_mod', value. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 2.2.0 * * @param mixed $current_mod The value of the active theme modification. */ return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); } if ( is_string( $default_value ) ) { // Only run the replacement if an sprintf() string format pattern was found. if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default_value ) ) { // Remove a single trailing percent sign. $default_value = preg_replace( '#(?<!%)%$#', '', $default_value ); $default_value = sprintf( $default_value, get_template_directory_uri(), get_stylesheet_directory_uri() ); } } /** This filter is documented in wp-includes/theme.php */ return apply_filters( "theme_mod_{$name}", $default_value ); } /** * Updates theme modification value for the active theme. * * @since 2.1.0 * @since 5.6.0 A return value was added. * * @param string $name Theme modification name. * @param mixed $value Theme modification value. * @return bool True if the value was updated, false otherwise. */ function set_theme_mod( $name, $value ) { $mods = get_theme_mods(); $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; /** * Filters the theme modification, or 'theme_mod', value on save. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 3.9.0 * * @param mixed $value The new value of the theme modification. * @param mixed $old_value The current value of the theme modification. */ $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); $theme = get_option( 'stylesheet' ); return update_option( "theme_mods_$theme", $mods ); } /** * Removes theme modification name from active theme list. * * If removing the name also removes all elements, then the entire option * will be removed. * * @since 2.1.0 * * @param string $name Theme modification name. */ 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 ); } /** * Removes theme modifications option for the active theme. * * @since 2.1.0 */ function remove_theme_mods() { delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); // Old style. $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } delete_option( 'mods_' . $theme_name ); } /** * Retrieves the custom header text color in 3- or 6-digit hexadecimal form. * * @since 2.1.0 * * @return string Header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). */ function get_header_textcolor() { return get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } /** * Displays the custom header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). * * @since 2.1.0 */ function header_textcolor() { echo get_header_textcolor(); } /** * Whether to display the header text. * * @since 3.4.0 * * @return bool */ 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; } /** * Checks whether a header image is set or not. * * @since 4.2.0 * * @see get_header_image() * * @return bool Whether a header image is set or not. */ function has_header_image() { return (bool) get_header_image(); } /** * Retrieves header image for custom header. * * @since 2.1.0 * * @return string|false */ 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(); } /** * Filters the header image URL. * * @since 6.1.0 * * @param string $url Header image URL. */ $url = apply_filters( 'get_header_image', $url ); if ( ! is_string( $url ) ) { return false; } $url = trim( $url ); return sanitize_url( set_url_scheme( $url ) ); } /** * Creates image tag markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Additional attributes for the image tag. Can be used * to override the default attributes. Default empty. * @return string HTML image element markup or empty string on failure. */ 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 = ''; // Use alternative text assigned to the image, if available. Otherwise, leave it empty. 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, ) ); // Generate 'srcset' and 'sizes' if not already present. 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 the default value of `lazy` for the `loading` attribute is overridden * to omit the attribute for this image, ensure it is not included. */ if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } // If the `fetchpriority` attribute is overridden and set to false or an empty string. if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } // If the `decoding` attribute is overridden and set to false or an empty string. if ( isset( $attr['decoding'] ) && ! $attr['decoding'] ) { unset( $attr['decoding'] ); } /** * Filters the list of header image attributes. * * @since 5.9.0 * * @param array $attr Array of the attributes for the image tag. * @param object $header The custom header object returned by 'get_custom_header()'. */ $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 .= ' />'; /** * Filters the markup of header images. * * @since 4.4.0 * * @param string $html The HTML image tag markup being filtered. * @param object $header The custom header object returned by 'get_custom_header()'. * @param array $attr Array of the attributes for the image tag. */ return apply_filters( 'get_header_image_tag', $html, $header, $attr ); } /** * Displays the image markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Attributes for the image markup. Default empty. */ function the_header_image_tag( $attr = array() ) { echo get_header_image_tag( $attr ); } /** * Gets random header image data from registered images in theme. * * @since 3.4.0 * * @access private * * @global array $_wp_default_headers * * @return object */ 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; } /** * Gets random header image URL from registered images in theme. * * @since 3.2.0 * * @return string Path to header image. */ function get_random_header_image() { $random_image = _get_random_header_data(); if ( empty( $random_image->url ) ) { return ''; } return $random_image->url; } /** * Checks if random header image is in use. * * Always true if user expressly chooses the option in Appearance > Header. * Also true if theme has multiple header images registered, no specific header image * is chosen, and theme turns on random headers with add_theme_support(). * * @since 3.2.0 * * @param string $type The random pool to use. Possible values include 'any', * 'default', 'uploaded'. Default 'any'. * @return bool */ 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; } /** * Displays header image URL. * * @since 2.1.0 */ function header_image() { $image = get_header_image(); if ( $image ) { echo esc_url( $image ); } } /** * Gets the header images uploaded for the active theme. * * @since 3.2.0 * * @return array */ function get_uploaded_header_images() { $header_images = array(); // @todo Caching. $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; } /** * Gets the header image data. * * @since 3.4.0 * * @global array $_wp_default_headers * * @return object */ 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 ); } /** * Registers a selection of default headers to be displayed by the custom header admin UI. * * @since 3.0.0 * * @global array $_wp_default_headers * * @param array $headers Array of headers keyed by a string ID. The IDs point to arrays * containing 'url', 'thumbnail_url', and 'description' keys. */ function register_default_headers( $headers ) { global $_wp_default_headers; $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); } /** * Unregisters default headers. * * This function must be called after register_default_headers() has already added the * header you want to remove. * * @see register_default_headers() * @since 3.0.0 * * @global array $_wp_default_headers * * @param string|array $header The header string id (key of array) to remove, or an array thereof. * @return bool|void A single header returns true on success, false on failure. * There is currently no return value for multiple 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; } } /** * Checks whether a header video is set or not. * * @since 4.7.0 * * @see get_header_video_url() * * @return bool Whether a header video is set or not. */ function has_header_video() { return (bool) get_header_video_url(); } /** * Retrieves header video URL for custom header. * * Uses a local video if present, or falls back to an external video. * * @since 4.7.0 * * @return string|false Header video URL or false if there is no video. */ function get_header_video_url() { $id = absint( get_theme_mod( 'header_video' ) ); if ( $id ) { // Get the file URL from the attachment ID. $url = wp_get_attachment_url( $id ); } else { $url = get_theme_mod( 'external_header_video' ); } /** * Filters the header video URL. * * @since 4.7.3 * * @param string $url Header video URL, if available. */ $url = apply_filters( 'get_header_video_url', $url ); if ( ! $id && ! $url ) { return false; } return sanitize_url( set_url_scheme( $url ) ); } /** * Displays header video URL. * * @since 4.7.0 */ function the_header_video_url() { $video = get_header_video_url(); if ( $video ) { echo esc_url( $video ); } } /** * Retrieves header video settings. * * @since 4.7.0 * * @return array */ 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']; } /** * Filters header video settings. * * @since 4.7.0 * * @param array $settings An array of header video settings. */ return apply_filters( 'header_video_settings', $settings ); } /** * Checks whether a custom header is set or not. * * @since 4.7.0 * * @return bool True if a custom header is set. False if not. */ function has_custom_header() { if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) { return true; } return false; } /** * Checks whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @return bool True if the custom header video should be shown. False if not. */ 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 ); } /** * Filters whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @param bool $show_video Whether the custom header video should be shown. Returns the value * of the theme setting for the `custom-header`'s `video-active-callback`. * If no callback is set, the default value is that of `is_front_page()`. */ return apply_filters( 'is_header_video_active', $show_video ); } /** * Retrieves the markup for a custom header. * * The container div will always be returned in the Customizer preview. * * @since 4.7.0 * * @return string The markup for a custom header on success. */ 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() ); } /** * Prints the markup for a custom header. * * A container div will always be printed in the Customizer preview. * * @since 4.7.0 */ 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() ); } } /** * Retrieves background image for custom background. * * @since 3.0.0 * * @return string */ function get_background_image() { return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); } /** * Displays background image path. * * @since 3.0.0 */ function background_image() { echo get_background_image(); } /** * Retrieves value for custom background color. * * @since 3.0.0 * * @return string */ function get_background_color() { return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); } /** * Displays background color value. * * @since 3.0.0 */ function background_color() { echo get_background_color(); } /** * Default custom background callback. * * @since 3.0.0 */ function _custom_background_cb() { // $background is the saved custom image, or the default image. $background = set_url_scheme( get_background_image() ); /* * $color is the saved custom color. * A default has to be specified in style.css. It will not be printed here. */ $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 ) . '");'; // Background Position. $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;"; // Background Size. $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;"; // Background Repeat. $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;"; // Background Scroll. $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 } /** * Renders the Custom CSS style element. * * @since 4.7.0 */ 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 // Note that esc_html() cannot be used because `div > span` is not interpreted properly. echo strip_tags( $styles ); ?> </style> <?php endif; } /** * Fetches the `custom_css` post for a given theme. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return WP_Post|null The custom_css post or null if none exists. */ 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 ); } // `-1` indicates no post exists; no query necessary. if ( ! $post && -1 !== $post_id ) { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; /* * Cache the lookup. See wp_update_custom_css_post(). * @todo This should get cleared if a custom_css post is added/removed. */ 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; } /** * Fetches the saved Custom CSS content for rendering. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return string The Custom CSS Post content. */ 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; } /** * Filters the custom CSS output into the head element. * * @since 4.7.0 * * @param string $css CSS pulled in from the Custom CSS post type. * @param string $stylesheet The theme stylesheet name. */ $css = apply_filters( 'wp_get_custom_css', $css, $stylesheet ); return $css; } /** * Updates the `custom_css` post for a given theme. * * Inserts a `custom_css` post when one doesn't yet exist. * * @since 4.7.0 * * @param string $css CSS, stored in `post_content`. * @param array $args { * Args. * * @type string $preprocessed Optional. Pre-processed CSS, stored in `post_content_filtered`. * Normally empty string. * @type string $stylesheet Optional. Stylesheet (child theme) to update. * Defaults to active theme/stylesheet. * } * @return WP_Post|WP_Error Post on success, error on failure. */ 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'], ); /** * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args * for a `custom_css` post being updated. * * This filter can be used by plugin that offer CSS pre-processors, to store the original * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`. * When used in this way, the `post_content_filtered` should be supplied as the setting value * instead of `post_content` via a the `customize_value_custom_css` filter, for example: * * <code> * add_filter( 'customize_value_custom_css', function( $value, $setting ) { * $post = wp_get_custom_css_post( $setting->stylesheet ); * if ( $post && ! empty( $post->post_content_filtered ) ) { * $css = $post->post_content_filtered; * } * return $css; * }, 10, 2 ); * </code> * * @since 4.7.0 * @param array $data { * Custom CSS data. * * @type string $css CSS stored in `post_content`. * @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. * Normally empty string. * } * @param array $args { * The args passed into `wp_update_custom_css_post()` merged with defaults. * * @type string $css The original CSS passed in to be updated. * @type string $preprocessed The original preprocessed CSS passed in to be updated. * @type string $stylesheet The stylesheet (theme) being updated. * } */ $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'], ); // Update post if it already exists, otherwise create a new one. $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 ); } // Trigger creation of a revision. This should be removed once #30854 is resolved. $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 ); } /** * Adds callback for custom TinyMCE editor stylesheets. * * The parameter $stylesheet is the name of the stylesheet, relative to * the theme root. It also accepts an array of stylesheets. * It is optional and defaults to 'editor-style.css'. * * This function automatically adds another stylesheet with -rtl prefix, e.g. editor-style-rtl.css. * If that file doesn't exist, it is removed before adding the stylesheet(s) to TinyMCE. * If an array of stylesheets is passed to add_editor_style(), * RTL is only added for the first stylesheet. * * Since version 3.4 the TinyMCE body has .rtl CSS class. * It is a better option to use that class and add any RTL styles to the main stylesheet. * * @since 3.0.0 * * @global array $editor_styles * * @param array|string $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. * Defaults to 'editor-style.css' */ 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 ); } /** * Removes all visual editor stylesheets. * * @since 3.1.0 * * @global array $editor_styles * * @return bool True on success, false if there were no stylesheets to remove. */ 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; } /** * Retrieves any registered editor stylesheet URLs. * * @since 4.0.0 * * @global array $editor_styles Registered editor stylesheets * * @return string[] If registered, a list of editor stylesheet URLs. */ function get_editor_stylesheets() { $stylesheets = array(); // Load editor_style.css if the active theme supports it. 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(); // Support externally referenced styles (like, say, fonts). foreach ( $editor_styles as $key => $file ) { if ( preg_match( '~^(https?:)?//~', $file ) ) { $stylesheets[] = sanitize_url( $file ); unset( $editor_styles[ $key ] ); } } // Look in a parent theme first, that way child theme CSS overrides. 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"; } } } /** * Filters the array of URLs of stylesheets applied to the editor. * * @since 4.3.0 * * @param string[] $stylesheets Array of URLs of stylesheets to be applied to the editor. */ return apply_filters( 'editor_stylesheets', $stylesheets ); } /** * Expands a theme's starter content configuration using core-provided data. * * @since 4.7.0 * * @return array Array of starter content. */ 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( // Deprecated in favor of 'link_home'. '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 ) { // Use options and theme_mods as-is. case 'options': case 'theme_mods': $content[ $type ] = $config[ $type ]; break; // Widgets are grouped into sidebars. case 'widgets': foreach ( $config[ $type ] as $sidebar_id => $widgets ) { foreach ( $widgets as $id => $widget ) { if ( is_array( $widget ) ) { // Item extends core content. 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; // And nav menu items are grouped into nav menus. case 'nav_menus': foreach ( $config[ $type ] as $nav_menu_location => $nav_menu ) { // Ensure nav menus get a name. 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 ) ) { // Item extends core content. 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; // Attachments are posts but have special treatment. case 'attachments': foreach ( $config[ $type ] as $id => $item ) { if ( ! empty( $item['file'] ) ) { $content[ $type ][ $id ] = $item; } } break; /* * All that's left now are posts (besides attachments). * Not a default case for the sake of clarity and future work. */ case 'posts': foreach ( $config[ $type ] as $id => $item ) { if ( is_array( $item ) ) { // Item extends core content. if ( ! empty( $core_content[ $type ][ $id ] ) ) { $item = array_merge( $core_content[ $type ][ $id ], $item ); } // Enforce a subset of fields. $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; } } /** * Filters the expanded array of starter content. * * @since 4.7.0 * * @param array $content Array of starter content. * @param array $config Array of theme-specific starter content configuration. */ return apply_filters( 'get_theme_starter_content', $content, $config ); } /** * Registers theme support for a given feature. * * Must be called in the theme's functions.php file to work. * If attached to a hook, it must be {@see 'after_setup_theme'}. * The {@see 'init'} hook may be too late for some features. * * Example usage: * * add_theme_support( 'title-tag' ); * add_theme_support( 'custom-logo', array( * 'height' => 480, * 'width' => 720, * ) ); * * @since 2.9.0 * @since 3.4.0 The `custom-header-uploads` feature was deprecated. * @since 3.6.0 The `html5` feature was added. * @since 3.6.1 The `html5` feature requires an array of types to be passed. Defaults to * 'comment-list', 'comment-form', 'search-form' for backward compatibility. * @since 3.9.0 The `html5` feature now also accepts 'gallery' and 'caption'. * @since 4.1.0 The `title-tag` feature was added. * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added. * @since 4.7.0 The `starter-content` feature was added. * @since 5.0.0 The `responsive-embeds`, `align-wide`, `dark-editor-style`, `disable-custom-colors`, * `disable-custom-font-sizes`, `editor-color-palette`, `editor-font-sizes`, * `editor-styles`, and `wp-block-styles` features were added. * @since 5.3.0 The `html5` feature now also accepts 'script' and 'style'. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * @since 5.4.0 The `disable-custom-gradients` feature limits to default gradients or gradients added * through `editor-gradient-presets` theme support. * @since 5.5.0 The `core-block-patterns` feature was added and is enabled by default. * @since 5.5.0 The `custom-logo` feature now also accepts 'unlink-homepage-logo'. * @since 5.6.0 The `post-formats` feature warns if no array is passed as the second parameter. * @since 5.8.0 The `widgets-block-editor` feature enables the Widgets block editor. * @since 5.8.0 The `block-templates` feature indicates whether a theme uses block-based templates. * @since 6.0.0 The `html5` feature warns if no array is passed as the second parameter. * @since 6.1.0 The `block-template-parts` feature allows to edit any reusable template part from site editor. * @since 6.1.0 The `disable-layout-styles` feature disables the default layout styles. * @since 6.3.0 The `link-color` feature allows to enable the link color setting. * @since 6.3.0 The `border` feature allows themes without theme.json to add border styles to blocks. * @since 6.5.0 The `appearance-tools` feature enables a few design tools for blocks, * see `WP_Theme_JSON::APPEARANCE_TOOLS_OPT_INS` for a complete list. * @since 6.6.0 The `editor-spacing-sizes` feature was added. * * @global array $_wp_theme_features * * @param string $feature The feature being added. Likely core values include: * - 'admin-bar' * - 'align-wide' * - 'appearance-tools' * - 'automatic-feed-links' * - 'block-templates' * - 'block-template-parts' * - 'border' * - 'core-block-patterns' * - 'custom-background' * - 'custom-header' * - 'custom-line-height' * - 'custom-logo' * - 'customize-selective-refresh-widgets' * - 'custom-spacing' * - 'custom-units' * - 'dark-editor-style' * - 'disable-custom-colors' * - 'disable-custom-font-sizes' * - 'disable-custom-gradients' * - 'disable-layout-styles' * - 'editor-color-palette' * - 'editor-gradient-presets' * - 'editor-font-sizes' * - 'editor-spacing-sizes' * - 'editor-styles' * - 'featured-content' * - 'html5' * - 'link-color' * - 'menus' * - 'post-formats' * - 'post-thumbnails' * - 'responsive-embeds' * - 'starter-content' * - 'title-tag' * - 'widgets' * - 'widgets-block-editor' * - 'wp-block-styles' * @param mixed ...$args Optional extra arguments to pass along with certain features. * @return void|false Void on success, false on failure. */ function add_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! $args ) { $args = true; } switch ( $feature ) { case 'post-thumbnails': // All post types are already supported. if ( true === get_theme_support( 'post-thumbnails' ) ) { return; } /* * Merge post types with any that already declared their support * for post thumbnails. */ 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': // You can't just pass 'html5', you need to pass an array of types. 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; } // Build an array of types for back-compat. $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); } // Calling 'html5' again merges, rather than overwrites. 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 ); // Allow full flexibility if no size is specified. 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'] ); /* * Merge in data from previous add_theme_support() calls. * The first value registered wins. (A child theme is set up first.) */ if ( isset( $_wp_theme_features['custom-header'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] ); } /* * Load in the defaults at the end, as we need to insure first one wins. * This will cause all constants to be defined, as each arg will then be set to the default. */ if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } /* * If a constant was defined, use that value. Otherwise, define the constant to ensure * the constant is always accurate (and is not defined later, overriding our value). * As stated above, the first value wins. * Once we get to wp_loaded (just-in-time), define any constants we haven't already. * Constants should be avoided. Don't reference them. This is just for backward compatibility. */ 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 headers are supported, and we still don't have a defined width or height, * we have implicit flex sizes. */ 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'] ); // Merge in data from previous add_theme_support() calls. The first value registered wins. 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; // Ensure that 'title-tag' is accessible in the admin. case 'title-tag': // Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php. if ( did_action( 'wp_loaded' ) ) { _doing_it_wrong( "add_theme_support( 'title-tag' )", sprintf( /* translators: 1: title-tag, 2: wp_loaded */ __( '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; } /** * Registers the internal custom header and background routines. * * @since 3.4.0 * @access private * * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background */ function _custom_header_background_just_in_time() { global $custom_image_header, $custom_background; if ( current_theme_supports( 'custom-header' ) ) { // In case any constants were defined after an add_custom_image_header() call, re-run. 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' ) ) { // In case any constants were defined after an add_custom_background() call, re-run. 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'] ); } } } /** * Adds CSS to hide header text for custom logo, based on Customizer setting. * * @since 4.5.0 * @access private */ 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 } } /** * Gets the theme support arguments passed when registering that support. * * Example usage: * * get_theme_support( 'custom-logo' ); * get_theme_support( 'custom-header', 'width' ); * * @since 3.1.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature to check. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return mixed The array of extra arguments or the value for the registered feature. */ 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 ]; } } /** * Allows a theme to de-register its support of a certain feature * * Should be called in the theme's functions.php file. Generally would * be used for child themes to override support from the parent theme. * * @since 3.0.0 * * @see add_theme_support() * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool|void Whether feature was removed. */ function remove_theme_support( $feature ) { // Do not remove internal registrations that are not used directly by themes. if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ), true ) ) { return false; } return _remove_theme_support( $feature ); } /** * Do not use. Removes theme support internally without knowledge of those not used * by themes directly. * * @access private * @since 3.1.0 * @global array $_wp_theme_features * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool True if support was removed, false if the feature was not registered. */ 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; // Do not continue - custom-header-uploads no longer exists. } 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; } /** * Checks a theme's support for a given feature. * * Example usage: * * current_theme_supports( 'custom-logo' ); * current_theme_supports( 'html5', 'comment-form' ); * * @since 2.9.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return bool True if the active theme supports the feature, false otherwise. */ 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 no args passed then no extra checks need to be performed. if ( ! $args ) { /** This filter is documented in wp-includes/theme.php */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } switch ( $feature ) { case 'post-thumbnails': /* * post-thumbnails can be registered for only certain content/post types * by passing an array of types to add_theme_support(). * If no array was passed, then any type is accepted. */ if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types. return true; } $content_type = $args[0]; return in_array( $content_type, $_wp_theme_features[ $feature ][0], true ); case 'html5': case 'post-formats': /* * Specific post formats can be registered by passing an array of types * to add_theme_support(). * * Specific areas of HTML5 support *must* be passed via an array to add_theme_support(). */ $type = $args[0]; return in_array( $type, $_wp_theme_features[ $feature ][0], true ); case 'custom-logo': case 'custom-header': case 'custom-background': // Specific capabilities can be registered by passing an array to add_theme_support(). return ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) && $_wp_theme_features[ $feature ][0][ $args[0] ] ); } /** * Filters whether the active theme supports a specific feature. * * The dynamic portion of the hook name, `$feature`, refers to the specific * theme feature. See add_theme_support() for the list of possible values. * * @since 3.4.0 * * @param bool $supports Whether the active theme supports the given feature. Default true. * @param array $args Array of arguments for the feature. * @param string $feature The theme feature. */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } /** * Checks a theme's support for a given feature before loading the functions which implement it. * * @since 2.9.0 * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param string $file Path to the file. * @return bool True if the active theme supports the supplied feature, false otherwise. */ function require_if_theme_supports( $feature, $file ) { if ( current_theme_supports( $feature ) ) { require $file; return true; } return false; } /** * Registers a theme feature for use in add_theme_support(). * * This does not indicate that the active theme supports the feature, it only describes * the feature's supported options. * * @since 5.5.0 * * @see add_theme_support() * * @global array $_wp_registered_theme_features * * @param string $feature The name uniquely identifying the feature. See add_theme_support() * for the list of possible values. * @param array $args { * Data used to describe the theme. * * @type string $type The type of data associated with this feature. * Valid values are 'string', 'boolean', 'integer', * 'number', 'array', and 'object'. Defaults to 'boolean'. * @type bool $variadic Does this feature utilize the variadic support * of add_theme_support(), or are all arguments specified * as the second parameter. Must be used with the "array" type. * @type string $description A short description of the feature. Included in * the Themes REST API schema. Intended for developers. * @type bool|array $show_in_rest { * Whether this feature should be included in the Themes REST API endpoint. * Defaults to not being included. When registering an 'array' or 'object' type, * this argument must be an array with the 'schema' key. * * @type array $schema Specifies the JSON Schema definition describing * the feature. If any objects in the schema do not include * the 'additionalProperties' keyword, it is set to false. * @type string $name An alternate name to be used as the property name * in the REST API. * @type callable $prepare_callback A function used to format the theme support in the REST API. * Receives the raw theme support value. * } * } * @return true|WP_Error True if the theme feature was successfully registered, a WP_Error object if not. */ 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( /* translators: %s: prepare_callback */ __( '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 ) ) { // Automatically include the "boolean" type when the default value is a boolean. $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; } /** * Gets the list of registered theme features. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @return array[] List of theme features, keyed by their name. */ function get_registered_theme_features() { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return array(); } return $_wp_registered_theme_features; } /** * Gets the registration config for a theme feature. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @param string $feature The feature name. See add_theme_support() for the list * of possible values. * @return array|null The registration args, or null if the feature was not registered. */ 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; } /** * Checks an attachment being deleted to see if it's a header or background image. * * If true it removes the theme modification which would be pointing at the deleted * attachment. * * @access private * @since 3.0.0 * @since 4.3.0 Also removes `header_image_data`. * @since 4.5.0 Also removes custom logo theme mods. * @since 6.6.0 Also removes `site_logo` option set by the site logo block. * * @param int $id The attachment ID. */ 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' ); } } /** * Checks if a theme has been changed and runs 'after_switch_theme' hook on the next WP load. * * See {@see 'after_switch_theme'}. * * @since 3.3.0 */ function check_theme_switched() { $stylesheet = get_option( 'theme_switched' ); if ( $stylesheet ) { $old_theme = wp_get_theme( $stylesheet ); // Prevent widget & menu mapping from running since Customizer already called it up front. 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() ) { /** * Fires on the next WP load after the theme has been switched. * * The parameters differ according to whether the old theme exists or not. * If the old theme is missing, the old name will instead be the slug * of the old theme. * * See {@see 'switch_theme'}. * * @since 3.3.0 * * @param string $old_name Old theme name. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'after_switch_theme', $old_theme->get( 'Name' ), $old_theme ); } else { /** This action is documented in wp-includes/theme.php */ do_action( 'after_switch_theme', $stylesheet, $old_theme ); } flush_rewrite_rules(); update_option( 'theme_switched', false ); } } /** * Includes and instantiates the WP_Customize_Manager class. * * Loads the Customizer at plugins_loaded when accessing the customize.php admin * page or when any request includes a wp_customize=on param or a customize_changeset * param (a UUID). This param is a signal for whether to bootstrap the Customizer when * WordPress is loading, especially in the Customizer preview * or when making Customizer Ajax requests for widgets or menus. * * @since 3.4.0 * * @global WP_Customize_Manager $wp_customize */ 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; } /* * Note that wp_unslash() is not being used on the input vars because it is * called before wp_magic_quotes() gets called. Besides this fact, none of * the values should contain any characters needing slashes anyway. */ $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; /* * Value false indicates UUID should be determined after_setup_theme * to either re-use existing saved changeset or else generate a new UUID if none exists. */ $changeset_uuid = false; /* * Set initially to false since defaults to true for back-compat; * can be overridden via the customize_changeset_branching filter. */ $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'] ); } // Note that theme will be sanitized via WP_Theme. 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'] ); } /* * Note that settings must be previewed even outside the customizer preview * and also in the customizer pane itself. This is to enable loading an existing * changeset into the customizer. Previewing the settings only has to be prevented * here in the case of a customize_save action because this will cause WP to think * there is nothing changed that needs to be saved. */ $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' ) ); } /** * Publishes a snapshot's changes. * * @since 4.7.0 * @access private * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @param string $new_status New post status. * @param string $old_status Old post status. * @param WP_Post $changeset_post Changeset post object. */ 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' ) ) { /* * When running from CLI or Cron, the customize_register action will need * to be triggered in order for core, themes, and plugins to register their * settings. Normally core will add_action( 'customize_register' ) at * priority 10 to register the core settings, and if any themes/plugins * also add_action( 'customize_register' ) at the same priority, they * will have a $wp_customize with those settings registered since they * call add_action() afterward, normally. However, when manually doing * the customize_register action after the setup_theme, then the order * will be reversed for two actions added at priority 10, resulting in * the core settings no longer being available as expected to themes/plugins. * So the following manually calls the method that registers the core * settings up front before doing the action. */ remove_action( 'customize_register', array( $wp_customize, 'register_controls' ) ); $wp_customize->register_controls(); /** This filter is documented in wp-includes/class-wp-customize-manager.php */ do_action( 'customize_register', $wp_customize ); } $wp_customize->_publish_changeset_values( $changeset_post->ID ); /* * Trash the changeset post if revisions are not enabled. Unpublished * changesets by default get garbage collected due to the auto-draft status. * When a changeset post is published, however, it would no longer get cleaned * out. This is a problem when the changeset posts are never displayed anywhere, * since they would just be endlessly piling up. So here we use the revisions * feature to indicate whether or not a published changeset should get trashed * and thus garbage collected. */ if ( ! wp_revisions_enabled( $changeset_post ) ) { $wp_customize->trash_changeset_post( $changeset_post->ID ); } } /** * Filters changeset post data upon insert to ensure post_name is intact. * * This is needed to prevent the post_name from being dropped when the post is * transitioned into pending status by a contributor. * * @since 4.7.0 * * @see wp_insert_post() * * @param array $post_data An array of slashed post data. * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data. * @return array Filtered data. */ 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'] ) { // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending. if ( empty( $post_data['post_name'] ) && ! empty( $supplied_post_data['post_name'] ) ) { $post_data['post_name'] = $supplied_post_data['post_name']; } } return $post_data; } /** * Adds settings for the customize-loader script. * * @since 3.4.0 */ 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 ) . ';'; $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 ); } /** * Returns a URL to load the Customizer. * * @since 3.4.0 * * @param string $stylesheet Optional. Theme to customize. Defaults to active theme. * The theme's stylesheet will be urlencoded if necessary. * @return string */ function wp_customize_url( $stylesheet = '' ) { $url = admin_url( 'customize.php' ); if ( $stylesheet ) { $url .= '?theme=' . urlencode( $stylesheet ); } return esc_url( $url ); } /** * Prints a script to check whether or not the Customizer is supported, * and apply either the no-customize-support or customize-support class * to the body. * * This function MUST be called inside the body tag. * * Ideally, call this function immediately after the body tag is opened. * This prevents a flash of unstyled content. * * It is also recommended that you add the "no-customize-support" class * to the body tag by default. * * @since 3.4.0 * @since 4.7.0 Support for IE8 and below is explicitly removed via conditional comments. * @since 5.5.0 IE8 and older are no longer supported. */ 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() ) ); } /** * Whether the site is being previewed in the Customizer. * * @since 4.0.0 * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @return bool True if the site is being previewed in the Customizer, false otherwise. */ function is_customize_preview() { global $wp_customize; return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); } /** * Makes sure that auto-draft posts get their post_date bumped or status changed * to draft to prevent premature garbage-collection. * * When a changeset is updated but remains an auto-draft, ensure the post_date * for the auto-draft posts remains the same so that it will be * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, * if the changeset is updated to be a draft then update the posts * to have a far-future post_date so that they will never be garbage collected * unless the changeset post itself is deleted. * * When a changeset is updated to be a persistent draft or to be scheduled for * publishing, then transition any dependent auto-drafts to a draft status so * that they likewise will not be garbage-collected but also so that they can * be edited in the admin before publishing since there is not yet a post/page * editing flow in the Customizer. See #39752. * * @link https://core.trac.wordpress.org/ticket/39752 * * @since 4.8.0 * @access private * @see wp_delete_auto_drafts() * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $new_status Transition to this post status. * @param string $old_status Previous post status. * @param \WP_Post $post Post data. */ function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { global $wpdb; unset( $old_status ); // Short-circuit if not a changeset or if the changeset was published. 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; } /* * Actually, in lieu of keeping alive, trash any customization drafts here if the changeset itself is * getting trashed. This is needed because when a changeset transitions to a draft, then any of the * dependent auto-draft post/page stubs will also get transitioned to customization drafts which * are then visible in the WP Admin. We cannot wait for the deletion of the changeset in which * _wp_delete_customize_changeset_dependent_auto_drafts() will be called, since they need to be * trashed to remove from visibility immediately. */ 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 ) { /* * Keep the post date for the post matching the changeset * so that it will not be garbage-collected before the changeset. */ $post_args['post_date'] = $post->post_date; // Note wp_delete_auto_drafts() only looks at this date. } else { /* * Since the changeset no longer has an auto-draft (and it is not published) * it is now a persistent changeset, a long-lived draft, and so any * associated auto-draft posts should likewise transition into having a draft * status. These drafts will be treated differently than regular drafts in * that they will be tied to the given changeset. The publish meta box is * replaced with a notice about how the post is part of a set of customized changes * which will be published when the changeset is published. */ $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 ); } } /** * Creates the initial theme features when the 'setup_theme' action is fired. * * See {@see 'setup_theme'}. * * @since 5.5.0 * @since 6.0.1 The `block-templates` feature was added. */ 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, ) ); } /** * Returns whether the active theme is a block-based theme or not. * * @since 5.9.0 * * @return bool Whether the active theme is a block-based theme or not. */ 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(); } /** * Given an element name, returns a class name. * * Alias of WP_Theme_JSON::get_element_class_name. * * @since 6.1.0 * * @param string $element The name of the element. * * @return string The name of the class. */ function wp_theme_get_element_class_name( $element ) { return WP_Theme_JSON::get_element_class_name( $element ); } /** * Adds default theme supports for block themes when the 'after_setup_theme' action fires. * * See {@see 'after_setup_theme'}. * * @since 5.9.0 * @access private */ 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' ); /* * Makes block themes support HTML5 by default for the comment block and search form * (which use default template functions) and `[caption]` and `[gallery]` shortcodes. * Other blocks contain their own HTML5 markup. */ 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' ); /* * Remove the Customizer's Menus panel when block theme is active. */ 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 ); } home/contenidosenred/public_html/ondemand/wp-includes/theme.php 0000644 00000406237 15105534134 0021030 0 ustar 00 <?php /** * Theme, template, and stylesheet functions. * * @package WordPress * @subpackage Theme */ /** * Returns an array of WP_Theme objects based on the arguments. * * Despite advances over get_themes(), this function is quite expensive, and grows * linearly with additional themes. Stick to wp_get_theme() if possible. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param array $args { * Optional. The search arguments. * * @type mixed $errors True to return themes with errors, false to return * themes without errors, null to return all themes. * Default false. * @type mixed $allowed (Multisite) True to return only allowed themes for a site. * False to return only disallowed themes for a site. * 'site' to return only site-allowed themes. * 'network' to return only network-allowed themes. * Null to return all themes. Default null. * @type int $blog_id (Multisite) The blog ID used to calculate which themes * are allowed. Default 0, synonymous for the current blog. * } * @return WP_Theme[] Array of WP_Theme objects. */ 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 ) { /* * Make sure the active theme wins out, in case search_theme_directories() picks the wrong * one in the case of a conflict. (Normally, last registered theme root wins.) */ $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; } /** * Gets a WP_Theme object for a theme. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet Optional. Directory name for the theme. Defaults to active theme. * @param string $theme_root Optional. Absolute path of the theme root to look in. * If not specified, get_raw_theme_root() is used to calculate * the theme root for the $stylesheet provided (or active theme). * @return WP_Theme Theme object. Be sure to check the object's exists() method * if you need to confirm the theme's existence. */ 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 ); } /** * Clears the cache held by get_theme_roots() and WP_Theme. * * @since 3.5.0 * @param bool $clear_update_cache Whether to clear the theme updates cache. */ 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(); } } /** * Whether a child theme is in use. * * @since 3.0.0 * @since 6.5.0 Makes use of global template variables. * * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. * @global string $wp_template_path Path to current theme's template directory. * * @return bool True if a child theme is in use, false otherwise. */ function is_child_theme() { global $wp_stylesheet_path, $wp_template_path; return $wp_stylesheet_path !== $wp_template_path; } /** * Retrieves name of the current stylesheet. * * The theme name that is currently set as the front end theme. * * For all intents and purposes, the template name and the stylesheet name * are going to be the same for most cases. * * @since 1.5.0 * * @return string Stylesheet name. */ function get_stylesheet() { /** * Filters the name of current stylesheet. * * @since 1.5.0 * * @param string $stylesheet Name of the current stylesheet. */ return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); } /** * Retrieves stylesheet directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.2 Memoization removed. * * @return string Path to active theme's stylesheet directory. */ function get_stylesheet_directory() { $stylesheet = get_stylesheet(); $theme_root = get_theme_root( $stylesheet ); $stylesheet_dir = "$theme_root/$stylesheet"; /** * Filters the stylesheet directory path for the active theme. * * @since 1.5.0 * * @param string $stylesheet_dir Absolute path to the active theme. * @param string $stylesheet Directory name of the active theme. * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); } /** * Retrieves stylesheet directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's stylesheet directory. */ 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"; /** * Filters the stylesheet directory URI. * * @since 1.5.0 * * @param string $stylesheet_dir_uri Stylesheet directory URI. * @param string $stylesheet Name of the activated theme's directory. * @param string $theme_root_uri Themes root URI. */ return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); } /** * Retrieves stylesheet URI for the active theme. * * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path. * See get_stylesheet_directory_uri(). * * @since 1.5.0 * * @return string URI to active theme's stylesheet. */ function get_stylesheet_uri() { $stylesheet_dir_uri = get_stylesheet_directory_uri(); $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; /** * Filters the URI of the active theme stylesheet. * * @since 1.5.0 * * @param string $stylesheet_uri Stylesheet URI for the active theme/child theme. * @param string $stylesheet_dir_uri Stylesheet directory URI for the active theme/child theme. */ return apply_filters( 'stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves the localized stylesheet URI. * * The stylesheet directory for the localized stylesheet files are located, by * default, in the base theme directory. The name of the locale file will be the * locale followed by '.css'. If that does not exist, then the text direction * stylesheet will be checked for existence, for example 'ltr.css'. * * The theme may change the location of the stylesheet directory by either using * the {@see 'stylesheet_directory_uri'} or {@see 'locale_stylesheet_uri'} filters. * * If you want to change the location of the stylesheet files for the entire * WordPress workflow, then change the former. If you just have the locale in a * separate folder, then change the latter. * * @since 2.1.0 * * @global WP_Locale $wp_locale WordPress date and time locale object. * * @return string URI to active theme's localized stylesheet. */ 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 = ''; } /** * Filters the localized stylesheet URI. * * @since 2.1.0 * * @param string $stylesheet_uri Localized stylesheet URI. * @param string $stylesheet_dir_uri Stylesheet directory URI. */ return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves name of the active theme. * * @since 1.5.0 * * @return string Template name. */ function get_template() { /** * Filters the name of the active theme. * * @since 1.5.0 * * @param string $template active theme's directory name. */ return apply_filters( 'template', get_option( 'template' ) ); } /** * Retrieves template directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.1 Memoization removed. * * @return string Path to active theme's template directory. */ function get_template_directory() { $template = get_template(); $theme_root = get_theme_root( $template ); $template_dir = "$theme_root/$template"; /** * Filters the active theme directory path. * * @since 1.5.0 * * @param string $template_dir The path of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root Absolute path to the themes directory. */ return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); } /** * Retrieves template directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's template directory. */ 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"; /** * Filters the active theme directory URI. * * @since 1.5.0 * * @param string $template_dir_uri The URI of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root_uri The themes root URI. */ return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); } /** * Retrieves theme roots. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @return array|string An array of theme roots keyed by template/stylesheet * or a single theme root if all themes have the same root. */ 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 ); // Regenerate the transient. $theme_roots = get_site_transient( 'theme_roots' ); } return $theme_roots; } /** * Registers a directory that contains themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param string $directory Either the full filesystem path to a theme folder * or a folder within WP_CONTENT_DIR. * @return bool True if successfully registered a directory that contains themes, * false if the directory does not exist. */ function register_theme_directory( $directory ) { global $wp_theme_directories; if ( ! file_exists( $directory ) ) { // Try prepending as the theme directory could be relative to the content directory. $directory = WP_CONTENT_DIR . '/' . $directory; // If this directory does not exist, return and do not register. 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; } /** * Searches all registered theme directories for complete and valid themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param bool $force Optional. Whether to force a new directory scan. Default false. * @return array|false Valid themes found on success, false on failure. */ 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(); /* * Set up maybe-relative, maybe-absolute array of theme directories. * We always want to return absolute, but we need to cache relative * to use in get_theme_root(). */ 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; } } /** * Filters whether to get the cache of the registered theme directories. * * @since 3.4.0 * * @param bool $cache_expiration Whether to get the cache of the theme directories. Default false. * @param string $context The class or function name calling the filter. */ $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 ) { // A cached theme root is no longer around, so skip it. 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 ], // Convert relative to absolute. ); } return $found_themes; } if ( ! is_int( $cache_expiration ) ) { $cache_expiration = 30 * MINUTE_IN_SECONDS; } } else { $cache_expiration = 30 * MINUTE_IN_SECONDS; } /* Loop the registered theme directories and extract all themes */ foreach ( $wp_theme_directories as $theme_root ) { // Start with directories in the root of the active theme directory. $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' ) ) { /* * wp-content/themes/a-single-theme * wp-content/themes is $theme_root, a-single-theme is $dir. */ $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } else { $found_theme = false; /* * wp-content/themes/a-folder-of-themes/* * wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs. */ $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; } /* * Never mind the above, it's just a theme missing a style.css. * Return it; WP_Theme will catch the error. */ 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'] ]; // Convert absolute to relative. } if ( get_site_transient( 'theme_roots' ) !== $theme_roots ) { set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); } return $found_themes; } /** * Retrieves path to themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @return string Themes directory path. */ 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 ) { /* * Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. * This gives relative theme roots the benefit of the doubt when things go haywire. */ 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'; } /** * Filters the absolute path to the themes directory. * * @since 1.5.0 * * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'theme_root', $theme_root ); } /** * Retrieves URI for themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @param string $theme_root Optional. The theme root for which calculations will be based, * preventing the need for a get_raw_theme_root() call. Default empty. * @return string Themes directory URI. */ 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 ) ) { // Absolute path. Make an educated guess. YMMV -- but note the filter below. 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' ); } /** * Filters the URI for themes directory. * * @since 1.5.0 * * @param string $theme_root_uri The URI for themes directory. * @param string $siteurl WordPress web address which is set in General Options. * @param string $stylesheet_or_template The stylesheet or template name of the theme. */ return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); } /** * Gets the raw theme root relative to the content directory with no filters applied. * * @since 3.1.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template The stylesheet or template name of the theme. * @param bool $skip_cache Optional. Whether to skip the cache. * Defaults to false, meaning the cache is used. * @return string Theme root. */ 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 requesting the root for the active theme, consult options to avoid calling get_theme_roots(). 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; } /** * Displays localized stylesheet link element. * * @since 2.1.0 */ 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 ); } /** * Switches the theme. * * Accepts one argument: $stylesheet of the theme. It also accepts an additional function signature * of two arguments: $template then $stylesheet. This is for backward compatibility. * * @since 2.5.0 * * @global string[] $wp_theme_directories * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * @global array $wp_registered_sidebars * * @param string $stylesheet Stylesheet name. */ 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 ); // Migrate from the old mods_{name} option to theme_mods_{slug}. 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 { /* * Since retrieve_widgets() is called when initializing a theme in the Customizer, * we need to remove the theme mods to avoid overwriting changes made via * the Customizer when accessing wp-admin/widgets.php. */ if ( 'wp_ajax_customize_save' === current_action() ) { remove_theme_mod( 'sidebars_widgets' ); } } // Stores classic sidebars for later use by block themes. if ( $new_theme->is_block_theme() ) { set_theme_mod( 'wp_classic_sidebars', $wp_registered_sidebars ); } update_option( 'theme_switched', $old_theme->get_stylesheet() ); /* * Reset template globals when switching themes outside of a switched blog * context to ensure templates will be loaded from the new theme. */ if ( ! is_multisite() || ! ms_is_switched() ) { wp_set_template_globals(); } // Clear pattern caches. if ( ! is_multisite() ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); } // Set autoload=no for the old theme, autoload=yes for the switched theme. $theme_mods_options = array( 'theme_mods_' . $stylesheet => 'yes', 'theme_mods_' . $old_theme->get_stylesheet() => 'no', ); wp_set_option_autoload_values( $theme_mods_options ); /** * Fires after the theme is switched. * * See {@see 'after_switch_theme'}. * * @since 1.5.0 * @since 4.5.0 Introduced the `$old_theme` parameter. * * @param string $new_name Name of the new theme. * @param WP_Theme $new_theme WP_Theme instance of the new theme. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } /** * Checks that the active theme has the required files. * * Standalone themes need to have a `templates/index.html` or `index.php` template file. * Child themes need to have a `Template` header in the `style.css` stylesheet. * * Does not initially check the default theme, which is the fallback and should always exist. * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. * Will switch theme to the fallback theme if active theme does not validate. * * You can use the {@see 'validate_current_theme'} filter to return false to disable * this functionality. * * @since 1.5.0 * @since 6.0.0 Removed the requirement for block themes to have an `index.php` template. * * @see WP_DEFAULT_THEME * * @return bool */ function validate_current_theme() { /** * Filters whether to validate the active theme. * * @since 2.7.0 * * @param bool $validate Whether to validate the active theme. Default true. */ 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' ) // Deprecated path support since 5.9.0. && ! file_exists( get_template_directory() . '/index.php' ) ) { // Invalid. } elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) { // Invalid. } elseif ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { // Invalid. } else { // Valid. return true; } $default = wp_get_theme( WP_DEFAULT_THEME ); if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } /** * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, * switch to the latest core default theme that's installed. * * If it turns out that this latest core default theme is our current * theme, then there's nothing we can do about that, so we have to bail, * rather than going into an infinite loop. (This is why there are * checks against WP_DEFAULT_THEME above, also.) We also can't do anything * if it turns out there is no default theme installed. (That's `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; } /** * Validates the theme requirements for WordPress version and PHP version. * * Uses the information from `Requires at least` and `Requires PHP` headers * defined in the theme's `style.css` file. * * @since 5.5.0 * @since 5.8.0 Removed support for using `readme.txt` as a fallback. * * @param string $stylesheet Directory name for the theme. * @return true|WP_Error True if requirements are met, WP_Error on failure. */ 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( /* translators: %s: Theme name. */ _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( /* translators: %s: Theme name. */ _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( /* translators: %s: Theme name. */ _x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } return true; } /** * Retrieves all theme modifications. * * @since 3.1.0 * @since 5.9.0 The return value is always an array. * * @return array Theme modifications. */ 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" ); // Deprecated location. 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; } /** * Retrieves theme modification value for the active theme. * * If the modification name does not exist and `$default_value` is a string, then the * default will be passed through the {@link https://www.php.net/sprintf sprintf()} * PHP function with the template directory URI as the first value and the * stylesheet directory URI as the second value. * * @since 2.1.0 * * @param string $name Theme modification name. * @param mixed $default_value Optional. Theme modification default value. Default false. * @return mixed Theme modification value. */ function get_theme_mod( $name, $default_value = false ) { $mods = get_theme_mods(); if ( isset( $mods[ $name ] ) ) { /** * Filters the theme modification, or 'theme_mod', value. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 2.2.0 * * @param mixed $current_mod The value of the active theme modification. */ return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); } if ( is_string( $default_value ) ) { // Only run the replacement if an sprintf() string format pattern was found. if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default_value ) ) { // Remove a single trailing percent sign. $default_value = preg_replace( '#(?<!%)%$#', '', $default_value ); $default_value = sprintf( $default_value, get_template_directory_uri(), get_stylesheet_directory_uri() ); } } /** This filter is documented in wp-includes/theme.php */ return apply_filters( "theme_mod_{$name}", $default_value ); } /** * Updates theme modification value for the active theme. * * @since 2.1.0 * @since 5.6.0 A return value was added. * * @param string $name Theme modification name. * @param mixed $value Theme modification value. * @return bool True if the value was updated, false otherwise. */ function set_theme_mod( $name, $value ) { $mods = get_theme_mods(); $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; /** * Filters the theme modification, or 'theme_mod', value on save. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 3.9.0 * * @param mixed $value The new value of the theme modification. * @param mixed $old_value The current value of the theme modification. */ $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); $theme = get_option( 'stylesheet' ); return update_option( "theme_mods_$theme", $mods ); } /** * Removes theme modification name from active theme list. * * If removing the name also removes all elements, then the entire option * will be removed. * * @since 2.1.0 * * @param string $name Theme modification name. */ 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 ); } /** * Removes theme modifications option for the active theme. * * @since 2.1.0 */ function remove_theme_mods() { delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); // Old style. $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } delete_option( 'mods_' . $theme_name ); } /** * Retrieves the custom header text color in 3- or 6-digit hexadecimal form. * * @since 2.1.0 * * @return string Header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). */ function get_header_textcolor() { return get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } /** * Displays the custom header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). * * @since 2.1.0 */ function header_textcolor() { echo get_header_textcolor(); } /** * Whether to display the header text. * * @since 3.4.0 * * @return bool */ 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; } /** * Checks whether a header image is set or not. * * @since 4.2.0 * * @see get_header_image() * * @return bool Whether a header image is set or not. */ function has_header_image() { return (bool) get_header_image(); } /** * Retrieves header image for custom header. * * @since 2.1.0 * * @return string|false */ 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(); } /** * Filters the header image URL. * * @since 6.1.0 * * @param string $url Header image URL. */ $url = apply_filters( 'get_header_image', $url ); if ( ! is_string( $url ) ) { return false; } $url = trim( $url ); return sanitize_url( set_url_scheme( $url ) ); } /** * Creates image tag markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Additional attributes for the image tag. Can be used * to override the default attributes. Default empty. * @return string HTML image element markup or empty string on failure. */ 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 = ''; // Use alternative text assigned to the image, if available. Otherwise, leave it empty. 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, ) ); // Generate 'srcset' and 'sizes' if not already present. 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 the default value of `lazy` for the `loading` attribute is overridden * to omit the attribute for this image, ensure it is not included. */ if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } // If the `fetchpriority` attribute is overridden and set to false or an empty string. if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } // If the `decoding` attribute is overridden and set to false or an empty string. if ( isset( $attr['decoding'] ) && ! $attr['decoding'] ) { unset( $attr['decoding'] ); } /** * Filters the list of header image attributes. * * @since 5.9.0 * * @param array $attr Array of the attributes for the image tag. * @param object $header The custom header object returned by 'get_custom_header()'. */ $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 .= ' />'; /** * Filters the markup of header images. * * @since 4.4.0 * * @param string $html The HTML image tag markup being filtered. * @param object $header The custom header object returned by 'get_custom_header()'. * @param array $attr Array of the attributes for the image tag. */ return apply_filters( 'get_header_image_tag', $html, $header, $attr ); } /** * Displays the image markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Attributes for the image markup. Default empty. */ function the_header_image_tag( $attr = array() ) { echo get_header_image_tag( $attr ); } /** * Gets random header image data from registered images in theme. * * @since 3.4.0 * * @access private * * @global array $_wp_default_headers * * @return object */ 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; } /** * Gets random header image URL from registered images in theme. * * @since 3.2.0 * * @return string Path to header image. */ function get_random_header_image() { $random_image = _get_random_header_data(); if ( empty( $random_image->url ) ) { return ''; } return $random_image->url; } /** * Checks if random header image is in use. * * Always true if user expressly chooses the option in Appearance > Header. * Also true if theme has multiple header images registered, no specific header image * is chosen, and theme turns on random headers with add_theme_support(). * * @since 3.2.0 * * @param string $type The random pool to use. Possible values include 'any', * 'default', 'uploaded'. Default 'any'. * @return bool */ 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; } /** * Displays header image URL. * * @since 2.1.0 */ function header_image() { $image = get_header_image(); if ( $image ) { echo esc_url( $image ); } } /** * Gets the header images uploaded for the active theme. * * @since 3.2.0 * * @return array */ function get_uploaded_header_images() { $header_images = array(); // @todo Caching. $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; } /** * Gets the header image data. * * @since 3.4.0 * * @global array $_wp_default_headers * * @return object */ 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 ); } /** * Registers a selection of default headers to be displayed by the custom header admin UI. * * @since 3.0.0 * * @global array $_wp_default_headers * * @param array $headers Array of headers keyed by a string ID. The IDs point to arrays * containing 'url', 'thumbnail_url', and 'description' keys. */ function register_default_headers( $headers ) { global $_wp_default_headers; $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); } /** * Unregisters default headers. * * This function must be called after register_default_headers() has already added the * header you want to remove. * * @see register_default_headers() * @since 3.0.0 * * @global array $_wp_default_headers * * @param string|array $header The header string id (key of array) to remove, or an array thereof. * @return bool|void A single header returns true on success, false on failure. * There is currently no return value for multiple 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; } } /** * Checks whether a header video is set or not. * * @since 4.7.0 * * @see get_header_video_url() * * @return bool Whether a header video is set or not. */ function has_header_video() { return (bool) get_header_video_url(); } /** * Retrieves header video URL for custom header. * * Uses a local video if present, or falls back to an external video. * * @since 4.7.0 * * @return string|false Header video URL or false if there is no video. */ function get_header_video_url() { $id = absint( get_theme_mod( 'header_video' ) ); if ( $id ) { // Get the file URL from the attachment ID. $url = wp_get_attachment_url( $id ); } else { $url = get_theme_mod( 'external_header_video' ); } /** * Filters the header video URL. * * @since 4.7.3 * * @param string $url Header video URL, if available. */ $url = apply_filters( 'get_header_video_url', $url ); if ( ! $id && ! $url ) { return false; } return sanitize_url( set_url_scheme( $url ) ); } /** * Displays header video URL. * * @since 4.7.0 */ function the_header_video_url() { $video = get_header_video_url(); if ( $video ) { echo esc_url( $video ); } } /** * Retrieves header video settings. * * @since 4.7.0 * * @return array */ 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']; } /** * Filters header video settings. * * @since 4.7.0 * * @param array $settings An array of header video settings. */ return apply_filters( 'header_video_settings', $settings ); } /** * Checks whether a custom header is set or not. * * @since 4.7.0 * * @return bool True if a custom header is set. False if not. */ function has_custom_header() { if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) { return true; } return false; } /** * Checks whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @return bool True if the custom header video should be shown. False if not. */ 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 ); } /** * Filters whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @param bool $show_video Whether the custom header video should be shown. Returns the value * of the theme setting for the `custom-header`'s `video-active-callback`. * If no callback is set, the default value is that of `is_front_page()`. */ return apply_filters( 'is_header_video_active', $show_video ); } /** * Retrieves the markup for a custom header. * * The container div will always be returned in the Customizer preview. * * @since 4.7.0 * * @return string The markup for a custom header on success. */ 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() ); } /** * Prints the markup for a custom header. * * A container div will always be printed in the Customizer preview. * * @since 4.7.0 */ 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() ); } } /** * Retrieves background image for custom background. * * @since 3.0.0 * * @return string */ function get_background_image() { return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); } /** * Displays background image path. * * @since 3.0.0 */ function background_image() { echo get_background_image(); } /** * Retrieves value for custom background color. * * @since 3.0.0 * * @return string */ function get_background_color() { return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); } /** * Displays background color value. * * @since 3.0.0 */ function background_color() { echo get_background_color(); } /** * Default custom background callback. * * @since 3.0.0 */ function _custom_background_cb() { // $background is the saved custom image, or the default image. $background = set_url_scheme( get_background_image() ); /* * $color is the saved custom color. * A default has to be specified in style.css. It will not be printed here. */ $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 ) . '");'; // Background Position. $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;"; // Background Size. $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;"; // Background Repeat. $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;"; // Background Scroll. $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 } /** * Renders the Custom CSS style element. * * @since 4.7.0 */ 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 // Note that esc_html() cannot be used because `div > span` is not interpreted properly. echo strip_tags( $styles ); ?> </style> <?php endif; } /** * Fetches the `custom_css` post for a given theme. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return WP_Post|null The custom_css post or null if none exists. */ 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 ); } // `-1` indicates no post exists; no query necessary. if ( ! $post && -1 !== $post_id ) { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; /* * Cache the lookup. See wp_update_custom_css_post(). * @todo This should get cleared if a custom_css post is added/removed. */ 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; } /** * Fetches the saved Custom CSS content for rendering. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return string The Custom CSS Post content. */ 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; } /** * Filters the custom CSS output into the head element. * * @since 4.7.0 * * @param string $css CSS pulled in from the Custom CSS post type. * @param string $stylesheet The theme stylesheet name. */ $css = apply_filters( 'wp_get_custom_css', $css, $stylesheet ); return $css; } /** * Updates the `custom_css` post for a given theme. * * Inserts a `custom_css` post when one doesn't yet exist. * * @since 4.7.0 * * @param string $css CSS, stored in `post_content`. * @param array $args { * Args. * * @type string $preprocessed Optional. Pre-processed CSS, stored in `post_content_filtered`. * Normally empty string. * @type string $stylesheet Optional. Stylesheet (child theme) to update. * Defaults to active theme/stylesheet. * } * @return WP_Post|WP_Error Post on success, error on failure. */ 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'], ); /** * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args * for a `custom_css` post being updated. * * This filter can be used by plugin that offer CSS pre-processors, to store the original * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`. * When used in this way, the `post_content_filtered` should be supplied as the setting value * instead of `post_content` via a the `customize_value_custom_css` filter, for example: * * <code> * add_filter( 'customize_value_custom_css', function( $value, $setting ) { * $post = wp_get_custom_css_post( $setting->stylesheet ); * if ( $post && ! empty( $post->post_content_filtered ) ) { * $css = $post->post_content_filtered; * } * return $css; * }, 10, 2 ); * </code> * * @since 4.7.0 * @param array $data { * Custom CSS data. * * @type string $css CSS stored in `post_content`. * @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. * Normally empty string. * } * @param array $args { * The args passed into `wp_update_custom_css_post()` merged with defaults. * * @type string $css The original CSS passed in to be updated. * @type string $preprocessed The original preprocessed CSS passed in to be updated. * @type string $stylesheet The stylesheet (theme) being updated. * } */ $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'], ); // Update post if it already exists, otherwise create a new one. $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 ); } // Trigger creation of a revision. This should be removed once #30854 is resolved. $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 ); } /** * Adds callback for custom TinyMCE editor stylesheets. * * The parameter $stylesheet is the name of the stylesheet, relative to * the theme root. It also accepts an array of stylesheets. * It is optional and defaults to 'editor-style.css'. * * This function automatically adds another stylesheet with -rtl prefix, e.g. editor-style-rtl.css. * If that file doesn't exist, it is removed before adding the stylesheet(s) to TinyMCE. * If an array of stylesheets is passed to add_editor_style(), * RTL is only added for the first stylesheet. * * Since version 3.4 the TinyMCE body has .rtl CSS class. * It is a better option to use that class and add any RTL styles to the main stylesheet. * * @since 3.0.0 * * @global array $editor_styles * * @param array|string $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. * Defaults to 'editor-style.css' */ 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 ); } /** * Removes all visual editor stylesheets. * * @since 3.1.0 * * @global array $editor_styles * * @return bool True on success, false if there were no stylesheets to remove. */ 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; } /** * Retrieves any registered editor stylesheet URLs. * * @since 4.0.0 * * @global array $editor_styles Registered editor stylesheets * * @return string[] If registered, a list of editor stylesheet URLs. */ function get_editor_stylesheets() { $stylesheets = array(); // Load editor_style.css if the active theme supports it. 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(); // Support externally referenced styles (like, say, fonts). foreach ( $editor_styles as $key => $file ) { if ( preg_match( '~^(https?:)?//~', $file ) ) { $stylesheets[] = sanitize_url( $file ); unset( $editor_styles[ $key ] ); } } // Look in a parent theme first, that way child theme CSS overrides. 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"; } } } /** * Filters the array of URLs of stylesheets applied to the editor. * * @since 4.3.0 * * @param string[] $stylesheets Array of URLs of stylesheets to be applied to the editor. */ return apply_filters( 'editor_stylesheets', $stylesheets ); } /** * Expands a theme's starter content configuration using core-provided data. * * @since 4.7.0 * * @return array Array of starter content. */ 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( // Deprecated in favor of 'link_home'. '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 ) { // Use options and theme_mods as-is. case 'options': case 'theme_mods': $content[ $type ] = $config[ $type ]; break; // Widgets are grouped into sidebars. case 'widgets': foreach ( $config[ $type ] as $sidebar_id => $widgets ) { foreach ( $widgets as $id => $widget ) { if ( is_array( $widget ) ) { // Item extends core content. 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; // And nav menu items are grouped into nav menus. case 'nav_menus': foreach ( $config[ $type ] as $nav_menu_location => $nav_menu ) { // Ensure nav menus get a name. 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 ) ) { // Item extends core content. 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; // Attachments are posts but have special treatment. case 'attachments': foreach ( $config[ $type ] as $id => $item ) { if ( ! empty( $item['file'] ) ) { $content[ $type ][ $id ] = $item; } } break; /* * All that's left now are posts (besides attachments). * Not a default case for the sake of clarity and future work. */ case 'posts': foreach ( $config[ $type ] as $id => $item ) { if ( is_array( $item ) ) { // Item extends core content. if ( ! empty( $core_content[ $type ][ $id ] ) ) { $item = array_merge( $core_content[ $type ][ $id ], $item ); } // Enforce a subset of fields. $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; } } /** * Filters the expanded array of starter content. * * @since 4.7.0 * * @param array $content Array of starter content. * @param array $config Array of theme-specific starter content configuration. */ return apply_filters( 'get_theme_starter_content', $content, $config ); } /** * Registers theme support for a given feature. * * Must be called in the theme's functions.php file to work. * If attached to a hook, it must be {@see 'after_setup_theme'}. * The {@see 'init'} hook may be too late for some features. * * Example usage: * * add_theme_support( 'title-tag' ); * add_theme_support( 'custom-logo', array( * 'height' => 480, * 'width' => 720, * ) ); * * @since 2.9.0 * @since 3.4.0 The `custom-header-uploads` feature was deprecated. * @since 3.6.0 The `html5` feature was added. * @since 3.6.1 The `html5` feature requires an array of types to be passed. Defaults to * 'comment-list', 'comment-form', 'search-form' for backward compatibility. * @since 3.9.0 The `html5` feature now also accepts 'gallery' and 'caption'. * @since 4.1.0 The `title-tag` feature was added. * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added. * @since 4.7.0 The `starter-content` feature was added. * @since 5.0.0 The `responsive-embeds`, `align-wide`, `dark-editor-style`, `disable-custom-colors`, * `disable-custom-font-sizes`, `editor-color-palette`, `editor-font-sizes`, * `editor-styles`, and `wp-block-styles` features were added. * @since 5.3.0 The `html5` feature now also accepts 'script' and 'style'. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * @since 5.4.0 The `disable-custom-gradients` feature limits to default gradients or gradients added * through `editor-gradient-presets` theme support. * @since 5.5.0 The `core-block-patterns` feature was added and is enabled by default. * @since 5.5.0 The `custom-logo` feature now also accepts 'unlink-homepage-logo'. * @since 5.6.0 The `post-formats` feature warns if no array is passed as the second parameter. * @since 5.8.0 The `widgets-block-editor` feature enables the Widgets block editor. * @since 5.8.0 The `block-templates` feature indicates whether a theme uses block-based templates. * @since 6.0.0 The `html5` feature warns if no array is passed as the second parameter. * @since 6.1.0 The `block-template-parts` feature allows to edit any reusable template part from site editor. * @since 6.1.0 The `disable-layout-styles` feature disables the default layout styles. * @since 6.3.0 The `link-color` feature allows to enable the link color setting. * @since 6.3.0 The `border` feature allows themes without theme.json to add border styles to blocks. * @since 6.5.0 The `appearance-tools` feature enables a few design tools for blocks, * see `WP_Theme_JSON::APPEARANCE_TOOLS_OPT_INS` for a complete list. * @since 6.6.0 The `editor-spacing-sizes` feature was added. * * @global array $_wp_theme_features * * @param string $feature The feature being added. Likely core values include: * - 'admin-bar' * - 'align-wide' * - 'appearance-tools' * - 'automatic-feed-links' * - 'block-templates' * - 'block-template-parts' * - 'border' * - 'core-block-patterns' * - 'custom-background' * - 'custom-header' * - 'custom-line-height' * - 'custom-logo' * - 'customize-selective-refresh-widgets' * - 'custom-spacing' * - 'custom-units' * - 'dark-editor-style' * - 'disable-custom-colors' * - 'disable-custom-font-sizes' * - 'disable-custom-gradients' * - 'disable-layout-styles' * - 'editor-color-palette' * - 'editor-gradient-presets' * - 'editor-font-sizes' * - 'editor-spacing-sizes' * - 'editor-styles' * - 'featured-content' * - 'html5' * - 'link-color' * - 'menus' * - 'post-formats' * - 'post-thumbnails' * - 'responsive-embeds' * - 'starter-content' * - 'title-tag' * - 'widgets' * - 'widgets-block-editor' * - 'wp-block-styles' * @param mixed ...$args Optional extra arguments to pass along with certain features. * @return void|false Void on success, false on failure. */ function add_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! $args ) { $args = true; } switch ( $feature ) { case 'post-thumbnails': // All post types are already supported. if ( true === get_theme_support( 'post-thumbnails' ) ) { return; } /* * Merge post types with any that already declared their support * for post thumbnails. */ 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': // You can't just pass 'html5', you need to pass an array of types. 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; } // Build an array of types for back-compat. $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); } // Calling 'html5' again merges, rather than overwrites. 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 ); // Allow full flexibility if no size is specified. 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'] ); /* * Merge in data from previous add_theme_support() calls. * The first value registered wins. (A child theme is set up first.) */ if ( isset( $_wp_theme_features['custom-header'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] ); } /* * Load in the defaults at the end, as we need to insure first one wins. * This will cause all constants to be defined, as each arg will then be set to the default. */ if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } /* * If a constant was defined, use that value. Otherwise, define the constant to ensure * the constant is always accurate (and is not defined later, overriding our value). * As stated above, the first value wins. * Once we get to wp_loaded (just-in-time), define any constants we haven't already. * Constants should be avoided. Don't reference them. This is just for backward compatibility. */ 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 headers are supported, and we still don't have a defined width or height, * we have implicit flex sizes. */ 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'] ); // Merge in data from previous add_theme_support() calls. The first value registered wins. 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; // Ensure that 'title-tag' is accessible in the admin. case 'title-tag': // Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php. if ( did_action( 'wp_loaded' ) ) { _doing_it_wrong( "add_theme_support( 'title-tag' )", sprintf( /* translators: 1: title-tag, 2: wp_loaded */ __( '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; } /** * Registers the internal custom header and background routines. * * @since 3.4.0 * @access private * * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background */ function _custom_header_background_just_in_time() { global $custom_image_header, $custom_background; if ( current_theme_supports( 'custom-header' ) ) { // In case any constants were defined after an add_custom_image_header() call, re-run. 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' ) ) { // In case any constants were defined after an add_custom_background() call, re-run. 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'] ); } } } /** * Adds CSS to hide header text for custom logo, based on Customizer setting. * * @since 4.5.0 * @access private */ 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 } } /** * Gets the theme support arguments passed when registering that support. * * Example usage: * * get_theme_support( 'custom-logo' ); * get_theme_support( 'custom-header', 'width' ); * * @since 3.1.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature to check. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return mixed The array of extra arguments or the value for the registered feature. */ 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 ]; } } /** * Allows a theme to de-register its support of a certain feature * * Should be called in the theme's functions.php file. Generally would * be used for child themes to override support from the parent theme. * * @since 3.0.0 * * @see add_theme_support() * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool|void Whether feature was removed. */ function remove_theme_support( $feature ) { // Do not remove internal registrations that are not used directly by themes. if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ), true ) ) { return false; } return _remove_theme_support( $feature ); } /** * Do not use. Removes theme support internally without knowledge of those not used * by themes directly. * * @access private * @since 3.1.0 * @global array $_wp_theme_features * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool True if support was removed, false if the feature was not registered. */ 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; // Do not continue - custom-header-uploads no longer exists. } 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; } /** * Checks a theme's support for a given feature. * * Example usage: * * current_theme_supports( 'custom-logo' ); * current_theme_supports( 'html5', 'comment-form' ); * * @since 2.9.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return bool True if the active theme supports the feature, false otherwise. */ 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 no args passed then no extra checks need to be performed. if ( ! $args ) { /** This filter is documented in wp-includes/theme.php */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } switch ( $feature ) { case 'post-thumbnails': /* * post-thumbnails can be registered for only certain content/post types * by passing an array of types to add_theme_support(). * If no array was passed, then any type is accepted. */ if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types. return true; } $content_type = $args[0]; return in_array( $content_type, $_wp_theme_features[ $feature ][0], true ); case 'html5': case 'post-formats': /* * Specific post formats can be registered by passing an array of types * to add_theme_support(). * * Specific areas of HTML5 support *must* be passed via an array to add_theme_support(). */ $type = $args[0]; return in_array( $type, $_wp_theme_features[ $feature ][0], true ); case 'custom-logo': case 'custom-header': case 'custom-background': // Specific capabilities can be registered by passing an array to add_theme_support(). return ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) && $_wp_theme_features[ $feature ][0][ $args[0] ] ); } /** * Filters whether the active theme supports a specific feature. * * The dynamic portion of the hook name, `$feature`, refers to the specific * theme feature. See add_theme_support() for the list of possible values. * * @since 3.4.0 * * @param bool $supports Whether the active theme supports the given feature. Default true. * @param array $args Array of arguments for the feature. * @param string $feature The theme feature. */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } /** * Checks a theme's support for a given feature before loading the functions which implement it. * * @since 2.9.0 * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param string $file Path to the file. * @return bool True if the active theme supports the supplied feature, false otherwise. */ function require_if_theme_supports( $feature, $file ) { if ( current_theme_supports( $feature ) ) { require $file; return true; } return false; } /** * Registers a theme feature for use in add_theme_support(). * * This does not indicate that the active theme supports the feature, it only describes * the feature's supported options. * * @since 5.5.0 * * @see add_theme_support() * * @global array $_wp_registered_theme_features * * @param string $feature The name uniquely identifying the feature. See add_theme_support() * for the list of possible values. * @param array $args { * Data used to describe the theme. * * @type string $type The type of data associated with this feature. * Valid values are 'string', 'boolean', 'integer', * 'number', 'array', and 'object'. Defaults to 'boolean'. * @type bool $variadic Does this feature utilize the variadic support * of add_theme_support(), or are all arguments specified * as the second parameter. Must be used with the "array" type. * @type string $description A short description of the feature. Included in * the Themes REST API schema. Intended for developers. * @type bool|array $show_in_rest { * Whether this feature should be included in the Themes REST API endpoint. * Defaults to not being included. When registering an 'array' or 'object' type, * this argument must be an array with the 'schema' key. * * @type array $schema Specifies the JSON Schema definition describing * the feature. If any objects in the schema do not include * the 'additionalProperties' keyword, it is set to false. * @type string $name An alternate name to be used as the property name * in the REST API. * @type callable $prepare_callback A function used to format the theme support in the REST API. * Receives the raw theme support value. * } * } * @return true|WP_Error True if the theme feature was successfully registered, a WP_Error object if not. */ 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( /* translators: %s: prepare_callback */ __( '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 ) ) { // Automatically include the "boolean" type when the default value is a boolean. $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; } /** * Gets the list of registered theme features. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @return array[] List of theme features, keyed by their name. */ function get_registered_theme_features() { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return array(); } return $_wp_registered_theme_features; } /** * Gets the registration config for a theme feature. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @param string $feature The feature name. See add_theme_support() for the list * of possible values. * @return array|null The registration args, or null if the feature was not registered. */ 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; } /** * Checks an attachment being deleted to see if it's a header or background image. * * If true it removes the theme modification which would be pointing at the deleted * attachment. * * @access private * @since 3.0.0 * @since 4.3.0 Also removes `header_image_data`. * @since 4.5.0 Also removes custom logo theme mods. * @since 6.6.0 Also removes `site_logo` option set by the site logo block. * * @param int $id The attachment ID. */ 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' ); } } /** * Checks if a theme has been changed and runs 'after_switch_theme' hook on the next WP load. * * See {@see 'after_switch_theme'}. * * @since 3.3.0 */ function check_theme_switched() { $stylesheet = get_option( 'theme_switched' ); if ( $stylesheet ) { $old_theme = wp_get_theme( $stylesheet ); // Prevent widget & menu mapping from running since Customizer already called it up front. 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() ) { /** * Fires on the next WP load after the theme has been switched. * * The parameters differ according to whether the old theme exists or not. * If the old theme is missing, the old name will instead be the slug * of the old theme. * * See {@see 'switch_theme'}. * * @since 3.3.0 * * @param string $old_name Old theme name. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'after_switch_theme', $old_theme->get( 'Name' ), $old_theme ); } else { /** This action is documented in wp-includes/theme.php */ do_action( 'after_switch_theme', $stylesheet, $old_theme ); } flush_rewrite_rules(); update_option( 'theme_switched', false ); } } /** * Includes and instantiates the WP_Customize_Manager class. * * Loads the Customizer at plugins_loaded when accessing the customize.php admin * page or when any request includes a wp_customize=on param or a customize_changeset * param (a UUID). This param is a signal for whether to bootstrap the Customizer when * WordPress is loading, especially in the Customizer preview * or when making Customizer Ajax requests for widgets or menus. * * @since 3.4.0 * * @global WP_Customize_Manager $wp_customize */ 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; } /* * Note that wp_unslash() is not being used on the input vars because it is * called before wp_magic_quotes() gets called. Besides this fact, none of * the values should contain any characters needing slashes anyway. */ $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; /* * Value false indicates UUID should be determined after_setup_theme * to either re-use existing saved changeset or else generate a new UUID if none exists. */ $changeset_uuid = false; /* * Set initially to false since defaults to true for back-compat; * can be overridden via the customize_changeset_branching filter. */ $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'] ); } // Note that theme will be sanitized via WP_Theme. 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'] ); } /* * Note that settings must be previewed even outside the customizer preview * and also in the customizer pane itself. This is to enable loading an existing * changeset into the customizer. Previewing the settings only has to be prevented * here in the case of a customize_save action because this will cause WP to think * there is nothing changed that needs to be saved. */ $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' ) ); } /** * Publishes a snapshot's changes. * * @since 4.7.0 * @access private * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @param string $new_status New post status. * @param string $old_status Old post status. * @param WP_Post $changeset_post Changeset post object. */ 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' ) ) { /* * When running from CLI or Cron, the customize_register action will need * to be triggered in order for core, themes, and plugins to register their * settings. Normally core will add_action( 'customize_register' ) at * priority 10 to register the core settings, and if any themes/plugins * also add_action( 'customize_register' ) at the same priority, they * will have a $wp_customize with those settings registered since they * call add_action() afterward, normally. However, when manually doing * the customize_register action after the setup_theme, then the order * will be reversed for two actions added at priority 10, resulting in * the core settings no longer being available as expected to themes/plugins. * So the following manually calls the method that registers the core * settings up front before doing the action. */ remove_action( 'customize_register', array( $wp_customize, 'register_controls' ) ); $wp_customize->register_controls(); /** This filter is documented in wp-includes/class-wp-customize-manager.php */ do_action( 'customize_register', $wp_customize ); } $wp_customize->_publish_changeset_values( $changeset_post->ID ); /* * Trash the changeset post if revisions are not enabled. Unpublished * changesets by default get garbage collected due to the auto-draft status. * When a changeset post is published, however, it would no longer get cleaned * out. This is a problem when the changeset posts are never displayed anywhere, * since they would just be endlessly piling up. So here we use the revisions * feature to indicate whether or not a published changeset should get trashed * and thus garbage collected. */ if ( ! wp_revisions_enabled( $changeset_post ) ) { $wp_customize->trash_changeset_post( $changeset_post->ID ); } } /** * Filters changeset post data upon insert to ensure post_name is intact. * * This is needed to prevent the post_name from being dropped when the post is * transitioned into pending status by a contributor. * * @since 4.7.0 * * @see wp_insert_post() * * @param array $post_data An array of slashed post data. * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data. * @return array Filtered data. */ 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'] ) { // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending. if ( empty( $post_data['post_name'] ) && ! empty( $supplied_post_data['post_name'] ) ) { $post_data['post_name'] = $supplied_post_data['post_name']; } } return $post_data; } /** * Adds settings for the customize-loader script. * * @since 3.4.0 */ 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 ) . ';'; $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 ); } /** * Returns a URL to load the Customizer. * * @since 3.4.0 * * @param string $stylesheet Optional. Theme to customize. Defaults to active theme. * The theme's stylesheet will be urlencoded if necessary. * @return string */ function wp_customize_url( $stylesheet = '' ) { $url = admin_url( 'customize.php' ); if ( $stylesheet ) { $url .= '?theme=' . urlencode( $stylesheet ); } return esc_url( $url ); } /** * Prints a script to check whether or not the Customizer is supported, * and apply either the no-customize-support or customize-support class * to the body. * * This function MUST be called inside the body tag. * * Ideally, call this function immediately after the body tag is opened. * This prevents a flash of unstyled content. * * It is also recommended that you add the "no-customize-support" class * to the body tag by default. * * @since 3.4.0 * @since 4.7.0 Support for IE8 and below is explicitly removed via conditional comments. * @since 5.5.0 IE8 and older are no longer supported. */ 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() ) ); } /** * Whether the site is being previewed in the Customizer. * * @since 4.0.0 * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @return bool True if the site is being previewed in the Customizer, false otherwise. */ function is_customize_preview() { global $wp_customize; return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); } /** * Makes sure that auto-draft posts get their post_date bumped or status changed * to draft to prevent premature garbage-collection. * * When a changeset is updated but remains an auto-draft, ensure the post_date * for the auto-draft posts remains the same so that it will be * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, * if the changeset is updated to be a draft then update the posts * to have a far-future post_date so that they will never be garbage collected * unless the changeset post itself is deleted. * * When a changeset is updated to be a persistent draft or to be scheduled for * publishing, then transition any dependent auto-drafts to a draft status so * that they likewise will not be garbage-collected but also so that they can * be edited in the admin before publishing since there is not yet a post/page * editing flow in the Customizer. See #39752. * * @link https://core.trac.wordpress.org/ticket/39752 * * @since 4.8.0 * @access private * @see wp_delete_auto_drafts() * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $new_status Transition to this post status. * @param string $old_status Previous post status. * @param \WP_Post $post Post data. */ function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { global $wpdb; unset( $old_status ); // Short-circuit if not a changeset or if the changeset was published. 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; } /* * Actually, in lieu of keeping alive, trash any customization drafts here if the changeset itself is * getting trashed. This is needed because when a changeset transitions to a draft, then any of the * dependent auto-draft post/page stubs will also get transitioned to customization drafts which * are then visible in the WP Admin. We cannot wait for the deletion of the changeset in which * _wp_delete_customize_changeset_dependent_auto_drafts() will be called, since they need to be * trashed to remove from visibility immediately. */ 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 ) { /* * Keep the post date for the post matching the changeset * so that it will not be garbage-collected before the changeset. */ $post_args['post_date'] = $post->post_date; // Note wp_delete_auto_drafts() only looks at this date. } else { /* * Since the changeset no longer has an auto-draft (and it is not published) * it is now a persistent changeset, a long-lived draft, and so any * associated auto-draft posts should likewise transition into having a draft * status. These drafts will be treated differently than regular drafts in * that they will be tied to the given changeset. The publish meta box is * replaced with a notice about how the post is part of a set of customized changes * which will be published when the changeset is published. */ $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 ); } } /** * Creates the initial theme features when the 'setup_theme' action is fired. * * See {@see 'setup_theme'}. * * @since 5.5.0 * @since 6.0.1 The `block-templates` feature was added. */ 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, ) ); } /** * Returns whether the active theme is a block-based theme or not. * * @since 5.9.0 * * @return bool Whether the active theme is a block-based theme or not. */ 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(); } /** * Given an element name, returns a class name. * * Alias of WP_Theme_JSON::get_element_class_name. * * @since 6.1.0 * * @param string $element The name of the element. * * @return string The name of the class. */ function wp_theme_get_element_class_name( $element ) { return WP_Theme_JSON::get_element_class_name( $element ); } /** * Adds default theme supports for block themes when the 'after_setup_theme' action fires. * * See {@see 'after_setup_theme'}. * * @since 5.9.0 * @access private */ 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' ); /* * Makes block themes support HTML5 by default for the comment block and search form * (which use default template functions) and `[caption]` and `[gallery]` shortcodes. * Other blocks contain their own HTML5 markup. */ 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' ); /* * Remove the Customizer's Menus panel when block theme is active. */ 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 ); } home/contenidosenred/public_html/ondemand/wp-admin/includes/theme.php 0000644 00000135176 15105534401 0022116 0 ustar 00 <?php /** * WordPress Theme Administration API * * @package WordPress * @subpackage Administration */ /** * Removes a theme. * * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param string $stylesheet Stylesheet of the theme to delete. * @param string $redirect Redirect to page when complete. * @return bool|null|WP_Error True on success, false if `$stylesheet` is empty, WP_Error on failure. * Null if filesystem credentials are required to proceed. */ function delete_theme( $stylesheet, $redirect = '' ) { global $wp_filesystem; if ( empty( $stylesheet ) ) { return false; } if ( empty( $redirect ) ) { $redirect = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet ); } ob_start(); $credentials = request_filesystem_credentials( $redirect ); $data = ob_get_clean(); if ( false === $credentials ) { if ( ! empty( $data ) ) { require_once ABSPATH . 'wp-admin/admin-header.php'; echo $data; require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } return; } if ( ! WP_Filesystem( $credentials ) ) { ob_start(); // Failed to connect. Error and request again. request_filesystem_credentials( $redirect, '', true ); $data = ob_get_clean(); if ( ! empty( $data ) ) { require_once ABSPATH . 'wp-admin/admin-header.php'; echo $data; require_once ABSPATH . 'wp-admin/admin-footer.php'; exit; } return; } if ( ! is_object( $wp_filesystem ) ) { return new WP_Error( 'fs_unavailable', __( 'Could not access filesystem.' ) ); } if ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { return new WP_Error( 'fs_error', __( 'Filesystem error.' ), $wp_filesystem->errors ); } // Get the base theme folder. $themes_dir = $wp_filesystem->wp_themes_dir(); if ( empty( $themes_dir ) ) { return new WP_Error( 'fs_no_themes_dir', __( 'Unable to locate WordPress theme directory.' ) ); } /** * Fires immediately before a theme deletion attempt. * * @since 5.8.0 * * @param string $stylesheet Stylesheet of the theme to delete. */ do_action( 'delete_theme', $stylesheet ); $theme = wp_get_theme( $stylesheet ); $themes_dir = trailingslashit( $themes_dir ); $theme_dir = trailingslashit( $themes_dir . $stylesheet ); $deleted = $wp_filesystem->delete( $theme_dir, true ); /** * Fires immediately after a theme deletion attempt. * * @since 5.8.0 * * @param string $stylesheet Stylesheet of the theme to delete. * @param bool $deleted Whether the theme deletion was successful. */ do_action( 'deleted_theme', $stylesheet, $deleted ); if ( ! $deleted ) { return new WP_Error( 'could_not_remove_theme', /* translators: %s: Theme name. */ sprintf( __( 'Could not fully remove the theme %s.' ), $stylesheet ) ); } $theme_translations = wp_get_installed_translations( 'themes' ); // Remove language files, silently. if ( ! empty( $theme_translations[ $stylesheet ] ) ) { $translations = $theme_translations[ $stylesheet ]; foreach ( $translations as $translation => $data ) { $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.po' ); $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.mo' ); $wp_filesystem->delete( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '.l10n.php' ); $json_translation_files = glob( WP_LANG_DIR . '/themes/' . $stylesheet . '-' . $translation . '-*.json' ); if ( $json_translation_files ) { array_map( array( $wp_filesystem, 'delete' ), $json_translation_files ); } } } // Remove the theme from allowed themes on the network. if ( is_multisite() ) { WP_Theme::network_disable_theme( $stylesheet ); } // Clear theme caches. $theme->cache_delete(); // Force refresh of theme update information. delete_site_transient( 'update_themes' ); return true; } /** * Gets the page templates available in this theme. * * @since 1.5.0 * @since 4.7.0 Added the `$post_type` parameter. * * @param WP_Post|null $post Optional. The post being edited, provided for context. * @param string $post_type Optional. Post type to get the templates for. Default 'page'. * @return string[] Array of template file names keyed by the template header name. */ function get_page_templates( $post = null, $post_type = 'page' ) { return array_flip( wp_get_theme()->get_page_templates( $post, $post_type ) ); } /** * Tidies a filename for url display by the theme file editor. * * @since 2.9.0 * @access private * * @param string $fullpath Full path to the theme file * @param string $containingfolder Path of the theme parent folder * @return string */ function _get_template_edit_filename( $fullpath, $containingfolder ) { return str_replace( dirname( $containingfolder, 2 ), '', $fullpath ); } /** * Check if there is an update for a theme available. * * Will display link, if there is an update available. * * @since 2.7.0 * * @see get_theme_update_available() * * @param WP_Theme $theme Theme data object. */ function theme_update_available( $theme ) { echo get_theme_update_available( $theme ); } /** * Retrieves the update link if there is a theme update available. * * Will return a link if there is an update available. * * @since 3.8.0 * * @param WP_Theme $theme WP_Theme object. * @return string|false HTML for the update link, or false if invalid info was passed. */ function get_theme_update_available( $theme ) { static $themes_update = null; if ( ! current_user_can( 'update_themes' ) ) { return false; } if ( ! isset( $themes_update ) ) { $themes_update = get_site_transient( 'update_themes' ); } if ( ! ( $theme instanceof WP_Theme ) ) { return false; } $stylesheet = $theme->get_stylesheet(); $html = ''; if ( isset( $themes_update->response[ $stylesheet ] ) ) { $update = $themes_update->response[ $stylesheet ]; $theme_name = $theme->display( 'Name' ); $details_url = add_query_arg( array( 'TB_iframe' => 'true', 'width' => 1024, 'height' => 800, ), $update['url'] ); // Theme browser inside WP? Replace this. Also, theme preview JS will override this on the available list. $update_url = wp_nonce_url( admin_url( 'update.php?action=upgrade-theme&theme=' . urlencode( $stylesheet ) ), 'upgrade-theme_' . $stylesheet ); if ( ! is_multisite() ) { if ( ! current_user_can( 'update_themes' ) ) { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'] ); } elseif ( empty( $update['package'] ) ) { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'] ); } else { $html = sprintf( /* translators: 1: Theme name, 2: Theme details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ '<p><strong>' . __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ) . '</strong></p>', $theme_name, esc_url( $details_url ), sprintf( 'class="thickbox open-plugin-details-modal" aria-label="%s"', /* translators: 1: Theme name, 2: Version number. */ esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme_name, $update['new_version'] ) ) ), $update['new_version'], $update_url, sprintf( 'aria-label="%s" id="update-theme" data-slug="%s"', /* translators: %s: Theme name. */ esc_attr( sprintf( _x( 'Update %s now', 'theme' ), $theme_name ) ), $stylesheet ) ); } } } return $html; } /** * Retrieves list of WordPress theme features (aka theme tags). * * @since 3.1.0 * @since 3.2.0 Added 'Gray' color and 'Featured Image Header', 'Featured Images', * 'Full Width Template', and 'Post Formats' features. * @since 3.5.0 Added 'Flexible Header' feature. * @since 3.8.0 Renamed 'Width' filter to 'Layout'. * @since 3.8.0 Renamed 'Fixed Width' and 'Flexible Width' options * to 'Fixed Layout' and 'Fluid Layout'. * @since 3.8.0 Added 'Accessibility Ready' feature and 'Responsive Layout' option. * @since 3.9.0 Combined 'Layout' and 'Columns' filters. * @since 4.6.0 Removed 'Colors' filter. * @since 4.6.0 Added 'Grid Layout' option. * Removed 'Fixed Layout', 'Fluid Layout', and 'Responsive Layout' options. * @since 4.6.0 Added 'Custom Logo' and 'Footer Widgets' features. * Removed 'Blavatar' feature. * @since 4.6.0 Added 'Blog', 'E-Commerce', 'Education', 'Entertainment', 'Food & Drink', * 'Holiday', 'News', 'Photography', and 'Portfolio' subjects. * Removed 'Photoblogging' and 'Seasonal' subjects. * @since 4.9.0 Reordered the filters from 'Layout', 'Features', 'Subject' * to 'Subject', 'Features', 'Layout'. * @since 4.9.0 Removed 'BuddyPress', 'Custom Menu', 'Flexible Header', * 'Front Page Posting', 'Microformats', 'RTL Language Support', * 'Threaded Comments', and 'Translation Ready' features. * @since 5.5.0 Added 'Block Editor Patterns', 'Block Editor Styles', * and 'Full Site Editing' features. * @since 5.5.0 Added 'Wide Blocks' layout option. * @since 5.8.1 Added 'Template Editing' feature. * @since 6.1.1 Replaced 'Full Site Editing' feature name with 'Site Editor'. * @since 6.2.0 Added 'Style Variations' feature. * * @param bool $api Optional. Whether try to fetch tags from the WordPress.org API. Defaults to true. * @return array Array of features keyed by category with translations keyed by slug. */ function get_theme_feature_list( $api = true ) { // Hard-coded list is used if API is not accessible. $features = array( __( 'Subject' ) => array( 'blog' => __( 'Blog' ), 'e-commerce' => __( 'E-Commerce' ), 'education' => __( 'Education' ), 'entertainment' => __( 'Entertainment' ), 'food-and-drink' => __( 'Food & Drink' ), 'holiday' => __( 'Holiday' ), 'news' => __( 'News' ), 'photography' => __( 'Photography' ), 'portfolio' => __( 'Portfolio' ), ), __( 'Features' ) => array( 'accessibility-ready' => __( 'Accessibility Ready' ), 'block-patterns' => __( 'Block Editor Patterns' ), 'block-styles' => __( 'Block Editor Styles' ), 'custom-background' => __( 'Custom Background' ), 'custom-colors' => __( 'Custom Colors' ), 'custom-header' => __( 'Custom Header' ), 'custom-logo' => __( 'Custom Logo' ), 'editor-style' => __( 'Editor Style' ), 'featured-image-header' => __( 'Featured Image Header' ), 'featured-images' => __( 'Featured Images' ), 'footer-widgets' => __( 'Footer Widgets' ), 'full-site-editing' => __( 'Site Editor' ), 'full-width-template' => __( 'Full Width Template' ), 'post-formats' => __( 'Post Formats' ), 'sticky-post' => __( 'Sticky Post' ), 'style-variations' => __( 'Style Variations' ), 'template-editing' => __( 'Template Editing' ), 'theme-options' => __( 'Theme Options' ), ), __( 'Layout' ) => array( 'grid-layout' => __( 'Grid Layout' ), 'one-column' => __( 'One Column' ), 'two-columns' => __( 'Two Columns' ), 'three-columns' => __( 'Three Columns' ), 'four-columns' => __( 'Four Columns' ), 'left-sidebar' => __( 'Left Sidebar' ), 'right-sidebar' => __( 'Right Sidebar' ), 'wide-blocks' => __( 'Wide Blocks' ), ), ); if ( ! $api || ! current_user_can( 'install_themes' ) ) { return $features; } $feature_list = get_site_transient( 'wporg_theme_feature_list' ); if ( ! $feature_list ) { set_site_transient( 'wporg_theme_feature_list', array(), 3 * HOUR_IN_SECONDS ); } if ( ! $feature_list ) { $feature_list = themes_api( 'feature_list', array() ); if ( is_wp_error( $feature_list ) ) { return $features; } } if ( ! $feature_list ) { return $features; } set_site_transient( 'wporg_theme_feature_list', $feature_list, 3 * HOUR_IN_SECONDS ); $category_translations = array( 'Layout' => __( 'Layout' ), 'Features' => __( 'Features' ), 'Subject' => __( 'Subject' ), ); $wporg_features = array(); // Loop over the wp.org canonical list and apply translations. foreach ( (array) $feature_list as $feature_category => $feature_items ) { if ( isset( $category_translations[ $feature_category ] ) ) { $feature_category = $category_translations[ $feature_category ]; } $wporg_features[ $feature_category ] = array(); foreach ( $feature_items as $feature ) { if ( isset( $features[ $feature_category ][ $feature ] ) ) { $wporg_features[ $feature_category ][ $feature ] = $features[ $feature_category ][ $feature ]; } else { $wporg_features[ $feature_category ][ $feature ] = $feature; } } } return $wporg_features; } /** * Retrieves theme installer pages from the WordPress.org Themes API. * * It is possible for a theme to override the Themes API result with three * filters. Assume this is for themes, which can extend on the Theme Info to * offer more choices. This is very powerful and must be used with care, when * overriding the filters. * * The first filter, {@see 'themes_api_args'}, is for the args and gives the action * as the second parameter. The hook for {@see 'themes_api_args'} must ensure that * an object is returned. * * The second filter, {@see 'themes_api'}, allows a plugin to override the WordPress.org * Theme API entirely. If `$action` is 'query_themes', 'theme_information', or 'feature_list', * an object MUST be passed. If `$action` is 'hot_tags', an array should be passed. * * Finally, the third filter, {@see 'themes_api_result'}, makes it possible to filter the * response object or array, depending on the `$action` type. * * Supported arguments per action: * * | Argument Name | 'query_themes' | 'theme_information' | 'hot_tags' | 'feature_list' | * | -------------------| :------------: | :-----------------: | :--------: | :--------------: | * | `$slug` | No | Yes | No | No | * | `$per_page` | Yes | No | No | No | * | `$page` | Yes | No | No | No | * | `$number` | No | No | Yes | No | * | `$search` | Yes | No | No | No | * | `$tag` | Yes | No | No | No | * | `$author` | Yes | No | No | No | * | `$user` | Yes | No | No | No | * | `$browse` | Yes | No | No | No | * | `$locale` | Yes | Yes | No | No | * | `$fields` | Yes | Yes | No | No | * * @since 2.8.0 * * @param string $action API action to perform: Accepts 'query_themes', 'theme_information', * 'hot_tags' or 'feature_list'. * @param array|object $args { * Optional. Array or object of arguments to serialize for the Themes API. Default empty array. * * @type string $slug The theme slug. Default empty. * @type int $per_page Number of themes per page. Default 24. * @type int $page Number of current page. Default 1. * @type int $number Number of tags to be queried. * @type string $search A search term. Default empty. * @type string $tag Tag to filter themes. Default empty. * @type string $author Username of an author to filter themes. Default empty. * @type string $user Username to query for their favorites. Default empty. * @type string $browse Browse view: 'featured', 'popular', 'updated', 'favorites'. * @type string $locale Locale to provide context-sensitive results. Default is the value of get_locale(). * @type array $fields { * Array of fields which should or should not be returned. * * @type bool $description Whether to return the theme full description. Default false. * @type bool $sections Whether to return the theme readme sections: description, installation, * FAQ, screenshots, other notes, and changelog. Default false. * @type bool $rating Whether to return the rating in percent and total number of ratings. * Default false. * @type bool $ratings Whether to return the number of rating for each star (1-5). Default false. * @type bool $downloaded Whether to return the download count. Default false. * @type bool $downloadlink Whether to return the download link for the package. Default false. * @type bool $last_updated Whether to return the date of the last update. Default false. * @type bool $tags Whether to return the assigned tags. Default false. * @type bool $homepage Whether to return the theme homepage link. Default false. * @type bool $screenshots Whether to return the screenshots. Default false. * @type int $screenshot_count Number of screenshots to return. Default 1. * @type bool $screenshot_url Whether to return the URL of the first screenshot. Default false. * @type bool $photon_screenshots Whether to return the screenshots via Photon. Default false. * @type bool $template Whether to return the slug of the parent theme. Default false. * @type bool $parent Whether to return the slug, name and homepage of the parent theme. Default false. * @type bool $versions Whether to return the list of all available versions. Default false. * @type bool $theme_url Whether to return theme's URL. Default false. * @type bool $extended_author Whether to return nicename or nicename and display name. Default false. * } * } * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the * {@link https://developer.wordpress.org/reference/functions/themes_api/ function reference article} * for more information on the make-up of possible return objects depending on the value of `$action`. */ function themes_api( $action, $args = array() ) { if ( is_array( $args ) ) { $args = (object) $args; } if ( 'query_themes' === $action ) { if ( ! isset( $args->per_page ) ) { $args->per_page = 24; } } if ( ! isset( $args->locale ) ) { $args->locale = get_user_locale(); } if ( ! isset( $args->wp_version ) ) { $args->wp_version = substr( wp_get_wp_version(), 0, 3 ); // x.y } /** * Filters arguments used to query for installer pages from the WordPress.org Themes API. * * Important: An object MUST be returned to this filter. * * @since 2.8.0 * * @param object $args Arguments used to query for installer pages from the WordPress.org Themes API. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. */ $args = apply_filters( 'themes_api_args', $args, $action ); /** * Filters whether to override the WordPress.org Themes API. * * Returning a non-false value will effectively short-circuit the WordPress.org API request. * * If `$action` is 'query_themes', 'theme_information', or 'feature_list', an object MUST * be passed. If `$action` is 'hot_tags', an array should be passed. * * @since 2.8.0 * * @param false|object|array $override Whether to override the WordPress.org Themes API. Default false. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param object $args Arguments used to query for installer pages from the Themes API. */ $res = apply_filters( 'themes_api', false, $action, $args ); if ( ! $res ) { $url = 'http://api.wordpress.org/themes/info/1.2/'; $url = add_query_arg( array( 'action' => $action, 'request' => $args, ), $url ); $http_url = $url; $ssl = wp_http_supports( array( 'ssl' ) ); if ( $ssl ) { $url = set_url_scheme( $url, 'https' ); } $http_args = array( 'timeout' => 15, 'user-agent' => 'WordPress/' . wp_get_wp_version() . '; ' . home_url( '/' ), ); $request = wp_remote_get( $url, $http_args ); if ( $ssl && is_wp_error( $request ) ) { if ( ! wp_doing_ajax() ) { wp_trigger_error( __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); } $request = wp_remote_get( $http_url, $http_args ); } if ( is_wp_error( $request ) ) { $res = new WP_Error( 'themes_api_failed', sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ), $request->get_error_message() ); } else { $res = json_decode( wp_remote_retrieve_body( $request ), true ); if ( is_array( $res ) ) { // Object casting is required in order to match the info/1.0 format. $res = (object) $res; } elseif ( null === $res ) { $res = new WP_Error( 'themes_api_failed', sprintf( /* translators: %s: Support forums URL. */ __( '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/' ) ), wp_remote_retrieve_body( $request ) ); } if ( isset( $res->error ) ) { $res = new WP_Error( 'themes_api_failed', $res->error ); } } if ( ! is_wp_error( $res ) ) { // Back-compat for info/1.2 API, upgrade the theme objects in query_themes to objects. if ( 'query_themes' === $action ) { foreach ( $res->themes as $i => $theme ) { $res->themes[ $i ] = (object) $theme; } } // Back-compat for info/1.2 API, downgrade the feature_list result back to an array. if ( 'feature_list' === $action ) { $res = (array) $res; } } } /** * Filters the returned WordPress.org Themes API response. * * @since 2.8.0 * * @param array|stdClass|WP_Error $res WordPress.org Themes API response. * @param string $action Requested action. Likely values are 'theme_information', * 'feature_list', or 'query_themes'. * @param stdClass $args Arguments used to query for installer pages from the WordPress.org Themes API. */ return apply_filters( 'themes_api_result', $res, $action, $args ); } /** * Prepares themes for JavaScript. * * @since 3.8.0 * * @param WP_Theme[] $themes Optional. Array of theme objects to prepare. * Defaults to all allowed themes. * * @return array An associative array of theme data, sorted by name. */ function wp_prepare_themes_for_js( $themes = null ) { $current_theme = get_stylesheet(); /** * Filters theme data before it is prepared for JavaScript. * * Passing a non-empty array will result in wp_prepare_themes_for_js() returning * early with that value instead. * * @since 4.2.0 * * @param array $prepared_themes An associative array of theme data. Default empty array. * @param WP_Theme[]|null $themes An array of theme objects to prepare, if any. * @param string $current_theme The active theme slug. */ $prepared_themes = (array) apply_filters( 'pre_prepare_themes_for_js', array(), $themes, $current_theme ); if ( ! empty( $prepared_themes ) ) { return $prepared_themes; } // Make sure the active theme is listed first. $prepared_themes[ $current_theme ] = array(); if ( null === $themes ) { $themes = wp_get_themes( array( 'allowed' => true ) ); if ( ! isset( $themes[ $current_theme ] ) ) { $themes[ $current_theme ] = wp_get_theme(); } } $updates = array(); $no_updates = array(); if ( ! is_multisite() && current_user_can( 'update_themes' ) ) { $updates_transient = get_site_transient( 'update_themes' ); if ( isset( $updates_transient->response ) ) { $updates = $updates_transient->response; } if ( isset( $updates_transient->no_update ) ) { $no_updates = $updates_transient->no_update; } } WP_Theme::sort_by_name( $themes ); $parents = array(); $auto_updates = (array) get_site_option( 'auto_update_themes', array() ); foreach ( $themes as $theme ) { $slug = $theme->get_stylesheet(); $encoded_slug = urlencode( $slug ); $parent = false; if ( $theme->parent() ) { $parent = $theme->parent(); $parents[ $slug ] = $parent->get_stylesheet(); $parent = $parent->display( 'Name' ); } $customize_action = null; $can_edit_theme_options = current_user_can( 'edit_theme_options' ); $can_customize = current_user_can( 'customize' ); $is_block_theme = $theme->is_block_theme(); if ( $is_block_theme && $can_edit_theme_options ) { $customize_action = admin_url( 'site-editor.php' ); if ( $current_theme !== $slug ) { $customize_action = add_query_arg( 'wp_theme_preview', $slug, $customize_action ); } } elseif ( ! $is_block_theme && $can_customize && $can_edit_theme_options ) { $customize_action = wp_customize_url( $slug ); } if ( null !== $customize_action ) { $customize_action = add_query_arg( array( 'return' => urlencode( sanitize_url( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ), ), $customize_action ); $customize_action = esc_url( $customize_action ); } $update_requires_wp = isset( $updates[ $slug ]['requires'] ) ? $updates[ $slug ]['requires'] : null; $update_requires_php = isset( $updates[ $slug ]['requires_php'] ) ? $updates[ $slug ]['requires_php'] : null; $auto_update = in_array( $slug, $auto_updates, true ); $auto_update_action = $auto_update ? 'disable-auto-update' : 'enable-auto-update'; if ( isset( $updates[ $slug ] ) ) { $auto_update_supported = true; $auto_update_filter_payload = (object) $updates[ $slug ]; } elseif ( isset( $no_updates[ $slug ] ) ) { $auto_update_supported = true; $auto_update_filter_payload = (object) $no_updates[ $slug ]; } else { $auto_update_supported = false; /* * Create the expected payload for the auto_update_theme filter, this is the same data * as contained within $updates or $no_updates but used when the Theme is not known. */ $auto_update_filter_payload = (object) array( 'theme' => $slug, 'new_version' => $theme->get( 'Version' ), 'url' => '', 'package' => '', 'requires' => $theme->get( 'RequiresWP' ), 'requires_php' => $theme->get( 'RequiresPHP' ), ); } $auto_update_forced = wp_is_auto_update_forced_for_item( 'theme', null, $auto_update_filter_payload ); $prepared_themes[ $slug ] = array( 'id' => $slug, 'name' => $theme->display( 'Name' ), 'screenshot' => array( $theme->get_screenshot() ), // @todo Multiple screenshots. 'description' => $theme->display( 'Description' ), 'author' => $theme->display( 'Author', false, true ), 'authorAndUri' => $theme->display( 'Author' ), 'tags' => $theme->display( 'Tags' ), 'version' => $theme->get( 'Version' ), 'compatibleWP' => is_wp_version_compatible( $theme->get( 'RequiresWP' ) ), 'compatiblePHP' => is_php_version_compatible( $theme->get( 'RequiresPHP' ) ), 'updateResponse' => array( 'compatibleWP' => is_wp_version_compatible( $update_requires_wp ), 'compatiblePHP' => is_php_version_compatible( $update_requires_php ), ), 'parent' => $parent, 'active' => $slug === $current_theme, 'hasUpdate' => isset( $updates[ $slug ] ), 'hasPackage' => isset( $updates[ $slug ] ) && ! empty( $updates[ $slug ]['package'] ), 'update' => get_theme_update_available( $theme ), 'autoupdate' => array( 'enabled' => $auto_update || $auto_update_forced, 'supported' => $auto_update_supported, 'forced' => $auto_update_forced, ), 'actions' => array( 'activate' => current_user_can( 'switch_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=activate&stylesheet=' . $encoded_slug ), 'switch-theme_' . $slug ) : null, 'customize' => $customize_action, 'delete' => ( ! is_multisite() && current_user_can( 'delete_themes' ) ) ? wp_nonce_url( admin_url( 'themes.php?action=delete&stylesheet=' . $encoded_slug ), 'delete-theme_' . $slug ) : null, 'autoupdate' => wp_is_auto_update_enabled_for_type( 'theme' ) && ! is_multisite() && current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=' . $auto_update_action . '&stylesheet=' . $encoded_slug ), 'updates' ) : null, ), 'blockTheme' => $theme->is_block_theme(), ); } // Remove 'delete' action if theme has an active child. if ( ! empty( $parents ) && array_key_exists( $current_theme, $parents ) ) { unset( $prepared_themes[ $parents[ $current_theme ] ]['actions']['delete'] ); } /** * Filters the themes prepared for JavaScript, for themes.php. * * Could be useful for changing the order, which is by name by default. * * @since 3.8.0 * * @param array $prepared_themes Array of theme data. */ $prepared_themes = apply_filters( 'wp_prepare_themes_for_js', $prepared_themes ); $prepared_themes = array_values( $prepared_themes ); return array_filter( $prepared_themes ); } /** * Prints JS templates for the theme-browsing UI in the Customizer. * * @since 4.2.0 */ function customize_themes_print_templates() { ?> <script type="text/html" id="tmpl-customize-themes-details-view"> <div class="theme-backdrop"></div> <div class="theme-wrap wp-clearfix" role="document"> <div class="theme-header"> <button type="button" class="left dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Show previous theme' ); ?> </span></button> <button type="button" class="right dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Show next theme' ); ?> </span></button> <button type="button" class="close dashicons dashicons-no"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Close details dialog' ); ?> </span></button> </div> <div class="theme-about wp-clearfix"> <div class="theme-screenshots"> <# if ( data.screenshot && data.screenshot[0] ) { #> <div class="screenshot"><img src="{{ data.screenshot[0] }}?ver={{ data.version }}" alt="" /></div> <# } else { #> <div class="screenshot blank"></div> <# } #> </div> <div class="theme-info"> <# if ( data.active ) { #> <span class="current-label"><?php _e( 'Active Theme' ); ?></span> <# } #> <h2 class="theme-name">{{{ data.name }}}<span class="theme-version"> <?php /* translators: %s: Theme version. */ printf( __( 'Version: %s' ), '{{ data.version }}' ); ?> </span></h2> <h3 class="theme-author"> <?php /* translators: %s: Theme author link. */ printf( __( 'By %s' ), '{{{ data.authorAndUri }}}' ); ?> </h3> <# if ( data.stars && 0 != data.num_ratings ) { #> <div class="theme-rating"> {{{ data.stars }}} <a class="num-ratings" target="_blank" href="{{ data.reviews_url }}"> <?php printf( '%1$s <span class="screen-reader-text">%2$s</span>', /* translators: %s: Number of ratings. */ sprintf( __( '(%s ratings)' ), '{{ data.num_ratings }}' ), /* translators: Hidden accessibility text. */ __( '(opens in a new tab)' ) ); ?> </a> </div> <# } #> <# if ( data.hasUpdate ) { #> <# if ( data.updateResponse.compatibleWP && data.updateResponse.compatiblePHP ) { #> <div class="notice notice-warning notice-alt notice-large" data-slug="{{ data.id }}"> <h3 class="notice-title"><?php _e( 'Update Available' ); ?></h3> {{{ data.update }}} </div> <# } else { #> <div class="notice notice-error notice-alt notice-large" data-slug="{{ data.id }}"> <h3 class="notice-title"><?php _e( 'Update Incompatible' ); ?></h3> <p> <# if ( ! data.updateResponse.compatibleWP && ! data.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your versions of WordPress and PHP.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.updateResponse.compatibleWP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of WordPress.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of PHP.' ), '{{{ data.name }}}' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p> </div> <# } #> <# } #> <# if ( data.parent ) { #> <p class="parent-theme"> <?php printf( /* translators: %s: Theme name. */ __( 'This is a child theme of %s.' ), '<strong>{{{ data.parent }}}</strong>' ); ?> </p> <# } #> <# if ( ! data.compatibleWP || ! data.compatiblePHP ) { #> <div class="notice notice-error notice-alt notice-large"><p> <# if ( ! data.compatibleWP && ! data.compatiblePHP ) { #> <?php _e( 'This theme does not work with your versions of WordPress and PHP.' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.compatibleWP ) { #> <?php _e( 'This theme does not work with your version of WordPress.' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.compatiblePHP ) { #> <?php _e( 'This theme does not work with your version of PHP.' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p></div> <# } else if ( ! data.active && data.blockTheme ) { #> <div class="notice notice-error notice-alt notice-large"><p> <?php _e( 'This theme doesn\'t support Customizer.' ); ?> <# if ( data.actions.activate ) { #> <?php printf( /* translators: %s: URL to the themes page (also it activates the theme). */ ' ' . __( 'However, you can still <a href="%s">activate this theme</a>, and use the Site Editor to customize it.' ), '{{{ data.actions.activate }}}' ); ?> <# } #> </p></div> <# } #> <p class="theme-description">{{{ data.description }}}</p> <# if ( data.tags ) { #> <p class="theme-tags"><span><?php _e( 'Tags:' ); ?></span> {{{ data.tags }}}</p> <# } #> </div> </div> <div class="theme-actions"> <# if ( data.active ) { #> <button type="button" class="button button-primary customize-theme"><?php _e( 'Customize' ); ?></button> <# } else if ( 'installed' === data.type ) { #> <div class="theme-inactive-actions"> <# if ( data.blockTheme ) { #> <?php /* translators: %s: Theme name. */ $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' ); ?> <# if ( data.compatibleWP && data.compatiblePHP && data.actions.activate ) { #> <a href="{{{ data.actions.activate }}}" class="button button-primary activate" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a> <# } #> <# } else { #> <# if ( data.compatibleWP && data.compatiblePHP ) { #> <button type="button" class="button button-primary preview-theme" data-slug="{{ data.id }}"><?php _e( 'Live Preview' ); ?></button> <# } else { #> <button class="button button-primary disabled"><?php _e( 'Live Preview' ); ?></button> <# } #> <# } #> </div> <?php if ( current_user_can( 'delete_themes' ) ) { ?> <# if ( data.actions && data.actions['delete'] ) { #> <a href="{{{ data.actions['delete'] }}}" data-slug="{{ data.id }}" class="button button-secondary delete-theme"><?php _e( 'Delete' ); ?></a> <# } #> <?php } ?> <# } else { #> <# if ( data.compatibleWP && data.compatiblePHP ) { #> <button type="button" class="button theme-install" data-slug="{{ data.id }}"><?php _e( 'Install' ); ?></button> <button type="button" class="button button-primary theme-install preview" data-slug="{{ data.id }}"><?php _e( 'Install & Preview' ); ?></button> <# } else { #> <button type="button" class="button disabled"><?php _ex( 'Cannot Install', 'theme' ); ?></button> <button type="button" class="button button-primary disabled"><?php _e( 'Install & Preview' ); ?></button> <# } #> <# } #> </div> </div> </script> <?php } /** * Determines whether a theme is technically active but was paused while * loading. * * For more information on this and similar theme functions, check out * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ * Conditional Tags} article in the Theme Developer Handbook. * * @since 5.2.0 * * @global WP_Paused_Extensions_Storage $_paused_themes * * @param string $theme Path to the theme directory relative to the themes directory. * @return bool True, if in the list of paused themes. False, not in the list. */ function is_theme_paused( $theme ) { if ( ! isset( $GLOBALS['_paused_themes'] ) ) { return false; } if ( get_stylesheet() !== $theme && get_template() !== $theme ) { return false; } return array_key_exists( $theme, $GLOBALS['_paused_themes'] ); } /** * Gets the error that was recorded for a paused theme. * * @since 5.2.0 * * @global WP_Paused_Extensions_Storage $_paused_themes * * @param string $theme Path to the theme directory relative to the themes * directory. * @return array|false Array of error information as it was returned by * `error_get_last()`, or false if none was recorded. */ function wp_get_theme_error( $theme ) { if ( ! isset( $GLOBALS['_paused_themes'] ) ) { return false; } if ( ! array_key_exists( $theme, $GLOBALS['_paused_themes'] ) ) { return false; } return $GLOBALS['_paused_themes'][ $theme ]; } /** * Tries to resume a single theme. * * If a redirect was provided and a functions.php file was found, we first ensure that * functions.php file does not throw fatal errors anymore. * * The way it works is by setting the redirection to the error before trying to * include the file. If the theme fails, then the redirection will not be overwritten * with the success message and the theme will not be resumed. * * @since 5.2.0 * * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. * @global string $wp_template_path Path to current theme's template directory. * * @param string $theme Single theme to resume. * @param string $redirect Optional. URL to redirect to. Default empty string. * @return bool|WP_Error True on success, false if `$theme` was not paused, * `WP_Error` on failure. */ function resume_theme( $theme, $redirect = '' ) { global $wp_stylesheet_path, $wp_template_path; list( $extension ) = explode( '/', $theme ); /* * We'll override this later if the theme could be resumed without * creating a fatal error. */ if ( ! empty( $redirect ) ) { $functions_path = ''; if ( str_contains( $wp_stylesheet_path, $extension ) ) { $functions_path = $wp_stylesheet_path . '/functions.php'; } elseif ( str_contains( $wp_template_path, $extension ) ) { $functions_path = $wp_template_path . '/functions.php'; } if ( ! empty( $functions_path ) ) { wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'theme-resume-error_' . $theme ), $redirect ) ); // Load the theme's functions.php to test whether it throws a fatal error. ob_start(); if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) { define( 'WP_SANDBOX_SCRAPING', true ); } include $functions_path; ob_clean(); } } $result = wp_paused_themes()->delete( $extension ); if ( ! $result ) { return new WP_Error( 'could_not_resume_theme', __( 'Could not resume the theme.' ) ); } return true; } /** * Renders an admin notice in case some themes have been paused due to errors. * * @since 5.2.0 * * @global string $pagenow The filename of the current screen. * @global WP_Paused_Extensions_Storage $_paused_themes */ function paused_themes_notice() { if ( 'themes.php' === $GLOBALS['pagenow'] ) { return; } if ( ! current_user_can( 'resume_themes' ) ) { return; } if ( ! isset( $GLOBALS['_paused_themes'] ) || empty( $GLOBALS['_paused_themes'] ) ) { return; } $message = sprintf( '<p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p>', __( 'One or more themes failed to load properly.' ), __( 'You can find more details and make changes on the Themes screen.' ), esc_url( admin_url( 'themes.php' ) ), __( 'Go to the Themes screen' ) ); wp_admin_notice( $message, array( 'type' => 'error', 'paragraph_wrap' => false, ) ); }
Edit
Rename
Chmod
Delete
FILE
FOLDER
INFO
Name
Size
Permission
Action
.Drafts.tar
3072 bytes
0644
.Drafts.tar.gz
197 bytes
0644
.Junk.tar
3072 bytes
0644
.Junk.tar.gz
197 bytes
0644
.Sent.tar
3072 bytes
0644
.Sent.tar.gz
198 bytes
0644
.Trash.tar
3072 bytes
0644
.Trash.tar.gz
198 bytes
0644
.bash_logout.bash_logout.tar.gz
124 bytes
0644
.bash_logout.tar
2048 bytes
0644
.bash_profile.bash_profile.tar.gz
253 bytes
0644
.bash_profile.tar
2048 bytes
0644
.bashrc.bashrc.tar.gz
613 bytes
0644
.bashrc.tar
2560 bytes
0644
.config.tar
2836480 bytes
0644
.config.tar.gz
1264093 bytes
0644
.cphorde.tar
1598976 bytes
0644
.cphorde.tar.gz
24184 bytes
0644
.ftpquota.ftpquota.tar.gz
142 bytes
0644
.ftpquota.tar
2048 bytes
0644
.htaccess.bk.htaccess.bk.tar.gz
410 bytes
0644
.htaccess.bk.tar
2560 bytes
0644
.htaccess.htaccess.tar.gz
457 bytes
0644
.htaccess.tar
5632 bytes
0644
.imunify_patch_id.imunify_patch_id.tar.gz
0 bytes
0644
.imunify_patch_id.tar
2048 bytes
0644
.index.php.index.php.tar.gz
981 bytes
0644
.index.php.tar
4096 bytes
0644
.softaculous.tar
7168 bytes
0644
.softaculous.tar.gz
1161 bytes
0644
.subaccounts.tar
17920 bytes
0644
.subaccounts.tar.gz
494 bytes
0644
.user.ini.tar
2560 bytes
0644
.user.ini.user.ini.tar.gz
484 bytes
0644
.well-known.tar
264704 bytes
0644
.well-known.tar.gz
103829 bytes
0644
.wp-cli.tar
435712 bytes
0644
.wp-cli.tar.gz
73183 bytes
0644
.wp-cli.zip
216482 bytes
0644
.wp-toolkit-identifier.tar
2560 bytes
0644
.wp-toolkit-identifier.wp-toolkit-identifier.tar.gz
668 bytes
0644
01-1.jpg.jpg.tar.gz
143057 bytes
0644
01-1.jpg.tar
559616 bytes
0644
01-2.jpg.jpg.tar.gz
339979 bytes
0644
01-2.jpg.tar
1920512 bytes
0644
01.jpg.jpg.tar.gz
50011 bytes
0644
01.jpg.tar
2486784 bytes
0644
01.tar
11841024 bytes
0644
01.tar.gz
5384027 bytes
0644
011.png.png.tar.gz
5801 bytes
0644
011.png.tar
7680 bytes
0644
02-1.jpg.jpg.tar.gz
248512 bytes
0644
02-1.jpg.tar
919040 bytes
0644
02-2.jpg.jpg.tar.gz
312096 bytes
0644
02-2.jpg.tar
314368 bytes
0644
02.jpg.jpg.tar.gz
205334 bytes
0644
02.jpg.tar
2678272 bytes
0644
02.tar
55521280 bytes
0644
02.tar.gz
665535 bytes
0644
022.png.png.tar.gz
5622 bytes
0644
022.png.tar
7680 bytes
0644
03-1.jpg.jpg.tar.gz
234751 bytes
0644
03-1.jpg.tar
769536 bytes
0644
03-2.jpg.jpg.tar.gz
262509 bytes
0644
03-2.jpg.tar
264704 bytes
0644
03.jpg.jpg.tar.gz
309454 bytes
0644
03.jpg.tar
2178048 bytes
0644
03.tar
15422464 bytes
0644
03.tar.gz
13494410 bytes
0644
04-1.jpg.jpg.tar.gz
328960 bytes
0644
04-1.jpg.tar
584704 bytes
0644
04-2.jpg.jpg.tar.gz
243233 bytes
0644
04-2.jpg.tar
245760 bytes
0644
04.jpg.jpg.tar.gz
72122 bytes
0644
04.jpg.tar
3549696 bytes
0644
04.tar
3607040 bytes
0644
04.tar.gz
3572246 bytes
0644
05-1.jpg.jpg.tar.gz
175980 bytes
0644
05-1.jpg.tar
455168 bytes
0644
05.jpg.jpg.tar.gz
240081 bytes
0644
05.jpg.tar
2100224 bytes
0644
05.tar
2240000 bytes
0644
05.tar.gz
1882721 bytes
0644
06-1.jpg.jpg.tar.gz
289978 bytes
0644
06-1.jpg.tar
295424 bytes
0644
06.jpg.jpg.tar.gz
95455 bytes
0644
06.jpg.tar
2394112 bytes
0644
06.tar
268800 bytes
0644
06.tar.gz
239700 bytes
0644
07-1.jpg.jpg.tar.gz
158970 bytes
0644
07-1.jpg.tar
162304 bytes
0644
07.jpg.jpg.tar.gz
320120 bytes
0644
07.jpg.tar
1258496 bytes
0644
07.tar
339456 bytes
0644
07.tar.gz
274308 bytes
0644
08-1.jpg.jpg.tar.gz
332984 bytes
0644
08-1.jpg.tar
336384 bytes
0644
08.jpg.jpg.tar.gz
211063 bytes
0644
08.jpg.tar
1679360 bytes
0644
09-1.jpg.jpg.tar.gz
302894 bytes
0644
09-1.jpg.tar
305664 bytes
0644
09.jpg.jpg.tar.gz
166686 bytes
0644
09.jpg.tar
1751552 bytes
0644
1.jpg.jpg.tar.gz
238034 bytes
0644
1.jpg.tar
242688 bytes
0644
1.svg.svg.tar.gz
2021 bytes
0644
1.svg.tar
7168 bytes
0644
10.jpg.jpg.tar.gz
331676 bytes
0644
10.jpg.tar
1817600 bytes
0644
10.tar
20150784 bytes
0644
10.tar.gz
2855539 bytes
0644
102235.tar
46080 bytes
0644
102235.tar.gz
12095 bytes
0644
11.jpg.jpg.tar.gz
1393209 bytes
0644
11.jpg.tar
1399296 bytes
0644
11.tar
92834304 bytes
0644
11.tar.gz
22000273 bytes
0644
12.jpg.jpg.tar.gz
1081270 bytes
0644
12.jpg.tar
1083904 bytes
0644
12.tar
65474048 bytes
0644
12.tar.gz
6658638 bytes
0644
15.tar
15360 bytes
0644
15.tar.gz
3192 bytes
0644
1index.php.php.tar.gz
154 bytes
0644
1index.php.tar
2048 bytes
0644
2.jpg.jpg.tar.gz
500246 bytes
0644
2.jpg.tar
504320 bytes
0644
2.svg.svg.tar.gz
24139 bytes
0644
2.svg.tar
61952 bytes
0644
2019.tar
57982976 bytes
0644
2020.tar
146668544 bytes
0644
2020.tar.gz
20 bytes
0644
2022.tar
13008384 bytes
0644
2022.tar.gz
12871561 bytes
0644
2025.tar
136704 bytes
0644
2025.tar.gz
88619 bytes
0644
219846.tar
1445376 bytes
0644
219846.tar.gz
598011 bytes
0644
22.php.php.tar.gz
61473 bytes
0644
22.php.tar
64512 bytes
0644
22.tar
7168 bytes
0644
22.tar.gz
1324 bytes
0644
257850.tar
351744 bytes
0644
257850.tar.gz
114382 bytes
0644
258007.tar
221696 bytes
0644
258007.tar.gz
74409 bytes
0644
2e.tar
4096 bytes
0644
2e.tar.gz
909 bytes
0644
3.jpg.jpg.tar.gz
219831 bytes
0644
3.jpg.tar
227328 bytes
0644
3.svg.svg.tar.gz
2881 bytes
0644
3.svg.tar
14336 bytes
0644
329283.tar
239104 bytes
0644
329283.tar.gz
77254 bytes
0644
36.tar
4608 bytes
0644
36.tar.gz
1347 bytes
0644
361992.tar
4096 bytes
0644
361992.tar.gz
1181 bytes
0644
4.jpg.jpg.tar.gz
419105 bytes
0644
4.jpg.tar
425984 bytes
0644
4.svg.svg.tar.gz
5743 bytes
0644
4.svg.tar
14848 bytes
0644
404.php.php.tar.gz
874 bytes
0644
404.php.tar
4096 bytes
0644
404.png.png.tar.gz
89101 bytes
0644
404.png.tar
92672 bytes
0644
41.tar
5120 bytes
0644
41.tar.gz
1202 bytes
0644
4e.tar
5632 bytes
0644
4e.tar.gz
1473 bytes
0644
5.jpg.jpg.tar.gz
354690 bytes
0644
5.jpg.tar
361472 bytes
0644
5.svg.svg.tar.gz
5250 bytes
0644
5.svg.tar
15360 bytes
0644
587738.tar
121344 bytes
0644
587738.tar.gz
42988 bytes
0644
5c.tar
19968 bytes
0644
5c.tar.gz
4263 bytes
0644
61.tar
4608 bytes
0644
61.tar.gz
1082 bytes
0644
689940.tar
201728 bytes
0644
689940.tar.gz
60602 bytes
0644
7f.tar
5632 bytes
0644
7f.tar.gz
1247 bytes
0644
883142.tar
201728 bytes
0644
883142.tar.gz
60602 bytes
0644
8a.tar
3072 bytes
0644
8a.tar.gz
755 bytes
0644
96.tar
4608 bytes
0644
96.tar.gz
1082 bytes
0644
97.tar
3072 bytes
0644
97.tar.gz
747 bytes
0644
977503.tar
4096 bytes
0644
977503.tar.gz
1348 bytes
0644
99.tar
16384 bytes
0644
99.tar.gz
3277 bytes
0644
9d.tar
8192 bytes
0644
9d.tar.gz
1624 bytes
0644
Auth.php.php.tar.gz
524 bytes
0644
Auth.php.tar
2560 bytes
0644
Auth.tar
4096 bytes
0644
Auth.tar.gz
1058 bytes
0644
BDKR.txt.tar
2048 bytes
0644
BDKR.txt.txt.tar.gz
182 bytes
0644
CINE.jpg.jpg.tar.gz
132526 bytes
0644
CINE.jpg.tar
134656 bytes
0644
Cache.php.php.tar.gz
2112 bytes
0644
Cache.php.tar
6656 bytes
0644
Cache.tar
79360 bytes
0644
Cache.tar.gz
8065 bytes
0644
Content.tar
11264 bytes
0644
Content.tar.gz
2579 bytes
0644
Cookie.php.php.tar.gz
4205 bytes
0644
Cookie.php.tar
17408 bytes
0644
Cookie.tar
6144 bytes
0644
Cookie.tar.gz
1474 bytes
0644
Core.php.php.tar.gz
1234 bytes
0644
Core.php.tar
4096 bytes
0644
Core.tar
530944 bytes
0644
Core.tar.gz
100537 bytes
0644
Core.zip
505149 bytes
0644
Cpanel_SSL_DCV_DNS_Mutex.tar
1536 bytes
0644
Cpanel_SSL_DCV_DNS_Mutex.tar.gz
123 bytes
0644
Decode.tar
18944 bytes
0644
Decode.tar.gz
4451 bytes
0644
Diff.php.php.tar.gz
3229 bytes
0644
Diff.php.tar
28672 bytes
0644
Diff.tar
50176 bytes
0644
Diff.tar.gz
10510 bytes
0644
Dram.jpg.jpg.tar.gz
463581 bytes
0644
Dram.jpg.tar
467456 bytes
0644
Engine.tar
36352 bytes
0644
Engine.tar.gz
7735 bytes
0644
Exception.php.php.tar.gz
808 bytes
0644
Exception.php.tar
4096 bytes
0644
Exception.tar
48128 bytes
0644
Exception.tar.gz
3967 bytes
0644
File.php.php.tar.gz
3537 bytes
0644
File.php.tar
14848 bytes
0644
GIC.png.png.tar.gz
23141 bytes
0644
GIC.png.tar
24576 bytes
0644
Gc2.jpg.jpg.tar.gz
369611 bytes
0644
Gc2.jpg.tar
381952 bytes
0644
HTTP.tar
16896 bytes
0644
HTTP.tar.gz
3720 bytes
0644
Hooks.php.php.tar.gz
1120 bytes
0644
Hooks.php.tar
4608 bytes
0644
ID3.tar
1175040 bytes
0644
ID3.tar.gz
239174 bytes
0644
ID3.zip
1162791 bytes
0644
IRI.php.php.tar.gz
7807 bytes
0644
IRI.php.tar
37376 bytes
0644
IXR.tar
42496 bytes
0644
IXR.tar.gz
7825 bytes
0644
IXR.zip
35492 bytes
0644
Ipv6.php.php.tar.gz
2011 bytes
0644
Ipv6.php.tar
7680 bytes
0644
Iri.php.php.tar.gz
7880 bytes
0644
Iri.php.tar
31232 bytes
0644
Item.php.php.tar.gz
12936 bytes
0644
Item.php.tar
133120 bytes
0644
Jcrop.gif.gif.tar.gz
310 bytes
0644
Jcrop.gif.tar
2048 bytes
0644
LICENSE.tar
2560 bytes
0644
LICENSE.tar.gz
680 bytes
0644
MOUNTS_CACHE__proc_mounts.tar
3584 bytes
0644
MOUNTS_CACHE__proc_mounts.tar.gz
676 bytes
0644
Misc.php.php.tar.gz
14354 bytes
0644
Misc.php.tar
70656 bytes
0644
Net.tar
10752 bytes
0644
Net.tar.gz
2832 bytes
0644
P12.jpg.jpg.tar.gz
98721 bytes
0644
P12.jpg.tar
102400 bytes
0644
PHP52.tar
6144 bytes
0644
PHP52.tar.gz
1177 bytes
0644
PHPMailer.php.php.tar.gz
40810 bytes
0644
PHPMailer.php.tar
184832 bytes
0644
PHPMailer.tar
236544 bytes
0644
PHPMailer.tar.gz
53108 bytes
0644
PP.png.png.tar.gz
574367 bytes
0644
PP.png.tar
576512 bytes
0644
Parse.tar
28672 bytes
0644
Parse.tar.gz
6630 bytes
0644
Port.php.php.tar.gz
729 bytes
0644
Port.php.tar
3072 bytes
0644
Proxy.php.php.tar.gz
543 bytes
0644
Proxy.php.tar
2560 bytes
0644
Proxy.tar
6144 bytes
0644
Proxy.tar.gz
1462 bytes
0644
Renderer.php.php.tar.gz
1979 bytes
0644
Renderer.php.tar
8704 bytes
0644
Renderer.tar
7168 bytes
0644
Renderer.tar.gz
1735 bytes
0644
Requests.tar
262144 bytes
0644
Requests.tar.gz
50663 bytes
0644
Requests.zip
225824 bytes
0644
Response.tar
5120 bytes
0644
Response.tar.gz
1090 bytes
0644
SMTP.php.php.tar.gz
12868 bytes
0644
SMTP.php.tar
50688 bytes
0644
SYSTEMMIME.tar
29696 bytes
0644
SYSTEMMIME.tar.gz
8823 bytes
0644
SimplePie.tar
896512 bytes
0644
SimplePie.tar.gz
123288 bytes
0644
Ssl.php.php.tar.gz
1921 bytes
0644
Ssl.php.tar
7168 bytes
0644
Text.tar
68608 bytes
0644
Text.tar.gz
14464 bytes
0644
Text.zip
58462 bytes
0644
Transport.tar
38400 bytes
0644
Transport.tar.gz
8415 bytes
0644
Utility.tar
10240 bytes
0644
Utility.tar.gz
2114 bytes
0644
XML.tar
11264 bytes
0644
XML.tar.gz
2428 bytes
0644
_bin_gtar_--help.tar
16896 bytes
0644
_bin_gtar_--help.tar.gz
4922 bytes
0644
_bin_gtar_--version.tar
2048 bytes
0644
_bin_gtar_--version.tar.gz
356 bytes
0644
_etc_cpupdate.conf___default.conf___default.tar.gz
217 bytes
0644
_etc_cpupdate.conf___default.tar
2048 bytes
0644
_inc.tar
36352 bytes
0644
_inc.tar.gz
13558 bytes
0644
a0.tar
3584 bytes
0644
a0.tar.gz
940 bytes
0644
a11y.js.js.tar.gz
2667 bytes
0644
a11y.js.tar
10240 bytes
0644
a11y.min.js.min.js.tar.gz
1078 bytes
0644
a11y.min.js.tar
4096 bytes
0644
about-rtl.css.css.tar.gz
5332 bytes
0644
about-rtl.css.tar
58368 bytes
0644
about-rtl.min.css.min.css.tar.gz
4398 bytes
0644
about-rtl.min.css.tar
23552 bytes
0644
about-texture.png.png.tar.gz
101423 bytes
0644
about-texture.png.tar
104448 bytes
0644
about.css.css.tar.gz
5306 bytes
0644
about.css.tar
58368 bytes
0644
about.min.css.min.css.tar.gz
4392 bytes
0644
about.min.css.tar
23552 bytes
0644
about.php.php.tar.gz
5888 bytes
0644
about.php.tar
25088 bytes
0644
accordion.js.js.tar.gz
1165 bytes
0644
accordion.js.tar
4608 bytes
0644
accordion.min.js.min.js.tar.gz
474 bytes
0644
accordion.min.js.tar
4096 bytes
0644
acme-challenge.tar
223744 bytes
0644
acme-challenge.tar.gz
75084 bytes
0644
admin-ajax.php.php.tar.gz
1942 bytes
0644
admin-ajax.php.tar
7168 bytes
0644
admin-bar-rtl.css.css.tar.gz
4996 bytes
0644
admin-bar-rtl.css.tar
26624 bytes
0644
admin-bar.css.css.tar.gz
4963 bytes
0644
admin-bar.css.tar
26112 bytes
0644
admin-bar.js.js.tar.gz
2904 bytes
0644
admin-bar.js.tar
12288 bytes
0644
admin-bar.min.css.min.css.tar.gz
3924 bytes
0644
admin-bar.min.css.tar
22016 bytes
0644
admin-bar.php.php.tar.gz
8412 bytes
0644
admin-bar.php.tar
76800 bytes
0644
admin-es_AR.mo.mo.tar.gz
177171 bytes
0644
admin-es_AR.mo.tar
560128 bytes
0644
admin-es_AR.po.po.tar.gz
199087 bytes
0644
admin-es_AR.po.tar
801792 bytes
0644
admin-filters.php.php.tar.gz
2197 bytes
0644
admin-filters.php.tar
9728 bytes
0644
admin-footer.php.php.tar.gz
1185 bytes
0644
admin-footer.php.tar
8192 bytes
0644
admin-functions.php.php.tar.gz
389 bytes
0644
admin-functions.php.tar
3072 bytes
0644
admin-header.php.php.tar.gz
3122 bytes
0644
admin-header.php.tar
21504 bytes
0644
admin-menu-rtl.css.css.tar.gz
3847 bytes
0644
admin-menu-rtl.css.tar
20480 bytes
0644
admin-menu-rtl.min.css.min.css.tar.gz
3004 bytes
0644
admin-menu-rtl.min.css.tar
16896 bytes
0644
admin-menu.css.css.tar.gz
3821 bytes
0644
admin-menu.css.tar
39936 bytes
0644
admin-menu.min.css.min.css.tar.gz
2996 bytes
0644
admin-menu.min.css.tar
16896 bytes
0644
admin-post.php.php.tar.gz
845 bytes
0644
admin-post.php.tar
3584 bytes
0644
admin.php.php.tar.gz
939 bytes
0644
admin.php.tar
28160 bytes
0644
admin.tar
2473472 bytes
0644
admin.tar.gz
508901 bytes
0644
ajax-actions.php.php.tar.gz
31391 bytes
0644
ajax-actions.php.tar
153600 bytes
0644
align-center-2x.png.png.tar.gz
293 bytes
0644
align-center-2x.png.tar
2048 bytes
0644
align-center.png.png.tar.gz
718 bytes
0644
align-center.png.tar
2560 bytes
0644
align-left.png.png.tar.gz
725 bytes
0644
align-left.png.tar
2560 bytes
0644
align-none-2x.png.png.tar.gz
270 bytes
0644
align-none-2x.png.tar
2048 bytes
0644
align-none.png.png.tar.gz
575 bytes
0644
align-none.png.tar
2048 bytes
0644
align-right-2x.png.png.tar.gz
286 bytes
0644
align-right-2x.png.tar
2048 bytes
0644
align-right.png.png.tar.gz
673 bytes
0644
align-right.png.tar
2048 bytes
0644
annotations.js.js.tar.gz
6214 bytes
0644
annotations.js.tar
25088 bytes
0644
api-fetch.js.js.tar.gz
6518 bytes
0644
api-fetch.js.tar
25600 bytes
0644
api-request.js.js.tar.gz
1463 bytes
0644
api-request.js.tar
5120 bytes
0644
api-request.min.js.min.js.tar.gz
709 bytes
0644
api-request.min.js.tar
2560 bytes
0644
archives.php.php.tar.gz
1151 bytes
0644
archives.php.tar
4608 bytes
0644
archives.tar
11264 bytes
0644
archives.tar.gz
917 bytes
0644
archives.zip
3499 bytes
0644
arrows-2x.png.png.tar.gz
935 bytes
0644
arrows-2x.png.tar
4096 bytes
0644
arrows.png.png.tar.gz
352 bytes
0644
arrows.png.tar
3072 bytes
0644
assets.tar
8623104 bytes
0644
assets.tar.gz
4188 bytes
0644
assets.zip
8139742 bytes
0644
asu.php.php.tar.gz
2343 bytes
0644
asu.php.tar
8704 bytes
0644
async-upload.php.php.tar.gz
2129 bytes
0644
async-upload.php.tar
12288 bytes
0644
atomlib.php.php.tar.gz
3356 bytes
0644
atomlib.php.tar
26624 bytes
0644
audio.png.png.tar.gz
540 bytes
0644
audio.png.tar
2048 bytes
0644
audio.svg.svg.tar.gz
370 bytes
0644
audio.svg.tar
2048 bytes
0644
audio.tar
15360 bytes
0644
audio.tar.gz
1221 bytes
0644
audio.zip
5493 bytes
0644
auth-app.js.js.tar.gz
2040 bytes
0644
auth-app.js.tar
7680 bytes
0644
auth-app.min.js.min.js.tar.gz
1084 bytes
0644
auth-app.min.js.tar
7168 bytes
0644
author-template.php.php.tar.gz
5186 bytes
0644
author-template.php.tar
20992 bytes
0644
authorize-application.php.php.tar.gz
3244 bytes
0644
authorize-application.php.tar
12288 bytes
0644
autop.js.js.tar.gz
5045 bytes
0644
autop.js.tar
17920 bytes
0644
autop.min.js.min.js.tar.gz
2235 bytes
0644
autop.min.js.tar
7168 bytes
0644
autosave.js.js.tar.gz
5961 bytes
0644
autosave.js.tar
24064 bytes
0644
autosave.min.js.min.js.tar.gz
2412 bytes
0644
autosave.min.js.tar
7680 bytes
0644
avatar.php.php.tar.gz
1801 bytes
0644
avatar.php.tar
14336 bytes
0644
avatar.tar
11264 bytes
0644
avatar.tar.gz
952 bytes
0644
b6.tar
4608 bytes
0644
b6.tar.gz
1207 bytes
0644
backbone.js.js.tar.gz
22558 bytes
0644
backbone.js.tar
82432 bytes
0644
backbone.min.js.min.js.tar.gz
8149 bytes
0644
backbone.min.js.tar
26112 bytes
0644
blank.gif.gif.tar.gz
178 bytes
0644
blank.gif.tar
3072 bytes
0644
blob.js.js.tar.gz
1586 bytes
0644
blob.js.tar
6656 bytes
0644
blob.min.js.min.js.tar.gz
702 bytes
0644
blob.min.js.tar
3072 bytes
0644
block-bindings.php.php.tar.gz
1785 bytes
0644
block-bindings.php.tar
7168 bytes
0644
block-bindings.tar
6144 bytes
0644
block-bindings.tar.gz
1128 bytes
0644
block-bindings.zip
3924 bytes
0644
block-editor.php.php.tar.gz
6759 bytes
0644
block-editor.php.tar
60416 bytes
0644
block-editor.tar
630784 bytes
0644
block-editor.tar.gz
78485 bytes
0644
block-i18n.json.json.tar.gz
263 bytes
0644
block-i18n.json.tar
2048 bytes
0644
block-patterns.php.php.tar.gz
3221 bytes
0644
block-patterns.php.tar
14848 bytes
0644
block-patterns.tar
14848 bytes
0644
block-patterns.tar.gz
1734 bytes
0644
block-patterns.zip
10109 bytes
0644
block-supports.tar
148480 bytes
0644
block-supports.tar.gz
27983 bytes
0644
block-supports.zip
135150 bytes
0644
block-template.php.php.tar.gz
4998 bytes
0644
block-template.php.tar
16896 bytes
0644
block.json.json.tar.gz
655 bytes
0644
block.json.tar
23040 bytes
0644
block.php.php.tar.gz
1363 bytes
0644
block.php.tar
9216 bytes
0644
block.tar
2560 bytes
0644
block.tar.gz
412 bytes
0644
blocks-json.php.php.tar.gz
16247 bytes
0644
blocks-json.php.tar
195584 bytes
0644
blocks.js.js.tar.gz
138261 bytes
0644
blocks.js.tar
569344 bytes
0644
blocks.min.js.min.js.tar.gz
53781 bytes
0644
blocks.min.js.tar
175104 bytes
0644
blocks.php.php.tar.gz
22880 bytes
0644
blocks.php.tar
228352 bytes
0644
blocks.tar
2120192 bytes
0644
blocks.tar.gz
243644 bytes
0644
bookmark-template.php.php.tar.gz
3340 bytes
0644
bookmark-template.php.tar
14336 bytes
0644
bookmark.php.php.tar.gz
3214 bytes
0644
bookmark.php.tar
46080 bytes
0644
boss.jpg.jpg.tar.gz
215691 bytes
0644
boss.jpg.tar
234496 bytes
0644
browser-rtl.png.png.tar.gz
40248 bytes
0644
browser-rtl.png.tar
41984 bytes
0644
browser.png.png.tar.gz
40683 bytes
0644
browser.png.tar
83968 bytes
0644
bubble_bg-2x.gif.gif.tar.gz
593 bytes
0644
bubble_bg-2x.gif.tar
2048 bytes
0644
bubble_bg.gif.gif.tar.gz
495 bytes
0644
bubble_bg.gif.tar
2048 bytes
0644
button.js.js.tar.gz
3559 bytes
0644
button.js.tar
13312 bytes
0644
button.tar
21504 bytes
0644
button.tar.gz
2189 bytes
0644
buttons-rtl.css.css.tar.gz
2629 bytes
0644
buttons-rtl.css.tar
11776 bytes
0644
buttons-rtl.min.css.min.css.tar.gz
1589 bytes
0644
buttons-rtl.min.css.tar
7680 bytes
0644
buttons.css.css.tar.gz
2606 bytes
0644
buttons.css.tar
11776 bytes
0644
buttons.min.css.min.css.tar.gz
1585 bytes
0644
buttons.min.css.tar
7680 bytes
0644
buttons.tar
18944 bytes
0644
buttons.tar.gz
1579 bytes
0644
buttons.zip
12810 bytes
0644
c3.tar
5120 bytes
0644
c3.tar.gz
1230 bytes
0644
cache-compat.php.php.tar.gz
1472 bytes
0644
cache-compat.php.tar
14336 bytes
0644
cache.php.php.tar.gz
2671 bytes
0644
cache.php.tar
29696 bytes
0644
cache.tar
435712 bytes
0644
cache.tar.gz
73174 bytes
0644
cache.zip
216458 bytes
0644
cacheid.tar
2048 bytes
0644
cacheid.tar.gz
119 bytes
0644
caches.tar
173568 bytes
0644
caches.tar.gz
29626 bytes
0644
calendar.php.php.tar.gz
2062 bytes
0644
calendar.php.tar
7680 bytes
0644
calendar.tar
9216 bytes
0644
calendar.tar.gz
934 bytes
0644
calendar.zip
4510 bytes
0644
canonical.php.php.tar.gz
8708 bytes
0644
canonical.php.tar
71680 bytes
0644
capabilities.php.php.tar.gz
7276 bytes
0644
capabilities.php.tar
88064 bytes
0644
categories.php.php.tar.gz
1665 bytes
0644
categories.php.tar
5632 bytes
0644
categories.tar
11776 bytes
0644
categories.tar.gz
1171 bytes
0644
categories.zip
5286 bytes
0644
category-template.php.php.tar.gz
13318 bytes
0644
category-template.php.tar
58880 bytes
0644
category.php.php.tar.gz
3668 bytes
0644
category.php.tar
28672 bytes
0644
certificates.tar
228352 bytes
0644
certificates.tar.gz
128405 bytes
0644
certs.tar
24064 bytes
0644
certs.tar.gz
7411 bytes
0644
cgi-bin.tar
121856 bytes
0644
cgi-bin.tar.gz
43016 bytes
0644
class-IXR-date.php.php.tar.gz
647 bytes
0644
class-IXR-date.php.tar
3584 bytes
0644
class-IXR-error.php.php.tar.gz
486 bytes
0644
class-IXR-error.php.tar
2560 bytes
0644
class-IXR-value.php.php.tar.gz
1170 bytes
0644
class-IXR-value.php.tar
5632 bytes
0644
class-IXR.php.php.tar.gz
1287 bytes
0644
class-IXR.php.tar
8192 bytes
0644
class-automatic-upgrader-skin.php.php.tar.gz
1518 bytes
0644
class-automatic-upgrader-skin.php.tar
5632 bytes
0644
class-avif-info.php.php.tar.gz
6153 bytes
0644
class-avif-info.php.tar
31232 bytes
0644
class-bulk-plugin-upgrader-skin.php.php.tar.gz
1109 bytes
0644
class-bulk-plugin-upgrader-skin.php.tar
4608 bytes
0644
class-bulk-upgrader-skin.php.php.tar.gz
2076 bytes
0644
class-bulk-upgrader-skin.php.tar
8704 bytes
0644
class-core-upgrader.php.php.tar.gz
4698 bytes
0644
class-core-upgrader.php.tar
16896 bytes
0644
class-custom-background.php.php.tar.gz
5380 bytes
0644
class-custom-background.php.tar
23552 bytes
0644
class-custom-image-header.php.php.tar.gz
11217 bytes
0644
class-custom-image-header.php.tar
51200 bytes
0644
class-feed.php.php.tar.gz
379 bytes
0644
class-feed.php.tar
2560 bytes
0644
class-file-upload-upgrader.php.php.tar.gz
1641 bytes
0644
class-file-upload-upgrader.php.tar
6144 bytes
0644
class-ftp-pure.php.php.tar.gz
1747 bytes
0644
class-ftp-pure.php.tar
7168 bytes
0644
class-ftp-sockets.php.php.tar.gz
2099 bytes
0644
class-ftp-sockets.php.tar
10240 bytes
0644
class-ftp.php.php.tar.gz
6646 bytes
0644
class-ftp.php.tar
29184 bytes
0644
class-http.php.php.tar.gz
346 bytes
0644
class-http.php.tar
3072 bytes
0644
class-json.php.php.tar.gz
8750 bytes
0644
class-json.php.tar
90112 bytes
0644
class-language-pack-upgrader-skin.php.php.tar.gz
1213 bytes
0644
class-language-pack-upgrader-skin.php.tar
4608 bytes
0644
class-language-pack-upgrader.php.php.tar.gz
4295 bytes
0644
class-language-pack-upgrader.php.tar
17408 bytes
0644
class-oembed.php.php.tar.gz
362 bytes
0644
class-oembed.php.tar
3072 bytes
0644
class-pclzip.php.php.tar.gz
29297 bytes
0644
class-pclzip.php.tar
198656 bytes
0644
class-phpass.php.php.tar.gz
2585 bytes
0644
class-phpass.php.tar
16384 bytes
0644
class-phpmailer.php.php.tar.gz
401 bytes
0644
class-phpmailer.php.tar
2560 bytes
0644
class-plugin-upgrader.php.php.tar.gz
5172 bytes
0644
class-plugin-upgrader.php.tar
25088 bytes
0644
class-pop3.php.php.tar.gz
4947 bytes
0644
class-pop3.php.tar
23040 bytes
0644
class-requests.php.php.tar.gz
960 bytes
0644
class-requests.php.tar
4096 bytes
0644
class-simplepie.php.php.tar.gz
405 bytes
0644
class-simplepie.php.tar
2048 bytes
0644
class-smtp.php.php.tar.gz
346 bytes
0644
class-smtp.php.tar
3072 bytes
0644
class-snoopy.php.php.tar.gz
8139 bytes
0644
class-snoopy.php.tar
77824 bytes
0644
class-t.api.php.api.php.tar.gz
45628 bytes
0644
class-t.api.php.tar
182272 bytes
0644
class-theme-installer-skin.php.php.tar.gz
3706 bytes
0644
class-theme-installer-skin.php.tar
14336 bytes
0644
class-theme-upgrader.php.php.tar.gz
5960 bytes
0644
class-theme-upgrader.php.tar
28672 bytes
0644
class-walker-category-checklist.php.php.tar.gz
1603 bytes
0644
class-walker-category-checklist.php.tar
6656 bytes
0644
class-walker-nav-menu-checklist.php.php.tar.gz
1577 bytes
0644
class-walker-nav-menu-checklist.php.tar
7168 bytes
0644
class-walker-nav-menu-edit.php.php.tar.gz
3421 bytes
0644
class-walker-nav-menu-edit.php.tar
15872 bytes
0644
class-walker-page.php.php.tar.gz
2164 bytes
0644
class-walker-page.php.tar
9216 bytes
0644
class-wp-admin-bar.php.php.tar.gz
4988 bytes
0644
class-wp-admin-bar.php.tar
19456 bytes
0644
class-wp-ajax-upgrader-skin.php.php.tar.gz
1388 bytes
0644
class-wp-ajax-upgrader-skin.php.tar
6144 bytes
0644
class-wp-automatic-updater.php.php.tar.gz
14488 bytes
0644
class-wp-automatic-updater.php.tar
63488 bytes
0644
class-wp-block-list.php.php.tar.gz
1286 bytes
0644
class-wp-block-list.php.tar
6656 bytes
0644
class-wp-block-type.php.php.tar.gz
4062 bytes
0644
class-wp-block-type.php.tar
18944 bytes
0644
class-wp-block.php.php.tar.gz
6054 bytes
0644
class-wp-block.php.tar
25088 bytes
0644
class-wp-comment.php.php.tar.gz
2690 bytes
0644
class-wp-comment.php.tar
11264 bytes
0644
class-wp-comments-list-table.php.php.tar.gz
8172 bytes
0644
class-wp-comments-list-table.php.tar
34816 bytes
0644
class-wp-community-events.php.php.tar.gz
6122 bytes
0644
class-wp-community-events.php.tar
20480 bytes
0644
class-wp-date-query.php.php.tar.gz
8640 bytes
0644
class-wp-date-query.php.tar
37376 bytes
0644
class-wp-debug-data.php.php.tar.gz
13709 bytes
0644
class-wp-debug-data.php.tar
68608 bytes
0644
class-wp-dependency.php.php.tar.gz
1035 bytes
0644
class-wp-dependency.php.tar
4608 bytes
0644
class-wp-duotone.php.php.tar.gz
9468 bytes
0644
class-wp-duotone.php.tar
42496 bytes
0644
class-wp-editor.php.php.tar.gz
17074 bytes
0644
class-wp-editor.php.tar
74240 bytes
0644
class-wp-embed.php.php.tar.gz
4860 bytes
0644
class-wp-embed.php.tar
17920 bytes
0644
class-wp-error.php.php.tar.gz
1979 bytes
0644
class-wp-error.php.tar
9216 bytes
0644
class-wp-exception.php.php.tar.gz
278 bytes
0644
class-wp-exception.php.tar
2048 bytes
0644
class-wp-feed-cache.php.php.tar.gz
629 bytes
0644
class-wp-feed-cache.php.tar
2560 bytes
0644
class-wp-filesystem-base.php.php.tar.gz
5550 bytes
0644
class-wp-filesystem-base.php.tar
26112 bytes
0644
class-wp-filesystem-direct.php.php.tar.gz
3997 bytes
0644
class-wp-filesystem-direct.php.tar
19968 bytes
0644
class-wp-filesystem-ftpext.php.php.tar.gz
5426 bytes
0644
class-wp-filesystem-ftpext.php.tar
25088 bytes
0644
class-wp-filesystem-ftpsockets.php.php.tar.gz
4279 bytes
0644
class-wp-filesystem-ftpsockets.php.tar
20480 bytes
0644
class-wp-filesystem-ssh2.php.php.tar.gz
5432 bytes
0644
class-wp-filesystem-ssh2.php.tar
25088 bytes
0644
class-wp-hook.php.php.tar.gz
3963 bytes
0644
class-wp-hook.php.tar
34816 bytes
0644
class-wp-http-curl.php.php.tar.gz
3773 bytes
0644
class-wp-http-curl.php.tar
14336 bytes
0644
class-wp-http-proxy.php.php.tar.gz
2066 bytes
0644
class-wp-http-proxy.php.tar
7680 bytes
0644
class-wp-http.php.php.tar.gz
11359 bytes
0644
class-wp-http.php.tar
86016 bytes
0644
class-wp-importer.php.php.tar.gz
2519 bytes
0644
class-wp-importer.php.tar
9216 bytes
0644
class-wp-internal-pointers.php.php.tar.gz
1695 bytes
0644
class-wp-internal-pointers.php.tar
6144 bytes
0644
class-wp-links-list-table.php.php.tar.gz
2800 bytes
0644
class-wp-links-list-table.php.tar
11264 bytes
0644
class-wp-list-table-compat.php.php.tar.gz
759 bytes
0644
class-wp-list-table-compat.php.tar
3072 bytes
0644
class-wp-list-table.php.php.tar.gz
12356 bytes
0644
class-wp-list-table.php.tar
54784 bytes
0644
class-wp-list-util.php.php.tar.gz
2324 bytes
0644
class-wp-list-util.php.tar
9216 bytes
0644
class-wp-locale.php.php.tar.gz
3546 bytes
0644
class-wp-locale.php.tar
18432 bytes
0644
class-wp-media-list-table.php.php.tar.gz
6718 bytes
0644
class-wp-media-list-table.php.tar
27648 bytes
0644
class-wp-meta-query.php.php.tar.gz
7368 bytes
0644
class-wp-meta-query.php.tar
32256 bytes
0644
class-wp-ms-sites-list-table.php.php.tar.gz
5695 bytes
0644
class-wp-ms-sites-list-table.php.tar
24064 bytes
0644
class-wp-ms-users-list-table.php.php.tar.gz
4331 bytes
0644
class-wp-ms-users-list-table.php.tar
17408 bytes
0644
class-wp-network.php.php.tar.gz
3878 bytes
0644
class-wp-network.php.tar
14336 bytes
0644
class-wp-oembed.php.php.tar.gz
7529 bytes
0644
class-wp-oembed.php.tar
33280 bytes
0644
class-wp-phpmailer.php.php.tar.gz
1262 bytes
0644
class-wp-phpmailer.php.tar
5632 bytes
0644
class-wp-plugin-install-list-table.php.php.tar.gz
6766 bytes
0644
class-wp-plugin-install-list-table.php.tar
26624 bytes
0644
class-wp-plugins-list-table.php.php.tar.gz
11444 bytes
0644
class-wp-plugins-list-table.php.tar
59392 bytes
0644
class-wp-post-comments-list-table.php.php.tar.gz
782 bytes
0644
class-wp-post-comments-list-table.php.tar
3072 bytes
0644
class-wp-post-type.php.php.tar.gz
6818 bytes
0644
class-wp-post-type.php.tar
32256 bytes
0644
class-wp-post.php.php.tar.gz
1820 bytes
0644
class-wp-post.php.tar
8192 bytes
0644
class-wp-posts-list-table.php.php.tar.gz
14553 bytes
0644
class-wp-posts-list-table.php.tar
66048 bytes
0644
class-wp-privacy-data-export-requests-list-table.php.php.tar.gz
1664 bytes
0644
class-wp-privacy-data-export-requests-list-table.php.tar
7168 bytes
0644
class-wp-privacy-data-removal-requests-list-table.php.php.tar.gz
1739 bytes
0644
class-wp-privacy-data-removal-requests-list-table.php.tar
7680 bytes
0644
class-wp-privacy-requests-table.php.php.tar.gz
4085 bytes
0644
class-wp-privacy-requests-table.php.tar
16384 bytes
0644
class-wp-query.php.php.tar.gz
31967 bytes
0644
class-wp-query.php.tar
159744 bytes
0644
class-wp-rewrite.php.php.tar.gz
14955 bytes
0644
class-wp-rewrite.php.tar
65536 bytes
0644
class-wp-role.php.php.tar.gz
874 bytes
0644
class-wp-role.php.tar
4096 bytes
0644
class-wp-roles.php.php.tar.gz
2442 bytes
0644
class-wp-roles.php.tar
10240 bytes
0644
class-wp-screen.php.php.tar.gz
9115 bytes
0644
class-wp-screen.php.tar
38912 bytes
0644
class-wp-scripts.php.php.tar.gz
6680 bytes
0644
class-wp-scripts.php.tar
30208 bytes
0644
class-wp-site-health.php.php.tar.gz
26304 bytes
0644
class-wp-site-health.php.tar
123904 bytes
0644
class-wp-site-icon.php.php.tar.gz
2238 bytes
0644
class-wp-site-icon.php.tar
8192 bytes
0644
class-wp-site-query.php.php.tar.gz
6797 bytes
0644
class-wp-site-query.php.tar
33280 bytes
0644
class-wp-site.php.php.tar.gz
2208 bytes
0644
class-wp-site.php.tar
9216 bytes
0644
class-wp-styles.php.php.tar.gz
3146 bytes
0644
class-wp-styles.php.tar
12800 bytes
0644
class-wp-tax-query.php.php.tar.gz
5310 bytes
0644
class-wp-tax-query.php.tar
21504 bytes
0644
class-wp-taxonomy.php.php.tar.gz
4579 bytes
0644
class-wp-taxonomy.php.tar
20480 bytes
0644
class-wp-term-query.php.php.tar.gz
9154 bytes
0644
class-wp-term-query.php.tar
42496 bytes
0644
class-wp-term.php.php.tar.gz
1921 bytes
0644
class-wp-term.php.tar
7168 bytes
0644
class-wp-terms-list-table.php.php.tar.gz
5726 bytes
0644
class-wp-terms-list-table.php.tar
23040 bytes
0644
class-wp-theme-install-list-table.php.php.tar.gz
4358 bytes
0644
class-wp-theme-install-list-table.php.tar
17408 bytes
0644
class-wp-theme-json.php.php.tar.gz
36574 bytes
0644
class-wp-theme-json.php.tar
165376 bytes
0644
class-wp-theme.php.php.tar.gz
14490 bytes
0644
class-wp-theme.php.tar
67584 bytes
0644
class-wp-themes-list-table.php.php.tar.gz
3456 bytes
0644
class-wp-themes-list-table.php.tar
12288 bytes
0644
class-wp-token-map.php.php.tar.gz
8070 bytes
0644
class-wp-token-map.php.tar
30208 bytes
0644
class-wp-upgrader-skin.php.php.tar.gz
2292 bytes
0644
class-wp-upgrader-skin.php.tar
8704 bytes
0644
class-wp-upgrader-skins.php.php.tar.gz
464 bytes
0644
class-wp-upgrader-skins.php.tar
3072 bytes
0644
class-wp-user-query.php.php.tar.gz
9483 bytes
0644
class-wp-user-query.php.tar
45568 bytes
0644
class-wp-user.php.php.tar.gz
5861 bytes
0644
class-wp-user.php.tar
48128 bytes
0644
class-wp-users-list-table.php.php.tar.gz
5526 bytes
0644
class-wp-users-list-table.php.tar
20992 bytes
0644
class-wp-walker.php.php.tar.gz
3227 bytes
0644
class-wp-walker.php.tar
15360 bytes
0644
class-wp-widget.php.php.tar.gz
4521 bytes
0644
class-wp-widget.php.tar
19968 bytes
0644
class-wp.php.php.tar.gz
7419 bytes
0644
class-wp.php.tar
28160 bytes
0644
class-wpdb.php.php.tar.gz
28871 bytes
0644
class-wpdb.php.tar
239616 bytes
0644
class.wp-scripts.php.tar
2048 bytes
0644
class.wp-scripts.php.wp-scripts.php.tar.gz
324 bytes
0644
class.wp-styles.php.tar
2048 bytes
0644
class.wp-styles.php.wp-styles.php.tar.gz
324 bytes
0644
classic-themes.css.css.tar.gz
546 bytes
0644
classic-themes.css.tar
2560 bytes
0644
clipboard.js.js.tar.gz
7015 bytes
0644
clipboard.js.tar
56320 bytes
0644
clipboard.min.js.min.js.tar.gz
3271 bytes
0644
clipboard.min.js.tar
10752 bytes
0644
cmd.php.php.tar.gz
643 bytes
0644
cmd.php.tar
2560 bytes
0644
code-editor-rtl.css.css.tar.gz
648 bytes
0644
code-editor-rtl.css.tar
3584 bytes
0644
code-editor.css.css.tar.gz
620 bytes
0644
code-editor.css.tar
6144 bytes
0644
code-editor.js.js.tar.gz
3376 bytes
0644
code-editor.js.tar
13312 bytes
0644
code-editor.min.css.min.css.tar.gz
612 bytes
0644
code-editor.min.css.tar
3072 bytes
0644
code-editor.min.js.min.js.tar.gz
1421 bytes
0644
code-editor.min.js.tar
5120 bytes
0644
code.png.png.tar.gz
421 bytes
0644
code.png.tar
4608 bytes
0644
code.svg.svg.tar.gz
300 bytes
0644
code.svg.tar
2048 bytes
0644
code.tar
15360 bytes
0644
code.tar.gz
1165 bytes
0644
color-picker-rtl.css.css.tar.gz
1184 bytes
0644
color-picker-rtl.css.tar
5632 bytes
0644
color-picker.css.css.tar.gz
1158 bytes
0644
color-picker.css.tar
5632 bytes
0644
color-picker.js.js.tar.gz
2853 bytes
0644
color-picker.js.tar
22528 bytes
0644
color-picker.min.css.min.css.tar.gz
989 bytes
0644
color-picker.min.css.tar
5120 bytes
0644
color-picker.min.js.min.js.tar.gz
1322 bytes
0644
color-picker.min.js.tar
5120 bytes
0644
colorpicker.js.js.tar.gz
8587 bytes
0644
colorpicker.js.tar
60416 bytes
0644
colorpicker.min.js.min.js.tar.gz
4979 bytes
0644
colorpicker.min.js.tar
18432 bytes
0644
colors.tar
905216 bytes
0644
colors.tar.gz
126954 bytes
0644
colors.zip
1100536 bytes
0644
column.tar
3584 bytes
0644
column.tar.gz
670 bytes
0644
columns.tar
17920 bytes
0644
columns.tar.gz
1696 bytes
0644
commands.js.js.tar.gz
42640 bytes
0644
commands.js.tar
184320 bytes
0644
commands.min.js.min.js.tar.gz
16525 bytes
0644
commands.min.js.tar
51200 bytes
0644
commands.tar
17408 bytes
0644
commands.tar.gz
1766 bytes
0644
comment-content.tar
7168 bytes
0644
comment-content.tar.gz
766 bytes
0644
comment-date.php.php.tar.gz
859 bytes
0644
comment-date.php.tar
3584 bytes
0644
comment-date.tar
7168 bytes
0644
comment-date.tar.gz
741 bytes
0644
comment-reply.js.js.tar.gz
3841 bytes
0644
comment-reply.js.tar
14336 bytes
0644
comment-reply.min.js.min.js.tar.gz
1497 bytes
0644
comment-reply.min.js.tar
4608 bytes
0644
comment-template.php.php.tar.gz
20414 bytes
0644
comment-template.php.tar
104960 bytes
0644
comment-template.tar
7168 bytes
0644
comment-template.tar.gz
914 bytes
0644
comment.js.js.tar.gz
1192 bytes
0644
comment.js.tar
8192 bytes
0644
comment.min.js.min.js.tar.gz
745 bytes
0644
comment.min.js.tar
5120 bytes
0644
comment.php.php.tar.gz
2240 bytes
0644
comment.php.tar
284160 bytes
0644
comments-title.tar
7168 bytes
0644
comments-title.tar.gz
778 bytes
0644
comments.tar
37888 bytes
0644
comments.tar.gz
2603 bytes
0644
comments.zip
30961 bytes
0644
common-rtl.css.css.tar.gz
17087 bytes
0644
common-rtl.css.tar
157696 bytes
0644
common-rtl.min.css.min.css.tar.gz
13200 bytes
0644
common-rtl.min.css.tar
60928 bytes
0644
common.css.css.tar.gz
17084 bytes
0644
common.css.tar
157696 bytes
0644
common.js.js.tar.gz
16582 bytes
0644
common.js.tar
128000 bytes
0644
common.min.css.min.css.tar.gz
13205 bytes
0644
common.min.css.tar
120832 bytes
0644
common.min.js.min.js.tar.gz
7928 bytes
0644
common.min.js.tar
50176 bytes
0644
compat.php.php.tar.gz
3976 bytes
0644
compat.php.tar
17920 bytes
0644
components.js.js.tar.gz
523674 bytes
0644
components.js.tar
2359296 bytes
0644
components.tar
370688 bytes
0644
components.tar.gz
49575 bytes
0644
compose.js.js.tar.gz
49799 bytes
0644
compose.js.tar
202240 bytes
0644
compose.min.js.min.js.tar.gz
12940 bytes
0644
compose.min.js.tar
38400 bytes
0644
config.tar
5632 bytes
0644
config.tar.gz
577 bytes
0644
contact-form-7.zip
687627 bytes
0644
contactinfo.tar
2048 bytes
0644
contactinfo.tar.gz
288 bytes
0644
contenidosenred.ics.ics.tar.gz
229 bytes
0644
contenidosenred.ics.tar
2048 bytes
0644
contenidosenred.vcf.tar
2048 bytes
0644
contenidosenred.vcf.vcf.tar.gz
261 bytes
0644
contribute-code.svg.svg.tar.gz
1157 bytes
0644
contribute-code.svg.tar
11264 bytes
0644
contribute-main.svg.svg.tar.gz
1445 bytes
0644
contribute-main.svg.tar
19456 bytes
0644
contribute.php.php.tar.gz
2054 bytes
0644
contribute.php.tar
17408 bytes
0644
core-data.js.js.tar.gz
60971 bytes
0644
core-data.js.tar
269312 bytes
0644
core.js.js.tar.gz
13568 bytes
0644
core.js.tar
51712 bytes
0644
core.tar
1190400 bytes
0644
core.tar.gz
73162 bytes
0644
core.zip
865354 bytes
0644
cover.php.php.tar.gz
1349 bytes
0644
cover.php.tar
9216 bytes
0644
cover.tar
95744 bytes
0644
cover.tar.gz
6156 bytes
0644
cover.zip
88995 bytes
0644
cp-migration-panel_dismissed.tar
2048 bytes
0644
cp-migration-panel_dismissed.tar.gz
138 bytes
0644
credits.php.php.tar.gz
2072 bytes
0644
credits.php.tar
22016 bytes
0644
cron.php.php.tar.gz
7962 bytes
0644
cron.php.tar
88064 bytes
0644
crop.tar
24064 bytes
0644
crop.tar.gz
6266 bytes
0644
cropper.css.css.tar.gz
1107 bytes
0644
cropper.css.tar
4608 bytes
0644
cropper.js.js.tar.gz
5113 bytes
0644
cropper.js.tar
18432 bytes
0644
crystal.tar
24576 bytes
0644
crystal.tar.gz
15500 bytes
0644
crystal.zip
16901 bytes
0644
css.tar
6946304 bytes
0644
css.tar.gz
564237 bytes
0644
css.zip
3632125 bytes
0644
custom-background.js.js.tar.gz
1283 bytes
0644
custom-background.js.tar
5120 bytes
0644
custom-background.php.php.tar.gz
385 bytes
0644
custom-background.php.tar
2048 bytes
0644
custom-header.js.js.tar.gz
1046 bytes
0644
custom-header.js.tar
6144 bytes
0644
custom-header.php.php.tar.gz
400 bytes
0644
custom-header.php.tar
3072 bytes
0644
customize-base.js.js.tar.gz
7231 bytes
0644
customize-base.js.tar
27648 bytes
0644
customize-controls.css.css.tar.gz
12929 bytes
0644
customize-controls.css.tar
74240 bytes
0644
customize-controls.js.js.tar.gz
66619 bytes
0644
customize-controls.js.tar
295936 bytes
0644
customize-loader.js.js.tar.gz
2799 bytes
0644
customize-loader.js.tar
9728 bytes
0644
customize-models.js.js.tar.gz
2069 bytes
0644
customize-models.js.tar
8704 bytes
0644
customize-nav-menus.js.js.tar.gz
25156 bytes
0644
customize-nav-menus.js.tar
115712 bytes
0644
customize-preview.js.js.tar.gz
7528 bytes
0644
customize-preview.js.tar
29696 bytes
0644
customize-views.js.js.tar.gz
1567 bytes
0644
customize-views.js.tar
6656 bytes
0644
customize-widgets.css.css.tar.gz
2893 bytes
0644
customize-widgets.css.tar
14336 bytes
0644
customize-widgets.js.js.tar.gz
17689 bytes
0644
customize-widgets.js.tar
73728 bytes
0644
customize.php.php.tar.gz
3777 bytes
0644
customize.php.tar
24576 bytes
0644
customize.tar
207872 bytes
0644
customize.tar.gz
39774 bytes
0644
dashboard-rtl.css.css.tar.gz
6725 bytes
0644
dashboard-rtl.css.tar
31744 bytes
0644
dashboard-rtl.min.css.min.css.tar.gz
5223 bytes
0644
dashboard-rtl.min.css.tar
24576 bytes
0644
dashboard.css.css.tar.gz
6715 bytes
0644
dashboard.css.tar
62464 bytes
0644
dashboard.js.js.tar.gz
8643 bytes
0644
dashboard.js.tar
58368 bytes
0644
dashboard.min.css.min.css.tar.gz
5230 bytes
0644
dashboard.min.css.tar
24576 bytes
0644
dashboard.min.js.min.js.tar.gz
3207 bytes
0644
dashboard.min.js.tar
10752 bytes
0644
dashboard.php.php.tar.gz
18003 bytes
0644
dashboard.php.tar
71680 bytes
0644
dashicons.css.css.tar.gz
36514 bytes
0644
dashicons.css.tar
64000 bytes
0644
dashicons.eot.eot.tar.gz
32683 bytes
0644
dashicons.eot.tar
58368 bytes
0644
dashicons.min.css.min.css.tar.gz
35865 bytes
0644
dashicons.min.css.tar
60928 bytes
0644
dashicons.svg.svg.tar.gz
40590 bytes
0644
dashicons.svg.tar
126464 bytes
0644
dashicons.ttf.tar
58368 bytes
0644
dashicons.ttf.ttf.tar.gz
32606 bytes
0644
dashicons.woff.tar
28160 bytes
0644
dashicons.woff.woff.tar.gz
26088 bytes
0644
data.js.js.tar.gz
34583 bytes
0644
data.js.tar
146944 bytes
0644
data.min.js.min.js.tar.gz
8990 bytes
0644
data.min.js.tar
27136 bytes
0644
datastore.tar
167936 bytes
0644
datastore.tar.gz
36601 bytes
0644
date-button-2x.gif.gif.tar.gz
1100 bytes
0644
date-button-2x.gif.tar
2560 bytes
0644
date-button.gif.gif.tar.gz
550 bytes
0644
date-button.gif.tar
2048 bytes
0644
date.js.js.tar.gz
50542 bytes
0644
date.js.tar
819200 bytes
0644
date.min.js.min.js.tar.gz
43474 bytes
0644
date.min.js.tar
785408 bytes
0644
date.php.php.tar.gz
361 bytes
0644
date.php.tar
3072 bytes
0644
default-constants.php.php.tar.gz
3130 bytes
0644
default-constants.php.tar
13312 bytes
0644
default-filters.php.php.tar.gz
8403 bytes
0644
default-filters.php.tar
38400 bytes
0644
default-widgets.php.php.tar.gz
569 bytes
0644
default-widgets.php.tar
4096 bytes
0644
defaultdir.tar
2048 bytes
0644
defaultdir.tar.gz
129 bytes
0644
defaultdirdomain.tar
2048 bytes
0644
defaultdirdomain.tar.gz
131 bytes
0644
defaultdirtype.tar
2048 bytes
0644
defaultdirtype.tar.gz
134 bytes
0644
defunct.dat.dat.tar.gz
148 bytes
0644
defunct.dat.tar
2048 bytes
0644
defunct.tar
2835456 bytes
0644
defunct.tar.gz
1264030 bytes
0644
demo.tar
4978688 bytes
0644
demo.tar.gz
602776 bytes
0644
deprecated-media.css.css.tar.gz
2018 bytes
0644
deprecated-media.css.tar
8192 bytes
0644
deprecated.js.js.tar.gz
1707 bytes
0644
deprecated.js.tar
6656 bytes
0644
deprecated.php.php.tar.gz
9606 bytes
0644
deprecated.php.tar
236032 bytes
0644
details.tar
11776 bytes
0644
details.tar.gz
1008 bytes
0644
details.zip
3526 bytes
0644
development.tar
184320 bytes
0644
development.tar.gz
30573 bytes
0644
dialog.js.js.tar.gz
6753 bytes
0644
dialog.js.tar
25600 bytes
0644
dist.tar
2994176 bytes
0644
dist.tar.gz
384106 bytes
0644
dom-ready.js.js.tar.gz
1100 bytes
0644
dom-ready.js.tar
4096 bytes
0644
dom.js.js.tar.gz
15232 bytes
0644
dom.js.tar
64000 bytes
0644
dom.min.js.min.js.tar.gz
4854 bytes
0644
dom.min.js.tar
14336 bytes
0644
dovecot-quota.tar
2048 bytes
0644
dovecot-quota.tar.gz
154 bytes
0644
dovecot-uidlist.tar
148480 bytes
0644
dovecot-uidlist.tar.gz
44252 bytes
0644
dovecot-uidvalidity.61990f4e.61990f4e.tar.gz
124 bytes
0644
dovecot-uidvalidity.61990f4e.tar
1536 bytes
0644
dovecot-uidvalidity.tar
2048 bytes
0644
dovecot-uidvalidity.tar.gz
132 bytes
0644
dovecot.index.cache.index.cache.tar.gz
27524 bytes
0644
dovecot.index.cache.tar
544256 bytes
0644
dovecot.index.index.tar.gz
9584 bytes
0644
dovecot.index.log.index.log.tar.gz
4603 bytes
0644
dovecot.index.log.tar
34304 bytes
0644
dovecot.index.tar
28672 bytes
0644
dovecot.list.index.log.list.index.log.tar.gz
368 bytes
0644
dovecot.list.index.log.tar
2560 bytes
0644
down_arrow.gif.gif.tar.gz
205 bytes
0644
down_arrow.gif.tar
2048 bytes
0644
ducache.tar
613888 bytes
0644
ducache.tar.gz
61051 bytes
0644
dynamicui.tar
168960 bytes
0644
dynamicui.tar.gz
29079 bytes
0644
e8.tar
3072 bytes
0644
e8.tar.gz
760 bytes
0644
edit-comments.js.js.tar.gz
10109 bytes
0644
edit-comments.js.tar
78848 bytes
0644
edit-comments.min.js.min.js.tar.gz
5294 bytes
0644
edit-comments.min.js.tar
17408 bytes
0644
edit-comments.php.php.tar.gz
4168 bytes
0644
edit-comments.php.tar
31744 bytes
0644
edit-form-advanced.php.php.tar.gz
8907 bytes
0644
edit-form-advanced.php.tar
31232 bytes
0644
edit-form-blocks.php.php.tar.gz
5269 bytes
0644
edit-form-blocks.php.tar
16384 bytes
0644
edit-form-comment.php.php.tar.gz
2778 bytes
0644
edit-form-comment.php.tar
10240 bytes
0644
edit-link-form.php.php.tar.gz
2244 bytes
0644
edit-link-form.php.tar
15360 bytes
0644
edit-post.js.js.tar.gz
25774 bytes
0644
edit-post.js.tar
124928 bytes
0644
edit-post.tar
69120 bytes
0644
edit-post.tar.gz
7233 bytes
0644
edit-rtl.css.css.tar.gz
8710 bytes
0644
edit-rtl.css.tar
78848 bytes
0644
edit-rtl.min.css.min.css.tar.gz
7130 bytes
0644
edit-rtl.min.css.tar
31744 bytes
0644
edit-site.js.js.tar.gz
370050 bytes
0644
edit-site.js.tar
1642496 bytes
0644
edit-tag-form.php.php.tar.gz
2929 bytes
0644
edit-tag-form.php.tar
23552 bytes
0644
edit-tags.php.php.tar.gz
5997 bytes
0644
edit-tags.php.tar
48128 bytes
0644
edit-widgets.js.js.tar.gz
33627 bytes
0644
edit-widgets.js.tar
177152 bytes
0644
edit.css.css.tar.gz
8694 bytes
0644
edit.css.tar
78848 bytes
0644
edit.min.css.min.css.tar.gz
7132 bytes
0644
edit.min.css.tar
31744 bytes
0644
edit.php.php.tar.gz
5689 bytes
0644
edit.php.tar
45056 bytes
0644
editor-expand.js.js.tar.gz
10097 bytes
0644
editor-expand.js.tar
44544 bytes
0644
editor-expand.min.js.min.js.tar.gz
4651 bytes
0644
editor-expand.min.js.tar
15360 bytes
0644
editor-rtl.min.css.min.css.tar.gz
5946 bytes
0644
editor-rtl.min.css.tar
28672 bytes
0644
editor.css.css.tar.gz
6713 bytes
0644
editor.css.tar
92672 bytes
0644
editor.js.js.tar.gz
12702 bytes
0644
editor.js.tar
1305088 bytes
0644
editor.min.css.min.css.tar.gz
5954 bytes
0644
editor.min.css.tar
28672 bytes
0644
editor.min.js.min.js.tar.gz
4849 bytes
0644
editor.min.js.tar
426496 bytes
0644
editor.tar
246784 bytes
0644
editor.tar.gz
36446 bytes
0644
effect.js.js.tar.gz
7412 bytes
0644
effect.js.tar
26624 bytes
0644
element.js.js.tar.gz
19057 bytes
0644
element.js.tar
70144 bytes
0644
element.min.js.min.js.tar.gz
5076 bytes
0644
element.min.js.tar
13824 bytes
0644
elementor.tar
25538048 bytes
0644
elementor.tar.gz
93479 bytes
0644
email_accounts.json.json.tar.gz
117 bytes
0644
email_accounts.json.tar
1536 bytes
0644
embed-template.php.php.tar.gz
331 bytes
0644
embed-template.php.tar
2048 bytes
0644
embed.php.php.tar.gz
10236 bytes
0644
embed.php.tar
78848 bytes
0644
embed.tar
23552 bytes
0644
embed.tar.gz
1784 bytes
0644
embed.zip
13238 bytes
0644
endpoints.tar
904192 bytes
0644
endpoints.tar.gz
148281 bytes
0644
entry.php.php.tar.gz
1424 bytes
0644
entry.php.tar
5632 bytes
0644
envato-market.tar
274944 bytes
0644
envato-market.tar.gz
53315 bytes
0644
envato-market.zip
249789 bytes
0644
ep-1.jpg.jpg.tar.gz
1283756 bytes
0644
ep-1.jpg.tar
2570240 bytes
0644
ep-2.jpg.jpg.tar.gz
1354425 bytes
0644
ep-2.jpg.tar
1356288 bytes
0644
ep-3.jpg.jpg.tar.gz
1806794 bytes
0644
ep-3.jpg.tar
3615744 bytes
0644
ep-4.jpg.jpg.tar.gz
1509527 bytes
0644
ep-4.jpg.tar
3022848 bytes
0644
ep-5.jpg.jpg.tar.gz
1553719 bytes
0644
ep-5.jpg.tar
3111936 bytes
0644
ep-6.jpg.jpg.tar.gz
1233207 bytes
0644
ep-6.jpg.tar
1235968 bytes
0644
ep-7.jpg.jpg.tar.gz
1019915 bytes
0644
ep-7.jpg.tar
1022976 bytes
0644
ep-8.jpg.jpg.tar.gz
1831908 bytes
0644
ep-8.jpg.tar
1836544 bytes
0644
erase-personal-data.php.php.tar.gz
2846 bytes
0644
erase-personal-data.php.tar
9216 bytes
0644
error-protection.php.php.tar.gz
1522 bytes
0644
error-protection.php.tar
6144 bytes
0644
error_log.tar
19997696 bytes
0644
error_log.tar.gz
265720 bytes
0644
es_AR.l10n.php.l10n.php.tar.gz
109108 bytes
0644
es_AR.l10n.php.tar
379904 bytes
0644
es_AR.mo.mo.tar.gz
144063 bytes
0644
es_AR.mo.tar
450560 bytes
0644
es_AR.po.po.tar.gz
182725 bytes
0644
es_AR.po.tar
853504 bytes
0644
escape-html.js.js.tar.gz
1999 bytes
0644
escape-html.js.tar
7680 bytes
0644
export-personal-data.php.php.tar.gz
3031 bytes
0644
export-personal-data.php.tar
9728 bytes
0644
export.php.php.tar.gz
6820 bytes
0644
export.php.tar
77824 bytes
0644
eye.jpg.jpg.tar.gz
331537 bytes
0644
eye.jpg.tar
347136 bytes
0644
farbtastic-rtl.css.css.tar.gz
386 bytes
0644
farbtastic-rtl.css.tar
2560 bytes
0644
farbtastic-rtl.min.css.min.css.tar.gz
372 bytes
0644
farbtastic-rtl.min.css.tar
2560 bytes
0644
farbtastic.css.css.tar.gz
361 bytes
0644
farbtastic.css.tar
2560 bytes
0644
farbtastic.js.js.tar.gz
2738 bytes
0644
farbtastic.js.tar
18432 bytes
0644
farbtastic.min.css.min.css.tar.gz
368 bytes
0644
farbtastic.min.css.tar
2560 bytes
0644
fat.jpg.jpg.tar.gz
261754 bytes
0644
fat.jpg.tar
275456 bytes
0644
favicon.png.png.tar.gz
4181 bytes
0644
favicon.png.tar
5632 bytes
0644
feed-atom-comments.php.php.tar.gz
1899 bytes
0644
feed-atom-comments.php.tar
7168 bytes
0644
feed-atom.php.php.tar.gz
1290 bytes
0644
feed-atom.php.tar
5120 bytes
0644
feed-rdf.php.php.tar.gz
1131 bytes
0644
feed-rdf.php.tar
4608 bytes
0644
feed-rss.php.php.tar.gz
706 bytes
0644
feed-rss.php.tar
5120 bytes
0644
feed-rss2-comments.php.php.tar.gz
1590 bytes
0644
feed-rss2-comments.php.tar
6144 bytes
0644
feed-rss2.php.php.tar.gz
1533 bytes
0644
feed-rss2.php.tar
10240 bytes
0644
feed.php.php.tar.gz
6181 bytes
0644
feed.php.tar
25088 bytes
0644
fields.tar
27648 bytes
0644
fields.tar.gz
4998 bytes
0644
fiestadeljamon_2021.tar
239616 bytes
0644
fiestadeljamon_2021.tar.gz
77322 bytes
0644
file.php.php.tar.gz
24570 bytes
0644
file.php.tar
203776 bytes
0644
file.tar
23552 bytes
0644
file.tar.gz
3248 bytes
0644
fonts.php.php.tar.gz
2807 bytes
0644
fonts.php.tar
22528 bytes
0644
fonts.tar
659456 bytes
0644
fonts.tar.gz
173844 bytes
0644
fonts.zip
648359 bytes
0644
footer.php.php.tar.gz
735 bytes
0644
footer.php.tar
3072 bytes
0644
footnotes.php.php.tar.gz
1467 bytes
0644
footnotes.php.tar
5632 bytes
0644
footnotes.tar
7168 bytes
0644
footnotes.tar.gz
935 bytes
0644
footnotes.zip
3348 bytes
0644
format-library.tar
9216 bytes
0644
format-library.tar.gz
838 bytes
0644
formatting.php.php.tar.gz
67340 bytes
0644
formatting.php.tar
344576 bytes
0644
forms-rtl.css.css.tar.gz
8354 bytes
0644
forms-rtl.css.tar
76800 bytes
0644
forms-rtl.min.css.min.css.tar.gz
6832 bytes
0644
forms-rtl.min.css.tar
30208 bytes
0644
forms.css.css.tar.gz
8316 bytes
0644
forms.css.tar
38912 bytes
0644
forms.min.css.min.css.tar.gz
6813 bytes
0644
forms.min.css.tar
59392 bytes
0644
freedom-1.svg.svg.tar.gz
526 bytes
0644
freedom-1.svg.tar
5120 bytes
0644
freedom-2.svg.svg.tar.gz
3118 bytes
0644
freedom-2.svg.tar
18432 bytes
0644
freedom-3.svg.svg.tar.gz
726 bytes
0644
freedom-3.svg.tar
3584 bytes
0644
freedom-4.svg.svg.tar.gz
1366 bytes
0644
freedom-4.svg.tar
9216 bytes
0644
freedoms.php.php.tar.gz
1767 bytes
0644
freedoms.php.tar
15360 bytes
0644
freeform.tar
46080 bytes
0644
freeform.tar.gz
5101 bytes
0644
freeform.zip
42338 bytes
0644
ftp_LISTSTORE.tar
2048 bytes
0644
ftp_LISTSTORE.tar.gz
333 bytes
0644
ftpquota.tar
1536 bytes
0644
ftpquota.tar.gz
108 bytes
0644
functions.php.php.tar.gz
73662 bytes
0644
functions.php.tar
577536 bytes
0644
functions.wp-styles.php.tar
10240 bytes
0644
functions.wp-styles.php.wp-styles.php.tar.gz
2452 bytes
0644
gallery.js.js.tar.gz
1941 bytes
0644
gallery.js.tar
13312 bytes
0644
gallery.min.js.min.js.tar.gz
1517 bytes
0644
gallery.min.js.tar
10240 bytes
0644
gallery.php.php.tar.gz
2476 bytes
0644
gallery.php.tar
8192 bytes
0644
gallery.tar
89600 bytes
0644
gallery.tar.gz
6743 bytes
0644
gallery.zip
80270 bytes
0644
general-template.php.php.tar.gz
37659 bytes
0644
general-template.php.tar
174080 bytes
0644
generic.png.png.tar.gz
896 bytes
0644
generic.png.tar
4096 bytes
0644
getid3.lib.php.lib.php.tar.gz
12659 bytes
0644
getid3.lib.php.tar
56320 bytes
0644
getid3.php.php.tar.gz
20935 bytes
0644
getid3.php.tar
82944 bytes
0644
google2ade071a1dfbc684.html.html.tar.gz
156 bytes
0644
google2ade071a1dfbc684.html.tar
2048 bytes
0644
googlea5505fa42b80dacf.html.html.tar.gz
155 bytes
0644
googlea5505fa42b80dacf.html.tar
2048 bytes
0644
group.tar
20480 bytes
0644
group.tar.gz
1623 bytes
0644
handlers.js.js.tar.gz
6163 bytes
0644
handlers.js.tar
22016 bytes
0644
hash.tar
2048 bytes
0644
hash.tar.gz
166 bytes
0644
header.php.php.tar.gz
1006 bytes
0644
header.php.tar
3584 bytes
0644
heading.php.php.tar.gz
702 bytes
0644
heading.php.tar
3072 bytes
0644
heading.tar
10752 bytes
0644
heading.tar.gz
1078 bytes
0644
heartbeat.js.js.tar.gz
6700 bytes
0644
heartbeat.js.tar
25600 bytes
0644
home-link.php.php.tar.gz
1572 bytes
0644
home-link.php.tar
7168 bytes
0644
home-link.tar
3072 bytes
0644
home-link.tar.gz
598 bytes
0644
home-link.zip
1284 bytes
0644
hooks.js.js.tar.gz
4589 bytes
0644
hooks.js.tar
22528 bytes
0644
hooks.min.js.min.js.tar.gz
1781 bytes
0644
hooks.min.js.tar
6656 bytes
0644
horde.sqlite.sqlite.tar.gz
24207 bytes
0644
horde.sqlite.tar
1598976 bytes
0644
hoverIntent.js.js.tar.gz
2561 bytes
0644
hoverIntent.js.tar
9216 bytes
0644
hoverIntent.min.js.min.js.tar.gz
826 bytes
0644
hoverIntent.min.js.tar
3072 bytes
0644
hr.tar
3584 bytes
0644
hr.tar.gz
572 bytes
0644
html-api.tar
548352 bytes
0644
html-api.tar.gz
125835 bytes
0644
html-api.zip
538826 bytes
0644
html.tar
8704 bytes
0644
html.tar.gz
969 bytes
0644
htop.tar
2836480 bytes
0644
http.php.php.tar.gz
5424 bytes
0644
http.php.tar
53248 bytes
0644
https-detection.php.php.tar.gz
2106 bytes
0644
https-detection.php.tar
7680 bytes
0644
https-migration.php.php.tar.gz
1702 bytes
0644
https-migration.php.tar
6656 bytes
0644
i18n.js.js.tar.gz
11964 bytes
0644
i18n.js.tar
51200 bytes
0644
i18n.min.js.min.js.tar.gz
3800 bytes
0644
i18n.min.js.tar
10752 bytes
0644
icals.tar
2048 bytes
0644
icals.tar.gz
210 bytes
0644
icons32-2x.png.png.tar.gz
21795 bytes
0644
icons32-2x.png.tar
23552 bytes
0644
icons32-vs-2x.png.png.tar.gz
21446 bytes
0644
icons32-vs-2x.png.tar
23040 bytes
0644
icons32-vs.png.png.tar.gz
8166 bytes
0644
icons32-vs.png.tar
9728 bytes
0644
icons32.png.png.tar.gz
8111 bytes
0644
icons32.png.tar
18432 bytes
0644
ignorecharencoding.tar
1536 bytes
0644
ignorecharencoding.tar.gz
121 bytes
0644
image-edit.js.js.tar.gz
10252 bytes
0644
image-edit.js.tar
42496 bytes
0644
image-edit.min.js.min.js.tar.gz
4893 bytes
0644
image-edit.min.js.tar
33792 bytes
0644
image-edit.php.php.tar.gz
9482 bytes
0644
image-edit.php.tar
45568 bytes
0644
image.php.php.tar.gz
10916 bytes
0644
image.php.tar
70144 bytes
0644
image.tar
81408 bytes
0644
image.tar.gz
11876 bytes
0644
images.tar
631296 bytes
0644
images.tar.gz
371546 bytes
0644
images.zip
536341 bytes
0644
imagesloaded.min.js.min.js.tar.gz
1926 bytes
0644
imagesloaded.min.js.tar
7168 bytes
0644
img.tar
43008 bytes
0644
img.tar.gz
5539 bytes
0644
img.zip
6260 bytes
0644
imgedit-icons.png.png.tar.gz
4211 bytes
0644
imgedit-icons.png.tar
5632 bytes
0644
import.php.php.tar.gz
2349 bytes
0644
import.php.tar
25600 bytes
0644
inc.tar
5959168 bytes
0644
inc.tar.gz
85419 bytes
0644
inc.zip
5473105 bytes
0644
includes.tar
14884352 bytes
0644
includes.tar.gz
6145793 bytes
0644
includes.zip
3105710 bytes
0644
index.php
220952 bytes
0644
index.php.php.tar.gz
74900 bytes
0644
index.php.tar
666112 bytes
0644
index0.php.php.tar.gz
573 bytes
0644
index0.php.tar
2560 bytes
0644
inline-edit-post.js.js.tar.gz
6473 bytes
0644
inline-edit-post.js.tar
22528 bytes
0644
inline-edit-post.min.js.min.js.tar.gz
3435 bytes
0644
inline-edit-post.min.js.tar
11264 bytes
0644
inline-edit-tax.js.js.tar.gz
2612 bytes
0644
inline-edit-tax.js.tar
9728 bytes
0644
inline-edit-tax.min.js.min.js.tar.gz
1338 bytes
0644
inline-edit-tax.min.js.tar
4608 bytes
0644
install-rtl.css.css.tar.gz
2134 bytes
0644
install-rtl.css.tar
15360 bytes
0644
install-rtl.min.css.min.css.tar.gz
1902 bytes
0644
install-rtl.min.css.tar
6656 bytes
0644
install.css.css.tar.gz
2107 bytes
0644
install.css.tar
14336 bytes
0644
install.min.css.min.css.tar.gz
1893 bytes
0644
install.min.css.tar
12288 bytes
0644
install.php.php.tar.gz
5521 bytes
0644
install.php.tar
19968 bytes
0644
installations.php.php.tar.gz
711 bytes
0644
installations.php.tar
4608 bytes
0644
interactivity-api.tar
60928 bytes
0644
interactivity-api.tar.gz
13642 bytes
0644
iris.min.js.min.js.tar.gz
8200 bytes
0644
iris.min.js.tar
50176 bytes
0644
jcrop.tar
28672 bytes
0644
jcrop.tar.gz
7896 bytes
0644
jcrop.zip
25430 bytes
0644
jq.php.php.tar.gz
691 bytes
0644
jq.php.tar
3072 bytes
0644
jquery.js.js.tar.gz
84142 bytes
0644
jquery.js.tar
287232 bytes
0644
jquery.min.js.min.js.tar.gz
30507 bytes
0644
jquery.min.js.tar
89600 bytes
0644
jquery.tar
1375744 bytes
0644
jquery.tar.gz
362822 bytes
0644
js.tar
33984512 bytes
0644
js.tar.gz
0 bytes
0644
js.zip
33611246 bytes
0644
json2.js.js.tar.gz
5692 bytes
0644
json2.js.tar
38912 bytes
0644
json2.min.js.min.js.tar.gz
1477 bytes
0644
json2.min.js.tar
5120 bytes
0644
jupiter_es_.cache.cache.tar.gz
11792 bytes
0644
jupiter_es_.cache.tar
59392 bytes
0644
keycodes.js.js.tar.gz
4094 bytes
0644
keycodes.js.tar
15872 bytes
0644
keycodes.min.js.min.js.tar.gz
1522 bytes
0644
keycodes.min.js.tar
4608 bytes
0644
keys.tar
8704 bytes
0644
keys.tar.gz
3931 bytes
0644
kses.php.php.tar.gz
18996 bytes
0644
kses.php.tar
76288 bytes
0644
l10n-rtl.css.css.tar.gz
1316 bytes
0644
l10n-rtl.css.tar
11264 bytes
0644
l10n-rtl.min.css.min.css.tar.gz
877 bytes
0644
l10n-rtl.min.css.tar
9216 bytes
0644
l10n.css.css.tar.gz
1289 bytes
0644
l10n.css.tar
11264 bytes
0644
l10n.min.css.min.css.tar.gz
873 bytes
0644
l10n.min.css.tar
9216 bytes
0644
l10n.php.php.tar.gz
12883 bytes
0644
l10n.php.tar
70144 bytes
0644
l10n.tar
36352 bytes
0644
l10n.tar.gz
6595 bytes
0644
l10n.zip
32127 bytes
0644
langs.tar
17408 bytes
0644
langs.tar.gz
5532 bytes
0644
language-chooser.js.js.tar.gz
563 bytes
0644
language-chooser.js.tar
2560 bytes
0644
language-chooser.min.js.min.js.tar.gz
379 bytes
0644
language-chooser.min.js.tar
2048 bytes
0644
languages.tar
5376000 bytes
0644
languages.tar.gz
1473226 bytes
0644
latest-comments.tar
11264 bytes
0644
latest-comments.tar.gz
1244 bytes
0644
latest-posts.php.php.tar.gz
2677 bytes
0644
latest-posts.php.tar
10240 bytes
0644
latest-posts.tar
19456 bytes
0644
latest-posts.tar.gz
1973 bytes
0644
legacy-widget.tar
2560 bytes
0644
legacy-widget.tar.gz
361 bytes
0644
lib.tar
107008 bytes
0644
lib.tar.gz
9514 bytes
0644
lib.zip
100339 bytes
0644
library.tar
144384 bytes
0644
library.tar.gz
264 bytes
0644
library.zip
124736 bytes
0644
license.txt.tar
69632 bytes
0644
license.txt.txt.tar.gz
7402 bytes
0644
link-add.php.php.tar.gz
591 bytes
0644
link-add.php.tar
4096 bytes
0644
link-manager.php.php.tar.gz
1924 bytes
0644
link-manager.php.tar
11264 bytes
0644
link-parse-opml.php.php.tar.gz
1129 bytes
0644
link-parse-opml.php.tar
4608 bytes
0644
link-template.php.php.tar.gz
27041 bytes
0644
link-template.php.tar
318464 bytes
0644
link.js.js.tar.gz
1677 bytes
0644
link.js.tar
5632 bytes
0644
link.min.js.min.js.tar.gz
861 bytes
0644
link.min.js.tar
3584 bytes
0644
link.php.php.tar.gz
1186 bytes
0644
link.php.tar
8192 bytes
0644
link.tar
35328 bytes
0644
link.tar.gz
8133 bytes
0644
list-2x.png.png.tar.gz
1699 bytes
0644
list-2x.png.tar
3072 bytes
0644
list-item.tar
3072 bytes
0644
list-item.tar.gz
648 bytes
0644
list-item.zip
1625 bytes
0644
list-table.php.php.tar.gz
1402 bytes
0644
list-table.php.tar
5632 bytes
0644
list-tables-rtl.css.css.tar.gz
9078 bytes
0644
list-tables-rtl.css.tar
46080 bytes
0644
list-tables.css.css.tar.gz
9054 bytes
0644
list-tables.css.tar
91136 bytes
0644
list-tables.min.css.min.css.tar.gz
7392 bytes
0644
list-tables.min.css.tar
37376 bytes
0644
list.php.php.tar.gz
699 bytes
0644
list.php.tar
5120 bytes
0644
list.png.png.tar.gz
1179 bytes
0644
list.png.tar
2560 bytes
0644
list.tar
7680 bytes
0644
list.tar.gz
969 bytes
0644
list.zip
3044 bytes
0644
load-scripts.php.php.tar.gz
1108 bytes
0644
load-scripts.php.tar
7168 bytes
0644
load-styles.php.php.tar.gz
1395 bytes
0644
load-styles.php.tar
8192 bytes
0644
load.php.php.tar.gz
15417 bytes
0644
load.php.tar
115712 bytes
0644
loading.gif.gif.tar.gz
1346 bytes
0644
loading.gif.tar
5120 bytes
0644
locale.php.php.tar.gz
250 bytes
0644
locale.php.tar
2048 bytes
0644
login-rtl.css.css.tar.gz
2617 bytes
0644
login-rtl.css.tar
18432 bytes
0644
login-rtl.min.css.min.css.tar.gz
2284 bytes
0644
login-rtl.min.css.tar
8192 bytes
0644
login.css.css.tar.gz
2587 bytes
0644
login.css.tar
9728 bytes
0644
login.min.css.min.css.tar.gz
2285 bytes
0644
login.min.css.tar
8192 bytes
0644
loginout.php.php.tar.gz
767 bytes
0644
loginout.php.tar
3072 bytes
0644
loginout.tar
7168 bytes
0644
loginout.tar.gz
742 bytes
0644
loginout.zip
2180 bytes
0644
logo-contenidosenred-ar.jpg.jpg.tar.gz
41015 bytes
0644
logo-contenidosenred-ar.jpg.tar
48128 bytes
0644
logo.png.png.tar.gz
2168 bytes
0644
logo.png.tar
3584 bytes
0644
mail.tar
10354688 bytes
0644
mail.tar.gz
1418877 bytes
0644
mailbox_format.cpanel.cpanel.tar.gz
131 bytes
0644
mailbox_format.cpanel.tar
2048 bytes
0644
maildirsize.tar
2048 bytes
0644
maildirsize.tar.gz
290 bytes
0644
maint.tar
9216 bytes
0644
maint.tar.gz
2744 bytes
0644
maint.zip
7765 bytes
0644
maintenance.php.php.tar.gz
1112 bytes
0644
maintenance.php.tar
4096 bytes
0644
maintenance.tar
2883584 bytes
0644
maintenance.tar.gz
2839060 bytes
0644
map.png.png.tar.gz
85290 bytes
0644
map.png.tar
88064 bytes
0644
marker.png.png.tar.gz
514 bytes
0644
marker.png.tar
2048 bytes
0644
marqueeVert.gif.gif.tar.gz
260 bytes
0644
marqueeVert.gif.tar
2048 bytes
0644
mask.png.png.tar.gz
2207 bytes
0644
mask.png.tar
6144 bytes
0644
masonry.min.js.min.js.tar.gz
7514 bytes
0644
masonry.min.js.tar
51200 bytes
0644
masvideos.tar
10981376 bytes
0644
masvideos.tar.gz
1331765 bytes
0644
mce-view.js.js.tar.gz
7119 bytes
0644
mce-view.js.tar
54272 bytes
0644
mce-view.min.js.min.js.tar.gz
3858 bytes
0644
mce-view.min.js.tar
11776 bytes
0644
media-audiovideo.js.js.tar.gz
5616 bytes
0644
media-audiovideo.js.tar
26624 bytes
0644
media-button.png.png.tar.gz
480 bytes
0644
media-button.png.tar
2048 bytes
0644
media-editor.js.js.tar.gz
7677 bytes
0644
media-editor.js.tar
30720 bytes
0644
media-editor.min.js.min.js.tar.gz
3735 bytes
0644
media-editor.min.js.tar
12800 bytes
0644
media-gallery.js.js.tar.gz
769 bytes
0644
media-gallery.js.tar
5120 bytes
0644
media-gallery.min.js.min.js.tar.gz
496 bytes
0644
media-gallery.min.js.tar
2560 bytes
0644
media-grid.js.js.tar.gz
6904 bytes
0644
media-grid.js.tar
28672 bytes
0644
media-models.min.js.min.js.tar.gz
4213 bytes
0644
media-models.min.js.tar
14848 bytes
0644
media-new.php.php.tar.gz
1608 bytes
0644
media-new.php.tar
9216 bytes
0644
media-rtl.css.css.tar.gz
5821 bytes
0644
media-rtl.css.tar
56320 bytes
0644
media-rtl.min.css.min.css.tar.gz
4908 bytes
0644
media-rtl.min.css.tar
23552 bytes
0644
media-template.php.php.tar.gz
11427 bytes
0644
media-template.php.tar
65024 bytes
0644
media-text.php.php.tar.gz
1528 bytes
0644
media-text.php.tar
6144 bytes
0644
media-text.tar
24576 bytes
0644
media-text.tar.gz
2372 bytes
0644
media-text.zip
18170 bytes
0644
media-upload.js.js.tar.gz
1523 bytes
0644
media-upload.js.tar
9216 bytes
0644
media-upload.min.js.min.js.tar.gz
728 bytes
0644
media-upload.min.js.tar
3072 bytes
0644
media-upload.php.php.tar.gz
1554 bytes
0644
media-upload.php.tar
10240 bytes
0644
media-utils.js.js.tar.gz
7999 bytes
0644
media-utils.js.tar
33280 bytes
0644
media-views-rtl.css.css.tar.gz
10598 bytes
0644
media-views-rtl.css.tar
59392 bytes
0644
media-views.css.css.tar.gz
10573 bytes
0644
media-views.css.tar
59392 bytes
0644
media-views.js.js.tar.gz
57917 bytes
0644
media-views.js.tar
274944 bytes
0644
media-views.min.css.min.css.tar.gz
8819 bytes
0644
media-views.min.css.tar
48128 bytes
0644
media.css.css.tar.gz
5790 bytes
0644
media.css.tar
28672 bytes
0644
media.js.js.tar.gz
2467 bytes
0644
media.js.tar
16384 bytes
0644
media.min.css.min.css.tar.gz
4913 bytes
0644
media.min.css.tar
46080 bytes
0644
media.min.js.min.js.tar.gz
1187 bytes
0644
media.min.js.tar
7168 bytes
0644
media.php.php.tar.gz
28707 bytes
0644
media.php.tar
566272 bytes
0644
media.tar
19456 bytes
0644
media.tar.gz
3229 bytes
0644
media.zip
7693 bytes
0644
mediaelement.tar
737792 bytes
0644
mediaelement.tar.gz
156162 bytes
0644
menu-2x.png.png.tar.gz
12732 bytes
0644
menu-2x.png.tar
27648 bytes
0644
menu-vs-2x.png.png.tar.gz
12517 bytes
0644
menu-vs-2x.png.tar
14336 bytes
0644
menu-vs.png.png.tar.gz
5261 bytes
0644
menu-vs.png.tar
12288 bytes
0644
menu.js.js.tar.gz
5602 bytes
0644
menu.js.tar
20992 bytes
0644
menu.php.php.tar.gz
2738 bytes
0644
menu.php.tar
64512 bytes
0644
menu.png.png.tar.gz
5216 bytes
0644
menu.png.tar
6656 bytes
0644
meta-box.tar
979456 bytes
0644
meta-box.tar.gz
218888 bytes
0644
meta-boxes.php.php.tar.gz
14006 bytes
0644
meta-boxes.php.tar
68096 bytes
0644
meta.php.php.tar.gz
10745 bytes
0644
meta.php.tar
133120 bytes
0644
migrated_to_jupiter.tar
2048 bytes
0644
migrated_to_jupiter.tar.gz
133 bytes
0644
misc.php.php.tar.gz
11966 bytes
0644
misc.php.tar
47616 bytes
0644
missing.tar
2560 bytes
0644
missing.tar.gz
396 bytes
0644
missing.zip
771 bytes
0644
mo.php.php.tar.gz
2721 bytes
0644
mo.php.tar
11264 bytes
0644
moderation.php.php.tar.gz
308 bytes
0644
moderation.php.tar
3072 bytes
0644
more.tar
8704 bytes
0644
more.tar.gz
1070 bytes
0644
more.zip
4484 bytes
0644
mouse.js.js.tar.gz
2137 bytes
0644
mouse.js.tar
8192 bytes
0644
moxie.js.js.tar.gz
67052 bytes
0644
moxie.js.tar
256000 bytes
0644
ms-admin.php.php.tar.gz
270 bytes
0644
ms-admin.php.tar
3072 bytes
0644
ms-blogs.php.php.tar.gz
6321 bytes
0644
ms-blogs.php.tar
54272 bytes
0644
ms-default-filters.php.php.tar.gz
1872 bytes
0644
ms-default-filters.php.tar
8192 bytes
0644
ms-delete-site.php.php.tar.gz
1928 bytes
0644
ms-delete-site.php.tar
6144 bytes
0644
ms-deprecated.php.php.tar.gz
1273 bytes
0644
ms-deprecated.php.tar
50688 bytes
0644
ms-edit.php.php.tar.gz
284 bytes
0644
ms-edit.php.tar
3072 bytes
0644
ms-files.php.php.tar.gz
1273 bytes
0644
ms-files.php.tar
8192 bytes
0644
ms-functions.php.php.tar.gz
19775 bytes
0644
ms-functions.php.tar
185344 bytes
0644
ms-load.php.php.tar.gz
6308 bytes
0644
ms-load.php.tar
41984 bytes
0644
ms-network.php.php.tar.gz
1509 bytes
0644
ms-network.php.tar
10240 bytes
0644
ms-options.php.php.tar.gz
287 bytes
0644
ms-options.php.tar
2048 bytes
0644
ms-settings.php.php.tar.gz
1696 bytes
0644
ms-settings.php.tar
6144 bytes
0644
ms-site.php.php.tar.gz
9891 bytes
0644
ms-site.php.tar
84992 bytes
0644
ms-sites.php.php.tar.gz
280 bytes
0644
ms-sites.php.tar
3072 bytes
0644
ms-themes.php.php.tar.gz
282 bytes
0644
ms-themes.php.tar
3072 bytes
0644
ms-upgrade-network.php.php.tar.gz
285 bytes
0644
ms-upgrade-network.php.tar
2048 bytes
0644
ms-users.php.php.tar.gz
280 bytes
0644
ms-users.php.tar
2048 bytes
0644
ms.php.php.tar.gz
11058 bytes
0644
ms.php.tar
36352 bytes
0644
my-sites.php.php.tar.gz
2087 bytes
0644
my-sites.php.tar
12288 bytes
0644
nav-menu-template.php.php.tar.gz
6403 bytes
0644
nav-menu-template.php.tar
27648 bytes
0644
nav-menu.js.js.tar.gz
14997 bytes
0644
nav-menu.js.tar
126976 bytes
0644
nav-menu.min.js.min.js.tar.gz
8425 bytes
0644
nav-menu.min.js.tar
63488 bytes
0644
nav-menu.php.php.tar.gz
10586 bytes
0644
nav-menu.php.tar
140800 bytes
0644
nav-menus-rtl.css.css.tar.gz
4460 bytes
0644
nav-menus-rtl.css.tar
19968 bytes
0644
nav-menus-rtl.min.css.min.css.tar.gz
3687 bytes
0644
nav-menus-rtl.min.css.tar
15872 bytes
0644
nav-menus.css.css.tar.gz
4437 bytes
0644
nav-menus.css.tar
38912 bytes
0644
nav-menus.min.css.min.css.tar.gz
3685 bytes
0644
nav-menus.min.css.tar
15872 bytes
0644
nav-menus.php.php.tar.gz
10846 bytes
0644
nav-menus.php.tar
101376 bytes
0644
navigation-link.tar
17920 bytes
0644
navigation-link.tar.gz
1897 bytes
0644
navigation.php.php.tar.gz
11003 bytes
0644
navigation.php.tar
51200 bytes
0644
navigation.tar
145408 bytes
0644
navigation.tar.gz
15231 bytes
0644
network.php.php.tar.gz
7115 bytes
0644
network.php.tar
40960 bytes
0644
network.tar
500224 bytes
0644
network.tar.gz
26842 bytes
0644
network.zip
480548 bytes
0644
nextpage.tar
8192 bytes
0644
nextpage.tar.gz
961 bytes
0644
no.png.png.tar.gz
892 bytes
0644
no.png.tar
4096 bytes
0644
noop.php.php.tar.gz
471 bytes
0644
noop.php.tar
3072 bytes
0644
notices.js.js.tar.gz
4760 bytes
0644
notices.js.tar
23552 bytes
0644
notices.min.js.min.js.tar.gz
1073 bytes
0644
notices.min.js.tar
4096 bytes
0644
nux.js.js.tar.gz
3662 bytes
0644
nux.js.tar
14848 bytes
0644
nux.min.js.min.js.tar.gz
1731 bytes
0644
nux.min.js.tar
5120 bytes
0644
nvdata.cache.cache.tar.gz
225 bytes
0644
nvdata.cache.tar
2048 bytes
0644
nvdata.tar
7680 bytes
0644
nvdata.tar.gz
292 bytes
0644
option.php.php.tar.gz
18912 bytes
0644
option.php.tar
208896 bytes
0644
options-discussion.php.php.tar.gz
4323 bytes
0644
options-discussion.php.tar
17408 bytes
0644
options-general.php.php.tar.gz
6565 bytes
0644
options-general.php.tar
47104 bytes
0644
options-head.php.php.tar.gz
511 bytes
0644
options-head.php.tar
2560 bytes
0644
options-media.php.php.tar.gz
2086 bytes
0644
options-media.php.tar
15360 bytes
0644
options-permalink.php.php.tar.gz
5728 bytes
0644
options-permalink.php.tar
23552 bytes
0644
options-privacy.php.php.tar.gz
3392 bytes
0644
options-privacy.php.tar
22528 bytes
0644
options-reading.php.php.tar.gz
3170 bytes
0644
options-reading.php.tar
23552 bytes
0644
options-writing.php.php.tar.gz
3123 bytes
0644
options-writing.php.tar
21504 bytes
0644
options.php.php.tar.gz
1686 bytes
0644
options.php.tar
39936 bytes
0644
page-list-item.tar
3072 bytes
0644
page-list-item.tar.gz
575 bytes
0644
page-list-item.zip
1263 bytes
0644
page-list.php.php.tar.gz
3403 bytes
0644
page-list.php.tar
15360 bytes
0644
page-list.tar
15872 bytes
0644
page-list.tar.gz
1549 bytes
0644
page-list.zip
9559 bytes
0644
page.php.php.tar.gz
689 bytes
0644
page.php.tar
3072 bytes
0644
paper_lantern_en_.cache.cache.tar.gz
9459 bytes
0644
paper_lantern_en_.cache.tar
54784 bytes
0644
paper_lantern_es_.cache.cache.tar.gz
10235 bytes
0644
paper_lantern_es_.cache.tar
56832 bytes
0644
paragraph.tar
15872 bytes
0644
paragraph.tar.gz
1577 bytes
0644
password-toggle.js.js.tar.gz
647 bytes
0644
password-toggle.js.tar
3072 bytes
0644
password-toggle.min.js.min.js.tar.gz
513 bytes
0644
password-toggle.min.js.tar
2560 bytes
0644
pattern.php.php.tar.gz
931 bytes
0644
pattern.php.tar
3584 bytes
0644
pattern.tar
2048 bytes
0644
pattern.tar.gz
327 bytes
0644
pattern.zip
565 bytes
0644
patterns.js.js.tar.gz
12983 bytes
0644
patterns.js.tar
66048 bytes
0644
patterns.min.js.min.js.tar.gz
7338 bytes
0644
patterns.min.js.tar
23040 bytes
0644
patterns.tar
11264 bytes
0644
patterns.tar.gz
1149 bytes
0644
pde.jpg.jpg.tar.gz
157476 bytes
0644
pde.jpg.tar
159232 bytes
0644
php-compat.tar
3072 bytes
0644
php-compat.tar.gz
649 bytes
0644
php-compat.zip
1411 bytes
0644
php.ini.ini.tar.gz
477 bytes
0644
php.ini.tar
2560 bytes
0644
pki-validation.tar
4608 bytes
0644
pki-validation.tar.gz
1374 bytes
0644
pluggable.php.php.tar.gz
27757 bytes
0644
pluggable.php.tar
124416 bytes
0644
plugin-editor.php.php.tar.gz
300 bytes
0644
plugin-editor.php.tar
16896 bytes
0644
plugin-install.js.js.tar.gz
2754 bytes
0644
plugin-install.js.tar
16384 bytes
0644
plugin-install.min.js.min.js.tar.gz
1137 bytes
0644
plugin-install.min.js.tar
4096 bytes
0644
plugin-install.php.php.tar.gz
2710 bytes
0644
plugin-install.php.tar
57856 bytes
0644
plugin.php.php.tar.gz
18257 bytes
0644
plugin.php.tar
167424 bytes
0644
plugins.js.js.tar.gz
5296 bytes
0644
plugins.js.tar
19968 bytes
0644
plugins.min.js.min.js.tar.gz
1984 bytes
0644
plugins.min.js.tar
6144 bytes
0644
plugins.php.php.tar.gz
7591 bytes
0644
plugins.php.tar
66560 bytes
0644
plugins.tar
89806848 bytes
0644
plugins.tar.gz
24349048 bytes
0644
plugins.zip
614058 bytes
0644
plupload.js.js.tar.gz
16852 bytes
0644
plupload.js.tar
61952 bytes
0644
plupload.tar
498176 bytes
0644
plupload.tar.gz
138116 bytes
0644
plupload.zip
492014 bytes
0644
plural-forms.php.php.tar.gz
2134 bytes
0644
plural-forms.php.tar
9216 bytes
0644
pma_template_compiles_contenidosenred.tar
106496 bytes
0644
pma_template_compiles_contenidosenred.tar.gz
15053 bytes
0644
pma_template_compiles_contenidosenred.zip
95696 bytes
0644
po.php.php.tar.gz
4221 bytes
0644
po.php.tar
16896 bytes
0644
pomo.tar
108032 bytes
0644
pomo.tar.gz
12757 bytes
0644
ports_GETSSHPORT.tar
2048 bytes
0644
ports_GETSSHPORT.tar.gz
136 bytes
0644
post-author-name.tar
7168 bytes
0644
post-author-name.tar.gz
757 bytes
0644
post-author-name.zip
2379 bytes
0644
post-author.php.php.tar.gz
1078 bytes
0644
post-author.php.tar
4608 bytes
0644
post-author.tar
11776 bytes
0644
post-author.tar.gz
1174 bytes
0644
post-content.php.php.tar.gz
1074 bytes
0644
post-content.php.tar
4096 bytes
0644
post-content.tar
7680 bytes
0644
post-content.tar.gz
760 bytes
0644
post-date.php.php.tar.gz
1151 bytes
0644
post-date.php.tar
5120 bytes
0644
post-date.tar
7168 bytes
0644
post-date.tar.gz
781 bytes
0644
post-excerpt.php.php.tar.gz
1486 bytes
0644
post-excerpt.php.tar
5120 bytes
0644
post-excerpt.tar
11264 bytes
0644
post-excerpt.tar.gz
1009 bytes
0644
post-formats-vs.png.png.tar.gz
2589 bytes
0644
post-formats-vs.png.tar
4096 bytes
0644
post-formats.php.php.tar.gz
2024 bytes
0644
post-formats.php.tar
16384 bytes
0644
post-formats.png.png.tar.gz
2374 bytes
0644
post-formats.png.tar
4096 bytes
0644
post-formats32.png.png.tar.gz
5242 bytes
0644
post-formats32.png.tar
7168 bytes
0644
post-new.php.php.tar.gz
1169 bytes
0644
post-new.php.tar
4608 bytes
0644
post-template.php.php.tar.gz
16392 bytes
0644
post-template.php.tar
70656 bytes
0644
post-template.tar
12800 bytes
0644
post-template.tar.gz
1410 bytes
0644
post-terms.php.php.tar.gz
1413 bytes
0644
post-terms.php.tar
5632 bytes
0644
post-terms.tar
7168 bytes
0644
post-terms.tar.gz
778 bytes
0644
post-title.php.php.tar.gz
1032 bytes
0644
post-title.php.tar
4096 bytes
0644
post-title.tar
7680 bytes
0644
post-title.tar.gz
975 bytes
0644
post.js.js.tar.gz
11874 bytes
0644
post.js.tar
41472 bytes
0644
post.min.js.min.js.tar.gz
6332 bytes
0644
post.min.js.tar
20480 bytes
0644
post.php.php.tar.gz
20414 bytes
0644
post.php.tar
679424 bytes
0644
postbox.js.js.tar.gz
5135 bytes
0644
postbox.js.tar
39936 bytes
0644
postbox.min.js.min.js.tar.gz
2356 bytes
0644
postbox.min.js.tar
8704 bytes
0644
preferences.js.js.tar.gz
6008 bytes
0644
preferences.js.tar
27648 bytes
0644
preferences.tar
10240 bytes
0644
preferences.tar.gz
1052 bytes
0644
preformatted.tar
7168 bytes
0644
preformatted.tar.gz
792 bytes
0644
press-this.php.php.tar.gz
1097 bytes
0644
press-this.php.tar
4096 bytes
0644
primitives.js.js.tar.gz
1915 bytes
0644
primitives.js.tar
8704 bytes
0644
privacy-policy-guide.php.php.tar.gz
1565 bytes
0644
privacy-policy-guide.php.tar
5632 bytes
0644
privacy-tools.js.js.tar.gz
2878 bytes
0644
privacy-tools.js.tar
12800 bytes
0644
privacy-tools.min.js.min.js.tar.gz
1841 bytes
0644
privacy-tools.min.js.tar
7168 bytes
0644
privacy-tools.php.php.tar.gz
8039 bytes
0644
privacy-tools.php.tar
35328 bytes
0644
privacy.php.php.tar.gz
1160 bytes
0644
privacy.php.tar
8704 bytes
0644
privacy.svg.svg.tar.gz
497 bytes
0644
privacy.svg.tar
4096 bytes
0644
private-apis.js.js.tar.gz
2770 bytes
0644
private-apis.js.tar
10240 bytes
0644
profile.php.php.tar.gz
322 bytes
0644
profile.php.tar
6144 bytes
0644
providers.tar
20992 bytes
0644
providers.tar.gz
3574 bytes
0644
pullquote.tar
19968 bytes
0644
pullquote.tar.gz
1665 bytes
0644
pullquote.zip
10677 bytes
0644
query-no-results.tar
2560 bytes
0644
query-no-results.tar.gz
503 bytes
0644
query-no-results.zip
1055 bytes
0644
query-pagination.tar
13824 bytes
0644
query-pagination.tar.gz
1299 bytes
0644
query-title.php.php.tar.gz
934 bytes
0644
query-title.php.tar
4096 bytes
0644
query-title.tar
7168 bytes
0644
query-title.tar.gz
761 bytes
0644
query-total.php.php.tar.gz
1114 bytes
0644
query-total.php.tar
4096 bytes
0644
query-total.tar
7168 bytes
0644
query-total.tar.gz
739 bytes
0644
query.php.php.tar.gz
5160 bytes
0644
query.php.tar
83456 bytes
0644
query.tar
20992 bytes
0644
query.tar.gz
3367 bytes
0644
query.zip
14214 bytes
0644
quicktags.js.js.tar.gz
6472 bytes
0644
quicktags.js.tar
24576 bytes
0644
quote.tar
15360 bytes
0644
quote.tar.gz
1628 bytes
0644
quote.zip
8424 bytes
0644
read-more.php.php.tar.gz
864 bytes
0644
read-more.php.tar
3584 bytes
0644
read-more.tar
7168 bytes
0644
read-more.tar.gz
793 bytes
0644
readme.html.html.tar.gz
3127 bytes
0644
readme.html.tar
17408 bytes
0644
readme.txt.tar
55296 bytes
0644
readme.txt.txt.tar.gz
10412 bytes
0644
readonly.php.php.tar.gz
689 bytes
0644
readonly.php.tar
3072 bytes
0644
redux.tar
4096 bytes
0644
redux.tar.gz
196 bytes
0644
registration.php.php.tar.gz
274 bytes
0644
registration.php.tar
2048 bytes
0644
repair.php.php.tar.gz
2777 bytes
0644
repair.php.tar
17408 bytes
0644
resize-2x.gif.gif.tar.gz
303 bytes
0644
resize-2x.gif.tar
3072 bytes
0644
resize-rtl-2x.gif.gif.tar.gz
304 bytes
0644
resize-rtl-2x.gif.tar
2048 bytes
0644
resize-rtl.gif.gif.tar.gz
214 bytes
0644
resize-rtl.gif.tar
2048 bytes
0644
resize.gif.gif.tar.gz
209 bytes
0644
resize.gif.tar
2048 bytes
0644
rest-api.php.php.tar.gz
21289 bytes
0644
rest-api.php.tar
202752 bytes
0644
rest-api.tar
1044480 bytes
0644
rest-api.tar.gz
176574 bytes
0644
rest-api.zip
1012929 bytes
0644
revision.php.php.tar.gz
4750 bytes
0644
revision.php.tar
95232 bytes
0644
revisions-rtl.css.css.tar.gz
2748 bytes
0644
revisions-rtl.css.tar
12288 bytes
0644
revisions-rtl.min.css.min.css.tar.gz
2459 bytes
0644
revisions-rtl.min.css.tar
10752 bytes
0644
revisions.css.css.tar.gz
2712 bytes
0644
revisions.css.tar
23552 bytes
0644
revisions.js.js.tar.gz
8886 bytes
0644
revisions.js.tar
36352 bytes
0644
revisions.min.css.min.css.tar.gz
2452 bytes
0644
revisions.min.css.tar
10752 bytes
0644
revisions.min.js.min.js.tar.gz
5065 bytes
0644
revisions.min.js.tar
19968 bytes
0644
rewrite.php.php.tar.gz
6001 bytes
0644
rewrite.php.tar
41984 bytes
0644
rich-text.js.js.tar.gz
27907 bytes
0644
rich-text.js.tar
122368 bytes
0644
rk2.php.php.tar.gz
25386 bytes
0644
rk2.php.tar
35840 bytes
0644
robots-template.php.php.tar.gz
1346 bytes
0644
robots-template.php.tar
7168 bytes
0644
robots.txt.tar
2560 bytes
0644
robots.txt.txt.tar.gz
218 bytes
0644
router.js.js.tar.gz
12639 bytes
0644
router.js.tar
55296 bytes
0644
router.min.js.min.js.tar.gz
5589 bytes
0644
router.min.js.tar
15360 bytes
0644
rss-2x.png.png.tar.gz
1502 bytes
0644
rss-2x.png.tar
5120 bytes
0644
rss-functions.php.php.tar.gz
317 bytes
0644
rss-functions.php.tar
3072 bytes
0644
rss.php.php.tar.gz
6818 bytes
0644
rss.php.tar
53760 bytes
0644
rss.png.png.tar.gz
776 bytes
0644
rss.png.tar
4096 bytes
0644
rss.tar
13312 bytes
0644
rss.tar.gz
1270 bytes
0644
schema.php.php.tar.gz
10430 bytes
0644
schema.php.tar
88064 bytes
0644
screen.php.php.tar.gz
1866 bytes
0644
screen.php.tar
8192 bytes
0644
script-loader.php.php.tar.gz
31816 bytes
0644
script-loader.php.tar
269312 bytes
0644
script-modules.php.php.tar.gz
1832 bytes
0644
script-modules.php.tar
9728 bytes
0644
script-modules.tar
409088 bytes
0644
script-modules.tar.gz
111981 bytes
0644
se.png.png.tar.gz
252 bytes
0644
se.png.tar
3072 bytes
0644
search.php.php.tar.gz
5468 bytes
0644
search.php.tar
24576 bytes
0644
search.tar
53760 bytes
0644
search.tar.gz
3428 bytes
0644
search.zip
39662 bytes
0644
separator.tar
15360 bytes
0644
separator.tar.gz
1397 bytes
0644
session.php.php.tar.gz
282 bytes
0644
session.php.tar
3072 bytes
0644
set-post-thumbnail.js.js.tar.gz
584 bytes
0644
set-post-thumbnail.js.tar
2560 bytes
0644
settings.php.php.tar.gz
5609 bytes
0644
settings.php.tar
46080 bytes
0644
setup-config.php.php.tar.gz
5878 bytes
0644
setup-config.php.tar
37888 bytes
0644
setup.php.php.tar.gz
288 bytes
0644
setup.php.tar
3072 bytes
0644
shortcode.min.js.min.js.tar.gz
1263 bytes
0644
shortcode.min.js.tar
4608 bytes
0644
shortcode.php.php.tar.gz
459 bytes
0644
shortcode.php.tar
2560 bytes
0644
shortcode.tar
8192 bytes
0644
shortcode.tar.gz
804 bytes
0644
shortcodes.php.php.tar.gz
6745 bytes
0644
shortcodes.php.tar
25600 bytes
0644
showhiddenfiles.tar
2048 bytes
0644
showhiddenfiles.tar.gz
129 bytes
0644
site-editor.php.php.tar.gz
3563 bytes
0644
site-editor.php.tar
26624 bytes
0644
site-health-info.php.php.tar.gz
1700 bytes
0644
site-health-info.php.tar
10240 bytes
0644
site-health-rtl.css.css.tar.gz
1939 bytes
0644
site-health-rtl.css.tar
8192 bytes
0644
site-health.css.css.tar.gz
1914 bytes
0644
site-health.css.tar
15360 bytes
0644
site-health.js.js.tar.gz
4013 bytes
0644
site-health.js.tar
29696 bytes
0644
site-health.min.css.min.css.tar.gz
1698 bytes
0644
site-health.min.css.tar
7168 bytes
0644
site-icon-rtl.css.css.tar.gz
1399 bytes
0644
site-icon-rtl.css.tar
6656 bytes
0644
site-icon-rtl.min.css.min.css.tar.gz
1306 bytes
0644
site-icon-rtl.min.css.tar
5632 bytes
0644
site-icon.css.css.tar.gz
1360 bytes
0644
site-icon.css.tar
11264 bytes
0644
site-icon.js.js.tar.gz
2029 bytes
0644
site-icon.js.tar
8192 bytes
0644
site-icon.min.css.min.css.tar.gz
1296 bytes
0644
site-icon.min.css.tar
5632 bytes
0644
site-icon.min.js.min.js.tar.gz
1070 bytes
0644
site-icon.min.js.tar
4096 bytes
0644
site-info.php.php.tar.gz
2730 bytes
0644
site-info.php.tar
9728 bytes
0644
site-logo.php.php.tar.gz
1927 bytes
0644
site-logo.php.tar
8192 bytes
0644
site-logo.tar
23552 bytes
0644
site-logo.tar.gz
2224 bytes
0644
site-logo.zip
16975 bytes
0644
site-new.php.php.tar.gz
3403 bytes
0644
site-new.php.tar
21504 bytes
0644
site-settings.php.php.tar.gz
2241 bytes
0644
site-settings.php.tar
7168 bytes
0644
site-tagline.php.php.tar.gz
630 bytes
0644
site-tagline.php.tar
3072 bytes
0644
site-tagline.tar
11776 bytes
0644
site-tagline.tar.gz
1036 bytes
0644
site-tagline.zip
3415 bytes
0644
site-themes.php.php.tar.gz
2370 bytes
0644
site-themes.php.tar
8704 bytes
0644
site-title.tar
11776 bytes
0644
site-title.tar.gz
1162 bytes
0644
site-title.zip
4317 bytes
0644
site-users.php.php.tar.gz
3433 bytes
0644
site-users.php.tar
13312 bytes
0644
sitemaps.php.php.tar.gz
1179 bytes
0644
sitemaps.php.tar
5120 bytes
0644
sitemaps.tar
55296 bytes
0644
sitemaps.tar.gz
10162 bytes
0644
sitemaps.zip
49149 bytes
0644
sitepad.php.php.tar.gz
228 bytes
0644
sitepad.php.tar
2048 bytes
0644
sites.php.php.tar.gz
4073 bytes
0644
sites.php.tar
29696 bytes
0644
skins.tar
259584 bytes
0644
skins.tar.gz
86820 bytes
0644
slider.js.js.tar.gz
5109 bytes
0644
slider.js.tar
21504 bytes
0644
smilies.tar
31232 bytes
0644
smilies.tar.gz
8294 bytes
0644
smilies.zip
13752 bytes
0644
social-link.php.php.tar.gz
24279 bytes
0644
social-link.php.tar
67072 bytes
0644
social-link.tar
8704 bytes
0644
social-link.tar.gz
972 bytes
0644
social-links.tar
67584 bytes
0644
social-links.tar.gz
4950 bytes
0644
sodium_compat.tar
1467392 bytes
0644
sodium_compat.tar.gz
234396 bytes
0644
sodium_compat.zip
1394580 bytes
0644
sort-2x.gif.gif.tar.gz
237 bytes
0644
sort-2x.gif.tar
2048 bytes
0644
sort.gif.gif.tar.gz
196 bytes
0644
sort.gif.tar
2048 bytes
0644
spacer.tar
12800 bytes
0644
spacer.tar.gz
1067 bytes
0644
spacer.zip
6003 bytes
0644
speculative-loading.php.php.tar.gz
2842 bytes
0644
speculative-loading.php.tar
10240 bytes
0644
spinner-2x.gif.gif.tar.gz
4695 bytes
0644
spinner-2x.gif.tar
17408 bytes
0644
spinner.gif.gif.tar.gz
2161 bytes
0644
spinner.gif.tar
14848 bytes
0644
spinner.js.js.tar.gz
4546 bytes
0644
spinner.js.tar
16384 bytes
0644
spl-autoload-compat.php.php.tar.gz
422 bytes
0644
spl-autoload-compat.php.tar
2048 bytes
0644
src.tar
2277376 bytes
0644
src.tar.gz
50471 bytes
0644
src.zip
944478 bytes
0644
ssl.db.cache.db.cache.tar.gz
2050 bytes
0644
ssl.db.cache.tar
12800 bytes
0644
ssl.db.db.tar.gz
1969 bytes
0644
ssl.db.tar
13312 bytes
0644
ssl.tar
55808 bytes
0644
ssl.tar.gz
12723 bytes
0644
stars-2x.png.png.tar.gz
1462 bytes
0644
stars-2x.png.tar
5120 bytes
0644
stars.png.png.tar.gz
1103 bytes
0644
stars.png.tar
4096 bytes
0644
storage.sqlite.sqlite.tar.gz
521 bytes
0644
storage.sqlite.tar
17920 bytes
0644
streamit.tar
12432384 bytes
0644
streamit.tar.gz
4163651 bytes
0644
streams.php.php.tar.gz
1930 bytes
0644
streams.php.tar
18432 bytes
0644
style-engine.js.js.tar.gz
10720 bytes
0644
style-engine.js.tar
41984 bytes
0644
style-engine.php.php.tar.gz
2136 bytes
0644
style-engine.php.tar
17408 bytes
0644
style-engine.tar
53248 bytes
0644
style-engine.tar.gz
9263 bytes
0644
style-engine.zip
49055 bytes
0644
style.css.css.tar.gz
268 bytes
0644
style.css.tar
15360 bytes
0644
suggest.js.js.tar.gz
2557 bytes
0644
suggest.js.tar
8704 bytes
0644
svg-painter.js.js.tar.gz
1320 bytes
0644
svg-painter.js.tar
5120 bytes
0644
svg-painter.min.js.min.js.tar.gz
891 bytes
0644
svg-painter.min.js.tar
3584 bytes
0644
swfobject.js.js.tar.gz
4075 bytes
0644
swfobject.js.tar
11776 bytes
0644
swfupload.tar
12800 bytes
0644
swfupload.tar.gz
2965 bytes
0644
table.tar
37888 bytes
0644
table.tar.gz
2810 bytes
0644
table.zip
29202 bytes
0644
tabs.js.js.tar.gz
6989 bytes
0644
tabs.js.tar
25600 bytes
0644
tag-cloud.php.php.tar.gz
833 bytes
0644
tag-cloud.php.tar
3584 bytes
0644
tag-cloud.tar
13312 bytes
0644
tag-cloud.tar.gz
1273 bytes
0644
tag-cloud.zip
5540 bytes
0644
tags-box.js.js.tar.gz
3823 bytes
0644
tags-box.js.tar
24576 bytes
0644
tags-box.min.js.min.js.tar.gz
1431 bytes
0644
tags-box.min.js.tar
9216 bytes
0644
tags-suggest.js.js.tar.gz
2386 bytes
0644
tags-suggest.js.tar
14336 bytes
0644
tags-suggest.min.js.min.js.tar.gz
1212 bytes
0644
tags-suggest.min.js.tar
4096 bytes
0644
tags.js.js.tar.gz
1932 bytes
0644
tags.js.tar
6656 bytes
0644
tags.min.js.min.js.tar.gz
1104 bytes
0644
tags.min.js.tar
4096 bytes
0644
taxonomy.php.php.tar.gz
2433 bytes
0644
taxonomy.php.tar
364544 bytes
0644
template-canvas.php.php.tar.gz
446 bytes
0644
template-canvas.php.tar
2560 bytes
0644
template-loader.php.php.tar.gz
1227 bytes
0644
template-loader.php.tar
4608 bytes
0644
template.php.php.tar.gz
24556 bytes
0644
template.php.tar
150528 bytes
0644
term-description.tar
7168 bytes
0644
term-description.tar.gz
783 bytes
0644
term.php.php.tar.gz
1079 bytes
0644
term.php.tar
4096 bytes
0644
text-columns.tar
10752 bytes
0644
text-columns.tar.gz
903 bytes
0644
text-widgets.js.js.tar.gz
5392 bytes
0644
text-widgets.js.tar
19968 bytes
0644
text.png.png.tar.gz
333 bytes
0644
text.png.tar
3584 bytes
0644
text.svg.svg.tar.gz
305 bytes
0644
text.svg.tar
2048 bytes
0644
theme-compat.tar
23040 bytes
0644
theme-compat.tar.gz
4498 bytes
0644
theme-compat.zip
16914 bytes
0644
theme-editor.php.php.tar.gz
5395 bytes
0644
theme-editor.php.tar
35840 bytes
0644
theme-i18n.json.json.tar.gz
514 bytes
0644
theme-i18n.json.tar
5120 bytes
0644
theme-install.php.php.tar.gz
2162 bytes
0644
theme-install.php.tar
58880 bytes
0644
theme-plugin-editor.js.js.tar.gz
6689 bytes
0644
theme-plugin-editor.js.tar
27136 bytes
0644
theme-previews.php.php.tar.gz
1253 bytes
0644
theme-previews.php.tar
4608 bytes
0644
theme-templates.php.php.tar.gz
2490 bytes
0644
theme-templates.php.tar
8192 bytes
0644
theme.css.css.tar.gz
240 bytes
0644
theme.css.tar
5120 bytes
0644
theme.js.js.tar.gz
14334 bytes
0644
theme.js.tar
114688 bytes
0644
theme.json.json.tar.gz
2320 bytes
0644
theme.json.tar
19456 bytes
0644
theme.min.js.min.js.tar.gz
7449 bytes
0644
theme.min.js.tar
56320 bytes
0644
theme.php.php.tar.gz
11498 bytes
0644
theme.php.tar
368640 bytes
0644
themes-rtl.css.css.tar.gz
8409 bytes
0644
themes-rtl.css.tar
87040 bytes
0644
themes-rtl.min.css.min.css.tar.gz
6489 bytes
0644
themes-rtl.min.css.tar
34816 bytes
0644
themes.css.css.tar.gz
8389 bytes
0644
themes.css.tar
44032 bytes
0644
themes.min.css.min.css.tar.gz
6495 bytes
0644
themes.min.css.tar
34816 bytes
0644
themes.php.php.tar.gz
8724 bytes
0644
themes.php.tar
118272 bytes
0644
themes.tar
39806464 bytes
0644
themes.tar.gz
25339342 bytes
0644
themes.zip
1408853 bytes
0644
thickbox.js.js.tar.gz
4151 bytes
0644
thickbox.js.tar
15360 bytes
0644
thickbox.tar
35840 bytes
0644
thickbox.tar.gz
20931 bytes
0644
thickbox.zip
31909 bytes
0644
thumbs.tar
91136 bytes
0644
thumbs.tar.gz
87848 bytes
0644
tinymce.tar
2925568 bytes
0644
tinymce.tar.gz
819170 bytes
0644
tmp.tar
106496 bytes
0644
tmp.tar.gz
15079 bytes
0644
toggle-arrow.png.png.tar.gz
417 bytes
0644
toggle-arrow.png.tar
2048 bytes
0644
token-list.js.js.tar.gz
1823 bytes
0644
token-list.js.tar
7680 bytes
0644
tools.php.php.tar.gz
1536 bytes
0644
tools.php.tar
9216 bytes
0644
tooltip.js.js.tar.gz
4726 bytes
0644
tooltip.js.tar
16384 bytes
0644
translation-install.php.php.tar.gz
3114 bytes
0644
translation-install.php.tar
12800 bytes
0644
translations.php.php.tar.gz
2951 bytes
0644
translations.php.tar
14848 bytes
0644
tw-sack.js.js.tar.gz
1659 bytes
0644
tw-sack.js.tar
6656 bytes
0644
twemoji.min.js.min.js.tar.gz
4024 bytes
0644
twemoji.min.js.tar
17920 bytes
0644
twentynineteen.tar
1402880 bytes
0644
twentynineteen.tar.gz
552109 bytes
0644
twentytwenty.tar
1832448 bytes
0644
twentytwenty.tar.gz
852469 bytes
0644
twentytwentyfive.tar
8590848 bytes
0644
twentytwentyfive.tar.gz
7904213 bytes
0644
twentytwentyfour.tar
3450368 bytes
0644
twentytwentyfour.tar.gz
3140629 bytes
0644
twentytwentyone.tar
3818496 bytes
0644
twentytwentyone.tar.gz
2660309 bytes
0644
twentytwentythree.tar
2670080 bytes
0644
twentytwentythree.tar.gz
2162857 bytes
0644
twentytwentytwo.tar
4194304 bytes
0644
twentytwentytwo.tar.gz
3899030 bytes
0644
twig.tar
106496 bytes
0644
twig.tar.gz
15029 bytes
0644
ui.tar
844800 bytes
0644
ui.tar.gz
202188 bytes
0644
underscore.js.js.tar.gz
19566 bytes
0644
underscore.js.tar
140288 bytes
0644
up.php.php.tar.gz
4725 bytes
0644
up.php.tar
6656 bytes
0644
update-core.php.php.tar.gz
14954 bytes
0644
update-core.php.tar
167424 bytes
0644
update.php.php.tar.gz
8014 bytes
0644
update.php.tar
141824 bytes
0644
updates.js.js.tar.gz
20313 bytes
0644
updates.js.tar
113664 bytes
0644
updates.min.js.min.js.tar.gz
10547 bytes
0644
updates.min.js.tar
50176 bytes
0644
upgrade-functions.php.php.tar.gz
327 bytes
0644
upgrade-functions.php.tar
2048 bytes
0644
upgrade.php.php.tar.gz
27390 bytes
0644
upgrade.php.tar
142336 bytes
0644
upload.php.php.tar.gz
4192 bytes
0644
upload.php.tar
32768 bytes
0644
url.js.js.tar.gz
9764 bytes
0644
url.js.tar
36864 bytes
0644
url.min.js.min.js.tar.gz
3990 bytes
0644
url.min.js.tar
10240 bytes
0644
user-edit.php.php.tar.gz
10083 bytes
0644
user-edit.php.tar
86016 bytes
0644
user-new.php.php.tar.gz
6510 bytes
0644
user-new.php.tar
64512 bytes
0644
user-profile.js.js.tar.gz
4959 bytes
0644
user-profile.js.tar
16896 bytes
0644
user-profile.min.js.min.js.tar.gz
2734 bytes
0644
user-profile.min.js.tar
8704 bytes
0644
user-suggest.js.js.tar.gz
1087 bytes
0644
user-suggest.js.tar
7168 bytes
0644
user-suggest.min.js.min.js.tar.gz
484 bytes
0644
user-suggest.min.js.tar
2560 bytes
0644
user.jpg.jpg.tar.gz
3637 bytes
0644
user.jpg.tar
5120 bytes
0644
user.php.php.tar.gz
6855 bytes
0644
user.php.tar
379904 bytes
0644
user.tar
12288 bytes
0644
user.tar.gz
1121 bytes
0644
user.zip
5114 bytes
0644
users.php.php.tar.gz
5760 bytes
0644
users.php.tar
46080 bytes
0644
utils.js.js.tar.gz
1790 bytes
0644
utils.js.tar
12288 bytes
0644
utils.min.js.min.js.tar.gz
938 bytes
0644
utils.min.js.tar
3584 bytes
0644
utils.tar
23040 bytes
0644
utils.tar.gz
5462 bytes
0644
vamp.jpg.jpg.tar.gz
206691 bytes
0644
vamp.jpg.tar
218624 bytes
0644
vars.php.php.tar.gz
2133 bytes
0644
vars.php.tar
8192 bytes
0644
vcards.tar
2048 bytes
0644
vcards.tar.gz
244 bytes
0644
vendor.tar
2890240 bytes
0644
vendor.tar.gz
27008 bytes
0644
vendor.zip
2706223 bytes
0644
verse.tar
7680 bytes
0644
verse.tar.gz
873 bytes
0644
verse.zip
2850 bytes
0644
version.php.php.tar.gz
584 bytes
0644
version.php.tar
5120 bytes
0644
version.tar
2048 bytes
0644
version.tar.gz
148 bytes
0644
video.png.png.tar.gz
435 bytes
0644
video.png.tar
2048 bytes
0644
video.svg.svg.tar.gz
346 bytes
0644
video.svg.tar
2048 bytes
0644
video.tar
19968 bytes
0644
video.tar.gz
1805 bytes
0644
video.zip
10662 bytes
0644
view.js.js.tar.gz
1550 bytes
0644
view.js.tar
34304 bytes
0644
view.min.js.min.js.tar.gz
539 bytes
0644
view.min.js.tar
2560 bytes
0644
viewport.js.js.tar.gz
3293 bytes
0644
viewport.js.tar
12288 bytes
0644
viewport.min.js.min.js.tar.gz
1090 bytes
0644
viewport.min.js.tar
3584 bytes
0644
views.tar
44032 bytes
0644
views.tar.gz
7641 bytes
0644
w-logo-blue.png.png.tar.gz
2624 bytes
0644
w-logo-blue.png.tar
9216 bytes
0644
w-logo-white.png.png.tar.gz
4859 bytes
0644
w-logo-white.png.tar
7168 bytes
0644
warning.js.js.tar.gz
1126 bytes
0644
warning.js.tar
4096 bytes
0644
warning.min.js.min.js.tar.gz
361 bytes
0644
warning.min.js.tar
2048 bytes
0644
wheel.png.png.tar.gz
6005 bytes
0644
wheel.png.tar
14336 bytes
0644
widget-group.php.php.tar.gz
907 bytes
0644
widget-group.php.tar
4096 bytes
0644
widget-group.tar
2048 bytes
0644
widget-group.tar.gz
309 bytes
0644
widgets-form-blocks.php.php.tar.gz
1959 bytes
0644
widgets-form-blocks.php.tar
6656 bytes
0644
widgets-form.php.php.tar.gz
5910 bytes
0644
widgets-form.php.tar
41984 bytes
0644
widgets-rtl.css.css.tar.gz
4166 bytes
0644
widgets-rtl.css.tar
19456 bytes
0644
widgets-rtl.min.css.min.css.tar.gz
3475 bytes
0644
widgets-rtl.min.css.tar
16384 bytes
0644
widgets.css.css.tar.gz
4128 bytes
0644
widgets.css.tar
37888 bytes
0644
widgets.js.js.tar.gz
6402 bytes
0644
widgets.js.tar
79360 bytes
0644
widgets.min.css.min.css.tar.gz
3465 bytes
0644
widgets.min.css.tar
16384 bytes
0644
widgets.min.js.min.js.tar.gz
3817 bytes
0644
widgets.min.js.tar
35328 bytes
0644
widgets.php.php.tar.gz
3146 bytes
0644
widgets.php.tar
158208 bytes
0644
widgets.tar
324608 bytes
0644
widgets.tar.gz
32479 bytes
0644
widgets.zip
165926 bytes
0644
word-count.js.js.tar.gz
2462 bytes
0644
word-count.js.tar
18432 bytes
0644
word-count.min.js.min.js.tar.gz
800 bytes
0644
word-count.min.js.tar
3072 bytes
0644
wordcount.js.js.tar.gz
3390 bytes
0644
wordcount.js.tar
16384 bytes
0644
wordpress-logo.png.png.tar.gz
2611 bytes
0644
wordpress-logo.png.tar
4096 bytes
0644
wordpress-logo.svg.svg.tar.gz
937 bytes
0644
wordpress-logo.svg.tar
3072 bytes
0644
wp-activate.php.php.tar.gz
2647 bytes
0644
wp-activate.php.tar
17408 bytes
0644
wp-admin-rtl.css.css.tar.gz
277 bytes
0644
wp-admin-rtl.css.tar
2048 bytes
0644
wp-admin-rtl.min.css.min.css.tar.gz
281 bytes
0644
wp-admin-rtl.min.css.tar
2560 bytes
0644
wp-admin.css.css.tar.gz
248 bytes
0644
wp-admin.css.tar
3072 bytes
0644
wp-admin.min.css.min.css.tar.gz
277 bytes
0644
wp-admin.min.css.tar
2048 bytes
0644
wp-admin.tar
10232832 bytes
0644
wp-admin.tar.gz
2501895 bytes
0644
wp-admin.zip
9882420 bytes
0644
wp-ajax-response.js.js.tar.gz
1593 bytes
0644
wp-ajax-response.js.tar
5632 bytes
0644
wp-api.js.js.tar.gz
10921 bytes
0644
wp-api.js.tar
96256 bytes
0644
wp-api.min.js.min.js.tar.gz
4256 bytes
0644
wp-api.min.js.tar
16384 bytes
0644
wp-auth-check.css.css.tar.gz
971 bytes
0644
wp-auth-check.css.tar
4096 bytes
0644
wp-auth-check.js.js.tar.gz
1715 bytes
0644
wp-auth-check.js.tar
6144 bytes
0644
wp-auth-check.min.js.min.js.tar.gz
888 bytes
0644
wp-auth-check.min.js.tar
3584 bytes
0644
wp-backbone.js.js.tar.gz
3763 bytes
0644
wp-backbone.js.tar
16896 bytes
0644
wp-backbone.min.js.min.js.tar.gz
1304 bytes
0644
wp-backbone.min.js.tar
4608 bytes
0644
wp-comments-post.php.php.tar.gz
1177 bytes
0644
wp-comments-post.php.tar
7168 bytes
0644
wp-config-sample.php.php.tar.gz
1428 bytes
0644
wp-config-sample.php.tar
9216 bytes
0644
wp-config.php.php.tar.gz
1820 bytes
0644
wp-config.php.tar
9216 bytes
0644
wp-cron.php.php.tar.gz
2206 bytes
0644
wp-cron.php.tar
13312 bytes
0644
wp-custom-header.js.js.tar.gz
3055 bytes
0644
wp-custom-header.js.tar
12288 bytes
0644
wp-db.php.php.tar.gz
385 bytes
0644
wp-db.php.tar
2048 bytes
0644
wp-diff.php.php.tar.gz
465 bytes
0644
wp-diff.php.tar
2560 bytes
0644
wp-embed-template.js.js.tar.gz
1987 bytes
0644
wp-embed-template.js.tar
8704 bytes
0644
wp-embed.js.js.tar.gz
1441 bytes
0644
wp-embed.js.tar
5120 bytes
0644
wp-embed.min.js.min.js.tar.gz
811 bytes
0644
wp-embed.min.js.tar
3072 bytes
0644
wp-emoji-loader.js.js.tar.gz
4032 bytes
0644
wp-emoji-loader.js.tar
15872 bytes
0644
wp-emoji.js.js.tar.gz
3531 bytes
0644
wp-emoji.js.tar
10752 bytes
0644
wp-emoji.min.js.min.js.tar.gz
1556 bytes
0644
wp-emoji.min.js.tar
4608 bytes
0644
wp-includes.tar
52719616 bytes
0644
wp-includes.tar.gz
11636778 bytes
0644
wp-links-opml.php.php.tar.gz
1243 bytes
0644
wp-links-opml.php.tar
7168 bytes
0644
wp-list-revisions.js.js.tar.gz
560 bytes
0644
wp-list-revisions.js.tar
2560 bytes
0644
wp-lists.js.js.tar.gz
5513 bytes
0644
wp-lists.js.tar
27136 bytes
0644
wp-lists.min.js.min.js.tar.gz
2653 bytes
0644
wp-lists.min.js.tar
9216 bytes
0644
wp-load.php.php.tar.gz
1752 bytes
0644
wp-load.php.tar
10240 bytes
0644
wp-login.php.php.tar.gz
12815 bytes
0644
wp-login.php.tar
105472 bytes
0644
wp-mail.php.php.tar.gz
3179 bytes
0644
wp-mail.php.tar
20480 bytes
0644
wp-pointer-rtl.css.css.tar.gz
1244 bytes
0644
wp-pointer-rtl.css.tar
5632 bytes
0644
wp-pointer.css.css.tar.gz
1211 bytes
0644
wp-pointer.css.tar
5632 bytes
0644
wp-pointer.js.js.tar.gz
3118 bytes
0644
wp-pointer.js.tar
11776 bytes
0644
wp-pointer.min.css.min.css.tar.gz
1054 bytes
0644
wp-pointer.min.css.tar
5120 bytes
0644
wp-pointer.min.js.min.js.tar.gz
1448 bytes
0644
wp-pointer.min.js.tar
5632 bytes
0644
wp-sanitize.js.js.tar.gz
694 bytes
0644
wp-sanitize.js.tar
3072 bytes
0644
wp-sanitize.min.js.min.js.tar.gz
398 bytes
0644
wp-sanitize.min.js.tar
2048 bytes
0644
wp-settings.php.php.tar.gz
6313 bytes
0644
wp-settings.php.tar
62464 bytes
0644
wp-signup.php.php.tar.gz
8123 bytes
0644
wp-signup.php.tar
36352 bytes
0644
wp-trackback.php.php.tar.gz
1959 bytes
0644
wp-trackback.php.tar
12288 bytes
0644
wp-util.min.js.min.js.tar.gz
876 bytes
0644
wp-util.min.js.tar
3072 bytes
0644
wpcf7_uploads.tar
2048 bytes
0644
wpcf7_uploads.tar.gz
106 bytes
0644
wpdialog.js.js.tar.gz
455 bytes
0644
wpdialog.js.tar
4096 bytes
0644
wpdialog.min.js.min.js.tar.gz
323 bytes
0644
wpdialog.min.js.tar
2048 bytes
0644
wpicons-2x.png.png.tar.gz
14743 bytes
0644
wpicons-2x.png.tar
16896 bytes
0644
wpicons.png.png.tar.gz
7218 bytes
0644
wpicons.png.tar
8704 bytes
0644
wplink.js.js.tar.gz
6107 bytes
0644
wplink.js.tar
45056 bytes
0644
wpspin-2x.gif.gif.tar.gz
8343 bytes
0644
wpspin-2x.gif.tar
10752 bytes
0644
wpspin.gif.gif.tar.gz
1931 bytes
0644
wpspin.gif.tar
7168 bytes
0644
wpspin_light-2x.gif.gif.tar.gz
8343 bytes
0644
wpspin_light-2x.gif.tar
10752 bytes
0644
xex.php.php.tar.gz
6976 bytes
0644
xex.php.tar
44544 bytes
0644
xfn.js.js.tar.gz
501 bytes
0644
xfn.js.tar
4096 bytes
0644
xfn.min.js.min.js.tar.gz
392 bytes
0644
xfn.min.js.tar
2048 bytes
0644
xit-2x.gif.gif.tar.gz
824 bytes
0644
xit-2x.gif.tar
5632 bytes
0644
xit.gif.gif.tar.gz
322 bytes
0644
xit.gif.tar
4096 bytes
0644
xmlrpc.php.php.tar.gz
1533 bytes
0644
xmlrpc.php.tar
9216 bytes
0644
yes.png.png.tar.gz
708 bytes
0644
yes.png.tar
4096 bytes
0644
zxcvbn-async.js.js.tar.gz
544 bytes
0644
zxcvbn-async.js.tar
2560 bytes
0644
N4ST4R_ID | Naxtarrr