From 31bc87336cfbfd35bd51c56987b9721160e02426 Mon Sep 17 00:00:00 2001 From: asisayag Date: Thu, 2 Apr 2020 22:37:57 +0300 Subject: [PATCH 01/14] Version 2.0.1 --- .../cloudinary.php | 2 +- .../readme.txt | 23 +++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php index a036384a1..4d9803e5a 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php @@ -3,7 +3,7 @@ * Plugin Name: Cloudinary * Plugin URI: https://cloudinary.com/documentation/wordpress_integration * Description: With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website’s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress. - * Version: 2.0.0 + * Version: 2.0.1 * Author: Cloudinary Ltd., XWP * Author URI: https://cloudinary.com/ * License: GPLv2+ diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt index 8aa55e3b4..f37fb8902 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt @@ -60,24 +60,24 @@ And with an embedded digital asset management platform offering full DAM capabil == Installation == = Install from within wordpress = -* Visit the plugins page within your dashboard and select `Add New` -* Search for `Cloudinary` -* Select `Cloudinary – Dynamic Image and Video Management` from the list -* Activate `Cloudinary` from your Plugins page +* Visit the plugins page within your dashboard and select `Add New`. +* Search for `Cloudinary`. +* Select `Cloudinary – Dynamic Image and Video Management` from the list. +* Activate `Cloudinary` from your Plugins page. * Go to `Setting up` below. = Install Cloudinary manually = -* Upload the `Cloudinary` folder to the /wp-content/plugins/ directory -* Activate the `Cloudinary` plugin through the `Plugins` menu in WordPress -* Go to `Setting up` below +* Upload the `Cloudinary` folder to the /wp-content/plugins/ directory. +* Activate the `Cloudinary` plugin through the `Plugins` menu in WordPress. +* Go to `Setting up` below. = Setting up = * Once the plugin is activated, go to the `Cloudinary` settings. * You’ll be prompted to “Add your Cloudinary URL”. -* Enter your “Cloudinary environment variable URL”, the format should be cloudinary://{API_Key}:{API_Secret}@{Cloud_Name} and can be found in the \"Account Details\" section of the Cloudinary Console Dashboard, then click save. +* Enter your “Cloudinary environment variable URL”, the format should be cloudinary://{API_Key}:{API_Secret}@{Cloud_Name} and can be found in the "Account Details" section of the Cloudinary Console Dashboard, then click save. * After saving, additional settings tabs will be available. -** Note ** +**Note** If you have two factor authentication configured for your account, you will need to open the Cloudinary Console and login before you can use the Cloudinary plugin. Your site is now setup to start using Cloudinary. @@ -94,7 +94,7 @@ Upgrade is seamless and requires no action from your side. The plugin will automatically sync all of your WordPress media to your Cloudinary account and start delivering assets from Cloudinary. = Where can I find more info? = -You can read the plugin [documentation] (https://cloudinary.com/documentation/wordpress_integration?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +You can read the plugin [documentation](https://cloudinary.com/documentation/wordpress_integration?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) == Screenshots == 1. Streamline Your Creative Workflow @@ -108,6 +108,9 @@ You can read the plugin [documentation] (https://cloudinary.com/documentation/wo 9. Easily Configure Your Account == Changelog == += 2.0.1 (02 Apr 2020) = + * Fix an issue with v1 migrating + = 2.0.0 (31 Mar 2020) = * Release of a new major version of the plugin From beff24e7d2ef74dc08ca3bebc7f430f989bf34bd Mon Sep 17 00:00:00 2001 From: Dukagjin Surdulli Date: Thu, 2 Apr 2020 18:11:12 -0400 Subject: [PATCH 02/14] Add check after cloudinary_id filter and see if what's filtered is appropriate --- .../php/class-media.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php index 3c654d76c..da9be2c3b 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php @@ -571,7 +571,7 @@ public function cloudinary_url( $attachment_id, $size = array(), $transformation 'version' => $this->get_post_meta( $attachment_id, Sync::META_KEYS['version'], true ), 'resource_type' => $resource_type, ); - + // Check size and correct if string or size. if ( is_string( $size ) || ( is_array( $size ) && 3 === count( $size ) ) ) { $intermediate = image_get_intermediate_size( $attachment_id, $size ); @@ -692,6 +692,11 @@ public function cloudinary_id( $attachment_id ) { * @return string|bool */ $cloudinary_id = apply_filters( 'cloudinary_id', $cloudinary_id, $attachment_id ); + + if ( empty( $cloudinary_id ) ) { + return false; + } + // Cache ID to prevent multiple lookups. if ( false !== $cloudinary_id ) { $this->cloudinary_ids[ $attachment_id ] = $cloudinary_id; @@ -762,10 +767,11 @@ public function image_srcset( $sources, $size_array, $image_src, $image_meta, $a if ( false === $cloudinary_id ) { return $sources; // Return WordPress default sources. } + // Get transformations from URL. $transformations = $this->get_transformations_from_string( $image_src ); + // Use Cloudinary breakpoints for same ratio. - if ( 'on' === $this->plugin->config['settings']['global_transformations']['enable_breakpoints'] && wp_image_matches_ratio( $image_meta['width'], $image_meta['height'], $size_array[0], $size_array[1] ) ) { $meta = $this->get_post_meta( $attachment_id, Sync::META_KEYS['breakpoints'], true ); if ( ! empty( $meta ) ) { @@ -801,11 +807,11 @@ function ( $item ) use ( $crop ) { ); } krsort( $sources, SORT_NUMERIC ); - + return $sources; } } - + // Add the main size as the largest srcset src. $crop = $this->get_crop_from_transformation( $transformations ); if ( ! empty( $crop ) ) { From a6a4913c4bf623453833978bcb4fbd46866d5675 Mon Sep 17 00:00:00 2001 From: Dukagjin Surdulli Date: Thu, 2 Apr 2020 19:43:13 -0400 Subject: [PATCH 03/14] Rollback to 2.0.0 --- .../cloudinary.php | 2 +- .../php/class-media.php | 14 ++++---------- .../php/class-sync.php | 1 - .../php/media/class-upgrade.php | 18 +----------------- .../php/sync/class-download-sync.php | 16 ++-------------- .../readme.txt | 3 --- 6 files changed, 8 insertions(+), 46 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php index 4d9803e5a..a036384a1 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php @@ -3,7 +3,7 @@ * Plugin Name: Cloudinary * Plugin URI: https://cloudinary.com/documentation/wordpress_integration * Description: With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website’s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress. - * Version: 2.0.1 + * Version: 2.0.0 * Author: Cloudinary Ltd., XWP * Author URI: https://cloudinary.com/ * License: GPLv2+ diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php index da9be2c3b..3c654d76c 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php @@ -571,7 +571,7 @@ public function cloudinary_url( $attachment_id, $size = array(), $transformation 'version' => $this->get_post_meta( $attachment_id, Sync::META_KEYS['version'], true ), 'resource_type' => $resource_type, ); - + // Check size and correct if string or size. if ( is_string( $size ) || ( is_array( $size ) && 3 === count( $size ) ) ) { $intermediate = image_get_intermediate_size( $attachment_id, $size ); @@ -692,11 +692,6 @@ public function cloudinary_id( $attachment_id ) { * @return string|bool */ $cloudinary_id = apply_filters( 'cloudinary_id', $cloudinary_id, $attachment_id ); - - if ( empty( $cloudinary_id ) ) { - return false; - } - // Cache ID to prevent multiple lookups. if ( false !== $cloudinary_id ) { $this->cloudinary_ids[ $attachment_id ] = $cloudinary_id; @@ -767,11 +762,10 @@ public function image_srcset( $sources, $size_array, $image_src, $image_meta, $a if ( false === $cloudinary_id ) { return $sources; // Return WordPress default sources. } - // Get transformations from URL. $transformations = $this->get_transformations_from_string( $image_src ); - // Use Cloudinary breakpoints for same ratio. + if ( 'on' === $this->plugin->config['settings']['global_transformations']['enable_breakpoints'] && wp_image_matches_ratio( $image_meta['width'], $image_meta['height'], $size_array[0], $size_array[1] ) ) { $meta = $this->get_post_meta( $attachment_id, Sync::META_KEYS['breakpoints'], true ); if ( ! empty( $meta ) ) { @@ -807,11 +801,11 @@ function ( $item ) use ( $crop ) { ); } krsort( $sources, SORT_NUMERIC ); - + return $sources; } } - + // Add the main size as the largest srcset src. $crop = $this->get_crop_from_transformation( $transformations ); if ( ! empty( $crop ) ) { diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php index 6d740dcd7..a2bcd3745 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php @@ -48,7 +48,6 @@ class Sync implements Setup, Assets { 'transformation' => '_transformations', 'sync_error' => '_sync_error', 'cloudinary' => '_cloudinary_v2', - 'attempts' => '_sync_attempts', ); /** diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php index 7621769eb..f4568904f 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php @@ -55,20 +55,6 @@ public function check_cloudinary_version( $cloudinary_id, $attachment_id ) { */ if ( ! empty( $meta['cloudinary'] ) && empty( $public_id ) ) { $cloudinary_id = $this->convert_cloudinary_version( $attachment_id ); - } elseif ( ! empty( $meta['cloudinary'] ) ) { - // Has public ID, but still has cloudinary, check pending status. - $is_pending = $this->media->get_post_meta( $attachment_id, Sync::META_KEYS['pending'], true ); - $attempts = (int) $this->media->get_post_meta( $attachment_id, Sync::META_KEYS['attempts'], true ); - if ( ( empty( $is_pending ) || $is_pending < time() - 5 * 60 ) && 10 > $attempts ) { - // Timeout. - $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['attempts'], $attempts + 1 ); - - // return proposed ID to allow front render. - return $this->convert_cloudinary_version( $attachment_id ); - } - $cloudinary_id = $public_id; - } else { - $cloudinary_id = $public_id; } } @@ -119,8 +105,6 @@ function ( $val ) use ( $media ) { $public_id = strstr( $public_id, '.' . $path['extension'], true ); // Save public ID. $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['public_id'], $public_id ); - // Set download started data. - $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['pending'], time() ); // Setup a call for a background sync. $params = array( @@ -141,7 +125,7 @@ public function setup_hooks() { add_filter( 'cloudinary_id', array( $this, 'check_cloudinary_version' ), 9, 2 ); // Priority 9, to take preference over prep_on_demand_upload. // Add a redirection to the new plugin settings, from the old plugin. - if ( is_admin() ) { + if( is_admin() ) { add_action( 'admin_menu', function () { global $plugin_page; if ( ! empty( $plugin_page ) && false !== strpos( $plugin_page, 'cloudinary-image-management-and-manipulation-in-the-cloud-cdn' ) ) { diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php index 92de295ba..cda52be93 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php @@ -7,8 +7,6 @@ namespace Cloudinary\Sync; -use Cloudinary\Sync; - /** * Class Download_Sync. * @@ -90,15 +88,9 @@ public function rest_can_upload_files( \WP_REST_Request $request ) { */ public function handle_failed_download( $attachment_id, $error ) { // @todo: Place a handler to catch the error for logging. + // Delete attachment temp. + wp_delete_attachment( $attachment_id, true ); - $is_pending = $this->plugin->components['media']->get_post_meta( $attachment_id, Sync::META_KEYS['pending'], true ); - if ( ! empty( $is_pending ) ) { - // Dont delete if it's a downsync. - $this->plugin->components['media']->update_post_meta( $attachment_id, Sync::META_KEYS['sync_error'], $error ); - } else { - // Delete attachment temp. - wp_delete_attachment( $attachment_id, true ); - } // Send error. wp_send_json_error( $error ); } @@ -189,10 +181,6 @@ public function rest_download_asset( \WP_REST_Request $request ) { 'data' => $attachment, ); - // Remove pending. - delete_post_meta( $attachment_id, Sync::META_KEYS['pending'] ); - delete_post_meta( $attachment_id, Sync::META_KEYS['sync_error'] ); - return rest_ensure_response( $response ); } } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt index f37fb8902..dc5e236e9 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt @@ -108,9 +108,6 @@ You can read the plugin [documentation](https://cloudinary.com/documentation/wor 9. Easily Configure Your Account == Changelog == -= 2.0.1 (02 Apr 2020) = - * Fix an issue with v1 migrating - = 2.0.0 (31 Mar 2020) = * Release of a new major version of the plugin From d165786d389c5b036ee8d7134078610718453108 Mon Sep 17 00:00:00 2001 From: asisayag Date: Fri, 3 Apr 2020 02:53:27 +0300 Subject: [PATCH 04/14] Version 2.0.2 --- .../cloudinary.php | 2 +- .../readme.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php index a036384a1..e7bef4441 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php @@ -3,7 +3,7 @@ * Plugin Name: Cloudinary * Plugin URI: https://cloudinary.com/documentation/wordpress_integration * Description: With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website’s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress. - * Version: 2.0.0 + * Version: 2.0.2 * Author: Cloudinary Ltd., XWP * Author URI: https://cloudinary.com/ * License: GPLv2+ diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt index dc5e236e9..ae3a1d32c 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt @@ -108,6 +108,12 @@ You can read the plugin [documentation](https://cloudinary.com/documentation/wor 9. Easily Configure Your Account == Changelog == += 2.0.2 (03 Apr 2020) = + * Rollback last fix + += 2.0.1 (02 Apr 2020) = + * Fix an issue with v1 migrating + = 2.0.0 (31 Mar 2020) = * Release of a new major version of the plugin From 13e0d709c05fd1522b33898e00f96b7c83b9042f Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 15:27:49 +0200 Subject: [PATCH 05/14] rewire to have sync both ways --- .../php/class-media.php | 21 ++++- .../php/class-rest-api.php | 3 +- .../php/media/class-upgrade.php | 18 +--- .../php/sync/class-download-sync.php | 94 ++++++++++++++++--- .../php/sync/class-push-sync.php | 35 +++++-- .../php/sync/class-upload-sync.php | 9 +- 6 files changed, 142 insertions(+), 38 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php index 3c654d76c..8f0ea364e 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php @@ -1243,7 +1243,9 @@ public function get_post_meta( $post_id, $key, $single = false ) { */ public function build_cached_meta( $post_id, $key, $single ) { $data = get_post_meta( $post_id, $key, $single ); - $this->update_post_meta( $post_id, $key, $data ); + if ( '' !== $data ) { + $this->update_post_meta( $post_id, $key, $data ); + } return $data; } @@ -1266,6 +1268,23 @@ public function update_post_meta( $post_id, $key, $data ) { update_post_meta( $post_id, $key, $data ); } + /** + * Delete cloudinary metadata. + * + * @param int $post_id The attachment ID. + * @param string $key The meta key to get. + */ + public function delete_post_meta( $post_id, $key ) { + $meta_data = wp_get_attachment_metadata( $post_id, true ); + if ( is_array( $meta_data ) && isset( $meta_data[ Sync::META_KEYS['cloudinary'] ] ) && is_array( $meta_data[ Sync::META_KEYS['cloudinary'] ] ) ) { + // Only do this side if has been set before. + unset( $meta_data[ Sync::META_KEYS['cloudinary'] ][ $key ] ); + wp_update_attachment_metadata( $post_id, $meta_data ); + } + // Delete meta data. + delete_post_meta( $post_id, $key ); + } + /** * Setup the hooks and base_url if configured. */ diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php index 90314aaa3..6bd2158e9 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php @@ -85,8 +85,9 @@ public function background_request( $endpoint, $params, $method = 'POST' ) { $url ), ); - $args['headers']['X-WP-Nonce'] = $params['nonce']; + } + $args['headers']['X-WP-Nonce'] = $params['nonce']; // Send request. wp_safe_remote_request( $url, $args ); diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php index f4568904f..af4ff4630 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php @@ -55,6 +55,9 @@ public function check_cloudinary_version( $cloudinary_id, $attachment_id ) { */ if ( ! empty( $meta['cloudinary'] ) && empty( $public_id ) ) { $cloudinary_id = $this->convert_cloudinary_version( $attachment_id ); + } elseif ( ! empty( $public_id ) ) { + // Has public ID, but not fully down synced. + $cloudinary_id = $public_id; } } @@ -103,17 +106,6 @@ function ( $val ) use ( $media ) { // Remove extension. $path = pathinfo( $public_id ); $public_id = strstr( $public_id, '.' . $path['extension'], true ); - // Save public ID. - $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['public_id'], $public_id ); - - // Setup a call for a background sync. - $params = array( - 'attachment_id' => $attachment_id, - 'src' => $file, - 'transformations' => $media->get_transformations_from_string( $file ), - 'filename' => basename( $file ), - ); - $media->plugin->components['api']->background_request( 'asset', $params ); return $public_id; } @@ -122,10 +114,10 @@ function ( $val ) use ( $media ) { * Setup hooks for the filters. */ public function setup_hooks() { - add_filter( 'cloudinary_id', array( $this, 'check_cloudinary_version' ), 9, 2 ); // Priority 9, to take preference over prep_on_demand_upload. + add_filter( 'cloudinary_id', array( $this, 'check_cloudinary_version' ), 10, 2 ); // Priority 10, to allow prep_on_demand_upload. // Add a redirection to the new plugin settings, from the old plugin. - if( is_admin() ) { + if ( is_admin() ) { add_action( 'admin_menu', function () { global $plugin_page; if ( ! empty( $plugin_page ) && false !== strpos( $plugin_page, 'cloudinary-image-management-and-manipulation-in-the-cloud-cdn' ) ) { diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php index cda52be93..cb4c9e6c6 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-download-sync.php @@ -7,6 +7,8 @@ namespace Cloudinary\Sync; +use Cloudinary\Sync; + /** * Class Download_Sync. * @@ -70,21 +72,16 @@ public function rest_endpoints( $endpoints ) { public function rest_can_upload_files( \WP_REST_Request $request ) { // This would have been from an ajax call. Therefore verify based on capability. - if ( is_user_logged_in() ) { - return current_user_can( 'upload_files' ); - } - - // If we get here, this is a background post, which will have a bg post nonce created. - $nonce = $request->get_param( 'nonce' ); - - return wp_verify_nonce( $nonce, 'wp_rest' ); + return current_user_can( 'upload_files' ); } /** - * Handle a failed download by deleting teh temp attachment and returning the error in json. + * Handle a failed download by deleting the temp attachment and returning the error in json. * * @param int $attachment_id The attachment ID. * @param string $error The error text to return. + * + * @return \WP_Error */ public function handle_failed_download( $attachment_id, $error ) { // @todo: Place a handler to catch the error for logging. @@ -109,6 +106,73 @@ public function rest_download_asset( \WP_REST_Request $request ) { $file_name = $request->get_param( 'filename' ); $transformations = (array) $request->get_param( 'transformations' ); + $response = $this->download_asset( $attachment_id, $file_path, $file_name, $transformations ); + if ( is_wp_error( $response ) ) { + $this->handle_failed_download( $attachment_id, $response->get_error_message() ); + } + + return rest_ensure_response( $response ); + } + + /** + * Prepare and sync down an asset stored remotely. + * + * @param $attachment_id + * + * @return array|\WP_Error + */ + public function down_sync( $attachment_id ) { + $file = get_post_meta( $attachment_id, '_wp_attached_file', true ); + $path = wp_parse_url( $file, PHP_URL_PATH ); + $media = $this->plugin->components['media']; + $parts = explode( '/', $path ); + $parts = array_map( + function ( $val ) use ( $media ) { + if ( empty( $val ) ) { + return false; + } + if ( $val === $media->credentials['cloud_name'] ) { + return false; + } + if ( in_array( $val, [ 'image', 'video', 'upload' ], true ) ) { + return false; + } + $transformation_maybe = $media->get_transformations_from_string( $val ); + if ( ! empty( $transformation_maybe ) ) { + return false; + } + if ( substr( $val, 0, 1 ) === 'v' && is_numeric( substr( $val, 1 ) ) ) { + return false; + } + + return $val; + }, + $parts + ); + // Build public_id. + $parts = array_filter( $parts ); + $public_id = implode( '/', $parts ); + // Remove extension. + $path = pathinfo( $public_id ); + $public_id = strstr( $public_id, '.' . $path['extension'], true ); + // Save public ID. + $media->update_post_meta( $attachment_id, Sync::META_KEYS['public_id'], $public_id ); + + return $this->download_asset( $attachment_id, $file, basename( $file ), $media->get_transformations_from_string( $file ) ); + } + + /** + * Download an attachment source to the file system. + * + * @param int $attachment_id The attachment ID. + * @param string $file_path The path of the file. + * @param string $file_name The filename. + * @param array|null $transformations + * + * @return array|\WP_Error + */ + public function download_asset( $attachment_id, $file_path, $file_name, $transformations = null ) { + // Get the image and update the attachment. require_once ABSPATH . WPINC . '/class-http.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; @@ -120,8 +184,7 @@ public function rest_download_asset( \WP_REST_Request $request ) { // Prime a file to stream to. $upload = wp_upload_bits( $file_name, null, 'temp' ); if ( ! empty( $upload['error'] ) ) { - $this->handle_failed_download( $attachment_id, $upload['error'] ); - wp_send_json_error( $upload['error'] ); + return new \WP_Error( 'download_error', $upload['error'] ); } // If the public_id of an asset includes a file extension, a derived item will have the extension duplicated, but not in the source URL. // This creates a 404. So, instead, we get the actual file name, and use that over the file name that the source url has. @@ -137,7 +200,7 @@ public function rest_download_asset( \WP_REST_Request $request ) { ); if ( is_wp_error( $response ) ) { - $this->handle_failed_download( $attachment_id, $response->get_error_message() ); + return $response; } if ( 200 !== $response['response']['code'] ) { $header_error = wp_remote_retrieve_header( $response, 'x-cld-error' ); @@ -146,7 +209,8 @@ public function rest_download_asset( \WP_REST_Request $request ) { } else { $error = __( 'Could not download the Cloudinary asset.', 'cloudinary' ); } - $this->handle_failed_download( $attachment_id, $error ); + + return new \WP_Error( 'download_error', $error ); } // Prepare the asset. @@ -157,7 +221,7 @@ public function rest_download_asset( \WP_REST_Request $request ) { wp_update_attachment_metadata( $attachment_id, $meta ); } catch ( \Exception $e ) { - $this->handle_failed_download( $attachment_id, $e->getMessage() ); + return new \WP_Error( 'download_error', $e->getMessage() ); } $attachment = wp_prepare_attachment_for_js( $attachment_id ); @@ -181,6 +245,6 @@ public function rest_download_asset( \WP_REST_Request $request ) { 'data' => $attachment, ); - return rest_ensure_response( $response ); + return $response; } } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php index fe98e4448..0a0284159 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php @@ -210,6 +210,7 @@ public function rest_push_attachments( \WP_REST_Request $request ) { // Check if there is a Cloudinary ID in case this was synced on-demand before being processed by the queue. add_filter( 'cloudinary_on_demand_sync_enabled', '__return_false' ); // Disable the on-demand sync since we want the status. + add_filter( 'cloudinary_id', '__return_false' ); // Disable the on-demand sync since we want the status. if ( false === $this->plugin->components['media']->cloudinary_id( $post_id ) ) { $stat = $this->push_attachments( array( $post_id ) ); if ( ! empty( $stat['processed'] ) ) { @@ -307,11 +308,12 @@ private function get_sync_type( $attachment ) { /** * Prepare an attachment for upload. * - * @param int|\WP_Post $post The attachment to prepare. + * @param int|\WP_Post $post The attachment to prepare. + * @param bool $down_sync Flag to determine if a missing file starts a downsync. * * @return array|\WP_Error */ - public function prepare_upload( $post ) { + public function prepare_upload( $post, $down_sync = false ) { if ( is_numeric( $post ) ) { $post = get_post( $post ); @@ -331,9 +333,28 @@ public function prepare_upload( $post ) { $file = get_attached_file( $post->ID ); if ( empty( $file ) ) { return new \WP_Error( 'attachment_no_file', __( 'Attachment did not have a file.', 'cloudinary' ) ); + } elseif ( ! file_exists( $file ) ) { + // May be an old upload type. + $src = get_post_meta( $post->ID, '_wp_attached_file', true ); + if ( $this->plugin->components['media']->is_cloudinary_url( $src ) ) { + // Download first maybe. + if ( true === $down_sync ) { + $download = $this->plugin->components['sync']->managers['download']->down_sync( $post->ID ); + if ( is_wp_error( $download ) ) { + update_post_meta( $post->ID, Sync::META_KEYS['sync_error'], $download->get_error_message() ); + + return new \WP_Error( 'attachment_download_error', $download->get_error_message() ); + } + $file = get_attached_file( $post->ID ); + $file_size = filesize( $file ); + } else { + $file_size = 0; + } + } + } else { + $file_size = filesize( $file ); } - $file_size = filesize( $file ); $resource_type = $this->get_resource_type( $post ); $max_size = ( 'image' === $resource_type ? 'max_image_size' : 'max_video_size' ); @@ -341,7 +362,7 @@ public function prepare_upload( $post ) { $max_size_hr = size_format( $this->plugin->components['connect']->usage[ $max_size ] ); // translators: variable is file size. $error = sprintf( __( 'File size exceeds the maximum of %s. This media asset will be served from WordPress.', 'cloudinary' ), $max_size_hr ); - delete_post_meta( $post->ID, Sync::META_KEYS['pending'] ); // Remove Flag. + $this->plugin->components['media']->delete_post_meta( $post->ID, Sync::META_KEYS['pending'] ); // Remove Flag. return new \WP_Error( 'upload_error', $error ); } @@ -481,7 +502,7 @@ public function push_attachments( $attachments ) { // Go over each attachment. foreach ( $attachments as $attachment ) { $attachment = get_post( $attachment ); - $upload = $this->prepare_upload( $attachment->ID ); + $upload = $this->prepare_upload( $attachment->ID, true ); // Filter out any attachments with problematic options. if ( is_wp_error( $upload ) ) { @@ -555,8 +576,8 @@ public function push_attachments( $attachments ) { if ( ! empty( $result['version'] ) ) { $meta_data[ Sync::META_KEYS['version'] ] = $result['version']; } - delete_post_meta( $attachment->ID, Sync::META_KEYS['pending'] ); - $this->plugin->components['media']->update_post_meta( $attachment->ID, Sync::META_KEYS['sync_error'], false ); + $this->plugin->components['media']->delete_post_meta( $attachment->ID, Sync::META_KEYS['pending'] ); + $this->plugin->components['media']->delete_post_meta( $attachment->ID, Sync::META_KEYS['sync_error'], false ); if ( ! empty( $this->plugin->config['settings']['global_transformations']['enable_breakpoints'] ) ) { if ( ! empty( $result['responsive_breakpoints'] ) ) { // Images only. $meta_data[ Sync::META_KEYS['breakpoints'] ] = $result['responsive_breakpoints'][0]['breakpoints']; diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-sync.php index d4ff3e4a1..2c4bc7f62 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-sync.php @@ -66,7 +66,7 @@ private function register_hooks() { // Add action to upload. add_action( 'add_attachment', array( $this, 'push_on_upload' ), 10 ); // Filter id for on-demand upload sync. - add_filter( 'cloudinary_id', array( $this, 'prep_on_demand_upload' ), 10, 2 ); + add_filter( 'cloudinary_id', array( $this, 'prep_on_demand_upload' ), 9, 2 ); // Show sync status. add_filter( 'cloudinary_media_status', array( $this, 'filter_status' ), 10, 2 ); // Hook for on demand upload push. @@ -119,6 +119,13 @@ public function prep_on_demand_upload( $cloudinary_id, $attachment_id ) { // Get the file size to make sure it can exist in cloudinary. if ( file_exists( $file ) && filesize( $file ) < $this->plugin->components['connect']->usage[ $max_size ] ) { $this->add_to_sync( $attachment_id ); + } else { + // Check if the src is a url. + $file = get_post_meta( $attachment_id, '_wp_attached_file', true ); + if ( $this->plugin->components['media']->is_cloudinary_url( $file ) ) { + // Download sync. + $this->add_to_sync( $attachment_id ); + } } } } From d5cc953ea4e239406a27db06d1c43df5bce069a2 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 15:29:34 +0200 Subject: [PATCH 06/14] version bump --- .../cloudinary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php index e7bef4441..65cb8434a 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php @@ -3,7 +3,7 @@ * Plugin Name: Cloudinary * Plugin URI: https://cloudinary.com/documentation/wordpress_integration * Description: With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website’s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress. - * Version: 2.0.2 + * Version: 2.0.3 * Author: Cloudinary Ltd., XWP * Author URI: https://cloudinary.com/ * License: GPLv2+ From 4374b49c0c6e4da4cf5214402831eb38495c42dd Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 16:43:57 +0200 Subject: [PATCH 07/14] noneed to verify --- .../php/class-rest-api.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php index 6bd2158e9..c857cc0dd 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-rest-api.php @@ -63,11 +63,12 @@ public function background_request( $endpoint, $params, $method = 'POST' ) { // Setup a call for a background sync. $params['nonce'] = wp_create_nonce( 'wp_rest' ); $args = array( - 'timeout' => 1, - 'blocking' => false, - 'method' => $method, - 'headers' => array(), - 'body' => $params, + 'timeout' => 1, + 'blocking' => false, + 'sslverify' => false, + 'method' => $method, + 'headers' => array(), + 'body' => $params, ); if ( is_user_logged_in() ) { // Setup cookie. @@ -75,7 +76,7 @@ public function background_request( $endpoint, $params, $method = 'POST' ) { array_pop( $logged_cookie ); // remove the scheme. // Add logged in cookie to request. - $args['cookies'] = array( + $args['cookies'] = array( new \WP_Http_Cookie( array( 'name' => LOGGED_IN_COOKIE, From 041a3c6700f1647ccf48795d84a61a809bc09783 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 16:55:21 +0200 Subject: [PATCH 08/14] capture id --- .../php/media/class-upgrade.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php index af4ff4630..55517a0db 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php @@ -106,6 +106,7 @@ function ( $val ) use ( $media ) { // Remove extension. $path = pathinfo( $public_id ); $public_id = strstr( $public_id, '.' . $path['extension'], true ); + $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['public_id'], $public_id ); return $public_id; } From 26bc56e3cf437c572238fd51928fabda98c0887b Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 17:16:12 +0200 Subject: [PATCH 09/14] set ID and delete correct folder --- .../php/sync/class-delete-sync.php | 2 +- .../php/sync/class-push-sync.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-delete-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-delete-sync.php index 47387dba4..3852f38a4 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-delete-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-delete-sync.php @@ -95,7 +95,7 @@ public function delete_asset( $post_id ) { } // Next we need to check that the file is in the cloudinary folder. $parts = explode( '/', $public_id ); - $cloudinary_folder = $this->plugin->config['settings']['general']['cloudinary_folder']; + $cloudinary_folder = $this->plugin->config['settings']['sync_media']['cloudinary_folder'] ? $this->plugin->config['settings']['sync_media']['cloudinary_folder'] : ''; if ( $cloudinary_folder === $parts[0] ) { $type = $this->plugin->components['sync']->managers['push']->get_resource_type( $post_id ); $options = array( diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php index 0a0284159..f69020e31 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php @@ -599,6 +599,7 @@ public function push_attachments( $attachments ) { $meta = wp_get_attachment_metadata( $attachment->ID, true ); $meta[ Sync::META_KEYS['cloudinary'] ] = $meta_data; wp_update_attachment_metadata( $attachment->ID, $meta ); + $this->plugin->components['media']->update_post_meta( $attachment->ID, Sync::META_KEYS['public_id'], $upload['options']['public_id'] ); // Search and update link references in content. $content_search = new \WP_Query( array( 's' => 'wp-image-' . $attachment->ID, 'fields' => 'ids', 'posts_per_page' => 1000 ) ); if ( ! empty( $content_search->found_posts ) ) { From 4929432d160fcdfacd3b2bf0bb3a0abe8490d9d7 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 17:36:26 +0200 Subject: [PATCH 10/14] video order --- .../tabs/settings-global-video-transformations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php index 7e3314634..9b750f944 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php @@ -32,10 +32,10 @@ 'label' => __( 'Video player', 'cloudinary' ), 'description' => __( 'Which video player to use on all videos.', 'cloudinary' ), 'type' => 'select', - 'default' => 'cld', + 'default' => 'wp', 'choices' => array( - 'cld' => __( 'Cloudinary Player', 'cloudinary' ), 'wp' => __( 'WordPress Player', 'cloudinary' ), + 'cld' => __( 'Cloudinary Player', 'cloudinary' ), ), ), 'video_controls' => array( From fafc160acfd2b8d320df1756b2e62dcc2db5f5e3 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 19:03:39 +0200 Subject: [PATCH 11/14] remove q_auto on videos --- .../php/class-media.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php index 8f0ea364e..cd966dc35 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php @@ -497,7 +497,6 @@ public function apply_default_transformations( array $transformations, $type = ' $global = $this->global_transformations->globals[ $type ]; $default = array(); if ( 'video' === $type ) { - $default['quality'] = 'auto'; if ( isset( $global['video_limit_bitrate'] ) && 'on' === $global['video_limit_bitrate'] ) { $default['bit_rate'] = $global['video_bitrate'] . 'k'; } From 45d3025c53cc4378986d03b0311c0670be500777 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 19:09:25 +0200 Subject: [PATCH 12/14] typo in value --- .../tabs/settings-global-video-transformations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php index 9b750f944..2976aff2b 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-global-video-transformations.php @@ -13,7 +13,7 @@ 'connect', ), 'sanitize_callback' => function ( $value ) { - if ( 'off' === $value['video_autoplay'] && 'off' === $value['video_controls'] && 'off' === $value['video_loop'] ) { + if ( 'off' === $value['video_autoplay_mode'] && 'off' === $value['video_controls'] && 'off' === $value['video_loop'] ) { return new WP_Error( 'cant_play', __( 'At least one of the video player settings must be set to "On".', 'cloudinary' ) ); } From ee0618445ec5b494fa0faa22f9c9092e7eb7a774 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 3 Apr 2020 19:22:25 +0200 Subject: [PATCH 13/14] remove signature key --- .../php/sync/class-upload-queue.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-queue.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-queue.php index df904c314..6d0b77683 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-queue.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-upload-queue.php @@ -199,13 +199,6 @@ public function build_queue() { 'key' => Sync::META_KEYS['public_id'], 'compare' => 'NOT EXISTS', ), - array( - 'relation' => 'OR', - array( - 'key' => Sync::META_KEYS['signature'], - 'compare' => 'NOT EXISTS', - ), - ), ), 'ignore_sticky_posts' => false, 'no_found_rows' => true, From e6e69211d6f151ad8cfb6478721e5d5b3f87ecfc Mon Sep 17 00:00:00 2001 From: asisayag Date: Fri, 3 Apr 2020 22:24:04 +0300 Subject: [PATCH 14/14] Version 2.0.3 --- .../readme.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt index ae3a1d32c..3cde4c176 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt @@ -108,6 +108,9 @@ You can read the plugin [documentation](https://cloudinary.com/documentation/wor 9. Easily Configure Your Account == Changelog == += 2.0.3 (03 Apr 2020) = + * Fix migration issue + = 2.0.2 (03 Apr 2020) = * Rollback last fix