WP_Customize_Manager::import_theme_starter_content PHP Method

import_theme_starter_content() public method

Import theme starter content into the customized state.
Since: 4.7.0
public import_theme_starter_content ( array $starter_content = [] )
$starter_content array 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()) {
            $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] = call_user_func_array('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']);
        }
        $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' => 'any', 'number' => -1));
            foreach ($existing_posts_query->posts as $existing_post) {
                $existing_starter_content_posts[$existing_post->post_type . ':' . $existing_post->post_name] = $existing_post;
            }
        }
        // Attachments are technically posts but handled differently.
        if (!empty($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';
            $attachment_ids = array();
            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_array = array();
                $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_array['name'] = basename($attachment['file']);
                // Skip file types that are not recognized.
                $checked_filetype = wp_check_filetype($file_array['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_array['name']));
                    }
                }
                $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(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', 'post_name')), array('post_status' => 'auto-draft'));
                    // In PHP < 5.6 filesize() returns 0 for the temp files unless we clear the file status cache.
                    // Technically, PHP < 5.6.0 || < 5.5.13 || < 5.4.29 but no need to be so targeted.
                    // See https://bugs.php.net/bug.php?id=65701
                    if (version_compare(PHP_VERSION, '5.6', '<')) {
                        clearstatcache();
                    }
                    $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());
                }
                $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'])) {
                    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<symbol>.+)}}$/', $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<nav_menu_id>-?\\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<symbol>.+)}}$/', $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) {
            if (preg_match('/^{{(?P<symbol>.+)}}$/', $value, $matches) && isset($posts[$matches['symbol']])) {
                $value = $posts[$matches['symbol']]['ID'];
            }
            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) {
            if (preg_match('/^{{(?P<symbol>.+)}}$/', $value, $matches) && isset($posts[$matches['symbol']])) {
                $value = $posts[$matches['symbol']]['ID'];
            }
            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);
            }
        }
    }

