From 5bf66662a9bdd62c5bccab15e607cd95cfb8fcab Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Mon, 27 Jul 2020 10:05:23 +0200 Subject: Removed wordpress and phpmyadmin, my server doesn't handle it well and it brings shame on my familly --- .../wp-includes/class-wp-customize-manager.php | 6048 -------------------- 1 file changed, 6048 deletions(-) delete mode 100644 srcs/wordpress/wp-includes/class-wp-customize-manager.php (limited to 'srcs/wordpress/wp-includes/class-wp-customize-manager.php') diff --git a/srcs/wordpress/wp-includes/class-wp-customize-manager.php b/srcs/wordpress/wp-includes/class-wp-customize-manager.php deleted file mode 100644 index 36b9c7b..0000000 --- a/srcs/wordpress/wp-includes/class-wp-customize-manager.php +++ /dev/null @@ -1,6048 +0,0 @@ -original_stylesheet = get_stylesheet(); - $this->theme = wp_get_theme( 0 === validate_file( $args['theme'] ) ? $args['theme'] : null ); - $this->messenger_channel = $args['messenger_channel']; - $this->_changeset_uuid = $args['changeset_uuid']; - - foreach ( array( 'settings_previewed', 'autosaved', 'branching' ) as $key ) { - if ( isset( $args[ $key ] ) ) { - $this->$key = (bool) $args[ $key ]; - } - } - - require_once( ABSPATH . WPINC . '/class-wp-customize-setting.php' ); - require_once( ABSPATH . WPINC . '/class-wp-customize-panel.php' ); - require_once( ABSPATH . WPINC . '/class-wp-customize-section.php' ); - require_once( ABSPATH . WPINC . '/class-wp-customize-control.php' ); - - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-code-editor-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); // @todo Remove in a future release. See #42364. - - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' ); - - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-panel.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); // @todo Remove in a future release. See #42364. - - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php' ); - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php' ); - - /** - * Filters the core Customizer components to load. - * - * This allows Core components to be excluded from being instantiated by - * filtering them out of the array. Note that this filter generally runs - * during the {@see 'plugins_loaded'} action, so it cannot be added - * in a theme. - * - * @since 4.4.0 - * - * @see WP_Customize_Manager::__construct() - * - * @param string[] $components Array of core components to load. - * @param WP_Customize_Manager $this WP_Customize_Manager instance. - */ - $components = apply_filters( 'customize_loaded_components', $this->components, $this ); - - require_once( ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php' ); - $this->selective_refresh = new WP_Customize_Selective_Refresh( $this ); - - if ( in_array( 'widgets', $components, true ) ) { - require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' ); - $this->widgets = new WP_Customize_Widgets( $this ); - } - - if ( in_array( 'nav_menus', $components, true ) ) { - require_once( ABSPATH . WPINC . '/class-wp-customize-nav-menus.php' ); - $this->nav_menus = new WP_Customize_Nav_Menus( $this ); - } - - add_action( 'setup_theme', array( $this, 'setup_theme' ) ); - add_action( 'wp_loaded', array( $this, 'wp_loaded' ) ); - - // Do not spawn cron (especially the alternate cron) while running the Customizer. - remove_action( 'init', 'wp_cron' ); - - // Do not run update checks when rendering the controls. - remove_action( 'admin_init', '_maybe_update_core' ); - remove_action( 'admin_init', '_maybe_update_plugins' ); - remove_action( 'admin_init', '_maybe_update_themes' ); - - add_action( 'wp_ajax_customize_save', array( $this, 'save' ) ); - add_action( 'wp_ajax_customize_trash', array( $this, 'handle_changeset_trash_request' ) ); - add_action( 'wp_ajax_customize_refresh_nonces', array( $this, 'refresh_nonces' ) ); - add_action( 'wp_ajax_customize_load_themes', array( $this, 'handle_load_themes_request' ) ); - add_filter( 'heartbeat_settings', array( $this, 'add_customize_screen_to_heartbeat_settings' ) ); - add_filter( 'heartbeat_received', array( $this, 'check_changeset_lock_with_heartbeat' ), 10, 3 ); - add_action( 'wp_ajax_customize_override_changeset_lock', array( $this, 'handle_override_changeset_lock_request' ) ); - add_action( 'wp_ajax_customize_dismiss_autosave_or_lock', array( $this, 'handle_dismiss_autosave_or_lock_request' ) ); - - add_action( 'customize_register', array( $this, 'register_controls' ) ); - add_action( 'customize_register', array( $this, 'register_dynamic_settings' ), 11 ); // allow code to create settings first - add_action( 'customize_controls_init', array( $this, 'prepare_controls' ) ); - add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_control_scripts' ) ); - - // Render Common, Panel, Section, and Control templates. - add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_panel_templates' ), 1 ); - add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_section_templates' ), 1 ); - add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_control_templates' ), 1 ); - - // Export header video settings with the partial response. - add_filter( 'customize_render_partials_response', array( $this, 'export_header_video_settings' ), 10, 3 ); - - // Export the settings to JS via the _wpCustomizeSettings variable. - add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_pane_settings' ), 1000 ); - - // Add theme update notices. - if ( current_user_can( 'install_themes' ) || current_user_can( 'update_themes' ) ) { - require_once ABSPATH . 'wp-admin/includes/update.php'; - add_action( 'customize_controls_print_footer_scripts', 'wp_print_admin_notice_templates' ); - } - } - - /** - * Return true if it's an Ajax request. - * - * @since 3.4.0 - * @since 4.2.0 Added `$action` param. - * - * @param string|null $action Whether the supplied Ajax action is being run. - * @return bool True if it's an Ajax request, false otherwise. - */ - public function doing_ajax( $action = null ) { - if ( ! wp_doing_ajax() ) { - return false; - } - - if ( ! $action ) { - return true; - } else { - /* - * Note: we can't just use doing_action( "wp_ajax_{$action}" ) because we need - * to check before admin-ajax.php gets to that point. - */ - return isset( $_REQUEST['action'] ) && wp_unslash( $_REQUEST['action'] ) === $action; - } - } - - /** - * Custom wp_die wrapper. Returns either the standard message for UI - * or the Ajax message. - * - * @since 3.4.0 - * - * @param mixed $ajax_message Ajax return - * @param mixed $message UI message - */ - protected function wp_die( $ajax_message, $message = null ) { - if ( $this->doing_ajax() ) { - wp_die( $ajax_message ); - } - - if ( ! $message ) { - $message = __( 'Something went wrong.' ); - } - - if ( $this->messenger_channel ) { - ob_start(); - wp_enqueue_scripts(); - wp_print_scripts( array( 'customize-base' ) ); - - $settings = array( - 'messengerArgs' => array( - 'channel' => $this->messenger_channel, - 'url' => wp_customize_url(), - ), - 'error' => $ajax_message, - ); - ?> - - doing_ajax() || isset( $_POST['customized'] ) ) { - return '_ajax_wp_die_handler'; - } - - return '_default_wp_die_handler'; - } - - /** - * Start preview and customize theme. - * - * Check if customize query variable exist. Init filters to filter the current theme. - * - * @since 3.4.0 - * - * @global string $pagenow - */ - public function setup_theme() { - global $pagenow; - - // Check permissions for customize.php access since this method is called before customize.php can run any code, - if ( 'customize.php' === $pagenow && ! current_user_can( 'customize' ) ) { - if ( ! is_user_logged_in() ) { - auth_redirect(); - } else { - wp_die( - '

