From 200da5b275b489c535a0fa20f788f4f70d5585e8 Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Mon, 14 Oct 2024 13:53:36 +0200 Subject: [PATCH 01/10] PLANET-7564: media replacement feature - Add basic implementation --- src/Loader.php | 1 + src/MediaReplacer.php | 89 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/MediaReplacer.php diff --git a/src/Loader.php b/src/Loader.php index 88d3695026..fe64c9b5fc 100644 --- a/src/Loader.php +++ b/src/Loader.php @@ -83,6 +83,7 @@ private function load_services(array $services): void PostMeta::class, GravityFormsExtensions::class, BlockSettings::class, + MediaReplacer::class, ]; if (is_admin()) { diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php new file mode 100644 index 0000000000..9582ce9b44 --- /dev/null +++ b/src/MediaReplacer.php @@ -0,0 +1,89 @@ + + + post_type === 'attachment') { + $form_fields['replace_media_button'] = array( + 'input' => 'html', + 'html' => '', + ); + } + return $form_fields; + } + + function replace_media_image() { + // Use the attachment ID instead of the URL + $old_image_id = 225; // Replace with the old image ID + $new_image_id = 224; // Replace with the new image ID + + // Get file paths + $old_image_path = get_attached_file($old_image_id); + $new_image_path = get_attached_file($new_image_id); + + // Check if the old image exists + if (file_exists($old_image_path)) { + unlink($old_image_path); // Delete the old image + } + + // Check if the new image exists before copying + if (file_exists($new_image_path)) { + copy($new_image_path, $old_image_path); // Copy the new image to the old image path + + // Get the image's file type (based on extension) + $filetype = wp_check_filetype($old_image_path); + + // Update the attachment metadata with new information + $attachment_data = array( + 'ID' => $old_image_id, + 'post_mime_type' => $filetype['type'], + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_image_path)), + 'post_content' => '', + 'post_status' => 'inherit' + ); + + // Update the database record for the image + wp_update_post($attachment_data); + + // Update image metadata + require_once(ABSPATH . 'wp-admin/includes/image.php'); + $attach_data = wp_generate_attachment_metadata($old_image_id, $old_image_path); + wp_update_attachment_metadata($old_image_id, $attach_data); + + } else { + error_log('New image does not exist at ' . $new_image_path); // Log an error if the new image is not found + } + } +} From 64f827605620072cdae323238ebb3dd6d03df7f7 Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Mon, 14 Oct 2024 14:04:13 +0200 Subject: [PATCH 02/10] PLANET-7564: media replacement feature - Add ajax call for the replacement --- src/MediaReplacer.php | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index 9582ce9b44..dc6bd1ca75 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -16,7 +16,18 @@ public function __construct() { add_action('admin_footer', [$this, 'enqueue_media_modal_script']); add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); - // add_action('init', [$this, 'replace_media_image']); + add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); // AJAX action for replacing media + } + + public function ajax_replace_media() { + // Check if the attachment ID is set + if (isset($_POST['attachment_id'])) { + $attachment_id = intval($_POST['attachment_id']); + $this->replace_media_image($attachment_id); // Call the function with the attachment ID + wp_send_json_success(); // Send a success response + } else { + wp_send_json_error('Attachment ID is missing.'); // Error response + } } function enqueue_media_modal_script() { @@ -26,12 +37,27 @@ function enqueue_media_modal_script() { $(document).on('click', '.custom-button', function(e) { e.preventDefault(); var attachmentId = $(this).data('attachment-id'); - alert('Button clicked for attachment ID: ' + attachmentId); // Replace with your action + + // Send AJAX request to replace the media + $.ajax({ + url: ajaxurl, // WordPress AJAX URL + type: 'POST', + data: { + action: 'replace_media', // Custom action name + attachment_id: attachmentId // Pass the attachment ID + }, + success: function(response) { + location.reload(true); + }, + error: function(xhr, status, error) { + alert('Error: ' + error); // Error message + } + }); }); }); Date: Mon, 14 Oct 2024 14:28:39 +0200 Subject: [PATCH 03/10] PLANET-7564: media replacement feature - Upload file from computer --- src/MediaReplacer.php | 132 +++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index dc6bd1ca75..ad2d2c2be6 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -20,15 +20,28 @@ public function __construct() } public function ajax_replace_media() { - // Check if the attachment ID is set - if (isset($_POST['attachment_id'])) { + // Check if the attachment ID and file are set + if (isset($_POST['attachment_id']) && !empty($_FILES['file'])) { $attachment_id = intval($_POST['attachment_id']); - $this->replace_media_image($attachment_id); // Call the function with the attachment ID - wp_send_json_success(); // Send a success response + + // Handle the uploaded file + $file = $_FILES['file']; + $upload_overrides = array('test_form' => false); // Avoid form tests + + // Upload the file + $movefile = wp_handle_upload($file, $upload_overrides); + + if ($movefile && !isset($movefile['error'])) { + // Replace the media image + $this->replace_media_image($attachment_id, $movefile['file']); // Pass the new file path + wp_send_json_success(); // Send a success response + } else { + wp_send_json_error($movefile['error']); // Error response + } } else { - wp_send_json_error('Attachment ID is missing.'); // Error response + wp_send_json_error('Attachment ID or file is missing.'); // Error response } - } + } function enqueue_media_modal_script() { ?> @@ -37,20 +50,39 @@ function enqueue_media_modal_script() { $(document).on('click', '.custom-button', function(e) { e.preventDefault(); var attachmentId = $(this).data('attachment-id'); + var fileInput = $(this).siblings('.replace-media-file'); - // Send AJAX request to replace the media - $.ajax({ - url: ajaxurl, // WordPress AJAX URL - type: 'POST', - data: { - action: 'replace_media', // Custom action name - attachment_id: attachmentId // Pass the attachment ID - }, - success: function(response) { - location.reload(true); - }, - error: function(xhr, status, error) { - alert('Error: ' + error); // Error message + // Show the file input + fileInput.trigger('click'); + + // When a file is selected + fileInput.on('change', function() { + var file = fileInput[0].files[0]; // Get the selected file + + if (file) { + var formData = new FormData(); + formData.append('action', 'replace_media'); + formData.append('attachment_id', attachmentId); + formData.append('file', file); // Append the file to FormData + + // Send AJAX request to replace the media + $.ajax({ + url: ajaxurl, // WordPress AJAX URL + type: 'POST', + data: formData, + contentType: false, // Prevent jQuery from overriding content type + processData: false, // Prevent jQuery from processing the data + success: function(response) { + if (response.success) { + location.reload(true); // Reload the current page + } else { + alert('Error: ' + response.data); // Show the error message + } + }, + error: function(xhr, status, error) { + alert('Error: ' + error); // Error message + } + }); } }); }); @@ -64,51 +96,43 @@ function add_replace_media_button($form_fields, $post) { if ($post->post_type === 'attachment') { $form_fields['replace_media_button'] = array( 'input' => 'html', - 'html' => '', + 'html' => ' + + + ', ); } return $form_fields; - } + } - function replace_media_image($old_image_id) { - // Assuming $new_image_id is defined or fetched appropriately - $new_image_id = 224; // Replace with the new image ID - - // Get file paths + function replace_media_image($old_image_id, $new_file_path) { + // Get the old image path $old_image_path = get_attached_file($old_image_id); - $new_image_path = get_attached_file($new_image_id); - + // Check if the old image exists if (file_exists($old_image_path)) { unlink($old_image_path); // Delete the old image } - - // Check if the new image exists before copying - if (file_exists($new_image_path)) { - copy($new_image_path, $old_image_path); // Copy the new image to the old image path - - // Get the image's file type (based on extension) - $filetype = wp_check_filetype($old_image_path); - // Update the attachment metadata with new information - $attachment_data = array( - 'ID' => $old_image_id, - 'post_mime_type' => $filetype['type'], - 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_image_path)), - 'post_content' => '', - 'post_status' => 'inherit' - ); + // Move the new file to the old image's location + rename($new_file_path, $old_image_path); - // Update the database record for the image - wp_update_post($attachment_data); + // Update the attachment metadata with new information + $filetype = wp_check_filetype($old_image_path); + $attachment_data = array( + 'ID' => $old_image_id, + 'post_mime_type' => $filetype['type'], + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_image_path)), + 'post_content' => '', + 'post_status' => 'inherit' + ); - // Update image metadata - require_once(ABSPATH . 'wp-admin/includes/image.php'); - $attach_data = wp_generate_attachment_metadata($old_image_id, $old_image_path); - wp_update_attachment_metadata($old_image_id, $attach_data); - - } else { - error_log('New image does not exist at ' . $new_image_path); // Log an error if the new image is not found - } - } + // Update the database record for the image + wp_update_post($attachment_data); + + // Update image metadata + require_once(ABSPATH . 'wp-admin/includes/image.php'); + $attach_data = wp_generate_attachment_metadata($old_image_id, $old_image_path); + wp_update_attachment_metadata($old_image_id, $attach_data); + } } From a5d3be3862e5d39ec9bc35116a2910e30be57437 Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Mon, 14 Oct 2024 14:42:08 +0200 Subject: [PATCH 04/10] PLANET-7564: media replacement feature - Separate JS logic in a different file --- admin/js/media_replacer.js | 43 +++++++++++++++++++++++++ src/MediaReplacer.php | 66 +++++++++----------------------------- 2 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 admin/js/media_replacer.js diff --git a/admin/js/media_replacer.js b/admin/js/media_replacer.js new file mode 100644 index 0000000000..dc96597456 --- /dev/null +++ b/admin/js/media_replacer.js @@ -0,0 +1,43 @@ +/* global ajaxurl */ + +jQuery(document).ready($ => { + $(document).on('click', '.custom-button', function(e) { + e.preventDefault(); + const attachmentId = $(this).data('attachment-id'); + const fileInput = $(this).siblings('.replace-media-file'); + + // Show the file input + fileInput.trigger('click'); + + // When a file is selected + fileInput.on('change', () => { + const file = fileInput[0].files[0]; // Get the selected file + + if (file) { + const formData = new FormData(); + formData.append('action', 'replace_media'); + formData.append('attachment_id', attachmentId); + formData.append('file', file); // Append the file to FormData + + // Send AJAX request to replace the media + $.ajax({ + url: ajaxurl, // WordPress AJAX URL + type: 'POST', + data: formData, + contentType: false, // Prevent jQuery from overriding content type + processData: false, // Prevent jQuery from processing the data + success(response) { + if (response.success) { + location.reload(true); // Reload the current page + } else { + alert('Error: ' + response.data); // Show the error message + } + }, + error(xhr, status, error) { + alert('Error: ' + error); // Error message + }, + }); + } + }); + }); +}); diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index ad2d2c2be6..ae21cea012 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -14,11 +14,25 @@ class MediaReplacer */ public function __construct() { - add_action('admin_footer', [$this, 'enqueue_media_modal_script']); + add_action('admin_enqueue_scripts', [$this, 'enqueue_media_modal_script']); add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); // AJAX action for replacing media } + function enqueue_media_modal_script() { + if (!wp_script_is('jquery', 'enqueued')) { + wp_enqueue_script('jquery'); + } + + wp_enqueue_script( + 'custom-media-replacer', + get_template_directory_uri() . '/admin/js/media_replacer.js', + ['jquery'], + Loader::theme_file_ver("admin/js/media_replacer.js"), + true + ); + } + public function ajax_replace_media() { // Check if the attachment ID and file are set if (isset($_POST['attachment_id']) && !empty($_FILES['file'])) { @@ -41,55 +55,7 @@ public function ajax_replace_media() { } else { wp_send_json_error('Attachment ID or file is missing.'); // Error response } - } - - function enqueue_media_modal_script() { - ?> - - Date: Mon, 14 Oct 2024 14:50:32 +0200 Subject: [PATCH 05/10] PLANET-7564: media replacement feature - Replace videos --- src/MediaReplacer.php | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index ae21cea012..7f339d40b2 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -46,8 +46,8 @@ public function ajax_replace_media() { $movefile = wp_handle_upload($file, $upload_overrides); if ($movefile && !isset($movefile['error'])) { - // Replace the media image - $this->replace_media_image($attachment_id, $movefile['file']); // Pass the new file path + // Replace the media file (image or video) + $this->replace_media_file($attachment_id, $movefile['file']); // Pass the new file path wp_send_json_success(); // Send a success response } else { wp_send_json_error($movefile['error']); // Error response @@ -64,41 +64,45 @@ function add_replace_media_button($form_fields, $post) { 'input' => 'html', 'html' => ' - + ', ); } return $form_fields; } - function replace_media_image($old_image_id, $new_file_path) { - // Get the old image path - $old_image_path = get_attached_file($old_image_id); + function replace_media_file($old_file_id, $new_file_path) { + // Get the old file path + $old_file_path = get_attached_file($old_file_id); - // Check if the old image exists - if (file_exists($old_image_path)) { - unlink($old_image_path); // Delete the old image + // Check if the old file exists + if (file_exists($old_file_path)) { + unlink($old_file_path); // Delete the old file } - // Move the new file to the old image's location - rename($new_file_path, $old_image_path); + // Move the new file to the old file's location + rename($new_file_path, $old_file_path); // Update the attachment metadata with new information - $filetype = wp_check_filetype($old_image_path); + $filetype = wp_check_filetype($old_file_path); $attachment_data = array( - 'ID' => $old_image_id, + 'ID' => $old_file_id, 'post_mime_type' => $filetype['type'], - 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_image_path)), + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), 'post_content' => '', 'post_status' => 'inherit' ); - // Update the database record for the image + // Update the database record for the file wp_update_post($attachment_data); - // Update image metadata - require_once(ABSPATH . 'wp-admin/includes/image.php'); - $attach_data = wp_generate_attachment_metadata($old_image_id, $old_image_path); - wp_update_attachment_metadata($old_image_id, $attach_data); + // Update file metadata + if (strpos($filetype['type'], 'image/') === 0) { + require_once(ABSPATH . 'wp-admin/includes/image.php'); + $attach_data = wp_generate_attachment_metadata($old_file_id, $old_file_path); + wp_update_attachment_metadata($old_file_id, $attach_data); + } elseif (strpos($filetype['type'], 'video/') === 0) { + wp_update_attachment_metadata($old_file_id, $attach_data); // Uncomment and customize if required + } } } From a9eed6e735566137858fdf65dc3fb2ea631c3ffc Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Mon, 14 Oct 2024 15:10:25 +0200 Subject: [PATCH 06/10] PLANET-7564: media replacement feature - Purge cloudflare --- src/MediaReplacer.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index 7f339d40b2..cbb47bbd17 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -2,6 +2,8 @@ namespace P4\MasterTheme; +use P4\MasterTheme\CloudflarePurger; + /** * Class MediaReplacer. * @@ -9,11 +11,15 @@ */ class MediaReplacer { + protected CloudflarePurger $cloud_flare_purger; + /** * Activator constructor. */ public function __construct() { + $this->cloud_flare_purger = new CloudflarePurger(); + add_action('admin_enqueue_scripts', [$this, 'enqueue_media_modal_script']); add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); // AJAX action for replacing media @@ -48,6 +54,13 @@ public function ajax_replace_media() { if ($movefile && !isset($movefile['error'])) { // Replace the media file (image or video) $this->replace_media_file($attachment_id, $movefile['file']); // Pass the new file path + + // Get the URL of the attachment + $attachment_url = [wp_get_attachment_url($attachment_id)]; + + // Purge Cloudflare with the attachment URL + $this->cloud_flare_purger->purge($attachment_url); + wp_send_json_success(); // Send a success response } else { wp_send_json_error($movefile['error']); // Error response @@ -55,7 +68,7 @@ public function ajax_replace_media() { } else { wp_send_json_error('Attachment ID or file is missing.'); // Error response } - } + } function add_replace_media_button($form_fields, $post) { // Check if the post type is 'attachment' From 92ec6863e9b66bd91af66cb36255eae739d46453 Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Tue, 15 Oct 2024 15:52:13 +0200 Subject: [PATCH 07/10] PLANET-7564: media replacement feature - Replace elements by name --- src/MediaReplacer.php | 98 ++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index cbb47bbd17..35971cc393 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -7,7 +7,7 @@ /** * Class MediaReplacer. * - * This class is used to handle blocks configuration. + * This class is used to handle media replacements. */ class MediaReplacer { @@ -18,7 +18,7 @@ class MediaReplacer */ public function __construct() { - $this->cloud_flare_purger = new CloudflarePurger(); + // $this->cloud_flare_purger = new CloudflarePurger(); add_action('admin_enqueue_scripts', [$this, 'enqueue_media_modal_script']); add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); @@ -56,10 +56,10 @@ public function ajax_replace_media() { $this->replace_media_file($attachment_id, $movefile['file']); // Pass the new file path // Get the URL of the attachment - $attachment_url = [wp_get_attachment_url($attachment_id)]; + // $attachment_url = [wp_get_attachment_url($attachment_id)]; // Purge Cloudflare with the attachment URL - $this->cloud_flare_purger->purge($attachment_url); + // $this->cloud_flare_purger->purge($attachment_url); wp_send_json_success(); // Send a success response } else { @@ -90,32 +90,74 @@ function replace_media_file($old_file_id, $new_file_path) { // Check if the old file exists if (file_exists($old_file_path)) { - unlink($old_file_path); // Delete the old file - } + $old_dir = pathinfo($old_file_path, PATHINFO_DIRNAME); + $old_file_base = pathinfo($old_file_path, PATHINFO_FILENAME); // Get base file name without extension - // Move the new file to the old file's location - rename($new_file_path, $old_file_path); - - // Update the attachment metadata with new information - $filetype = wp_check_filetype($old_file_path); - $attachment_data = array( - 'ID' => $old_file_id, - 'post_mime_type' => $filetype['type'], - 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), - 'post_content' => '', - 'post_status' => 'inherit' - ); + // Move the new file to the old original file location + rename($new_file_path, $old_file_path); + + // Find all files matching the pattern (e.g., c8b8bd7e-gp0stpsh7_flipped-404-*) + $pattern = $old_dir . '/' . $old_file_base . '*'; + $matching_files = glob($pattern); + + // Loop through all the matching files and replace them + foreach ($matching_files as $old_size_path) { + // Check if the file is different from the original image + if ($old_size_path !== $old_file_path) { + // Get the dimensions of the old size image + list($width, $height) = getimagesize($old_size_path); - // Update the database record for the file - wp_update_post($attachment_data); + // Use wp_get_image_editor to resize the new image + $image_editor = wp_get_image_editor($old_file_path); + + if (!is_wp_error($image_editor)) { + // Resize the image to the old size's dimensions + $image_editor->resize($width, $height, false); // false to keep aspect ratio + $resized_image_path = $image_editor->save(); + + if (!is_wp_error($resized_image_path)) { + // Delete the old size file + unlink($old_size_path); + + // Move the resized image to the old size file path + rename($resized_image_path['path'], $old_size_path); + } else { + error_log('Error saving resized image: ' . $resized_image_path->get_error_message()); + } + } else { + error_log('Error initializing image editor: ' . $image_editor->get_error_message()); + } + } + } - // Update file metadata - if (strpos($filetype['type'], 'image/') === 0) { - require_once(ABSPATH . 'wp-admin/includes/image.php'); - $attach_data = wp_generate_attachment_metadata($old_file_id, $old_file_path); - wp_update_attachment_metadata($old_file_id, $attach_data); - } elseif (strpos($filetype['type'], 'video/') === 0) { - wp_update_attachment_metadata($old_file_id, $attach_data); // Uncomment and customize if required + // Update file metadata with new dimensions but keep the same file names + $filetype = wp_check_filetype($old_file_path); + $attachment_data = array( + 'ID' => $old_file_id, + 'post_mime_type' => $filetype['type'], + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), + 'post_content' => '', + 'post_status' => 'inherit' + ); + + // Update the database record for the file + wp_update_post($attachment_data); + + // Update the metadata (if applicable) with new dimensions for all sizes + $meta = wp_get_attachment_metadata($old_file_id); + if (!empty($meta['sizes'])) { + foreach ($meta['sizes'] as $size => &$size_info) { + $old_size_file = $old_dir . '/' . $size_info['file']; + if (file_exists($old_size_file)) { + list($width, $height) = getimagesize($old_size_file); + $size_info['width'] = $width; + $size_info['height'] = $height; + } + } + } + + // Update the metadata in the database + wp_update_attachment_metadata($old_file_id, $meta); } - } + } } From a637a0c4d0d9807d611c1f12eff0ad1828f09f04 Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Tue, 15 Oct 2024 16:29:05 +0200 Subject: [PATCH 08/10] PLANET-7564: media replacement feature - Code refactor and cleanup --- src/MediaReplacer.php | 226 ++++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 107 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index 35971cc393..602628ab83 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -2,8 +2,6 @@ namespace P4\MasterTheme; -use P4\MasterTheme\CloudflarePurger; - /** * Class MediaReplacer. * @@ -11,18 +9,14 @@ */ class MediaReplacer { - protected CloudflarePurger $cloud_flare_purger; - /** * Activator constructor. */ public function __construct() { - // $this->cloud_flare_purger = new CloudflarePurger(); - add_action('admin_enqueue_scripts', [$this, 'enqueue_media_modal_script']); add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); - add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); // AJAX action for replacing media + add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); } function enqueue_media_modal_script() { @@ -41,46 +35,48 @@ function enqueue_media_modal_script() { public function ajax_replace_media() { // Check if the attachment ID and file are set - if (isset($_POST['attachment_id']) && !empty($_FILES['file'])) { - $attachment_id = intval($_POST['attachment_id']); - - // Handle the uploaded file - $file = $_FILES['file']; - $upload_overrides = array('test_form' => false); // Avoid form tests - - // Upload the file - $movefile = wp_handle_upload($file, $upload_overrides); - - if ($movefile && !isset($movefile['error'])) { - // Replace the media file (image or video) - $this->replace_media_file($attachment_id, $movefile['file']); // Pass the new file path - - // Get the URL of the attachment - // $attachment_url = [wp_get_attachment_url($attachment_id)]; - - // Purge Cloudflare with the attachment URL - // $this->cloud_flare_purger->purge($attachment_url); + if (!isset($_POST['attachment_id'])) { + wp_send_json_error('Attachment ID or file is missing.'); + return; + } + + if (empty($_FILES['file'])) { + wp_send_json_error('Attachment ID or file is missing.'); + return; + } - wp_send_json_success(); // Send a success response - } else { - wp_send_json_error($movefile['error']); // Error response - } - } else { - wp_send_json_error('Attachment ID or file is missing.'); // Error response + // Handle the uploaded file + $file = $_FILES['file']; + $upload_overrides = array('test_form' => false); // Avoid form tests + + // Upload the file + $movefile = wp_handle_upload($file, $upload_overrides); + + if (!$movefile) { + $error_message = isset($movefile['error']) ?? 'Move file not working'; + wp_send_json_error($error_message); + return; } + + // Replace the media file + $attachment_id = intval($_POST['attachment_id']); + $this->replace_media_file($attachment_id, $movefile['file']); + wp_send_json_success(); } function add_replace_media_button($form_fields, $post) { - // Check if the post type is 'attachment' - if ($post->post_type === 'attachment') { - $form_fields['replace_media_button'] = array( - 'input' => 'html', - 'html' => ' - - - ', - ); + if ($post->post_type !== 'attachment') { + return; } + + $form_fields['replace_media_button'] = array( + 'input' => 'html', + 'html' => ' + + + ', + ); + return $form_fields; } @@ -89,75 +85,91 @@ function replace_media_file($old_file_id, $new_file_path) { $old_file_path = get_attached_file($old_file_id); // Check if the old file exists - if (file_exists($old_file_path)) { - $old_dir = pathinfo($old_file_path, PATHINFO_DIRNAME); - $old_file_base = pathinfo($old_file_path, PATHINFO_FILENAME); // Get base file name without extension - - // Move the new file to the old original file location - rename($new_file_path, $old_file_path); - - // Find all files matching the pattern (e.g., c8b8bd7e-gp0stpsh7_flipped-404-*) - $pattern = $old_dir . '/' . $old_file_base . '*'; - $matching_files = glob($pattern); - - // Loop through all the matching files and replace them - foreach ($matching_files as $old_size_path) { - // Check if the file is different from the original image - if ($old_size_path !== $old_file_path) { - // Get the dimensions of the old size image - list($width, $height) = getimagesize($old_size_path); - - // Use wp_get_image_editor to resize the new image - $image_editor = wp_get_image_editor($old_file_path); - - if (!is_wp_error($image_editor)) { - // Resize the image to the old size's dimensions - $image_editor->resize($width, $height, false); // false to keep aspect ratio - $resized_image_path = $image_editor->save(); - - if (!is_wp_error($resized_image_path)) { - // Delete the old size file - unlink($old_size_path); - - // Move the resized image to the old size file path - rename($resized_image_path['path'], $old_size_path); - } else { - error_log('Error saving resized image: ' . $resized_image_path->get_error_message()); - } - } else { - error_log('Error initializing image editor: ' . $image_editor->get_error_message()); - } - } + if (!file_exists($old_file_path)) { + return; + } + + $old_dir = pathinfo($old_file_path, PATHINFO_DIRNAME); + $old_file_base = pathinfo($old_file_path, PATHINFO_FILENAME); // Get base file name without extension + + // Move the new file to the old original file location + rename($new_file_path, $old_file_path); + + // Find all files matching the pattern (e.g., c8b8bd7e-gp0stpsh7_flipped-404-*) + $pattern = $old_dir . '/' . $old_file_base . '*'; + $matching_files = glob($pattern); + + $this->replace_matching_files($matching_files, $old_file_path); + $this->update_main_file_meta($old_file_path, $old_file_id); + $this->update_all_sizes_files_meta($old_file_id, $old_dir); + } + + // Loop through all the matching files and replace them + function replace_matching_files($matching_files, $old_file_path) + { + foreach ($matching_files as $old_size_path) { + // Check if the file is different from the original image + if ($old_size_path === $old_file_path) { + continue; } - // Update file metadata with new dimensions but keep the same file names - $filetype = wp_check_filetype($old_file_path); - $attachment_data = array( - 'ID' => $old_file_id, - 'post_mime_type' => $filetype['type'], - 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), - 'post_content' => '', - 'post_status' => 'inherit' - ); - - // Update the database record for the file - wp_update_post($attachment_data); - - // Update the metadata (if applicable) with new dimensions for all sizes - $meta = wp_get_attachment_metadata($old_file_id); - if (!empty($meta['sizes'])) { - foreach ($meta['sizes'] as $size => &$size_info) { - $old_size_file = $old_dir . '/' . $size_info['file']; - if (file_exists($old_size_file)) { - list($width, $height) = getimagesize($old_size_file); - $size_info['width'] = $width; - $size_info['height'] = $height; - } - } + // Use wp_get_image_editor to resize the new image + $image_editor = wp_get_image_editor($old_file_path); + + if (is_wp_error($image_editor)) { + error_log('Error initializing image editor: ' . $image_editor->get_error_message()); + continue; + } + + // Get the dimensions of the old size image + list($width, $height) = getimagesize($old_size_path); + + // Resize the image to the old size's dimensions + $image_editor->resize($width, $height, false); // false to keep aspect ratio + $resized_image_path = $image_editor->save(); + + if (is_wp_error($resized_image_path)) { + error_log('Error saving resized image: ' . $resized_image_path->get_error_message()); + continue; } + + // Delete the old size file + unlink($old_size_path); + + // Move the resized image to the old size file path + rename($resized_image_path['path'], $old_size_path); + } + } - // Update the metadata in the database - wp_update_attachment_metadata($old_file_id, $meta); + // Update file metadata with new dimensions but keep the same file names + function update_main_file_meta($old_file_path, $old_file_id) + { + $attachment_data = array( + 'ID' => $old_file_id, + 'post_mime_type' => wp_check_filetype($old_file_path)['type'], + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), + 'post_content' => '', + 'post_status' => 'inherit' + ); + wp_update_post($attachment_data); + } + + // Update the metadata (if applicable) with new dimensions for all sizes + function update_all_sizes_files_meta($old_file_id, $old_dir) + { + $meta = wp_get_attachment_metadata($old_file_id); + + if(empty($meta)) { + return; } - } + foreach ($meta['sizes'] as $size => &$size_info) { + $old_size_file = $old_dir . '/' . $size_info['file']; + if (file_exists($old_size_file)) { + list($width, $height) = getimagesize($old_size_file); + $size_info['width'] = $width; + $size_info['height'] = $height; + } + } + wp_update_attachment_metadata($old_file_id, $meta); + } } From 53f080c5bfc93ddd860b4b7b8a8af823a789e51d Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Tue, 15 Oct 2024 16:46:32 +0200 Subject: [PATCH 09/10] PLANET-7564: media replacement feature - Add function docs --- src/MediaReplacer.php | 48 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index 602628ab83..356f0b1dc9 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -19,6 +19,10 @@ public function __construct() add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); } + /** + * Enqueue the custom script for the media replacer in the WordPress admin area. + * Ensures that jQuery is also enqueued. + */ function enqueue_media_modal_script() { if (!wp_script_is('jquery', 'enqueued')) { wp_enqueue_script('jquery'); @@ -33,6 +37,10 @@ function enqueue_media_modal_script() { ); } + /** + * Handle the AJAX request for replacing media. + * Validates the input, uploads the new file, and triggers the media replacement process. + */ public function ajax_replace_media() { // Check if the attachment ID and file are set if (!isset($_POST['attachment_id'])) { @@ -64,6 +72,13 @@ public function ajax_replace_media() { wp_send_json_success(); } + /** + * Adds a custom "Replace Media" button in the media library for attachments. + * + * @param array $form_fields Existing form fields for the attachment. + * @param object $post The post object representing the attachment. + * @return array Modified form fields with the "Replace Media" button added. + */ function add_replace_media_button($form_fields, $post) { if ($post->post_type !== 'attachment') { return; @@ -80,6 +95,13 @@ function add_replace_media_button($form_fields, $post) { return $form_fields; } + /** + * Replace the media file for a given attachment. + * Handles moving the new file to the old file's location, replacing all size variants. + * + * @param int $old_file_id The ID of the old attachment. + * @param string $new_file_path The path of the new file to replace the old one. + */ function replace_media_file($old_file_id, $new_file_path) { // Get the old file path $old_file_path = get_attached_file($old_file_id); @@ -90,7 +112,7 @@ function replace_media_file($old_file_id, $new_file_path) { } $old_dir = pathinfo($old_file_path, PATHINFO_DIRNAME); - $old_file_base = pathinfo($old_file_path, PATHINFO_FILENAME); // Get base file name without extension + $old_file_base = pathinfo($old_file_path, PATHINFO_FILENAME); // Move the new file to the old original file location rename($new_file_path, $old_file_path); @@ -104,7 +126,12 @@ function replace_media_file($old_file_id, $new_file_path) { $this->update_all_sizes_files_meta($old_file_id, $old_dir); } - // Loop through all the matching files and replace them + /** + * Loop through all the matching files and replace them with the resized version of the new image. + * + * @param array $matching_files Array of file paths that match the original file name pattern. + * @param string $old_file_path The path of the original file. + */ function replace_matching_files($matching_files, $old_file_path) { foreach ($matching_files as $old_size_path) { @@ -125,7 +152,7 @@ function replace_matching_files($matching_files, $old_file_path) list($width, $height) = getimagesize($old_size_path); // Resize the image to the old size's dimensions - $image_editor->resize($width, $height, false); // false to keep aspect ratio + $image_editor->resize($width, $height, false); $resized_image_path = $image_editor->save(); if (is_wp_error($resized_image_path)) { @@ -141,7 +168,12 @@ function replace_matching_files($matching_files, $old_file_path) } } - // Update file metadata with new dimensions but keep the same file names + /** + * Update the main file's metadata after replacing the media. + * + * @param string $old_file_path The path of the old file. + * @param int $old_file_id The ID of the old attachment. + */ function update_main_file_meta($old_file_path, $old_file_id) { $attachment_data = array( @@ -154,7 +186,13 @@ function update_main_file_meta($old_file_path, $old_file_id) wp_update_post($attachment_data); } - // Update the metadata (if applicable) with new dimensions for all sizes + /** + * Update the metadata for all size variants of the attachment. + * Ensures that the new dimensions are reflected for each size variant. + * + * @param int $old_file_id The ID of the old attachment. + * @param string $old_dir The directory where the old size files are stored. + */ function update_all_sizes_files_meta($old_file_id, $old_dir) { $meta = wp_get_attachment_metadata($old_file_id); From 0eda77b1f720c61021e3b7c895c794f53138340d Mon Sep 17 00:00:00 2001 From: Pedro Figueroa Date: Tue, 15 Oct 2024 16:50:57 +0200 Subject: [PATCH 10/10] PLANET-7564: media replacement feature - Fix lint issues --- admin/js/media_replacer.js | 6 ++-- src/MediaReplacer.php | 64 ++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/admin/js/media_replacer.js b/admin/js/media_replacer.js index dc96597456..bfd86df40c 100644 --- a/admin/js/media_replacer.js +++ b/admin/js/media_replacer.js @@ -30,11 +30,13 @@ jQuery(document).ready($ => { if (response.success) { location.reload(true); // Reload the current page } else { - alert('Error: ' + response.data); // Show the error message + // eslint-disable-next-line no-console + console.log('Error: ' + response.data); } }, error(xhr, status, error) { - alert('Error: ' + error); // Error message + // eslint-disable-next-line no-console + console.log('Error: ' + error); }, }); } diff --git a/src/MediaReplacer.php b/src/MediaReplacer.php index 356f0b1dc9..39ee52484d 100644 --- a/src/MediaReplacer.php +++ b/src/MediaReplacer.php @@ -15,19 +15,20 @@ class MediaReplacer public function __construct() { add_action('admin_enqueue_scripts', [$this, 'enqueue_media_modal_script']); - add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); add_action('wp_ajax_replace_media', [$this, 'ajax_replace_media']); + add_filter('attachment_fields_to_edit', [$this, 'add_replace_media_button'], 10, 2); } /** * Enqueue the custom script for the media replacer in the WordPress admin area. * Ensures that jQuery is also enqueued. */ - function enqueue_media_modal_script() { + public function enqueue_media_modal_script(): void + { if (!wp_script_is('jquery', 'enqueued')) { wp_enqueue_script('jquery'); } - + wp_enqueue_script( 'custom-media-replacer', get_template_directory_uri() . '/admin/js/media_replacer.js', @@ -36,12 +37,13 @@ function enqueue_media_modal_script() { true ); } - + /** * Handle the AJAX request for replacing media. * Validates the input, uploads the new file, and triggers the media replacement process. */ - public function ajax_replace_media() { + public function ajax_replace_media(): void + { // Check if the attachment ID and file are set if (!isset($_POST['attachment_id'])) { wp_send_json_error('Attachment ID or file is missing.'); @@ -52,7 +54,7 @@ public function ajax_replace_media() { wp_send_json_error('Attachment ID or file is missing.'); return; } - + // Handle the uploaded file $file = $_FILES['file']; $upload_overrides = array('test_form' => false); // Avoid form tests @@ -71,7 +73,8 @@ public function ajax_replace_media() { $this->replace_media_file($attachment_id, $movefile['file']); wp_send_json_success(); } - + + // phpcs:disable Generic.Files.LineLength.MaxExceeded /** * Adds a custom "Replace Media" button in the media library for attachments. * @@ -79,9 +82,10 @@ public function ajax_replace_media() { * @param object $post The post object representing the attachment. * @return array Modified form fields with the "Replace Media" button added. */ - function add_replace_media_button($form_fields, $post) { + public function add_replace_media_button(array $form_fields, object $post): array + { if ($post->post_type !== 'attachment') { - return; + return $form_fields; } $form_fields['replace_media_button'] = array( @@ -93,7 +97,8 @@ function add_replace_media_button($form_fields, $post) { ); return $form_fields; - } + } + // phpcs:enable Generic.Files.LineLength.MaxExceeded /** * Replace the media file for a given attachment. @@ -102,13 +107,14 @@ function add_replace_media_button($form_fields, $post) { * @param int $old_file_id The ID of the old attachment. * @param string $new_file_path The path of the new file to replace the old one. */ - function replace_media_file($old_file_id, $new_file_path) { + public function replace_media_file(int $old_file_id, string $new_file_path): void + { // Get the old file path $old_file_path = get_attached_file($old_file_id); - + // Check if the old file exists if (!file_exists($old_file_path)) { - return; + return; } $old_dir = pathinfo($old_file_path, PATHINFO_DIRNAME); @@ -132,56 +138,58 @@ function replace_media_file($old_file_id, $new_file_path) { * @param array $matching_files Array of file paths that match the original file name pattern. * @param string $old_file_path The path of the original file. */ - function replace_matching_files($matching_files, $old_file_path) + private function replace_matching_files(array $matching_files, string $old_file_path): void { foreach ($matching_files as $old_size_path) { // Check if the file is different from the original image if ($old_size_path === $old_file_path) { continue; } - + // Use wp_get_image_editor to resize the new image $image_editor = wp_get_image_editor($old_file_path); if (is_wp_error($image_editor)) { + //phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged error_log('Error initializing image editor: ' . $image_editor->get_error_message()); continue; } // Get the dimensions of the old size image - list($width, $height) = getimagesize($old_size_path); + [$width, $height] = getimagesize($old_size_path); // Resize the image to the old size's dimensions $image_editor->resize($width, $height, false); $resized_image_path = $image_editor->save(); if (is_wp_error($resized_image_path)) { + //phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged error_log('Error saving resized image: ' . $resized_image_path->get_error_message()); continue; } - + // Delete the old size file unlink($old_size_path); - + // Move the resized image to the old size file path rename($resized_image_path['path'], $old_size_path); } } - + /** * Update the main file's metadata after replacing the media. * * @param string $old_file_path The path of the old file. * @param int $old_file_id The ID of the old attachment. */ - function update_main_file_meta($old_file_path, $old_file_id) + private function update_main_file_meta(string $old_file_path, int $old_file_id): void { $attachment_data = array( 'ID' => $old_file_id, 'post_mime_type' => wp_check_filetype($old_file_path)['type'], 'post_title' => preg_replace('/\.[^.]+$/', '', basename($old_file_path)), 'post_content' => '', - 'post_status' => 'inherit' + 'post_status' => 'inherit', ); wp_update_post($attachment_data); } @@ -193,20 +201,22 @@ function update_main_file_meta($old_file_path, $old_file_id) * @param int $old_file_id The ID of the old attachment. * @param string $old_dir The directory where the old size files are stored. */ - function update_all_sizes_files_meta($old_file_id, $old_dir) + private function update_all_sizes_files_meta(int $old_file_id, string $old_dir): void { $meta = wp_get_attachment_metadata($old_file_id); - if(empty($meta)) { + if (empty($meta)) { return; } foreach ($meta['sizes'] as $size => &$size_info) { $old_size_file = $old_dir . '/' . $size_info['file']; - if (file_exists($old_size_file)) { - list($width, $height) = getimagesize($old_size_file); - $size_info['width'] = $width; - $size_info['height'] = $height; + if (!file_exists($old_size_file)) { + continue; } + + [$width, $height] = getimagesize($old_size_file); + $size_info['width'] = $width; + $size_info['height'] = $height; } wp_update_attachment_metadata($old_file_id, $meta); }