Usage Example

 /**
  * Test WP_Customize_Manager::import_theme_starter_content().
  *
  * @covers WP_Customize_Manager::import_theme_starter_content()
  * @covers WP_Customize_Manager::_save_starter_content_changeset()
  */
 function test_import_theme_starter_content()
 {
     wp_set_current_user(self::$admin_user_id);
     register_nav_menu('top', 'Top');
     add_theme_support('custom-logo');
     add_theme_support('custom-header');
     add_theme_support('custom-background');
     $canola_file = DIR_TESTDATA . '/images/canola.jpg';
     $existing_canola_attachment_id = self::factory()->attachment->create_object($canola_file, 0, array('post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', 'post_name' => 'canola'));
     $existing_published_home_page_id = $this->factory()->post->create(array('post_name' => 'home', 'post_type' => 'page', 'post_status' => 'publish'));
     $existing_auto_draft_about_page_id = $this->factory()->post->create(array('post_name' => 'about', 'post_type' => 'page', 'post_status' => 'auto-draft'));
     global $wp_customize;
     $wp_customize = new WP_Customize_Manager();
     $starter_content_config = array('widgets' => array('sidebar-1' => array('text_business_info', 'meta_custom' => array('meta', array('title' => 'Pre-hydrated meta widget.')))), 'nav_menus' => array('top' => array('name' => 'Menu Name', 'items' => array('link_home', 'page_about', 'page_blog', 'link_email', 'link_facebook', 'link_custom' => array('title' => 'Custom', 'url' => 'https://custom.example.com/')))), 'posts' => array('home', 'about' => array('template' => 'sample-page-template.php'), 'blog', 'custom' => array('post_type' => 'post', 'post_title' => 'Custom', 'thumbnail' => '{{waffles}}')), 'attachments' => array('waffles' => array('post_title' => 'Waffles', 'post_content' => 'Waffles Attachment Description', 'post_excerpt' => 'Waffles Attachment Caption', 'file' => DIR_TESTDATA . '/images/waffles.jpg'), 'canola' => array('post_title' => 'Canola', 'post_content' => 'Canola Attachment Description', 'post_excerpt' => 'Canola Attachment Caption', 'file' => DIR_TESTDATA . '/images/canola.jpg')), 'options' => array('blogname' => 'Starter Content Title', 'blogdescription' => 'Starter Content Tagline', 'show_on_front' => 'page', 'page_on_front' => '{{home}}', 'page_for_posts' => '{{blog}}'), 'theme_mods' => array('custom_logo' => '{{canola}}', 'header_image' => '{{waffles}}', 'background_image' => '{{waffles}}'));
     update_option('posts_per_page', 1);
     // To check #39022.
     add_theme_support('starter-content', $starter_content_config);
     $this->assertEmpty($wp_customize->unsanitized_post_values());
     $wp_customize->import_theme_starter_content();
     $changeset_values = $wp_customize->unsanitized_post_values();
     $expected_setting_ids = array('blogname', 'blogdescription', 'custom_logo', 'header_image_data', 'background_image', 'widget_text[2]', 'widget_meta[3]', 'sidebars_widgets[sidebar-1]', 'nav_menus_created_posts', 'nav_menu[-1]', 'nav_menu_item[-1]', 'nav_menu_item[-2]', 'nav_menu_item[-3]', 'nav_menu_item[-4]', 'nav_menu_item[-5]', 'nav_menu_item[-6]', 'nav_menu_locations[top]', 'show_on_front', 'page_on_front', 'page_for_posts');
     $this->assertEqualSets($expected_setting_ids, array_keys($changeset_values));
     foreach (array('widget_text[2]', 'widget_meta[3]') as $setting_id) {
         $this->assertInternalType('array', $changeset_values[$setting_id]);
         $instance_data = $wp_customize->widgets->sanitize_widget_instance($changeset_values[$setting_id]);
         $this->assertInternalType('array', $instance_data);
         $this->assertArrayHasKey('title', $instance_data);
     }
     $this->assertEquals(array('text-2', 'meta-3'), $changeset_values['sidebars_widgets[sidebar-1]']);
     $posts_by_name = array();
     $this->assertCount(6, $changeset_values['nav_menus_created_posts']);
     $this->assertContains($existing_published_home_page_id, $changeset_values['nav_menus_created_posts'], 'Expected reuse of non-auto-draft posts.');
     $this->assertContains($existing_canola_attachment_id, $changeset_values['nav_menus_created_posts'], 'Expected reuse of non-auto-draft attachment.');
     $this->assertNotContains($existing_auto_draft_about_page_id, $changeset_values['nav_menus_created_posts'], 'Expected non-reuse of auto-draft posts.');
     foreach ($changeset_values['nav_menus_created_posts'] as $post_id) {
         $post = get_post($post_id);
         if ($post->ID === $existing_published_home_page_id) {
             $this->assertEquals('publish', $post->post_status);
         } elseif ($post->ID === $existing_canola_attachment_id) {
             $this->assertEquals('inherit', $post->post_status);
         } else {
             $this->assertEquals('auto-draft', $post->post_status);
             $this->assertEmpty($post->post_name);
         }
         $post_name = $post->post_name;
         if (empty($post_name)) {
             $post_name = get_post_meta($post->ID, '_customize_draft_post_name', true);
         }
         $posts_by_name[$post_name] = $post->ID;
     }
     $this->assertEquals(array('waffles', 'canola', 'home', 'about', 'blog', 'custom'), array_keys($posts_by_name));
     $this->assertEquals('Custom', get_post($posts_by_name['custom'])->post_title);
     $this->assertEquals('sample-page-template.php', get_page_template_slug($posts_by_name['about']));
     $this->assertEquals('', get_page_template_slug($posts_by_name['blog']));
     $this->assertEquals($posts_by_name['waffles'], get_post_thumbnail_id($posts_by_name['custom']));
     $this->assertEquals('', get_post_thumbnail_id($posts_by_name['blog']));
     $attachment_metadata = wp_get_attachment_metadata($posts_by_name['waffles']);
     $this->assertEquals('Waffles', get_post($posts_by_name['waffles'])->post_title);
     $this->assertEquals('waffles', get_post_meta($posts_by_name['waffles'], '_customize_draft_post_name', true));
     $this->assertArrayHasKey('file', $attachment_metadata);
     $this->assertContains('waffles', $attachment_metadata['file']);
     $this->assertEquals('page', $changeset_values['show_on_front']);
     $this->assertEquals($posts_by_name['home'], $changeset_values['page_on_front']);
     $this->assertEquals($posts_by_name['blog'], $changeset_values['page_for_posts']);
     $this->assertEquals(-1, $changeset_values['nav_menu_locations[top]']);
     $this->assertEquals(0, $changeset_values['nav_menu_item[-1]']['object_id']);
     $this->assertEquals('custom', $changeset_values['nav_menu_item[-1]']['type']);
     $this->assertEquals(home_url(), $changeset_values['nav_menu_item[-1]']['url']);
     $this->assertEmpty($wp_customize->changeset_data());
     $this->assertNull($wp_customize->changeset_post_id());
     $this->assertEquals(1000, has_action('customize_register', array($wp_customize, '_save_starter_content_changeset')));
     do_action('customize_register', $wp_customize);
     // This will trigger the changeset save.
     $this->assertInternalType('int', $wp_customize->changeset_post_id());
     $this->assertNotEmpty($wp_customize->changeset_data());
     foreach ($wp_customize->changeset_data() as $setting_id => $setting_params) {
         $this->assertArrayHasKey('starter_content', $setting_params);
         $this->assertTrue($setting_params['starter_content']);
     }
     // Ensure that re-importing doesn't cause auto-drafts to balloon.
     $wp_customize->import_theme_starter_content();
     $changeset_data = $wp_customize->changeset_data();
     $this->assertEqualSets(array_values($posts_by_name), $changeset_data['nav_menus_created_posts']['value']);
     // Auto-drafts should not get re-created and amended with each import.
     // Test that saving non-starter content on top of the changeset clears the starter_content flag.
     $wp_customize->save_changeset_post(array('data' => array('blogname' => array('value' => 'Starter Content Modified'))));
     $changeset_data = $wp_customize->changeset_data();
     $this->assertArrayNotHasKey('starter_content', $changeset_data['blogname']);
     $this->assertArrayHasKey('starter_content', $changeset_data['blogdescription']);
     // Test that adding blogname starter content is ignored now that it is modified, but updating a non-modified starter content blog description passes.
     $previous_blogname = $changeset_data['blogname']['value'];
     $previous_blogdescription = $changeset_data['blogdescription']['value'];
     $wp_customize->import_theme_starter_content(array('options' => array('blogname' => 'Newer Starter Content Title', 'blogdescription' => 'Newer Starter Content Description')));
     $changeset_data = $wp_customize->changeset_data();
     $this->assertEquals($previous_blogname, $changeset_data['blogname']['value']);
     $this->assertArrayNotHasKey('starter_content', $changeset_data['blogname']);
     $this->assertNotEquals($previous_blogdescription, $changeset_data['blogdescription']['value']);
     $this->assertArrayHasKey('starter_content', $changeset_data['blogdescription']);
     // Publish.
     $this->assertEmpty(get_custom_logo());
     $this->assertEmpty(get_header_image());
     $this->assertEmpty(get_background_image());
     $this->assertEmpty(get_theme_mod('custom_logo'));
     $this->assertEmpty(get_theme_mod('header_image'));
     $this->assertEmpty(get_theme_mod('background_image'));
     $this->assertEquals('auto-draft', get_post($posts_by_name['about'])->post_status);
     $this->assertEquals('auto-draft', get_post($posts_by_name['waffles'])->post_status);
     $this->assertNotEquals($changeset_data['blogname']['value'], get_option('blogname'));
     $r = $wp_customize->save_changeset_post(array('status' => 'publish'));
     $this->assertInternalType('array', $r);
     $this->assertEquals('publish', get_post($posts_by_name['about'])->post_status);
     $this->assertEquals('inherit', get_post($posts_by_name['waffles'])->post_status);
     $this->assertEquals($changeset_data['blogname']['value'], get_option('blogname'));
     $this->assertNotEmpty(get_theme_mod('custom_logo'));
     $this->assertNotEmpty(get_theme_mod('header_image'));
     $this->assertNotEmpty(get_theme_mod('background_image'));
     $this->assertNotEmpty(get_custom_logo());
     $this->assertNotEmpty(get_header_image());
     $this->assertNotEmpty(get_background_image());
     $this->assertContains('canola', get_custom_logo());
     $this->assertContains('waffles', get_header_image());
     $this->assertContains('waffles', get_background_image());
     $this->assertEquals('waffles', get_post($posts_by_name['waffles'])->post_name);
     $this->assertEmpty(get_post_meta($posts_by_name['waffles'], '_customize_draft_post_name', true));
 }
WP_Customize_Manager