: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Handles importing sample themes.
* @link https://themify.me/
* @author Themify <themify@themify.me>
final class Tbp_Import_Demo {
public static function run() {
add_action( 'wp_ajax_tbp_import_term', array( __CLASS__, 'wp_ajax_tbp_import_term' ) );
add_action( 'wp_ajax_tbp_import_post', array( __CLASS__, 'wp_ajax_tbp_import_post' ) );
add_action( 'wp_ajax_tbp_import_thumbnail', array( __CLASS__, 'wp_ajax_tbp_import_thumbnail' ) );
add_action( 'admin_init', array( __CLASS__, 'admin_init' ) );
public static function admin_init() {
if ( isset( $_REQUEST['page'] ) && !empty( $_GET['tbp_erase_demo'] ) && $_REQUEST['page'] === Tbp_Themes::$post_type ) {
public static function wp_ajax_tbp_import_term() {
$old_id = $term['term_id'];
if ( $term_id = term_exists( $term['slug'], $term['taxonomy'] ) ) {
if ( is_array( $term_id ) ) $term_id = $term_id['term_id'];
if ( isset( $term['term_id'] ) ) {
update_term_meta( $term_id, '_tbp_demo_id', $old_id );
if ( empty( $term['parent'] ) ) {
$new_id = self::get_term_by_old_id( $term['parent'] );
$parent = term_exists( $new_id, $term['taxonomy'] );
if ( is_array( $parent ) ) $parent = $parent['term_id'];
$id = wp_insert_term( $term['name'], $term['taxonomy'], array(
'description' => $term['description'],
if ( ! is_wp_error( $id ) ) {
update_term_meta( $id['term_id'], '_tbp_demo_id', $old_id );
wp_send_json_success( array(
'oid' => $old_id, // original ID
wp_send_json_error( $id );
public static function wp_ajax_tbp_import_post() {
$post['post_author'] = (int) get_current_user_id();
$post['post_status'] = 'publish';
if ( ! post_type_exists( $post['post_type'] ) ) {
/* Menu items don't have reliable post_title, skip the post_exists check */
/* With tbp_template, different Themes can have duplicate templates so skip post_exists */
if ( $post['post_type'] !== 'nav_menu_item' && $post['post_type'] !== 'tbp_template' ) {
$post_exists = post_exists( $post['post_title'], '', $post['post_date'] );
if ( $post_exists && get_post_type( $post_exists ) === $post['post_type'] ) {
update_post_meta( $post_id, '_tbp_demo_id', $old_id );
wp_send_json_success( array(
'oid' => $old_id, // original ID
if ( $post['post_type'] === 'nav_menu_item' ) {
if ( ! isset( $post['tax_input']['nav_menu'] ) || ! term_exists( $post['tax_input']['nav_menu'], 'nav_menu' ) ) {
$_menu_item_type = $post['meta_input']['_menu_item_type'];
$_menu_item_object_id = $post['meta_input']['_menu_item_object_id'];
if ( 'taxonomy' === $_menu_item_type ) {
$new_id = self::get_term_by_old_id( intval( $_menu_item_object_id ) );
$post['meta_input']['_menu_item_object_id'] = $new_id;
} elseif ( 'post_type' === $_menu_item_type ) {
$new_id = self::get_post_by_old_id( intval( $_menu_item_object_id ) );
$post['meta_input']['_menu_item_object_id'] = $new_id;
$post_parent = ( $post['post_type'] == 'nav_menu_item' ) ? $post['meta_input']['_menu_item_menu_item_parent'] : (int) $post['post_parent'];
$post['post_parent'] = 0;
// if we already know the parent, map it to the new local ID
$new_id = self::get_post_by_old_id( $post_parent );
if( $post['post_type'] === 'nav_menu_item' ) {
$post['meta_input']['_menu_item_menu_item_parent'] = $new_id;
$post['post_parent'] = $new_id;
* for hierarchical taxonomies, IDs must be used so wp_set_post_terms can function properly
* convert term slugs to IDs for hierarchical taxonomies
if ( ! empty( $post['tax_input'] ) ) {
foreach( $post['tax_input'] as $tax => $terms ) {
if ( ! taxonomy_exists( $tax ) ) {
unset( $post['tax_input'][ $tax ] );
if( is_taxonomy_hierarchical( $tax ) ) {
$terms = explode( ', ', $terms );
$post['tax_input'][ $tax ] = array_map( 'self::get_term_id_by_slug', $terms, array_fill( 0, count( $terms ), $tax ) );
$post_id = wp_insert_post( $post, true );
if ( is_wp_error( $post_id ) ) {
wp_send_json_error( $post_id );
update_post_meta( $post_id, '_tbp_demo_id', $old_id );
// download featured image
if ( isset( $post['thumb'] ) ) {
$fetch = self::fetch_remote_file( $post['thumb'], $post_id );
if ( ! is_wp_error( $fetch ) ) {
set_post_thumbnail( $post_id, $fetch );
if ( isset( $post['is_home'] ) ) {
update_option( 'show_on_front', 'page' );
update_option( 'page_on_front', $post_id );
if ( $post['post_type'] === 'tbp_theme' ) {
Tbp_Utils::set_active_theme( $post_id );
elseif ( $post['post_type'] === 'tbp_template' ) {
$theme = (int) sanitize_text_field( $_POST['theme_id'] );
$theme_post = get_post( $theme );
update_post_meta( $post_id, 'tbp_associated_theme', $theme_post->post_name );
wp_send_json_success( array(
'oid' => $old_id, // original ID
public static function wp_ajax_tbp_import_thumbnail() {
$post_id = (int) $_POST['post_id'];
$url = sanitize_text_field( $_POST['thumb'] );
$fetch = self::fetch_remote_file( $url, $post_id );
if ( is_wp_error( $fetch ) ) {
wp_send_json_error( $fetch );
set_post_thumbnail( $post_id, $fetch );
* Remove all demo posts, signified by the existence of _tbp_demo_id meta
private static function erase_demo() {
$terms = get_terms( array(
'suppress_filters' => true,
foreach ( $terms as $term ) {
wp_delete_term( $term->term_id, $term->taxonomy );
$posts = get_posts( array(
'suppress_filters' => true,
foreach ( $posts as $post_id ) {
wp_delete_post( $post_id, true );
* Recieves a post_id from sample file and returns the same post that has been imported into the site
private static function get_post_by_old_id( $old_id ) {
$result = $wpdb->get_results( $wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_tbp_demo_id' AND meta_value = %d LIMIT 1",
if ( isset( $result[0]['post_id'] ) ) {
return $result[0]['post_id'];
private static function get_term_by_old_id( $old_id ) {
$result = $wpdb->get_results( $wpdb->prepare(
"SELECT post_id FROM {$wpdb->termmeta} WHERE meta_key = '_tbp_demo_id' AND meta_value = %d LIMIT 1",
if ( isset( $result[0]['term_id'] ) ) {
return $result[0]['term_id'];
* Download an image from external URL and returns the file
* @param $post_id Attachments may be associated with a parent post or page.
* @return WP_Error|int ID of created attachment, or WP_Error
private static function fetch_remote_file( $url, $post_id = null ) {
// extract the file name and extension from the url
$file_name = basename( $url );
// get placeholder file in the upload dir with a unique, sanitized filename
$upload = wp_upload_bits( $file_name, 0, '' );
return new WP_Error( 'upload_dir_error', $upload['error'] );
// fetch the remote url and write it to the placeholder file
$remote_response = wp_safe_remote_get( $url, array(
'filename' => $upload['file'],
$headers = wp_remote_retrieve_headers( $remote_response );
@unlink( $upload['file'] );
return new WP_Error( 'import_file_error', __('Remote server did not respond', 'tbp') );
$remote_response_code = wp_remote_retrieve_response_code( $remote_response );
// make sure the fetch was successful
if ( $remote_response_code != '200' ) {
@unlink( $upload['file'] );
return new WP_Error( 'import_file_error', sprintf( __('Remote server returned error response %1$d %2$s', 'tbp'), esc_html( $remote_response_code ), get_status_header_desc( $remote_response_code ) ) );
$filesize = filesize( $upload['file'] );
if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) {
/* note: this is intentionally disabled, if gZip is enabled, $headers['content-length'] and $filesize do not necessarily match */
@unlink( $upload['file'] );
return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'tbp') );
'post_status' => 'inherit',
if ( $info = wp_check_filetype( $upload['file'] ) )
$post['post_mime_type'] = $info['type'];
return new WP_Error( 'mime_type_error', __('Invalid file type', 'tbp') );
$attach_id = wp_insert_attachment( $post, $upload['file'], $post_id );
wp_update_attachment_metadata( $attach_id, wp_generate_attachment_metadata( $attach_id, $upload['file'] ) );
public static function get_term_id_by_slug( $slug, $tax ) {
$term = get_term_by( 'slug', $slug, $tax );