From 1718294fa9b213fab3b6b166eade6c863857a857 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 10 Oct 2024 14:48:19 -0600 Subject: [PATCH 01/16] After we download images to a site, update the URLs in the content if using the block editor and image blocks --- .../NetworkSiteConnection.php | 2 +- includes/utils.php | 88 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php index 0428347f7..ee3d5a98f 100644 --- a/includes/classes/InternalConnections/NetworkSiteConnection.php +++ b/includes/classes/InternalConnections/NetworkSiteConnection.php @@ -180,7 +180,7 @@ public function push( $post, $args = array() ) { */ if ( apply_filters( 'dt_push_post_media', true, $new_post_id, $post_media, $post_id, $args, $this ) ) { Utils\set_media( $new_post_id, $post_media, [ 'use_filesystem' => true ] ); - }; + } $media_errors = get_transient( 'dt_media_errors_' . $new_post_id ); diff --git a/includes/utils.php b/includes/utils.php index 3579a8d67..d4c49caa4 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -782,6 +782,11 @@ function set_media( $post_id, $media, $args = [] ) { set_meta( $image_id, $media_item['meta'] ); } + // Update media URLs in content. + if ( 'featured' !== $settings['media_handling'] ) { + update_content_image_urls( (int) $post_id, (int) $image_id, $media_item ); + } + // Transfer post properties wp_update_post( [ @@ -1031,6 +1036,89 @@ function process_media( $url, $post_id, $args = [] ) { return (int) $result; } +/** + * Update an image block with the new image information. + * + * @param array $blocks All blocks in a post. + * @param array $media_item The old media item details. + * @param int $image_id The new image ID. + * @return array + */ +function update_image_block_attributes( array $blocks, array $media_item, int $image_id ) { + // Find and update all image blocks that match the old image ID. + foreach ( $blocks as $key => $block ) { + // Recurse into inner blocks. + if ( ! empty( $block['innerBlocks'] ) ) { + $blocks[ $key ]['innerBlocks'] = update_image_block_attributes( $block['innerBlocks'], $media_item, $image_id ); + } + + // If the block is an image block and the ID matches, update the ID and URL. + if ( 'core/image' === $block['blockName'] && $media_item['id'] === $block['attrs']['id'] ) { + $blocks[ $key ]['attrs']['id'] = $image_id; + + $processor = new \WP_HTML_Tag_Processor( $blocks[ $key ]['innerHTML'] ); + + // Use the HTML API to update the image src and class. + if ( $processor->next_tag( 'img' ) ) { + $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); + $processor->add_class( 'wp-image-' . $image_id ); + $processor->remove_class( 'wp-image-' . $media_item['id'] ); + + $blocks[ $key ]['innerHTML'] = $processor->get_updated_html(); + $blocks[ $key ]['innerContent'][0] = $processor->get_updated_html(); + } + } + } + + return $blocks; +} + +/** + * For a specific image, update the old URL with the new one. + * + * @param int $post_id The post ID. + * @param int $image_id The new image ID. + * @param array $media_item The old media item details. + */ +function update_content_image_urls( int $post_id, int $image_id, array $media_item ) { + $dt_post = new DistributorPost( $post_id ); + + if ( ! $dt_post || ! $dt_post->has_blocks() ) { + return; + } + + /** + * Filter whether image URLS should be updated in the content. + * + * @since x.x.x + * @hook dt_update_content_image_urls + * + * @param {bool} true Whether image URLs should be updated. Default `true`. + * @param {int} $post_id The post ID. + * @param {int} $image_id The new image ID. + * @param {array} $media_item The old media item details. + * + * @return {bool} Whether image URLs should be updated. + */ + if ( ! apply_filters( 'dt_update_content_image_urls', true, $post_id, $image_id, $media_item ) ) { + return; + } + + // Parse out the blocks. + $blocks = parse_blocks( $dt_post->post->post_content ); + + // Update the image block attributes. + $blocks = update_image_block_attributes( $blocks, $media_item, $image_id ); + + // Update the post content. + wp_update_post( + [ + 'ID' => $post_id, + 'post_content' => serialize_blocks( $blocks ), + ] + ); +} + /** * Return whether a post type is compatible with the block editor. * From 414cc6817f8c665e42b999300d0b80a31588201d Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 10 Oct 2024 15:06:11 -0600 Subject: [PATCH 02/16] Update image URLs in the classic editor --- includes/utils.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/includes/utils.php b/includes/utils.php index d4c49caa4..967b90106 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1083,7 +1083,7 @@ function update_image_block_attributes( array $blocks, array $media_item, int $i function update_content_image_urls( int $post_id, int $image_id, array $media_item ) { $dt_post = new DistributorPost( $post_id ); - if ( ! $dt_post || ! $dt_post->has_blocks() ) { + if ( ! $dt_post ) { return; } @@ -1104,6 +1104,29 @@ function update_content_image_urls( int $post_id, int $image_id, array $media_it return; } + // Process classic editor differently. + if ( ! $dt_post->has_blocks() ) { + $processor = new \WP_HTML_Tag_Processor( $dt_post->post->post_content ); + + while ( $processor->next_tag( 'img' ) ) { + $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); + $processor->add_class( 'wp-image-' . $image_id ); + $processor->remove_class( 'wp-image-' . $media_item['id'] ); + $processor->remove_attribute( 'srcset' ); + $processor->remove_attribute( 'sizes' ); + } + + // Update the post content. + wp_update_post( + [ + 'ID' => $post_id, + 'post_content' => $processor->get_updated_html(), + ] + ); + + return; + } + // Parse out the blocks. $blocks = parse_blocks( $dt_post->post->post_content ); From 0a3f6fa65613debf5781a6e045b6af5ae10a8e28 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 10 Oct 2024 15:21:58 -0600 Subject: [PATCH 03/16] More efficient processing --- includes/utils.php | 62 +++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index 967b90106..e54ac63de 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1037,19 +1037,41 @@ function process_media( $url, $post_id, $args = [] ) { } /** - * Update an image block with the new image information. + * Find and update an image tag. + * + * @param string $content The post content. + * @param array $media_item The old media item details. + * @param int $image_id The new image ID. + * @return string + */ +function update_image_tag( string $content, array $media_item, int $image_id ) { + $processor = new \WP_HTML_Tag_Processor( $content ); + + while ( $processor->next_tag( 'img' ) ) { + $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); + $processor->add_class( 'wp-image-' . $image_id ); + $processor->remove_class( 'wp-image-' . $media_item['id'] ); + $processor->remove_attribute( 'srcset' ); + $processor->remove_attribute( 'sizes' ); + } + + return $processor->get_updated_html(); +} + +/** + * Find and update an image block. * * @param array $blocks All blocks in a post. * @param array $media_item The old media item details. * @param int $image_id The new image ID. * @return array */ -function update_image_block_attributes( array $blocks, array $media_item, int $image_id ) { +function update_image_block( array $blocks, array $media_item, int $image_id ) { // Find and update all image blocks that match the old image ID. foreach ( $blocks as $key => $block ) { // Recurse into inner blocks. if ( ! empty( $block['innerBlocks'] ) ) { - $blocks[ $key ]['innerBlocks'] = update_image_block_attributes( $block['innerBlocks'], $media_item, $image_id ); + $blocks[ $key ]['innerBlocks'] = update_image_block( $block['innerBlocks'], $media_item, $image_id ); } // If the block is an image block and the ID matches, update the ID and URL. @@ -1106,38 +1128,26 @@ function update_content_image_urls( int $post_id, int $image_id, array $media_it // Process classic editor differently. if ( ! $dt_post->has_blocks() ) { - $processor = new \WP_HTML_Tag_Processor( $dt_post->post->post_content ); - - while ( $processor->next_tag( 'img' ) ) { - $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); - $processor->add_class( 'wp-image-' . $image_id ); - $processor->remove_class( 'wp-image-' . $media_item['id'] ); - $processor->remove_attribute( 'srcset' ); - $processor->remove_attribute( 'sizes' ); - } + $content = update_image_tag( $dt_post->post->post_content, $media_item, $image_id ); + } else { + // Parse out the blocks. + $blocks = parse_blocks( $dt_post->post->post_content ); - // Update the post content. - wp_update_post( - [ - 'ID' => $post_id, - 'post_content' => $processor->get_updated_html(), - ] - ); + // Update the image block attributes. + $updated_blocks = update_image_block( $blocks, $media_item, $image_id ); + $content = serialize_blocks( $updated_blocks ); + } + // No need to update if the content wasn't modified. + if ( $content === $dt_post->post->post_content ) { return; } - // Parse out the blocks. - $blocks = parse_blocks( $dt_post->post->post_content ); - - // Update the image block attributes. - $blocks = update_image_block_attributes( $blocks, $media_item, $image_id ); - // Update the post content. wp_update_post( [ 'ID' => $post_id, - 'post_content' => serialize_blocks( $blocks ), + 'post_content' => $content, ] ); } From 7efd4a41b541906b044d5f3f33712b05f7ec7352 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Oct 2024 14:44:41 -0600 Subject: [PATCH 04/16] Instead of always using the full image size, try and use the same image size from the original content --- includes/utils.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index e54ac63de..468faca54 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1048,7 +1048,23 @@ function update_image_tag( string $content, array $media_item, int $image_id ) { $processor = new \WP_HTML_Tag_Processor( $content ); while ( $processor->next_tag( 'img' ) ) { - $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); + // Try to determine the image size from the size class WordPress adds. + $image_size = 'full'; + $classes = explode( ' ', $processor->get_attribute( 'class' ) ); + $size_classes = array_filter( + $classes, + function ( $image_class ) { + return false !== strpos( $image_class, 'size-' ); + } + ); + + if ( ! empty( $size_classes ) ) { + // If an image happens to have multiple size classes, just use the first. + $size_class = reset( $size_classes ); + $image_size = str_replace( 'size-', '', $size_class ); + } + + $processor->set_attribute( 'src', wp_get_attachment_image_url( $image_id, $image_size ) ); $processor->add_class( 'wp-image-' . $image_id ); $processor->remove_class( 'wp-image-' . $media_item['id'] ); $processor->remove_attribute( 'srcset' ); @@ -1076,13 +1092,15 @@ function update_image_block( array $blocks, array $media_item, int $image_id ) { // If the block is an image block and the ID matches, update the ID and URL. if ( 'core/image' === $block['blockName'] && $media_item['id'] === $block['attrs']['id'] ) { + $image_size = $block['attrs']['sizeSlug'] ?? 'full'; + $blocks[ $key ]['attrs']['id'] = $image_id; $processor = new \WP_HTML_Tag_Processor( $blocks[ $key ]['innerHTML'] ); // Use the HTML API to update the image src and class. if ( $processor->next_tag( 'img' ) ) { - $processor->set_attribute( 'src', wp_get_attachment_url( $image_id ) ); + $processor->set_attribute( 'src', wp_get_attachment_image_url( $image_id, $image_size ) ); $processor->add_class( 'wp-image-' . $image_id ); $processor->remove_class( 'wp-image-' . $media_item['id'] ); From 3e39ff270bf07496ec62207b4083c008b46ee3f1 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Oct 2024 15:02:54 -0600 Subject: [PATCH 05/16] Make things more efficient by only updating the post content once, after we've processed all image urls --- includes/utils.php | 51 +++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index 468faca54..0f826ed51 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -734,6 +734,8 @@ function set_media( $post_id, $media, $args = [] ) { $media = ( false !== $featured_key ) ? array( $media[ $featured_key ] ) : array(); } + $image_urls_to_update = []; + foreach ( $media as $media_item ) { $args['source_file'] = $media_item['source_file']; @@ -782,9 +784,9 @@ function set_media( $post_id, $media, $args = [] ) { set_meta( $image_id, $media_item['meta'] ); } - // Update media URLs in content. - if ( 'featured' !== $settings['media_handling'] ) { - update_content_image_urls( (int) $post_id, (int) $image_id, $media_item ); + // Save the images that we need to try updating in the content. + if ( 'featured' !== $settings['media_handling'] ) { // TODO: do we want a new setting for this? + $image_urls_to_update[ $image_id ] = $media_item; } // Transfer post properties @@ -798,6 +800,11 @@ function set_media( $post_id, $media, $args = [] ) { ); } + // Update image URLs in content if needed. + if ( ! empty( $image_urls_to_update ) ) { + update_content_image_urls( (int) $post_id, $image_urls_to_update ); + } + if ( ! $found_featured_image ) { delete_post_meta( $post_id, '_thumbnail_id' ); } @@ -1114,13 +1121,12 @@ function update_image_block( array $blocks, array $media_item, int $image_id ) { } /** - * For a specific image, update the old URL with the new one. + * Update all old image URLs with the new ones. * * @param int $post_id The post ID. - * @param int $image_id The new image ID. - * @param array $media_item The old media item details. + * @param array $images The old image details. */ -function update_content_image_urls( int $post_id, int $image_id, array $media_item ) { +function update_content_image_urls( int $post_id, array $images ) { $dt_post = new DistributorPost( $post_id ); if ( ! $dt_post ) { @@ -1133,27 +1139,30 @@ function update_content_image_urls( int $post_id, int $image_id, array $media_it * @since x.x.x * @hook dt_update_content_image_urls * - * @param {bool} true Whether image URLs should be updated. Default `true`. - * @param {int} $post_id The post ID. - * @param {int} $image_id The new image ID. - * @param {array} $media_item The old media item details. + * @param {bool} true Whether image URLs should be updated. Default `true`. + * @param {int} $post_id The post ID. + * @param {array} $images The old image details. * * @return {bool} Whether image URLs should be updated. */ - if ( ! apply_filters( 'dt_update_content_image_urls', true, $post_id, $image_id, $media_item ) ) { + if ( ! apply_filters( 'dt_update_content_image_urls', true, $post_id, $images ) ) { return; } - // Process classic editor differently. - if ( ! $dt_post->has_blocks() ) { - $content = update_image_tag( $dt_post->post->post_content, $media_item, $image_id ); - } else { - // Parse out the blocks. - $blocks = parse_blocks( $dt_post->post->post_content ); + $content = $dt_post->post->post_content; + $has_blocks = $dt_post->has_blocks(); + + foreach ( $images as $image_id => $media_item ) { + // Process block and classic editor content differently. + if ( $has_blocks ) { + $blocks = parse_blocks( $content ); - // Update the image block attributes. - $updated_blocks = update_image_block( $blocks, $media_item, $image_id ); - $content = serialize_blocks( $updated_blocks ); + // Update the image block attributes. + $updated_blocks = update_image_block( $blocks, $media_item, $image_id ); + $content = serialize_blocks( $updated_blocks ); + } else { + $content = update_image_tag( $content, $media_item, $image_id ); + } } // No need to update if the content wasn't modified. From 49d66e6ce51998471656f1c50aa09ba1c2ac9530 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Oct 2024 15:07:54 -0600 Subject: [PATCH 06/16] Ensure we only update images in the classic editor if they match the old image ID --- includes/utils.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/includes/utils.php b/includes/utils.php index 0f826ed51..e4827912f 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1055,9 +1055,16 @@ function update_image_tag( string $content, array $media_item, int $image_id ) { $processor = new \WP_HTML_Tag_Processor( $content ); while ( $processor->next_tag( 'img' ) ) { + $classes = explode( ' ', $processor->get_attribute( 'class' ) ?? ' ' ); + + // Only process the image that matches the old ID. + if ( ! is_array( $classes ) || ! in_array( 'wp-image-' . $media_item['id'], $classes, true ) ) { + continue; + } + // Try to determine the image size from the size class WordPress adds. $image_size = 'full'; - $classes = explode( ' ', $processor->get_attribute( 'class' ) ); + $classes = explode( ' ', $processor->get_attribute( 'class' ) ?? [] ); $size_classes = array_filter( $classes, function ( $image_class ) { From 3778154bb25da520f702a74b8266c678811237ae Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Oct 2024 15:32:21 -0600 Subject: [PATCH 07/16] Don't update the image src if we don't have an image URL. Better fallback if we can't find a resized image --- includes/utils.php | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index e4827912f..1a9ddfa5a 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1058,7 +1058,10 @@ function update_image_tag( string $content, array $media_item, int $image_id ) { $classes = explode( ' ', $processor->get_attribute( 'class' ) ?? ' ' ); // Only process the image that matches the old ID. - if ( ! is_array( $classes ) || ! in_array( 'wp-image-' . $media_item['id'], $classes, true ) ) { + if ( + ! is_array( $classes ) || + ! in_array( 'wp-image-' . $media_item['id'], $classes, true ) + ) { continue; } @@ -1078,7 +1081,19 @@ function ( $image_class ) { $image_size = str_replace( 'size-', '', $size_class ); } - $processor->set_attribute( 'src', wp_get_attachment_image_url( $image_id, $image_size ) ); + $src = wp_get_attachment_image_url( $image_id, $image_size ); + + // If the image size can't be found, try to get the full size. + if ( ! $src ) { + $src = wp_get_attachment_image_url( $image_id, 'full' ); + + // If we still don't have an image, skip this block. + if ( ! $src ) { + continue; + } + } + + $processor->set_attribute( 'src', $src ); $processor->add_class( 'wp-image-' . $image_id ); $processor->remove_class( 'wp-image-' . $media_item['id'] ); $processor->remove_attribute( 'srcset' ); @@ -1114,7 +1129,19 @@ function update_image_block( array $blocks, array $media_item, int $image_id ) { // Use the HTML API to update the image src and class. if ( $processor->next_tag( 'img' ) ) { - $processor->set_attribute( 'src', wp_get_attachment_image_url( $image_id, $image_size ) ); + $src = wp_get_attachment_image_url( $image_id, $image_size ); + + // If the image size can't be found, try to get the full size. + if ( ! $src ) { + $src = wp_get_attachment_image_url( $image_id, 'full' ); + + // If we still don't have an image, skip this block. + if ( ! $src ) { + continue; + } + } + + $processor->set_attribute( 'src', $src ); $processor->add_class( 'wp-image-' . $image_id ); $processor->remove_class( 'wp-image-' . $media_item['id'] ); From 434c0e088f1fdedf3a630c6d9e2cc230bdff9de5 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Tue, 21 Jan 2025 19:20:02 +0530 Subject: [PATCH 08/16] Fix ID comparison. --- includes/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/utils.php b/includes/utils.php index 1a9ddfa5a..dc6d19e26 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -1120,7 +1120,7 @@ function update_image_block( array $blocks, array $media_item, int $image_id ) { } // If the block is an image block and the ID matches, update the ID and URL. - if ( 'core/image' === $block['blockName'] && $media_item['id'] === $block['attrs']['id'] ) { + if ( 'core/image' === $block['blockName'] && (int) $media_item['id'] === (int) $block['attrs']['id'] ) { $image_size = $block['attrs']['sizeSlug'] ?? 'full'; $blocks[ $key ]['attrs']['id'] = $image_id; From 6c8f0f4ba505ac73b49e77fecc8f30fe6850a892 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Wed, 22 Jan 2025 15:42:54 +0530 Subject: [PATCH 09/16] Fix duplicate media creation. --- includes/utils.php | 57 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index dc6d19e26..d496c3076 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -397,6 +397,8 @@ function excluded_meta() { 'dt_original_post_url', 'dt_original_post_id', 'dt_original_blog_id', + 'dt_original_media_url', + 'dt_original_media_id', 'dt_connection_map', '_wp_old_slug', '_wp_old_date', @@ -738,7 +740,8 @@ function set_media( $post_id, $media, $args = [] ) { foreach ( $media as $media_item ) { - $args['source_file'] = $media_item['source_file']; + $args['original_media_id'] = $media_item['id']; + $args['source_file'] = $media_item['source_file']; // Delete duplicate if it exists (unless filter says otherwise) /** @@ -886,8 +889,9 @@ function process_media( $url, $post_id, $args = [] ) { $args = wp_parse_args( $args, [ - 'use_filesystem' => false, - 'source_file' => '', + 'use_filesystem' => false, + 'source_file' => '', + 'original_media_id' => 0 ] ); @@ -943,6 +947,15 @@ function process_media( $url, $post_id, $args = [] ) { return false; } + // Check if the media is already existing on the site. If it is, return the media ID. + if ( ! empty( $args['original_media_id'] ) && ! empty( $url ) ) { + $existing_media_id = get_attachment_id_by_original_data( $url, $args['original_media_id'] ); + + if ( $existing_media_id ) { + return $existing_media_id; + } + } + $file_array = array(); $file_array['name'] = $media_name; @@ -1043,6 +1056,44 @@ function process_media( $url, $post_id, $args = [] ) { return (int) $result; } +/** + * Get existing media ID based on the original source URL and original media ID. + * + * @param string $original_url The original source URL. + * @param int $original_id The original media ID. + * @return int|bool The existing media ID or false if not found. + */ +function get_attachment_id_by_original_data( $original_url, $original_id ) { + $attachments_query = new \WP_Query( array( + 'post_type' => 'attachment', + 'post_status' => 'any', + 'posts_per_page' => 1, + 'fields' => 'ids', + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'meta_query' => array( + 'relation' => 'AND', + array( + 'key' => 'dt_original_media_id', + 'value' => $original_id, + 'compare' => '=', + ), + array( + 'key' => 'dt_original_media_url', + 'value' => $original_url, + 'compare' => '=', + ) + ), + ) ); + + if ( ! empty( $attachments_query->posts ) && ! empty( $attachments_query->posts[0] ) ) { + return (int) $attachments_query->posts[0]; + } + + return false; +} + /** * Find and update an image tag. * From 0fbf1f180c209af854077c7b3f0a68d523ee2daa Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 18:40:06 +0530 Subject: [PATCH 10/16] Add image parsing from post content for the classic editor. --- includes/classes/DistributorPost.php | 48 ++++++++++++++++++++++++++++ includes/utils.php | 46 +++++++++++++------------- 2 files changed, 72 insertions(+), 22 deletions(-) diff --git a/includes/classes/DistributorPost.php b/includes/classes/DistributorPost.php index 26dd2a7f2..1bebe4a0e 100644 --- a/includes/classes/DistributorPost.php +++ b/includes/classes/DistributorPost.php @@ -626,6 +626,11 @@ protected function get_media() { $raw_media = $this->parse_media_blocks(); } else { $raw_media = get_attached_media( get_allowed_mime_types(), $post_id ); + // Parse images from post content. + $parsed_media = $this->parse_images_from_post_content(); + foreach ( $parsed_media as $media_post ) { + $raw_media[ $media_post->ID ] = $media_post; + } } $featured_image_id = $this->get_post_thumbnail_id(); @@ -652,6 +657,49 @@ protected function get_media() { return $media_array; } + /** + * Parse the post's content to obtain media items by image tags. + * + * @return array Array of media posts. + */ + protected function parse_images_from_post_content() { + $processor = new \WP_HTML_Tag_Processor( $this->post->post_content ); + + $media = array(); + while ( $processor->next_tag( 'img' ) ) { + $classes = explode( ' ', $processor->get_attribute( 'class' ) ?? ' ' ); + + if ( ! is_array( $classes ) ) { + continue; + } + + // Filter out classes that are not image classes. + $classes = array_filter( + $classes, + function( $class ) { + return strpos( $class, 'wp-image-' ) === 0; + } + ); + + if ( empty( $classes ) ) { + continue; + } + + $image_id = (int) str_replace( 'wp-image-', '', current( $classes ) ); + $media_post = get_post( $image_id ); + + if ( empty( $media_post ) ) { + continue; + } + + $media[ $media_post->ID ] = $media_post; + } + + $media = array_filter( $media ); + + return $media; + } + /** * Parse the post's content to obtain media items. * diff --git a/includes/utils.php b/includes/utils.php index d496c3076..626bd5f1c 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -891,7 +891,7 @@ function process_media( $url, $post_id, $args = [] ) { [ 'use_filesystem' => false, 'source_file' => '', - 'original_media_id' => 0 + 'original_media_id' => 0, ] ); @@ -1064,28 +1064,30 @@ function process_media( $url, $post_id, $args = [] ) { * @return int|bool The existing media ID or false if not found. */ function get_attachment_id_by_original_data( $original_url, $original_id ) { - $attachments_query = new \WP_Query( array( - 'post_type' => 'attachment', - 'post_status' => 'any', - 'posts_per_page' => 1, - 'fields' => 'ids', - 'no_found_rows' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'meta_query' => array( - 'relation' => 'AND', - array( - 'key' => 'dt_original_media_id', - 'value' => $original_id, - 'compare' => '=', + $attachments_query = new \WP_Query( + array( + 'post_type' => 'attachment', + 'post_status' => 'any', + 'posts_per_page' => 1, + 'fields' => 'ids', + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'relation' => 'AND', + array( + 'key' => 'dt_original_media_id', + 'value' => $original_id, + 'compare' => '=', + ), + array( + 'key' => 'dt_original_media_url', + 'value' => $original_url, + 'compare' => '=', + ), ), - array( - 'key' => 'dt_original_media_url', - 'value' => $original_url, - 'compare' => '=', - ) - ), - ) ); + ) + ); if ( ! empty( $attachments_query->posts ) && ! empty( $attachments_query->posts[0] ) ) { return (int) $attachments_query->posts[0]; From 40e59e702202f4966f96a04ed74d194a74bd7153 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 19:19:39 +0530 Subject: [PATCH 11/16] Add E2E tests. --- .wp-env.json | 3 +- tests/bin/initialize.sh | 1 + .../cypress/e2e/images-classic-editor.test.js | 170 +++++++++++++++++ tests/cypress/e2e/images.test.js | 172 ++++++++++++++++++ tests/cypress/support/commands.js | 40 +++- 5 files changed, 381 insertions(+), 5 deletions(-) create mode 100644 tests/cypress/e2e/images-classic-editor.test.js create mode 100644 tests/cypress/e2e/images.test.js diff --git a/.wp-env.json b/.wp-env.json index 3695c1a0f..84d044542 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -2,7 +2,8 @@ "core": null, "plugins": [ ".", - "./tests/Basic-Auth-master" + "./tests/Basic-Auth-master", + "https://downloads.wordpress.org/plugin/classic-editor.zip" ], "env": { "tests": { diff --git a/tests/bin/initialize.sh b/tests/bin/initialize.sh index 7b15041c6..120183b9f 100755 --- a/tests/bin/initialize.sh +++ b/tests/bin/initialize.sh @@ -3,6 +3,7 @@ set -e wp-env run tests-wordpress chmod -c ugo+w /var/www/html wp-env run tests-cli wp rewrite structure '/%postname%/' --hard +wp-env run tests-cli wp plugin deactivate classic-editor status=0 wp-env run tests-cli wp site list || status=$? diff --git a/tests/cypress/e2e/images-classic-editor.test.js b/tests/cypress/e2e/images-classic-editor.test.js new file mode 100644 index 000000000..343608715 --- /dev/null +++ b/tests/cypress/e2e/images-classic-editor.test.js @@ -0,0 +1,170 @@ +const { randomName } = require( '../support/functions' ); + +describe( '[Classic Editor] Image distribution tests', () => { + let externalConnectionOneToTwo, externalConnectionTwoToOne; + const attachImages = () => { + cy.get( '#postimagediv a#set-post-thumbnail' ).click(); + cy.get( '.media-menu-item' ).contains( 'Media Library' ).click(); + cy.get( '.attachments-browser .attachment' ).first().click(); + cy.get( '.media-button-select' ).click(); + cy.get( '#postimagediv img' ).should( 'be.visible' ); + + cy.get( 'button#insert-media-button' ).click(); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait( 1000 ); + cy.get( '.attachments-wrapper .attachments li.attachment:visible' ) + .eq( 1 ) + .click(); + cy.get( '.button-primary.media-button-insert' ).click(); + }; + + before( () => { + cy.login(); + cy.networkActivatePlugin( 'distributor' ); + cy.networkActivatePlugin( 'classic-editor' ); + cy.networkActivatePlugin( 'json-basic-authentication' ); + + externalConnectionOneToTwo = 'Site Two ' + randomName(); + cy.createExternalConnection( + externalConnectionOneToTwo, + 'http://localhost/second/wp-json' + ); + + externalConnectionTwoToOne = 'Site One ' + randomName(); + cy.createExternalConnection( + externalConnectionTwoToOne, + 'http://localhost/wp-json', + 'admin', + 'password', + 'second' + ); + + cy.visit( 'wp-admin/admin.php?page=distributor-settings' ); + cy.get( '.form-table input[type="checkbox"]' ).first().check(); + cy.get( 'input[type="radio"]' ).check( 'attached' ); + cy.get( '#submit' ).click(); + + cy.visit( '/second/wp-admin/admin.php?page=distributor-settings' ); + cy.get( '.form-table input[type="checkbox"]' ).first().check(); + cy.get( 'input[type="radio"]' ).check( 'attached' ); + cy.get( '#submit' ).click(); + + cy.visit( '/wp-admin/upload.php?mode=grid' ); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait( 2000 ); + cy.get( 'body' ).then( ( $body ) => { + if ( $body.find( 'ul.attachments li' ).length === 0 ) { + cy.uploadImage( './assets/img/banner-772x250.png' ); + cy.uploadImage( './assets/img/banner-1544x500.png' ); + } + } ); + } ); + + after( () => { + cy.networkDeactivatePlugin( 'classic-editor' ); + } ); + + it( 'Should distribute images when pushing to network connections.', () => { + const postTitle = 'Post to push ' + randomName(); + + cy.classicCreatePost( { + title: postTitle, + beforeSave: attachImages, + } ).then( ( sourcePostID ) => { + cy.distributorPushPost( + sourcePostID, + 'second', + '', + 'publish', + false, + true + ).then( ( distributedPost ) => { + cy.postContains( + distributedPost.distributedPostId, + ' src="http://localhost/wp-content/uploads/sites/2/', // For the push to network connection, image url will be generated from the source site, this is due to https://core.trac.wordpress.org/ticket/25650 + 'http://localhost/second/' + ); + } ); + } ); + } ); + + it( 'Should distribute images when pulling from network connections.', () => { + const postTitle = 'Post to pull ' + randomName(); + + cy.classicCreatePost( { + title: postTitle, + beforeSave: attachImages, + } ).then( ( sourcePostID ) => { + cy.distributorPullPost( + sourcePostID, + 'second', + '', + 'localhost' + ).then( ( distributedPost ) => { + const matches = + distributedPost.distributedEditUrl.match( /post=(\d+)/ ); + let distributedPostId; + if ( matches ) { + distributedPostId = matches[ 1 ]; + } + cy.postContains( + distributedPostId, + ' src="http://localhost/second/wp-content/uploads/', + 'http://localhost/second/' + ); + } ); + } ); + } ); + + it( 'Should distribute images when pushing to external connections.', () => { + const postTitle = 'Post to push ' + randomName(); + + cy.classicCreatePost( { + title: postTitle, + beforeSave: attachImages, + } ).then( ( sourcePostID ) => { + cy.distributorPushPost( + sourcePostID, + externalConnectionOneToTwo, + '', + 'publish', + false, + true + ).then( ( distributedPost ) => { + cy.postContains( + distributedPost.distributedPostId, + ' src="http://localhost/second/wp-content/uploads/', + 'http://localhost/second/' + ); + } ); + } ); + } ); + + it( 'Should distribute image when pulling from external connections.', () => { + const postTitle = 'Post to pull ' + randomName(); + + cy.classicCreatePost( { + title: postTitle, + beforeSave: attachImages, + } ).then( ( sourcePostID ) => { + cy.distributorPullPost( + sourcePostID, + '/second/', // Pull to second site. + '', // From primary site. + externalConnectionTwoToOne + ).then( ( distributedPost ) => { + const matches = + distributedPost.distributedEditUrl.match( /post=(\d+)/ ); + let distributedPostId; + if ( matches ) { + distributedPostId = matches[ 1 ]; + } + cy.postContains( + distributedPostId, + ' src="http://localhost/second/wp-content/uploads/', + 'http://localhost/second/' + ); + } ); + } ); + } ); +} ); diff --git a/tests/cypress/e2e/images.test.js b/tests/cypress/e2e/images.test.js new file mode 100644 index 000000000..416cb12a5 --- /dev/null +++ b/tests/cypress/e2e/images.test.js @@ -0,0 +1,172 @@ +const { randomName } = require( '../support/functions' ); + +describe( '[Block Editor] Image distribution tests', () => { + let externalConnectionOneToTwo, externalConnectionTwoToOne; + const attachImages = () => { + cy.openDocumentSettingsSidebar( 'Post' ); + cy.get( '.editor-post-featured-image__toggle' ).click(); + cy.get( '.media-menu-item' ).contains( 'Media Library' ).click(); + cy.get( '.attachments-browser .attachment' ).first().click(); + cy.get( '.media-button-select' ).click(); + cy.get( '.editor-post-featured-image__preview-image' ).should( + 'be.visible' + ); + + cy.insertBlock( 'core/image', 'Image' ).then( ( id ) => { + cy.getBlockEditor() + .find( `#${ id } button.components-button` ) + .contains( 'Media Library' ) + .click(); + cy.get( '.attachments-browser .attachment' ).eq( 1 ).click(); + cy.get( '.media-button-select' ).click(); + cy.getBlockEditor().find( `#${ id } img` ).should( 'be.visible' ); + } ); + }; + + before( () => { + cy.login(); + cy.networkDeactivatePlugin( 'classic-editor' ); + cy.networkActivatePlugin( 'distributor' ); + cy.networkActivatePlugin( 'json-basic-authentication' ); + + externalConnectionOneToTwo = 'Site Two ' + randomName(); + cy.createExternalConnection( + externalConnectionOneToTwo, + 'http://localhost/second/wp-json' + ); + + externalConnectionTwoToOne = 'Site One ' + randomName(); + cy.createExternalConnection( + externalConnectionTwoToOne, + 'http://localhost/wp-json', + 'admin', + 'password', + 'second' + ); + + cy.visit( 'wp-admin/admin.php?page=distributor-settings' ); + cy.get( '.form-table input[type="checkbox"]' ).first().check(); + cy.get( 'input[type="radio"]' ).check( 'attached' ); + cy.get( '#submit' ).click(); + + cy.visit( '/second/wp-admin/admin.php?page=distributor-settings' ); + cy.get( '.form-table input[type="checkbox"]' ).first().check(); + cy.get( 'input[type="radio"]' ).check( 'attached' ); + cy.get( '#submit' ).click(); + + cy.visit( '/wp-admin/upload.php?mode=grid' ); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait( 2000 ); + cy.get( 'body' ).then( ( $body ) => { + if ( $body.find( 'ul.attachments' ).length === 0 ) { + cy.uploadImage( './assets/img/banner-772x250.png' ); + cy.uploadImage( './assets/img/banner-1544x500.png' ); + } + } ); + } ); + + it( 'Should distribute images when pushing to network connections.', () => { + const postTitle = 'Post to push ' + randomName(); + + cy.createPost( { + title: postTitle, + beforeSave: attachImages, + } ).then( ( sourcePost ) => { + cy.distributorPushPost( + sourcePost.id, + 'second', + '', + 'publish' + ).then( ( distributedPost ) => { + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait( 1000 ); + cy.postContains( + distributedPost.distributedPostId, + ' { + const postTitle = 'Post to push ' + randomName(); + + cy.createPost( { title: postTitle, beforeSave: attachImages } ).then( + ( sourcePost ) => { + cy.distributorPushPost( + sourcePost.id, + externalConnectionOneToTwo, + '', + 'publish' + ).then( ( distributedPost ) => { + cy.postContains( + distributedPost.distributedPostId, + ' { } ); } ); +Cypress.Commands.add( 'networkDeactivatePlugin', ( slug ) => { + cy.visit( '/wp-admin/network/plugins.php' ); + cy.get( `#the-list tr[data-slug="${ slug }"]` ).then( ( $pluginRow ) => { + if ( $pluginRow.find( '.deactivate > a' ).length > 0 ) { + cy.get( `#the-list tr[data-slug="${ slug }"] .deactivate > a` ) + .should( 'have.text', 'Network Deactivate' ) + .click(); + } + } ); +} ); + Cypress.Commands.add( 'networkEnableTheme', ( slug ) => { cy.visit( '/wp-admin/network/themes.php' ); cy.get( `#the-list tr[data-slug="${ slug }"]` ).then( ( $themeRow ) => { @@ -130,7 +141,8 @@ Cypress.Commands.add( toConnectionName, fromBlogSlug = '', postStatus = 'publish', - external = false + external = false, + classicEditor = false ) => { const info = { originalEditUrl: @@ -158,9 +170,11 @@ Cypress.Commands.add( info.originalFrontUrl = originalFrontUrl; } ); - cy.disableFullscreenEditor(); - cy.dismissNUXTip(); - cy.closeWelcomeGuide(); + if ( ! classicEditor ) { + cy.disableFullscreenEditor(); + cy.dismissNUXTip(); + cy.closeWelcomeGuide(); + } cy.get( '#wp-admin-bar-distributor' ) .contains( 'Distributor' ) @@ -297,3 +311,21 @@ Cypress.Commands.add( 'postContains', ( postId, content, siteUrl ) => { } cy.wpCli( cliCommand ).its( 'stdout' ).should( 'contain', content ); } ); + +Cypress.Commands.add( 'uploadImage', ( imagePath ) => { + cy.visit( '/wp-admin/media-new.php' ); + cy.get( '#plupload-upload-ui' ).should( 'exist' ); + cy.get( '#plupload-upload-ui input[type=file]' ).selectFile( imagePath, { + force: true, + } ); + + cy.get( '#media-items .media-item a.edit-attachment', { + timeout: 20000, + } ).should( 'exist' ); + cy.get( '#media-items .media-item a.edit-attachment' ) + .invoke( 'attr', 'href' ) + .then( ( editLink = '' ) => { + const mediaId = editLink?.split( 'post=' )[ 1 ]?.split( '&' )[ 0 ]; + cy.wrap( mediaId ); + } ); +} ); From 7e12ecdf52e848c9af06dadd169a013e47412650 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 19:48:41 +0530 Subject: [PATCH 12/16] update tests for the wp minimum env. --- tests/cypress/e2e/images.test.js | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/cypress/e2e/images.test.js b/tests/cypress/e2e/images.test.js index 416cb12a5..61ede57c3 100644 --- a/tests/cypress/e2e/images.test.js +++ b/tests/cypress/e2e/images.test.js @@ -4,13 +4,30 @@ describe( '[Block Editor] Image distribution tests', () => { let externalConnectionOneToTwo, externalConnectionTwoToOne; const attachImages = () => { cy.openDocumentSettingsSidebar( 'Post' ); - cy.get( '.editor-post-featured-image__toggle' ).click(); - cy.get( '.media-menu-item' ).contains( 'Media Library' ).click(); - cy.get( '.attachments-browser .attachment' ).first().click(); - cy.get( '.media-button-select' ).click(); - cy.get( '.editor-post-featured-image__preview-image' ).should( - 'be.visible' - ); + cy.get( 'body' ).then( ( $body ) => { + if ( + $body.find( '.editor-post-featured-image__toggle:visible' ) + .length + ) { + cy.get( '.editor-post-featured-image__toggle' ).click(); + cy.get( '.media-menu-item' ) + .contains( 'Media Library' ) + .click(); + cy.get( '.attachments-browser .attachment' ).first().click(); + cy.get( '.media-button-select' ).click(); + cy.get( '.editor-post-featured-image__preview-image' ).should( + 'be.visible' + ); + } else { + cy.openDocumentSettingsPanel( 'Featured Image' ); + cy.get( '.editor-post-featured-image__toggle' ).click(); + cy.get( '.media-menu-item' ) + .contains( 'Media Library' ) + .click(); + cy.get( '.attachments-browser .attachment' ).first().click(); + cy.get( '.media-button-select' ).click(); + } + } ); cy.insertBlock( 'core/image', 'Image' ).then( ( id ) => { cy.getBlockEditor() From 8bcd31ff5ff5bb039468e0bda8be15bcf03e9d1f Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 20:13:46 +0530 Subject: [PATCH 13/16] Fix tests in wp trunk env. --- tests/cypress/e2e/images-classic-editor.test.js | 4 ++++ tests/cypress/e2e/images.test.js | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/cypress/e2e/images-classic-editor.test.js b/tests/cypress/e2e/images-classic-editor.test.js index 343608715..14c2d3bad 100644 --- a/tests/cypress/e2e/images-classic-editor.test.js +++ b/tests/cypress/e2e/images-classic-editor.test.js @@ -19,6 +19,10 @@ describe( '[Classic Editor] Image distribution tests', () => { }; before( () => { + // Prevent uncaught exceptions from failing the test on WP trunk. + Cypress.on( 'uncaught:exception', () => { + return false; + } ); cy.login(); cy.networkActivatePlugin( 'distributor' ); cy.networkActivatePlugin( 'classic-editor' ); diff --git a/tests/cypress/e2e/images.test.js b/tests/cypress/e2e/images.test.js index 61ede57c3..8ac70aa0e 100644 --- a/tests/cypress/e2e/images.test.js +++ b/tests/cypress/e2e/images.test.js @@ -1,13 +1,15 @@ const { randomName } = require( '../support/functions' ); describe( '[Block Editor] Image distribution tests', () => { + // prevent uncaught exceptions from failing the test on WP trunk. let externalConnectionOneToTwo, externalConnectionTwoToOne; const attachImages = () => { cy.openDocumentSettingsSidebar( 'Post' ); cy.get( 'body' ).then( ( $body ) => { if ( - $body.find( '.editor-post-featured-image__toggle:visible' ) - .length + $body.find( + '.editor-post-featured-image .editor-post-featured-image__toggle' + ).length ) { cy.get( '.editor-post-featured-image__toggle' ).click(); cy.get( '.media-menu-item' ) @@ -15,9 +17,6 @@ describe( '[Block Editor] Image distribution tests', () => { .click(); cy.get( '.attachments-browser .attachment' ).first().click(); cy.get( '.media-button-select' ).click(); - cy.get( '.editor-post-featured-image__preview-image' ).should( - 'be.visible' - ); } else { cy.openDocumentSettingsPanel( 'Featured Image' ); cy.get( '.editor-post-featured-image__toggle' ).click(); @@ -41,6 +40,10 @@ describe( '[Block Editor] Image distribution tests', () => { }; before( () => { + // Prevent uncaught exceptions from failing the test on WP trunk. + Cypress.on( 'uncaught:exception', () => { + return false; + } ); cy.login(); cy.networkDeactivatePlugin( 'classic-editor' ); cy.networkActivatePlugin( 'distributor' ); From 0cbd14dfb087c400015d55005f6792a3043b9333 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 20:23:12 +0530 Subject: [PATCH 14/16] Revert "Fix duplicate media creation." This reverts commit 6c8f0f4ba505ac73b49e77fecc8f30fe6850a892. --- includes/utils.php | 59 +++------------------------------------------- 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index 626bd5f1c..dc6d19e26 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -397,8 +397,6 @@ function excluded_meta() { 'dt_original_post_url', 'dt_original_post_id', 'dt_original_blog_id', - 'dt_original_media_url', - 'dt_original_media_id', 'dt_connection_map', '_wp_old_slug', '_wp_old_date', @@ -740,8 +738,7 @@ function set_media( $post_id, $media, $args = [] ) { foreach ( $media as $media_item ) { - $args['original_media_id'] = $media_item['id']; - $args['source_file'] = $media_item['source_file']; + $args['source_file'] = $media_item['source_file']; // Delete duplicate if it exists (unless filter says otherwise) /** @@ -889,9 +886,8 @@ function process_media( $url, $post_id, $args = [] ) { $args = wp_parse_args( $args, [ - 'use_filesystem' => false, - 'source_file' => '', - 'original_media_id' => 0, + 'use_filesystem' => false, + 'source_file' => '', ] ); @@ -947,15 +943,6 @@ function process_media( $url, $post_id, $args = [] ) { return false; } - // Check if the media is already existing on the site. If it is, return the media ID. - if ( ! empty( $args['original_media_id'] ) && ! empty( $url ) ) { - $existing_media_id = get_attachment_id_by_original_data( $url, $args['original_media_id'] ); - - if ( $existing_media_id ) { - return $existing_media_id; - } - } - $file_array = array(); $file_array['name'] = $media_name; @@ -1056,46 +1043,6 @@ function process_media( $url, $post_id, $args = [] ) { return (int) $result; } -/** - * Get existing media ID based on the original source URL and original media ID. - * - * @param string $original_url The original source URL. - * @param int $original_id The original media ID. - * @return int|bool The existing media ID or false if not found. - */ -function get_attachment_id_by_original_data( $original_url, $original_id ) { - $attachments_query = new \WP_Query( - array( - 'post_type' => 'attachment', - 'post_status' => 'any', - 'posts_per_page' => 1, - 'fields' => 'ids', - 'no_found_rows' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'relation' => 'AND', - array( - 'key' => 'dt_original_media_id', - 'value' => $original_id, - 'compare' => '=', - ), - array( - 'key' => 'dt_original_media_url', - 'value' => $original_url, - 'compare' => '=', - ), - ), - ) - ); - - if ( ! empty( $attachments_query->posts ) && ! empty( $attachments_query->posts[0] ) ) { - return (int) $attachments_query->posts[0]; - } - - return false; -} - /** * Find and update an image tag. * From 45afeb2bc95b5029ff6e90b52abaa265292ea336 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 23 Jan 2025 20:48:24 +0530 Subject: [PATCH 15/16] Fix PHPunit tests. --- tests/php/includes/common.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/php/includes/common.php b/tests/php/includes/common.php index d7ba845c9..ea3e10088 100644 --- a/tests/php/includes/common.php +++ b/tests/php/includes/common.php @@ -242,6 +242,30 @@ public function __construct( $post ) { } } +/** + * Mock WP_HTML_Tag_Processor + */ +class WP_HTML_Tag_Processor { + protected $html; + + /** + * Constructor. + * + * @param string $html HTML to process. + */ + public function __construct( $html ) { + $this->html = $html; + } + + public function next_tag() { + return false; + } + + public function get_attribute() { + return null; + } +} + /** * Return testing friendly url * From b6eef6439ee13fe24e10ace01ffb07c1ca283b7d Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Thu, 6 Feb 2025 12:54:06 -0700 Subject: [PATCH 16/16] Remove TODO statement --- includes/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/utils.php b/includes/utils.php index ab5e2ce0a..a06b038d7 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -793,7 +793,7 @@ function set_media( $post_id, $media, $args = [] ) { } // Save the images that we need to try updating in the content. - if ( 'featured' !== $settings['media_handling'] ) { // TODO: do we want a new setting for this? + if ( 'featured' !== $settings['media_handling'] ) { $image_urls_to_update[ $image_id ] = $media_item; }