' . __( 'You need a higher level of permission.' ) . '

' . - '

' . __( 'Sorry, you are not allowed to customize this site.' ) . '

', - 403 - ); - } - return; - } - - // If a changeset was provided is invalid. - if ( isset( $this->_changeset_uuid ) && false !== $this->_changeset_uuid && ! wp_is_uuid( $this->_changeset_uuid ) ) { - $this->wp_die( -1, __( 'Invalid changeset UUID' ) ); - } - - /* - * Clear incoming post data if the user lacks a CSRF token (nonce). Note that the customizer - * application will inject the customize_preview_nonce query parameter into all Ajax requests. - * For similar behavior elsewhere in WordPress, see rest_cookie_check_errors() which logs out - * a user when a valid nonce isn't present. - */ - $has_post_data_nonce = ( - check_ajax_referer( 'preview-customize_' . $this->get_stylesheet(), 'nonce', false ) - || - check_ajax_referer( 'save-customize_' . $this->get_stylesheet(), 'nonce', false ) - || - check_ajax_referer( 'preview-customize_' . $this->get_stylesheet(), 'customize_preview_nonce', false ) - ); - if ( ! current_user_can( 'customize' ) || ! $has_post_data_nonce ) { - unset( $_POST['customized'] ); - unset( $_REQUEST['customized'] ); - } - - /* - * If unauthenticated then require a valid changeset UUID to load the preview. - * In this way, the UUID serves as a secret key. If the messenger channel is present, - * then send unauthenticated code to prompt re-auth. - */ - if ( ! current_user_can( 'customize' ) && ! $this->changeset_post_id() ) { - $this->wp_die( $this->messenger_channel ? 0 : -1, __( 'Non-existent changeset UUID.' ) ); - } - - if ( ! headers_sent() ) { - send_origin_headers(); - } - - // Hide the admin bar if we're embedded in the customizer iframe. - if ( $this->messenger_channel ) { - show_admin_bar( false ); - } - - if ( $this->is_theme_active() ) { - // Once the theme is loaded, we'll validate it. - add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) ); - } else { - // If the requested theme is not the active theme and the user doesn't have the - // switch_themes cap, bail. - if ( ! current_user_can( 'switch_themes' ) ) { - $this->wp_die( -1, __( 'Sorry, you are not allowed to edit theme options on this site.' ) ); - } - - // If the theme has errors while loading, bail. - if ( $this->theme()->errors() ) { - $this->wp_die( -1, $this->theme()->errors()->get_error_message() ); - } - - // If the theme isn't allowed per multisite settings, bail. - if ( ! $this->theme()->is_allowed() ) { - $this->wp_die( -1, __( 'The requested theme does not exist.' ) ); - } - } - - // Make sure changeset UUID is established immediately after the theme is loaded. - add_action( 'after_setup_theme', array( $this, 'establish_loaded_changeset' ), 5 ); - - /* - * Import theme starter content for fresh installations when landing in the customizer. - * Import starter content at after_setup_theme:100 so that any - * add_theme_support( 'starter-content' ) calls will have been made. - */ - if ( get_option( 'fresh_site' ) && 'customize.php' === $pagenow ) { - add_action( 'after_setup_theme', array( $this, 'import_theme_starter_content' ), 100 ); - } - - $this->start_previewing_theme(); - } - - /** - * Establish the loaded changeset. - * - * This method runs right at after_setup_theme and applies the 'customize_changeset_branching' filter to determine - * whether concurrent changesets are allowed. Then if the Customizer is not initialized with a `changeset_uuid` param, - * this method will determine which UUID should be used. If changeset branching is disabled, then the most saved - * changeset will be loaded by default. Otherwise, if there are no existing saved changesets or if changeset branching is - * enabled, then a new UUID will be generated. - * - * @since 4.9.0 - * @global string $pagenow - */ - public function establish_loaded_changeset() { - global $pagenow; - - if ( empty( $this->_changeset_uuid ) ) { - $changeset_uuid = null; - - if ( ! $this->branching() && $this->is_theme_active() ) { - $unpublished_changeset_posts = $this->get_changeset_posts( - array( - 'post_status' => array_diff( get_post_stati(), array( 'auto-draft', 'publish', 'trash', 'inherit', 'private' ) ), - 'exclude_restore_dismissed' => false, - 'author' => 'any', - 'posts_per_page' => 1, - 'order' => 'DESC', - 'orderby' => 'date', - ) - ); - $unpublished_changeset_post = array_shift( $unpublished_changeset_posts ); - if ( ! empty( $unpublished_changeset_post ) && wp_is_uuid( $unpublished_changeset_post->post_name ) ) { - $changeset_uuid = $unpublished_changeset_post->post_name; - } - } - - // If no changeset UUID has been set yet, then generate a new one. - if ( empty( $changeset_uuid ) ) { - $changeset_uuid = wp_generate_uuid4(); - } - - $this->_changeset_uuid = $changeset_uuid; - } - - if ( is_admin() && 'customize.php' === $pagenow ) { - $this->set_changeset_lock( $this->changeset_post_id() ); - } - } - - /** - * Callback to validate a theme once it is loaded - * - * @since 3.4.0 - */ - public function after_setup_theme() { - $doing_ajax_or_is_customized = ( $this->doing_ajax() || isset( $_POST['customized'] ) ); - if ( ! $doing_ajax_or_is_customized && ! validate_current_theme() ) { - wp_redirect( 'themes.php?broken=true' ); - exit; - } - } - - /** - * If the theme to be previewed isn't the active theme, add filter callbacks - * to swap it out at runtime. - * - * @since 3.4.0 - */ - public function start_previewing_theme() { - // Bail if we're already previewing. - if ( $this->is_preview() ) { - return; - } - - $this->previewing = true; - - if ( ! $this->is_theme_active() ) { - add_filter( 'template', array( $this, 'get_template' ) ); - add_filter( 'stylesheet', array( $this, 'get_stylesheet' ) ); - add_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) ); - - // @link: https://core.trac.wordpress.org/ticket/20027 - add_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) ); - add_filter( 'pre_option_template', array( $this, 'get_template' ) ); - - // Handle custom theme roots. - add_filter( 'pre_option_stylesheet_root', array( $this, 'get_stylesheet_root' ) ); - add_filter( 'pre_option_template_root', array( $this, 'get_template_root' ) ); - } - - /** - * Fires once the Customizer theme preview has started. - * - * @since 3.4.0 - * - * @param WP_Customize_Manager $this WP_Customize_Manager instance. - */ - do_action( 'start_previewing_theme', $this ); - } - - /** - * Stop previewing the selected theme. - * - * Removes filters to change the current theme. - * - * @since 3.4.0 - */ - public function stop_previewing_theme() { - if ( ! $this->is_preview() ) { - return; - } - - $this->previewing = false; - - if ( ! $this->is_theme_active() ) { - remove_filter( 'template', array( $this, 'get_template' ) ); - remove_filter( 'stylesheet', array( $this, 'get_stylesheet' ) ); - remove_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) ); - - // @link: https://core.trac.wordpress.org/ticket/20027 - remove_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) ); - remove_filter( 'pre_option_template', array( $this, 'get_template' ) ); - - // Handle custom theme roots. - remove_filter( 'pre_option_stylesheet_root', array( $this, 'get_stylesheet_root' ) ); - remove_filter( 'pre_option_template_root', array( $this, 'get_template_root' ) ); - } - - /** - * Fires once the Customizer theme preview has stopped. - * - * @since 3.4.0 - * - * @param WP_Customize_Manager $this WP_Customize_Manager instance. - */ - do_action( 'stop_previewing_theme', $this ); - } - - /** - * Gets whether settings are or will be previewed. - * - * @since 4.9.0 - * @see WP_Customize_Setting::preview() - * - * @return bool - */ - public function settings_previewed() { - return $this->settings_previewed; - } - - /** - * Gets whether data from a changeset's autosaved revision should be loaded if it exists. - * - * @since 4.9.0 - * @see WP_Customize_Manager::changeset_data() - * - * @return bool Is using autosaved changeset revision. - */ - public function autosaved() { - return $this->autosaved; - } - - /** - * Whether the changeset branching is allowed. - * - * @since 4.9.0 - * @see WP_Customize_Manager::establish_loaded_changeset() - * - * @return bool Is changeset branching. - */ - public function branching() { - - /** - * Filters whether or not changeset branching is allowed. - * - * By default in core, when changeset branching is not allowed, changesets will operate - * linearly in that only one saved changeset will exist at a time (with a 'draft' or - * 'future' status). This makes the Customizer operate in a way that is similar to going to - * "edit" to one existing post: all users will be making changes to the same post, and autosave - * revisions will be made for that post. - * - * By contrast, when changeset branching is allowed, then the model is like users going - * to "add new" for a page and each user makes changes independently of each other since - * they are all operating on their own separate pages, each getting their own separate - * initial auto-drafts and then once initially saved, autosave revisions on top of that - * user's specific post. - * - * Since linear changesets are deemed to be more suitable for the majority of WordPress users, - * they are the default. For WordPress sites that have heavy site management in the Customizer - * by multiple users then branching changesets should be enabled by means of this filter. - * - * @since 4.9.0 - * - * @param bool $allow_branching Whether branching is allowed. If `false`, the default, - * then only one saved changeset exists at a time. - * @param WP_Customize_Manager $wp_customize Manager instance. - */ - $this->branching = apply_filters( 'customize_changeset_branching', $this->branching, $this ); - - return $this->branching; - } - - /** - * Get the changeset UUID. - * - * @since 4.7.0 - * @see WP_Customize_Manager::establish_loaded_changeset() - * - * @return string UUID. - */ - public function changeset_uuid() { - if ( empty( $this->_changeset_uuid ) ) { - $this->establish_loaded_changeset(); - } - return $this->_changeset_uuid; - } - - /** - * Get the theme being customized. - * - * @since 3.4.0 - * - * @return WP_Theme - */ - public function theme() { - if ( ! $this->theme ) { - $this->theme = wp_get_theme(); - } - return $this->theme; - } - - /** - * Get the registered settings. - * - * @since 3.4.0 - * - * @return array - */ - public function settings() { - return $this->settings; - } - - /** - * Get the registered controls. - * - * @since 3.4.0 - * - * @return array - */ - public function controls() { - return $this->controls; - } - - /** - * Get the registered containers. - * - * @since 4.0.0 - * - * @return array - */ - public function containers() { - return $this->containers; - } - - /** - * Get the registered sections. - * - * @since 3.4.0 - * - * @return array - */ - public function sections() { - return $this->sections; - } - - /** - * Get the registered panels. - * - * @since 4.0.0 - * - * @return array Panels. - */ - public function panels() { - return $this->panels; - } - - /** - * Checks if the current theme is active. - * - * @since 3.4.0 - * - * @return bool - */ - public function is_theme_active() { - return $this->get_stylesheet() == $this->original_stylesheet; - } - - /** - * Register styles/scripts and initialize the preview of each setting - * - * @since 3.4.0 - */ - public function wp_loaded() { - - // Unconditionally register core types for panels, sections, and controls in case plugin unhooks all customize_register actions. - $this->register_panel_type( 'WP_Customize_Panel' ); - $this->register_panel_type( 'WP_Customize_Themes_Panel' ); - $this->register_section_type( 'WP_Customize_Section' ); - $this->register_section_type( 'WP_Customize_Sidebar_Section' ); - $this->register_section_type( 'WP_Customize_Themes_Section' ); - $this->register_control_type( 'WP_Customize_Color_Control' ); - $this->register_control_type( 'WP_Customize_Media_Control' ); - $this->register_control_type( 'WP_Customize_Upload_Control' ); - $this->register_control_type( 'WP_Customize_Image_Control' ); - $this->register_control_type( 'WP_Customize_Background_Image_Control' ); - $this->register_control_type( 'WP_Customize_Background_Position_Control' ); - $this->register_control_type( 'WP_Customize_Cropped_Image_Control' ); - $this->register_control_type( 'WP_Customize_Site_Icon_Control' ); - $this->register_control_type( 'WP_Customize_Theme_Control' ); - $this->register_control_type( 'WP_Customize_Code_Editor_Control' ); - $this->register_control_type( 'WP_Customize_Date_Time_Control' ); - - /** - * Fires once WordPress has loaded, allowing scripts and styles to be initialized. - * - * @since 3.4.0 - * - * @param WP_Customize_Manager $this WP_Customize_Manager instance. - */ - do_action( 'customize_register', $this ); - - if ( $this->settings_previewed() ) { - foreach ( $this->settings as $setting ) { - $setting->preview(); - } - } - - if ( $this->is_preview() && ! is_admin() ) { - $this->customize_preview_init(); - } - } - - /** - * Prevents Ajax requests from following redirects when previewing a theme - * by issuing a 200 response instead of a 30x. - * - * Instead, the JS will sniff out the location header. - * - * @since 3.4.0 - * @deprecated 4.7.0 - * - * @param int $status Status. - * @return int - */ - public function wp_redirect_status( $status ) { - _deprecated_function( __FUNCTION__, '4.7.0' ); - - if ( $this->is_preview() && ! is_admin() ) { - return 200; - } - - return $status; - } - - /** - * Find the changeset post ID for a given changeset UUID. - * - * @since 4.7.0 - * - * @param string $uuid Changeset UUID. - * @return int|null Returns post ID on success and null on failure. - */ - public function find_changeset_post_id( $uuid ) { - $cache_group = 'customize_changeset_post'; - $changeset_post_id = wp_cache_get( $uuid, $cache_group ); - if ( $changeset_post_id && 'customize_changeset' === get_post_type( $changeset_post_id ) ) { - return $changeset_post_id; - } - - $changeset_post_query = new WP_Query( - array( - 'post_type' => 'customize_changeset', - 'post_status' => get_post_stati(), - 'name' => $uuid, - 'posts_per_page' => 1, - 'no_found_rows' => true, - 'cache_results' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'lazy_load_term_meta' => false, - ) - ); - if ( ! empty( $changeset_post_query->posts ) ) { - // Note: 'fields'=>'ids' is not being used in order to cache the post object as it will be needed. - $changeset_post_id = $changeset_post_query->posts[0]->ID; - wp_cache_set( $uuid, $changeset_post_id, $cache_group ); - return $changeset_post_id; - } - - return null; - } - - /** - * Get changeset posts. - * - * @since 4.9.0 - * - * @param array $args { - * Args to pass into `get_posts()` to query changesets. - * - * @type int $posts_per_page Number of posts to return. Defaults to -1 (all posts). - * @type int $author Post author. Defaults to current user. - * @type string $post_status Status of changeset. Defaults to 'auto-draft'. - * @type bool $exclude_restore_dismissed Whether to exclude changeset auto-drafts that have been dismissed. Defaults to true. - * } - * @return WP_Post[] Auto-draft changesets. - */ - protected function get_changeset_posts( $args = array() ) { - $default_args = array( - 'exclude_restore_dismissed' => true, - 'posts_per_page' => -1, - 'post_type' => 'customize_changeset', - 'post_status' => 'auto-draft', - 'order' => 'DESC', - 'orderby' => 'date', - 'no_found_rows' => true, - 'cache_results' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'lazy_load_term_meta' => false, - ); - if ( get_current_user_id() ) { - $default_args['author'] = get_current_user_id(); - } - $args = array_merge( $default_args, $args ); - - if ( ! empty( $args['exclude_restore_dismissed'] ) ) { - unset( $args['exclude_restore_dismissed'] ); - $args['meta_query'] = array( - array( - 'key' => '_customize_restore_dismissed', - 'compare' => 'NOT EXISTS', - ), - ); - } - - return get_posts( $args ); - } - - /** - * Dismiss all of the current user's auto-drafts (other than the present one). - * - * @since 4.9.0 - * @return int The number of auto-drafts that were dismissed. - */ - protected function dismiss_user_auto_draft_changesets() { - $changeset_autodraft_posts = $this->get_changeset_posts( - array( - 'post_status' => 'auto-draft', - 'exclude_restore_dismissed' => true, - 'posts_per_page' => -1, - ) - ); - $dismissed = 0; - foreach ( $changeset_autodraft_posts as $autosave_autodraft_post ) { - if ( $autosave_autodraft_post->ID === $this->changeset_post_id() ) { - continue; - } - if ( update_post_meta( $autosave_autodraft_post->ID, '_customize_restore_dismissed', true ) ) { - $dismissed++; - } - } - return $dismissed; - } - - /** - * Get the changeset post id for the loaded changeset. - * - * @since 4.7.0 - * - * @return int|null Post ID on success or null if there is no post yet saved. - */ - public function changeset_post_id() { - if ( ! isset( $this->_changeset_post_id ) ) { - $post_id = $this->find_changeset_post_id( $this->changeset_uuid() ); - if ( ! $post_id ) { - $post_id = false; - } - $this->_changeset_post_id = $post_id; - } - if ( false === $this->_changeset_post_id ) { - return null; - } - return $this->_changeset_post_id; - } - - /** - * Get the data stored in a changeset post. - * - * @since 4.7.0 - * - * @param int $post_id Changeset post ID. - * @return array|WP_Error Changeset data or WP_Error on error. - */ - protected function get_changeset_post_data( $post_id ) { - if ( ! $post_id ) { - return new WP_Error( 'empty_post_id' ); - } - $changeset_post = get_post( $post_id ); - if ( ! $changeset_post ) { - return new WP_Error( 'missing_post' ); - } - if ( 'revision' === $changeset_post->post_type ) { - if ( 'customize_changeset' !== get_post_type( $changeset_post->post_parent ) ) { - return new WP_Error( 'wrong_post_type' ); - } - } elseif ( 'customize_changeset' !== $changeset_post->post_type ) { - return new WP_Error( 'wrong_post_type' ); - } - $changeset_data = json_decode( $changeset_post->post_content, true ); - $last_error = json_last_error(); - if ( $last_error ) { - return new WP_Error( 'json_parse_error', '', $last_error ); - } - if ( ! is_array( $changeset_data ) ) { - return new WP_Error( 'expected_array' ); - } - return $changeset_data; - } - - /** - * Get changeset data. - * - * @since 4.7.0 - * @since 4.9.0 This will return the changeset's data with a user's autosave revision merged on top, if one exists and $autosaved is true. - * - * @return array Changeset data. - */ - public function changeset_data() { - if ( isset( $this->_changeset_data ) ) { - return $this->_changeset_data; - } - $changeset_post_id = $this->changeset_post_id(); - if ( ! $changeset_post_id ) { - $this->_changeset_data = array(); - } else { - if ( $this->autosaved() && is_user_logged_in() ) { - $autosave_post = wp_get_post_autosave( $changeset_post_id, get_current_user_id() ); - if ( $autosave_post ) { - $data = $this->get_changeset_post_data( $autosave_post->ID ); - if ( ! is_wp_error( $data ) ) { - $this->_changeset_data = $data; - } - } - } - - // Load data from the changeset if it was not loaded from an autosave. - if ( ! isset( $this->_changeset_data ) ) { - $data = $this->get_changeset_post_data( $changeset_post_id ); - if ( ! is_wp_error( $data ) ) { - $this->_changeset_data = $data; - } else { - $this->_changeset_data = array(); - } - } - } - return $this->_changeset_data; - } - - /** - * Starter content setting IDs. - * - * @since 4.7.0 - * @var array - */ - protected $pending_starter_content_settings_ids = array(); - - /** - * Import theme starter content into the customized state. - * - * @since 4.7.0 - * - * @param array $starter_content Starter content. Defaults to `get_theme_starter_content()`. - */ - function import_theme_starter_content( $starter_content = array() ) { - if ( empty( $starter_content ) ) { - $starter_content = get_theme_starter_content(); - } - - $changeset_data = array(); - if ( $this->changeset_post_id() ) { - /* - * Don't re-import starter content into a changeset saved persistently. - * This will need to be revisited in the future once theme switching - * is allowed with drafted/scheduled changesets, since switching to - * another theme could result in more starter content being applied. - * However, when doing an explicit save it is currently possible for - * nav menus and nav menu items specifically to lose their starter_content - * flags, thus resulting in duplicates being created since they fail - * to get re-used. See #40146. - */ - if ( 'auto-draft' !== get_post_status( $this->changeset_post_id() ) ) { - return; - } - - $changeset_data = $this->get_changeset_post_data( $this->changeset_post_id() ); - } - - $sidebars_widgets = isset( $starter_content['widgets'] ) && ! empty( $this->widgets ) ? $starter_content['widgets'] : array(); - $attachments = isset( $starter_content['attachments'] ) && ! empty( $this->nav_menus ) ? $starter_content['attachments'] : array(); - $posts = isset( $starter_content['posts'] ) && ! empty( $this->nav_menus ) ? $starter_content['posts'] : array(); - $options = isset( $starter_content['options'] ) ? $starter_content['options'] : array(); - $nav_menus = isset( $starter_content['nav_menus'] ) && ! empty( $this->nav_menus ) ? $starter_content['nav_menus'] : array(); - $theme_mods = isset( $starter_content['theme_mods'] ) ? $starter_content['theme_mods'] : array(); - - // Widgets. - $max_widget_numbers = array(); - foreach ( $sidebars_widgets as $sidebar_id => $widgets ) { - $sidebar_widget_ids = array(); - foreach ( $widgets as $widget ) { - list( $id_base, $instance ) = $widget; - - if ( ! isset( $max_widget_numbers[ $id_base ] ) ) { - - // When $settings is an array-like object, get an intrinsic array for use with array_keys(). - $settings = get_option( "widget_{$id_base}", array() ); - if ( $settings instanceof ArrayObject || $settings instanceof ArrayIterator ) { - $settings = $settings->getArrayCopy(); - } - - // Find the max widget number for this type. - $widget_numbers = array_keys( $settings ); - if ( count( $widget_numbers ) > 0 ) { - $widget_numbers[] = 1; - $max_widget_numbers[ $id_base ] = max( ...$widget_numbers ); - } else { - $max_widget_numbers[ $id_base ] = 1; - } - } - $max_widget_numbers[ $id_base ] += 1; - - $widget_id = sprintf( '%s-%d', $id_base, $max_widget_numbers[ $id_base ] ); - $setting_id = sprintf( 'widget_%s[%d]', $id_base, $max_widget_numbers[ $id_base ] ); - - $setting_value = $this->widgets->sanitize_widget_js_instance( $instance ); - if ( empty( $changeset_data[ $setting_id ] ) || ! empty( $changeset_data[ $setting_id ]['starter_content'] ) ) { - $this->set_post_value( $setting_id, $setting_value ); - $this->pending_starter_content_settings_ids[] = $setting_id; - } - $sidebar_widget_ids[] = $widget_id; - } - - $setting_id = sprintf( 'sidebars_widgets[%s]', $sidebar_id ); - if ( empty( $changeset_data[ $setting_id ] ) || ! empty( $changeset_data[ $setting_id ]['starter_content'] ) ) { - $this->set_post_value( $setting_id, $sidebar_widget_ids ); - $this->pending_starter_content_settings_ids[] = $setting_id; - } - } - - $starter_content_auto_draft_post_ids = array(); - if ( ! empty( $changeset_data['nav_menus_created_posts']['value'] ) ) { - $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, $changeset_data['nav_menus_created_posts']['value'] ); - } - - // Make an index of all the posts needed and what their slugs are. - $needed_posts = array(); - $attachments = $this->prepare_starter_content_attachments( $attachments ); - foreach ( $attachments as $attachment ) { - $key = 'attachment:' . $attachment['post_name']; - $needed_posts[ $key ] = true; - } - foreach ( array_keys( $posts ) as $post_symbol ) { - if ( empty( $posts[ $post_symbol ]['post_name'] ) && empty( $posts[ $post_symbol ]['post_title'] ) ) { - unset( $posts[ $post_symbol ] ); - continue; - } - if ( empty( $posts[ $post_symbol ]['post_name'] ) ) { - $posts[ $post_symbol ]['post_name'] = sanitize_title( $posts[ $post_symbol ]['post_title'] ); - } - if ( empty( $posts[ $post_symbol ]['post_type'] ) ) { - $posts[ $post_symbol ]['post_type'] = 'post'; - } - $needed_posts[ $posts[ $post_symbol ]['post_type'] . ':' . $posts[ $post_symbol ]['post_name'] ] = true; - } - $all_post_slugs = array_merge( - wp_list_pluck( $attachments, 'post_name' ), - wp_list_pluck( $posts, 'post_name' ) - ); - - /* - * Obtain all post types referenced in starter content to use in query. - * This is needed because 'any' will not account for post types not yet registered. - */ - $post_types = array_filter( array_merge( array( 'attachment' ), wp_list_pluck( $posts, 'post_type' ) ) ); - - // Re-use auto-draft starter content posts referenced in the current customized state. - $existing_starter_content_posts = array(); - if ( ! empty( $starter_content_auto_draft_post_ids ) ) { - $existing_posts_query = new WP_Query( - array( - 'post__in' => $starter_content_auto_draft_post_ids, - 'post_status' => 'auto-draft', - 'post_type' => $post_types, - 'posts_per_page' => -1, - ) - ); - foreach ( $existing_posts_query->posts as $existing_post ) { - $post_name = $existing_post->post_name; - if ( empty( $post_name ) ) { - $post_name = get_post_meta( $existing_post->ID, '_customize_draft_post_name', true ); - } - $existing_starter_content_posts[ $existing_post->post_type . ':' . $post_name ] = $existing_post; - } - } - - // Re-use non-auto-draft posts. - if ( ! empty( $all_post_slugs ) ) { - $existing_posts_query = new WP_Query( - array( - 'post_name__in' => $all_post_slugs, - 'post_status' => array_diff( get_post_stati(), array( 'auto-draft' ) ), - 'post_type' => 'any', - 'posts_per_page' => -1, - ) - ); - foreach ( $existing_posts_query->posts as $existing_post ) { - $key = $existing_post->post_type . ':' . $existing_post->post_name; - if ( isset( $needed_posts[ $key ] ) && ! isset( $existing_starter_content_posts[ $key ] ) ) { - $existing_starter_content_posts[ $key ] = $existing_post; - } - } - } - - // Attachments are technically posts but handled differently. - if ( ! empty( $attachments ) ) { - - $attachment_ids = array(); - - foreach ( $attachments as $symbol => $attachment ) { - $file_array = array( - 'name' => $attachment['file_name'], - ); - $file_path = $attachment['file_path']; - $attachment_id = null; - $attached_file = null; - if ( isset( $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ] ) ) { - $attachment_post = $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ]; - $attachment_id = $attachment_post->ID; - $attached_file = get_attached_file( $attachment_id ); - if ( empty( $attached_file ) || ! file_exists( $attached_file ) ) { - $attachment_id = null; - $attached_file = null; - } elseif ( $this->get_stylesheet() !== get_post_meta( $attachment_post->ID, '_starter_content_theme', true ) ) { - - // Re-generate attachment metadata since it was previously generated for a different theme. - $metadata = wp_generate_attachment_metadata( $attachment_post->ID, $attached_file ); - wp_update_attachment_metadata( $attachment_id, $metadata ); - update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() ); - } - } - - // Insert the attachment auto-draft because it doesn't yet exist or the attached file is gone. - if ( ! $attachment_id ) { - - // Copy file to temp location so that original file won't get deleted from theme after sideloading. - $temp_file_name = wp_tempnam( wp_basename( $file_path ) ); - if ( $temp_file_name && copy( $file_path, $temp_file_name ) ) { - $file_array['tmp_name'] = $temp_file_name; - } - if ( empty( $file_array['tmp_name'] ) ) { - continue; - } - - $attachment_post_data = array_merge( - wp_array_slice_assoc( $attachment, array( 'post_title', 'post_content', 'post_excerpt' ) ), - array( - 'post_status' => 'auto-draft', // So attachment will be garbage collected in a week if changeset is never published. - ) - ); - - $attachment_id = media_handle_sideload( $file_array, 0, null, $attachment_post_data ); - if ( is_wp_error( $attachment_id ) ) { - continue; - } - update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() ); - update_post_meta( $attachment_id, '_customize_draft_post_name', $attachment['post_name'] ); - } - - $attachment_ids[ $symbol ] = $attachment_id; - } - $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) ); - } - - // Posts & pages. - if ( ! empty( $posts ) ) { - foreach ( array_keys( $posts ) as $post_symbol ) { - if ( empty( $posts[ $post_symbol ]['post_type'] ) || empty( $posts[ $post_symbol ]['post_name'] ) ) { - continue; - } - $post_type = $posts[ $post_symbol ]['post_type']; - if ( ! empty( $posts[ $post_symbol ]['post_name'] ) ) { - $post_name = $posts[ $post_symbol ]['post_name']; - } elseif ( ! empty( $posts[ $post_symbol ]['post_title'] ) ) { - $post_name = sanitize_title( $posts[ $post_symbol ]['post_title'] ); - } else { - continue; - } - - // Use existing auto-draft post if one already exists with the same type and name. - if ( isset( $existing_starter_content_posts[ $post_type . ':' . $post_name ] ) ) { - $posts[ $post_symbol ]['ID'] = $existing_starter_content_posts[ $post_type . ':' . $post_name ]->ID; - continue; - } - - // Translate the featured image symbol. - if ( ! empty( $posts[ $post_symbol ]['thumbnail'] ) - && preg_match( '/^{{(?P.+)}}$/', $posts[ $post_symbol ]['thumbnail'], $matches ) - && isset( $attachment_ids[ $matches['symbol'] ] ) ) { - $posts[ $post_symbol ]['meta_input']['_thumbnail_id'] = $attachment_ids[ $matches['symbol'] ]; - } - - if ( ! empty( $posts[ $post_symbol ]['template'] ) ) { - $posts[ $post_symbol ]['meta_input']['_wp_page_template'] = $posts[ $post_symbol ]['template']; - } - - $r = $this->nav_menus->insert_auto_draft_post( $posts[ $post_symbol ] ); - if ( $r instanceof WP_Post ) { - $posts[ $post_symbol ]['ID'] = $r->ID; - } - } - - $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, wp_list_pluck( $posts, 'ID' ) ); - } - - // The nav_menus_created_posts setting is why nav_menus component is dependency for adding posts. - if ( ! empty( $this->nav_menus ) && ! empty( $starter_content_auto_draft_post_ids ) ) { - $setting_id = 'nav_menus_created_posts'; - $this->set_post_value( $setting_id, array_unique( array_values( $starter_content_auto_draft_post_ids ) ) ); - $this->pending_starter_content_settings_ids[] = $setting_id; - } - - // Nav menus. - $placeholder_id = -1; - $reused_nav_menu_setting_ids = array(); - foreach ( $nav_menus as $nav_menu_location => $nav_menu ) { - - $nav_menu_term_id = null; - $nav_menu_setting_id = null; - $matches = array(); - - // Look for an existing placeholder menu with starter content to re-use. - foreach ( $changeset_data as $setting_id => $setting_params ) { - $can_reuse = ( - ! empty( $setting_params['starter_content'] ) - && - ! in_array( $setting_id, $reused_nav_menu_setting_ids, true ) - && - preg_match( '#^nav_menu\[(?P-?\d+)\]$#', $setting_id, $matches ) - ); - if ( $can_reuse ) { - $nav_menu_term_id = intval( $matches['nav_menu_id'] ); - $nav_menu_setting_id = $setting_id; - $reused_nav_menu_setting_ids[] = $setting_id; - break; - } - } - - if ( ! $nav_menu_term_id ) { - while ( isset( $changeset_data[ sprintf( 'nav_menu[%d]', $placeholder_id ) ] ) ) { - $placeholder_id--; - } - $nav_menu_term_id = $placeholder_id; - $nav_menu_setting_id = sprintf( 'nav_menu[%d]', $placeholder_id ); - } - - $this->set_post_value( - $nav_menu_setting_id, - array( - 'name' => isset( $nav_menu['name'] ) ? $nav_menu['name'] : $nav_menu_location, - ) - ); - $this->pending_starter_content_settings_ids[] = $nav_menu_setting_id; - - // @todo Add support for menu_item_parent. - $position = 0; - foreach ( $nav_menu['items'] as $nav_menu_item ) { - $nav_menu_item_setting_id = sprintf( 'nav_menu_item[%d]', $placeholder_id-- ); - if ( ! isset( $nav_menu_item['position'] ) ) { - $nav_menu_item['position'] = $position++; - } - $nav_menu_item['nav_menu_term_id'] = $nav_menu_term_id; - - if ( isset( $nav_menu_item['object_id'] ) ) { - if ( 'post_type' === $nav_menu_item['type'] && preg_match( '/^{{(?P.+)}}$/', $nav_menu_item['object_id'], $matches ) && isset( $posts[ $matches['symbol'] ] ) ) { - $nav_menu_item['object_id'] = $posts[ $matches['symbol'] ]['ID']; - if ( empty( $nav_menu_item['title'] ) ) { - $original_object = get_post( $nav_menu_item['object_id'] ); - $nav_menu_item['title'] = $original_object->post_title; - } - } else { - continue; - } - } else { - $nav_menu_item['object_id'] = 0; - } - - if ( empty( $changeset_data[ $nav_menu_item_setting_id ] ) || ! empty( $changeset_data[ $nav_menu_item_setting_id ]['starter_content'] ) ) { - $this->set_post_value( $nav_menu_item_setting_id, $nav_menu_item ); - $this->pending_starter_content_settings_ids[] = $nav_menu_item_setting_id; - } - } - - $setting_id = sprintf( 'nav_menu_locations[%s]', $nav_menu_location ); - if ( empty( $changeset_data[ $setting_id ] ) || ! empty( $changeset_data[ $setting_id ]['starter_content'] ) ) { - $this->set_post_value( $setting_id, $nav_menu_term_id ); - $this->pending_starter_content_settings_ids[] = $setting_id; - } - } - - // Options. - foreach ( $options as $name => $value ) { - - // Serialize the value to check for post symbols. - $value = maybe_serialize( $value ); - - if ( is_serialized( $value ) ) { - if ( preg_match( '/s:\d+:"{{(?P.+)}}"/', $value, $matches ) ) { - if ( isset( $posts[ $matches['symbol'] ] ) ) { - $symbol_match = $posts[ $matches['symbol'] ]['ID']; - } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { - $symbol_match = $attachment_ids[ $matches['symbol'] ]; - } - - // If we have any symbol matches, update the values. - if ( isset( $symbol_match ) ) { - // Replace found string matches with post IDs. - $value = str_replace( $matches[0], "i:{$symbol_match}", $value ); - } else { - continue; - } - } - } elseif ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) ) { - if ( isset( $posts[ $matches['symbol'] ] ) ) { - $value = $posts[ $matches['symbol'] ]['ID']; - } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { - $value = $attachment_ids[ $matches['symbol'] ]; - } else { - continue; - } - } - - // Unserialize values after checking for post symbols, so they can be properly referenced. - $value = maybe_unserialize( $value ); - - if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) { - $this->set_post_value( $name, $value ); - $this->pending_starter_content_settings_ids[] = $name; - } - } - - // Theme mods. - foreach ( $theme_mods as $name => $value ) { - - // Serialize the value to check for post symbols. - $value = maybe_serialize( $value ); - - // Check if value was serialized. - if ( is_serialized( $value ) ) { - if ( preg_match( '/s:\d+:"{{(?P.+)}}"/', $value, $matches ) ) { - if ( isset( $posts[ $matches['symbol'] ] ) ) { - $symbol_match = $posts[ $matches['symbol'] ]['ID']; - } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { - $symbol_match = $attachment_ids[ $matches['symbol'] ]; - } - - // If we have any symbol matches, update the values. - if ( isset( $symbol_match ) ) { - // Replace found string matches with post IDs. - $value = str_replace( $matches[0], "i:{$symbol_match}", $value ); - } else { - continue; - } - } - } elseif ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) ) { - if ( isset( $posts[ $matches['symbol'] ] ) ) { - $value = $posts[ $matches['symbol'] ]['ID']; - } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { - $value = $attachment_ids[ $matches['symbol'] ]; - } else { - continue; - } - } - - // Unserialize values after checking for post symbols, so they can be properly referenced. - $value = maybe_unserialize( $value ); - - // Handle header image as special case since setting has a legacy format. - if ( 'header_image' === $name ) { - $name = 'header_image_data'; - $metadata = wp_get_attachment_metadata( $value ); - if ( empty( $metadata ) ) { - continue; - } - $value = array( - 'attachment_id' => $value, - 'url' => wp_get_attachment_url( $value ), - 'height' => $metadata['height'], - 'width' => $metadata['width'], - ); - } elseif ( 'background_image' === $name ) { - $value = wp_get_attachment_url( $value ); - } - - if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) { - $this->set_post_value( $name, $value ); - $this->pending_starter_content_settings_ids[] = $name; - } - } - - if ( ! empty( $this->pending_starter_content_settings_ids ) ) { - if ( did_action( 'customize_register' ) ) { - $this->_save_starter_content_changeset(); - } else { - add_action( 'customize_register', array( $this, '_save_starter_content_changeset' ), 1000 ); - } - } - } - - /** - * Prepare starter content attachments. - * - * Ensure that the attachments are valid and that they have slugs and file name/path. - * - * @since 4.7.0 - * - * @param array $attachments Attachments. - * @return array Prepared attachments. - */ - protected function prepare_starter_content_attachments( $attachments ) { - $prepared_attachments = array(); - if ( empty( $attachments ) ) { - return $prepared_attachments; - } - - // Such is The WordPress Way. - require_once( ABSPATH . 'wp-admin/includes/file.php' ); - require_once( ABSPATH . 'wp-admin/includes/media.php' ); - require_once( ABSPATH . 'wp-admin/includes/image.php' ); - - foreach ( $attachments as $symbol => $attachment ) { - - // A file is required and URLs to files are not currently allowed. - if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) { - continue; - } - - $file_path = null; - if ( file_exists( $attachment['file'] ) ) { - $file_path = $attachment['file']; // Could be absolute path to file in plugin. - } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) { - $file_path = get_stylesheet_directory() . '/' . $attachment['file']; - } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) { - $file_path = get_template_directory() . '/' . $attachment['file']; - } else { - continue; - } - $file_name = wp_basename( $attachment['file'] ); - - // Skip file types that are not recognized. - $checked_filetype = wp_check_filetype( $file_name ); - if ( empty( $checked_filetype['type'] ) ) { - continue; - } - - // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts. - if ( empty( $attachment['post_name'] ) ) { - if ( ! empty( $attachment['post_title'] ) ) { - $attachment['post_name'] = sanitize_title( $attachment['post_title'] ); - } else { - $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_name ) ); - } - } - - $attachment['file_name'] = $file_name; - $attachment['file_path'] = $file_path; - $prepared_attachments[ $symbol ] = $attachment; - } - return $prepared_attachments; - } - - /** - * Save starter content changeset. - * - * @since 4.7.0 - */ - public function _save_starter_content_changeset() { - - if ( empty( $this->pending_starter_content_settings_ids ) ) { - return; - } - - $this->save_changeset_post( - array( - 'data' => array_fill_keys( $this->pending_starter_content_settings_ids, array( 'starter_content' => true ) ), - 'starter_content' => true, - ) - ); - $this->saved_starter_content_changeset = true; - - $this->pending_starter_content_settings_ids = array(); - } - - /** - * Get dirty pre-sanitized setting values in the current customized state. - * - * The returned array consists of a merge of three sources: - * 1. If the theme is not currently active, then the base array is any stashed - * theme mods that were modified previously but never published. - * 2. The values from the current changeset, if it exists. - * 3. If the user can customize, the values parsed from the incoming - * `$_POST['customized']` JSON data. - * 4. Any programmatically-set post values via `WP_Customize_Manager::set_post_value()`. - * - * The name "unsanitized_post_values" is a carry-over from when the customized - * state was exclusively sourced from `$_POST['customized']`. Nevertheless, - * the value returned will come from the current changeset post and from the - * incoming post data. - * - * @since 4.1.1 - * @since 4.7.0 Added `$args` parameter and merging with changeset values and stashed theme mods. - * - * @param array $args { - * Args. - * - * @type bool $exclude_changeset Whether the changeset values should also be excluded. Defaults to false. - * @type bool $exclude_post_data Whether the post input values should also be excluded. Defaults to false when lacking the customize capability. - * } - * @return array - */ - public function unsanitized_post_values( $args = array() ) { - $args = array_merge( - array( - 'exclude_changeset' => false, - 'exclude_post_data' => ! current_user_can( 'customize' ), - ), - $args - ); - - $values = array(); - - // Let default values be from the stashed theme mods if doing a theme switch and if no changeset is present. - if ( ! $this->is_theme_active() ) { - $stashed_theme_mods = get_option( 'customize_stashed_theme_mods' ); - $stylesheet = $this->get_stylesheet(); - if ( isset( $stashed_theme_mods[ $stylesheet ] ) ) { - $values = array_merge( $values, wp_list_pluck( $stashed_theme_mods[ $stylesheet ], 'value' ) ); - } - } - - if ( ! $args['exclude_changeset'] ) { - foreach ( $this->changeset_data() as $setting_id => $setting_params ) { - if ( ! array_key_exists( 'value', $setting_params ) ) { - continue; - } - if ( isset( $setting_params['type'] ) && 'theme_mod' === $setting_params['type'] ) { - - // Ensure that theme mods values are only used if they were saved under the current theme. - $namespace_pattern = '/^(?P.+?)::(?P.+)$/'; - if ( preg_match( $namespace_pattern, $setting_id, $matches ) && $this->get_stylesheet() === $matches['stylesheet'] ) { - $values[ $matches['setting_id'] ] = $setting_params['value']; - } - } else { - $values[ $setting_id ] = $setting_params['value']; - } - } - } - - if ( ! $args['exclude_post_data'] ) { - if ( ! isset( $this->_post_values ) ) { - if ( isset( $_POST['customized'] ) ) { - $post_values = json_decode( wp_unslash( $_POST['customized'] ), true ); - } else { - $post_values = array(); - } - if ( is_array( $post_values ) ) { - $this->_post_values = $post_values; - } else { - $this->_post_values = array(); - } - } - $values = array_merge( $values, $this->_post_values ); - } - return $values; - } - - /** - * Returns the sanitized value for a given setting from the current customized state. - * - * The name "post_value" is a carry-over from when the customized state was exclusively - * sourced from `$_POST['customized']`. Nevertheless, the value returned will come - * from the current changeset post and from the incoming post data. - * - * @since 3.4.0 - * @since 4.1.1 Introduced the `$default` parameter. - * @since 4.6.0 `$default` is now returned early when the setting post value is invalid. - * - * @see WP_REST_Server::dispatch() - * @see WP_REST_Request::sanitize_params() - * @see WP_REST_Request::has_valid_params() - * - * @param WP_Customize_Setting $setting A WP_Customize_Setting derived object. - * @param mixed $default Value returned $setting has no post value (added in 4.2.0) - * or the post value is invalid (added in 4.6.0). - * @return string|mixed $post_value Sanitized value or the $default provided. - */ - public function post_v