diff --git a/src/class-wp-import.php b/src/class-wp-import.php index e1cb094..87fc0dd 100644 --- a/src/class-wp-import.php +++ b/src/class-wp-import.php @@ -93,6 +93,7 @@ function import( $file ) { $this->backfill_parents(); $this->backfill_attachment_urls(); $this->remap_featured_images(); + $this->remap_global_styles_fonts(); $this->import_end(); } @@ -675,8 +676,7 @@ function process_posts() { if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) { printf( __( '%1$s “%2$s” already exists.', 'wordpress-importer' ), $post_type_object->labels->singular_name, esc_html( $post['post_title'] ) ); echo '
'; - $comment_post_id = $post_exists; - $post_id = $post_exists; + $post_id = $post_exists; $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists ); } else { $post_parent = (int) $post['post_parent']; @@ -723,29 +723,44 @@ function process_posts() { $postdata = wp_slash( $postdata ); - if ( 'attachment' == $postdata['post_type'] ) { - $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid']; - - // try to use _wp_attached file for upload folder placement to ensure the same location as the export site - // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload() - $postdata['upload_date'] = $post['post_date']; - if ( isset( $post['postmeta'] ) ) { - foreach ( $post['postmeta'] as $meta ) { - if ( '_wp_attached_file' == $meta['key'] ) { - if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) { - $postdata['upload_date'] = $matches[0]; + switch ( $postdata['post_type'] ) { + case 'attachment': + $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid']; + + // try to use _wp_attached file for upload folder placement to ensure the same location as the export site + // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload() + $postdata['upload_date'] = $post['post_date']; + if ( isset( $post['postmeta'] ) ) { + foreach ( $post['postmeta'] as $meta ) { + if ( '_wp_attached_file' == $meta['key'] ) { + if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) { + $postdata['upload_date'] = $matches[0]; + } + break; } - break; } } - } - $comment_post_id = $this->process_attachment( $postdata, $remote_url ); - $post_id = $comment_post_id; - } else { - $comment_post_id = wp_insert_post( $postdata, true ); - $post_id = $comment_post_id; - do_action( 'wp_import_insert_post', $post_id, $original_post_id, $postdata, $post ); + $post_id = $this->process_attachment( $postdata, $remote_url ); + break; + + case 'wp_font_face': + $postdata = $this->process_font_face( $postdata ); + + if ( is_wp_error( $postdata ) ) { + // Assing the error to $post_id so it is handled later. + $post_id = $postdata; + break; + } + + $post_id = wp_insert_post( $postdata, true ); + $post['postmeta'] = $this->process_font_face_postmeta( $post['postmeta'], $postdata ); + break; + + default: + $post_id = wp_insert_post( $postdata, true ); + do_action( 'wp_import_insert_post', $post_id, $original_post_id, $postdata, $post ); + break; } if ( is_wp_error( $post_id ) ) { @@ -820,7 +835,7 @@ function process_posts() { $inserted_comments = array(); foreach ( $post['comments'] as $comment ) { $comment_id = $comment['comment_id']; - $newcomments[ $comment_id ]['comment_post_ID'] = $comment_post_id; + $newcomments[ $comment_id ]['comment_post_ID'] = $post_id; $newcomments[ $comment_id ]['comment_author'] = $comment['comment_author']; $newcomments[ $comment_id ]['comment_author_email'] = $comment['comment_author_email']; $newcomments[ $comment_id ]['comment_author_IP'] = $comment['comment_author_IP']; @@ -851,7 +866,7 @@ function process_posts() { $inserted_comments[ $key ] = wp_insert_comment( $comment_data ); - do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $comment_post_id, $post ); + do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $post_id, $post ); foreach ( $comment['commentmeta'] as $meta ) { $value = maybe_unserialize( $meta['value'] ); @@ -903,8 +918,6 @@ function process_posts() { } } } - - unset( $this->posts ); } /** @@ -999,6 +1012,104 @@ function process_menu_item( $item ) { } } + /** + * Process the font face data for a post. + * + * @param array $post The post data. + * @return array|WP_Error An array containing the modified post data and the font source URLs, or a WP_Error object if there is an error. + */ + function process_font_face( $post ) { + $post['post_content'] = wp_unslash( $post['post_content'] ); + $font_face = json_decode( $post['post_content'], true ); + + if ( ! $font_face ) { + return new WP_Error( + 'font_face_processing_error', + __( 'Invalid font face data', 'wordpress-importer' ) + ); + } + + $src = array(); + if ( isset( $font_face['src'] ) ) { + $font_dir = wp_get_font_dir(); + $set_upload_dir = function () use ( $font_dir ) { + return $font_dir; + }; + add_filter( 'upload_dir', $set_upload_dir ); + add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); + + $uploads = array(); + if ( is_array( $font_face['src'] ) ) { + foreach ( $font_face['src'] as $src ) { + // $upload = wp_handle_upload( $file ); + $uploads = $this->fetch_remote_file( $src ); + if ( is_wp_error( $upload ) ) { + return $upload; + } + $uploads[] = $upload; + + } + } else { + $upload = $this->fetch_remote_file( $font_face['src'], $font_face ); + if ( is_wp_error( $upload ) ) { + return $upload; + } + $uploads[] = $upload; + } + + $font_face['src'] = array_map( + function( $upload ) { + return $upload['url']; + }, + $uploads + ); + + remove_filter( 'upload_dir', $set_upload_dir ); + remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); + } + + $post['post_content'] = wp_json_encode( $font_face ); + $post['post_content'] = wp_slash( $post['post_content'] ); + + return $post; + } + + function process_font_face_postmeta( $postmeta, $postdata ) { + /* + * Removes all post meta with meta_key _wp_font_face_file. + * Adds the post meta for the font face with the potentially new file names. + * + * Because the assets name could have changed if the file already exists in the uploads folder. + */ + $non_font_face_file_postmeta = array_filter( + $postmeta, + function( $meta ) { + return '_wp_font_face_file' !== $meta['key']; + } + ); + + $post_content = wp_unslash( $postdata['post_content'] ); + $font_face = json_decode( $post_content, true ); + + if ( ! $font_face ) { + return $postmeta; + } + + $new_fonce_face_files_meta = array_map( + function ( $url ) { + return array( + 'key' => '_wp_font_face_file', + 'value' => basename( $url ), + ); + }, + $font_face['src'] + ); + + $postmeta = array_merge( $non_font_face_file_postmeta, $new_fonce_face_files_meta ); + + return $postmeta; + } + /** * If fetching attachments is enabled then attempt to create a new attachment * @@ -1052,13 +1163,13 @@ function process_attachment( $post, $url ) { } /** - * Attempt to download a remote file attachment + * Attempt to download a remote file. * * @param string $url URL of item to fetch - * @param array $post Attachment details + * @param array $post optional. Post details. * @return array|WP_Error Local file location details on success, WP_Error otherwise */ - function fetch_remote_file( $url, $post ) { + function fetch_remote_file( $url, $post = array() ) { // Extract the file name from the URL. $path = parse_url( $url, PHP_URL_PATH ); $file_name = ''; @@ -1175,7 +1286,10 @@ function fetch_remote_file( $url, $post ) { return new WP_Error( 'import_file_error', __( 'Sorry, this file type is not permitted for security reasons.', 'wordpress-importer' ) ); } - $uploads = wp_upload_dir( $post['upload_date'] ); + // $upload_date is used to determine the upload folder of attachments but not for font assets. + $upload_date = isset( $post['upload_date'] ) ? $post['upload_date'] : null; + + $uploads = wp_upload_dir( $upload_date ); if ( ! ( $uploads && false === $uploads['error'] ) ) { return new WP_Error( 'upload_dir_error', $uploads['error'] ); } @@ -1203,8 +1317,10 @@ function fetch_remote_file( $url, $post ) { ); // keep track of the old and new urls so we can substitute them later - $this->url_remap[ $url ] = $upload['url']; - $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed? + $this->url_remap[ $url ] = $upload['url']; + if ( isset( $post['guid'] ) ) { + $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed? + } // keep track of the destination if the remote url is redirected somewhere else if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] != $url ) { $this->url_remap[ $headers['x-final-location'] ] = $upload['url']; @@ -1295,6 +1411,39 @@ function remap_featured_images() { } } + /** + * Update global styles fonts to be remapped to the new imported fonts. + */ + function remap_global_styles_fonts() { + foreach ( $this->posts as $post ) { + // If the post is a global style. + if ( + ( 'wp_global_styles' === $post['post_type'] && 'Custom Styles' === $post['post_title'] ) || + ( 'revision' === $post['post_type'] && 'Custom Styles' === $post['post_title'] ) + ) { + $db_post = get_post( $this->processed_posts[ $post['post_id'] ] ); + $new_post_content = $db_post->post_content; + + foreach ( $this->url_remap as $from_url => $to_url ) { + $new_post_content = str_replace( + wp_json_encode( $from_url ), + wp_json_encode( $to_url ), + $new_post_content + ); + } + + // update the post content. + wp_update_post( + array( + 'ID' => $db_post->ID, + 'post_content' => wp_slash( $new_post_content ), + ) + ); + + } + } + } + /** * Parse a WXR file *