X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/wordpress.git/blobdiff_plain/e0feb3b2e5b436a06bbb04fbc838d1cd6ec95399..HEAD:/wp-includes/theme.php diff --git a/wp-includes/theme.php b/wp-includes/theme.php index 823d2ca4..84fdd23a 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -151,7 +151,7 @@ function is_child_theme() { */ function get_stylesheet() { /** - * Filter the name of current stylesheet. + * Filters the name of current stylesheet. * * @since 1.5.0 * @@ -173,11 +173,11 @@ function get_stylesheet_directory() { $stylesheet_dir = "$theme_root/$stylesheet"; /** - * Filter the stylesheet directory path for current theme. + * Filters the stylesheet directory path for current theme. * * @since 1.5.0 * - * @param string $stylesheet_dir Absolute path to the current them. + * @param string $stylesheet_dir Absolute path to the current theme. * @param string $stylesheet Directory name of the current theme. * @param string $theme_root Absolute path to themes directory. */ @@ -197,7 +197,7 @@ function get_stylesheet_directory_uri() { $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; /** - * Filter the stylesheet directory URI. + * Filters the stylesheet directory URI. * * @since 1.5.0 * @@ -209,10 +209,10 @@ function get_stylesheet_directory_uri() { } /** - * Retrieve URI of current theme stylesheet. + * Retrieves the URI of current theme stylesheet. * - * The stylesheet file name is 'style.css' which is appended to {@link - * get_stylesheet_directory_uri() stylesheet directory URI} path. + * 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 * @@ -222,7 +222,7 @@ function get_stylesheet_uri() { $stylesheet_dir_uri = get_stylesheet_directory_uri(); $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; /** - * Filter the URI of the current theme stylesheet. + * Filters the URI of the current theme stylesheet. * * @since 1.5.0 * @@ -233,7 +233,7 @@ function get_stylesheet_uri() { } /** - * Retrieve localized stylesheet 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 @@ -241,7 +241,8 @@ function get_stylesheet_uri() { * stylesheet will be checked for existence, for example 'ltr.css'. * * The theme may change the location of the stylesheet directory by either using - * the 'stylesheet_directory_uri' filter or the 'locale_stylesheet_uri' filter. + * 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. @@ -264,7 +265,7 @@ function get_locale_stylesheet_uri() { else $stylesheet_uri = ''; /** - * Filter the localized stylesheet URI. + * Filters the localized stylesheet URI. * * @since 2.1.0 * @@ -283,7 +284,7 @@ function get_locale_stylesheet_uri() { */ function get_template() { /** - * Filter the name of the current theme. + * Filters the name of the current theme. * * @since 1.5.0 * @@ -305,7 +306,7 @@ function get_template_directory() { $template_dir = "$theme_root/$template"; /** - * Filter the current theme directory path. + * Filters the current theme directory path. * * @since 1.5.0 * @@ -329,7 +330,7 @@ function get_template_directory_uri() { $template_dir_uri = "$theme_root_uri/$template"; /** - * Filter the current theme directory URI. + * Filters the current theme directory URI. * * @since 1.5.0 * @@ -434,7 +435,7 @@ function search_theme_directories( $force = false ) { } /** - * Filter whether to get the cache of the registered theme directories. + * Filters whether to get the cache of the registered theme directories. * * @since 3.4.0 * @@ -551,7 +552,7 @@ function get_theme_root( $stylesheet_or_template = false ) { } /** - * Filter the absolute path to the themes directory. + * Filters the absolute path to the themes directory. * * @since 1.5.0 * @@ -600,7 +601,7 @@ function get_theme_root_uri( $stylesheet_or_template = false, $theme_root = fals } /** - * Filter the URI for themes directory. + * Filters the URI for themes directory. * * @since 1.5.0 * @@ -664,7 +665,7 @@ function locale_stylesheet() { * 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 backwards compatibility. + * of two arguments: $template then $stylesheet. This is for backward compatibility. * * @since 2.5.0 * @@ -688,16 +689,16 @@ function switch_theme( $stylesheet ) { set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets ) ); } - $old_theme = wp_get_theme(); - $new_theme = wp_get_theme( $stylesheet ); + $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); if ( func_num_args() > 1 ) { - $template = $stylesheet; $stylesheet = func_get_arg( 1 ); - } else { - $template = $new_theme->get_template(); } + $old_theme = wp_get_theme(); + $new_theme = wp_get_theme( $stylesheet ); + $template = $new_theme->get_template(); + update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); @@ -716,36 +717,51 @@ function switch_theme( $stylesheet ) { // 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 to remove the theme mods to avoid overwriting changes made via + * 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' ); } + + if ( ! empty( $nav_menu_locations ) ) { + $nav_mods = get_theme_mod( 'nav_menu_locations' ); + if ( empty( $nav_mods ) ) { + set_theme_mod( 'nav_menu_locations', $nav_menu_locations ); + } + } } update_option( 'theme_switched', $old_theme->get_stylesheet() ); + /** * Fires after the theme is switched. * * @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 ); + do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } /** * Checks that current theme files 'index.php' and 'style.css' exists. * - * Does not check the default theme, which is the fallback and should always exist. + * 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 current theme does not validate. - * You can use the 'validate_current_theme' filter to return false to + * + * You can use the {@see 'validate_current_theme'} filter to return false to * disable this functionality. * * @since 1.5.0 @@ -755,31 +771,48 @@ function switch_theme( $stylesheet ) { */ function validate_current_theme() { /** - * Filter whether to validate the current theme. + * Filters whether to validate the current theme. * * @since 2.7.0 * - * @param bool true Validation flag to check the current theme. + * @param bool $validate Whether to validate the current theme. Default true. */ - if ( defined('WP_INSTALLING') || ! apply_filters( 'validate_current_theme', true ) ) + if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) return true; - if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { - switch_theme( WP_DEFAULT_THEME ); - return false; + if ( ! 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; } - if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { + $default = wp_get_theme( WP_DEFAULT_THEME ); + if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } - if ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { - 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; } - return true; + switch_theme( $default->get_stylesheet() ); + return false; } /** @@ -809,7 +842,7 @@ function get_theme_mods() { * Retrieve theme modification value for the current theme. * * If the modification name does not exist, then the $default will be passed - * through {@link http://php.net/sprintf sprintf()} PHP function with the first + * through {@link https://secure.php.net/sprintf sprintf()} PHP function with the first * string the template directory URI and the second string the stylesheet * directory URI. * @@ -824,7 +857,7 @@ function get_theme_mod( $name, $default = false ) { if ( isset( $mods[$name] ) ) { /** - * Filter the theme modification, or 'theme_mod', value. + * 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, @@ -858,7 +891,7 @@ function set_theme_mod( $name, $value ) { $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; /** - * Filter the theme mod value on save. + * Filters the 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', @@ -869,7 +902,7 @@ function set_theme_mod( $name, $value ) { * @param string $value The new value of the theme mod. * @param string $old_value The current value of the theme mod. */ - $mods[ $name ] = apply_filters( "pre_set_theme_mod_$name", $value, $old_value ); + $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); $theme = get_option( 'stylesheet' ); update_option( "theme_mods_$theme", $mods ); @@ -917,18 +950,18 @@ function remove_theme_mods() { } /** - * Retrieve text color for custom header. + * Retrieves the custom header text color in HEX format. * * @since 2.1.0 * - * @return string + * @return string Header text color in HEX format (minus the hash symbol). */ function get_header_textcolor() { return get_theme_mod('header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } /** - * Display text color for custom header. + * Displays the custom header text color in HEX format (minus the hash symbol). * * @since 2.1.0 */ @@ -983,6 +1016,84 @@ function get_header_image() { return esc_url_raw( set_url_scheme( $url ) ); } +/** + * Create 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 ); + + $attr = wp_parse_args( + $attr, + array( + 'src' => $header->url, + 'width' => $width, + 'height' => $height, + 'alt' => get_bloginfo( 'name' ), + ) + ); + + // 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 ); + $sizes = ! empty( $attr['sizes'] ) ? $attr['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_map( 'esc_attr', $attr ); + $html = ' $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 ); +} + +/** + * Display 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 ); +} + /** * Get random header image data from registered images in theme. * @@ -1098,7 +1209,7 @@ function get_uploaded_header_images() { foreach ( (array) $headers as $header ) { $url = esc_url_raw( wp_get_attachment_url( $header->ID ) ); $header_data = wp_get_attachment_metadata( $header->ID ); - $header_index = basename($url); + $header_index = $header->ID; $header_images[$header_index] = array(); $header_images[$header_index]['attachment_id'] = $header->ID; @@ -1154,6 +1265,7 @@ function get_custom_header() { '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 ); } @@ -1200,6 +1312,180 @@ function unregister_default_headers( $header ) { } } +/** + * Check 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(); +} + +/* Retrieve header video URL for custom header. + * + * Uses a local video if present, or falls back to an external video. Returns false if there is no video. + * + * @since 4.7.0 + * + * @return string|false + */ +function get_header_video_url() { + $id = absint( get_theme_mod( 'header_video' ) ); + $url = esc_url( get_theme_mod( 'external_header_video' ) ); + + if ( ! $id && ! $url ) { + return false; + } + + if ( $id ) { + // Get the file URL from the attachment ID. + $url = wp_get_attachment_url( $id ); + } + + return esc_url_raw( set_url_scheme( $url ) ); +} + +/** + * Display header video URL. + * + * @since 4.7.0 + */ +function the_header_video_url() { + $video = get_header_video_url(); + if ( $video ) { + echo esc_url( $video ); + } +} + +/** + * Retrieve 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']; + } + + return apply_filters( 'header_video_settings', $settings ); +} + +/** + * Check 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 ); + } + + /** + * Modify 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 ); +} + +/** + * Retrieve 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( + '
+ * 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 );
+ *
+ *
+ * @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.
+ if ( 0 === count( wp_get_post_revisions( $r ) ) ) {
+ wp_save_post_revision( $r );
+ }
+ }
+ }
+
+ if ( is_wp_error( $r ) ) {
+ return $r;
+ }
+ return get_post( $r );
+}
+
/**
* Add callback for custom TinyMCE editor stylesheets.
*
@@ -1394,7 +1909,7 @@ function get_editor_stylesheets() {
}
/**
- * Filter the array of stylesheets applied to the editor.
+ * Filters the array of stylesheets applied to the editor.
*
* @since 4.3.0
*
@@ -1404,17 +1919,295 @@ function get_editor_stylesheets() {
}
/**
- * Allows a theme to register its support of a certain feature
+ * Expand 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' => join( '', array(
+ '' . _x( 'Address', 'Theme starter content' ) . '
',
+ _x( '123 Main Street', 'Theme starter content' ) . '
' . _x( 'New York, NY 10001', 'Theme starter content' ) . '
' . _x( 'Hours', 'Theme starter content' ) . '
',
+ _x( 'Monday—Friday: 9:00AM–5:00PM', 'Theme starter content' ) . '
' . _x( 'Saturday & Sunday: 11:00AM–3:00PM', 'Theme starter content' ) . '
title-tag
', 'wp_loaded
' ), '4.1' );
+ 'title-tag
', 'wp_loaded
' ), '4.1.0' );
return false;
}
@@ -1622,6 +2456,30 @@ function _custom_header_background_just_in_time() {
}
}
+/**
+ * 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 );
+
+ ?>
+
+
+ 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 ) );
+ }
+
+ 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. Ths 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 ) ) {
+ $post = $changeset_post;
+ $post_id = $changeset_post->ID;
+
+ /*
+ * The following re-formulates the logic from wp_trash_post() as done in
+ * wp_publish_post(). The reason for bypassing wp_trash_post() is that it
+ * will mutate the the post_content and the post_name when they should be
+ * untouched.
+ */
+ if ( ! EMPTY_TRASH_DAYS ) {
+ wp_delete_post( $post_id, true );
+ } else {
+ /** This action is documented in wp-includes/post.php */
+ do_action( 'wp_trash_post', $post_id );
+
+ add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
+ add_post_meta( $post_id, '_wp_trash_meta_time', time() );
+
+ $old_status = $post->post_status;
+ $new_status = 'trash';
+ $wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $post->ID ) );
+ clean_post_cache( $post->ID );
+
+ $post->post_status = $new_status;
+ wp_transition_post_status( $new_status, $old_status, $post );
+
+ /** This action is documented in wp-includes/post.php */
+ do_action( 'edit_post', $post->ID, $post );
+
+ /** This action is documented in wp-includes/post.php */
+ do_action( "save_post_{$post->post_type}", $post->ID, $post, true );
+
+ /** This action is documented in wp-includes/post.php */
+ do_action( 'save_post', $post->ID, $post, true );
+
+ /** This action is documented in wp-includes/post.php */
+ do_action( 'wp_insert_post', $post->ID, $post, true );
+
+ /** This action is documented in wp-includes/post.php */
+ do_action( 'trashed_post', $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.
+ * @returns 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;
}
/**
@@ -1967,6 +3002,7 @@ function wp_customize_url( $stylesheet = null ) {
* 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.
*/
function wp_customize_support_script() {
$admin_origin = parse_url( admin_url() );
@@ -1974,20 +3010,28 @@ function wp_customize_support_script() {
$cross_domain = ( strtolower( $admin_origin[ 'host' ] ) != strtolower( $home_origin[ 'host' ] ) );
?>
-
+
+
+
+