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 004d4fb07..2ffd89d18 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 @@ -655,11 +655,7 @@ public function get_public_id( $attachment_id ) { public function get_cloudinary_id( $attachment_id ) { // A cloudinary_id is a public_id with a file extension. - $public_id = $this->get_public_id( $attachment_id ); - $suffix_data = $this->get_post_meta( $attachment_id, Sync::META_KEYS['suffix'], true ); - if ( is_array( $suffix_data ) && ! empty( $suffix_data['suffix'] ) && $suffix_data['public_id'] === $public_id ) { - $public_id = $public_id . $suffix_data['suffix']; - } + $public_id = $this->get_public_id( $attachment_id ); $file = get_attached_file( $attachment_id ); $info = pathinfo( $file ); $cloudinary_id = $public_id . '.' . $info['extension']; 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 35a34b1c9..7845b1904 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 @@ -49,7 +49,6 @@ class Sync implements Setup, Assets { 'sync_error' => '_sync_error', 'cloudinary' => '_cloudinary_v2', 'folder_sync' => '_folder_sync', - 'suffix' => '_suffix', 'syncing' => '_cloudinary_syncing', 'downloading' => '_cloudinary_downloading', ); @@ -173,77 +172,6 @@ public function get_signature( $post_id ) { return $return; } - /** - * Generate a new Public ID for an asset. - * - * @param int $attachment_id The attachment ID for the new public ID. - * - * @return string|null - */ - public function generate_public_id( $attachment_id ) { - $settings = $this->plugin->config['settings']; - $cld_folder = trailingslashit( $settings['sync_media']['cloudinary_folder'] ); - $file = get_attached_file( $attachment_id ); - $file_info = pathinfo( $file ); - $public_id = $cld_folder . $file_info['filename']; - - return $public_id; - } - - /** - * Maybe add a suffix to the public ID if it's not unique. - * - * @param string $public_id The public ID to maybe add a suffix. - * @param int $attachment_id The attachment ID. - * @param string|null $suffix The suffix to maybe add. - * - * @return string The public ID. - */ - public function add_suffix_maybe( $public_id, $attachment_id, $suffix = null ) { - - // Test if asset exists by calling just the head on the asset url, to prevent API rate limits. - $url = $this->plugin->components['connect']->api->cloudinary_url( $public_id . $suffix ); - $req = wp_remote_head( $url, array( 'body' => array( 'rdm' => wp_rand( 100, 999 ) ) ) ); - $asset_error = strtolower( wp_remote_retrieve_header( $req, 'x-cld-error' ) ); - $code = wp_remote_retrieve_response_code( $req ); - - // If the request is not a 404 & does not have a cld-error header stating resource not found, it exists and should be checked that it's not a resync or generate a prefixed ID. - if ( 404 !== $code && false === strpos( $asset_error, 'resource not found' ) ) { - - // Get the attachment type. - if ( wp_attachment_is( 'image', $attachment_id ) ) { - $type = 'image'; - } elseif ( wp_attachment_is( 'video', $attachment_id ) ) { - $type = 'video'; - } elseif ( wp_attachment_is( 'audio', $attachment_id ) ) { - $type = 'audio'; - } else { - // not supported. - return null; - } - $cld_asset = $this->plugin->components['connect']->api->get_asset_details( $public_id, $type ); - if ( ! is_wp_error( $cld_asset ) && ! empty( $cld_asset['public_id'] ) ) { - $context_id = null; - - // Exists, check to see if this asset originally belongs to this ID. - if ( ! empty( $cld_asset['context'] ) && ! empty( $cld_asset['context']['custom'] ) && ! empty( $cld_asset['context']['custom']['wp_id'] ) ) { - $context_id = (int) $cld_asset['context']['custom']['wp_id']; - } - - // Generate new ID only if context ID is not related. - if ( $context_id !== $attachment_id ) { - // Generate a new ID with a uniqueID prefix. - $suffix = '-' . uniqid(); - - // Return new potential suffixed ID. - return $this->add_suffix_maybe( $public_id, $attachment_id, $suffix ); - } - } - } - - return $suffix; - } - /** * Additional component setup. */ @@ -251,7 +179,6 @@ public function setup() { if ( $this->plugin->config['connect'] ) { $this->managers['upload']->setup(); $this->managers['delete']->setup(); - $this->managers['push']->setup(); } } } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/connect/class-api.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/connect/class-api.php index 08d80d6ec..279a7da93 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/connect/class-api.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/connect/class-api.php @@ -269,20 +269,6 @@ public function cloudinary_url( $public_id, $args = array(), $size = array(), $c return implode( '/', $url_parts ); } - /** - * Get the details of an asset by public ID. - * - * @param string $public_id The public_id to check. - * @param string $type The asset type. - * - * @return array|\WP_Error - */ - public function get_asset_details( $public_id, $type ) { - $url = $this->url( 'resources', $type . '/upload/' . $public_id, true ); - - return $this->call( $url, array( 'body' => $args ), 'get' ); - } - /** * Upload a large asset in chunks. * 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 7a3079394..cd48f0c6e 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 @@ -47,34 +47,6 @@ class Push_Sync { */ protected $post_id; - /** - * Holds the media component. - * - * @var \Cloudinary\Media - */ - protected $media; - - /** - * Holds the sync component. - * - * @var \Cloudinary\Sync\ - */ - protected $sync; - - /** - * Holds the connect component. - * - * @var \Cloudinary\Connect - */ - protected $connect; - - /** - * Holds the Rest_API component. - * - * @var \Cloudinary\REST_API - */ - protected $api; - /** * Push_Sync constructor. * @@ -104,17 +76,6 @@ private function register_hooks() { add_filter( 'cloudinary_api_rest_endpoints', array( $this, 'rest_endpoints' ) ); } - /** - * Setup this component. - */ - public function setup() { - // Setup components. - $this->media = $this->plugin->components['media']; - $this->sync = $this->plugin->components['sync']; - $this->connect = $this->plugin->components['connect']; - $this->api = $this->plugin->components['api']; - } - /** * Add endpoints to the \Cloudinary\REST_API::$endpoints array. * @@ -182,7 +143,7 @@ public function rest_get_queue_status() { return rest_ensure_response( array( 'success' => true, - 'data' => $this->sync->managers['queue']->get_queue_status(), + 'data' => $this->plugin->components['sync']->managers['queue']->get_queue_status(), ) ); } @@ -197,13 +158,13 @@ public function rest_get_queue_status() { public function rest_start_sync( \WP_REST_Request $request ) { $stop = $request->get_param( 'stop' ); - $queue = $this->sync->managers['queue']->get_queue(); + $queue = $this->plugin->components['sync']->managers['queue']->get_queue(); if ( empty( $queue['pending'] ) || ! empty( $stop ) ) { - $this->sync->managers['queue']->stop_queue(); + $this->plugin->components['sync']->managers['queue']->stop_queue(); return $this->rest_get_queue_status(); // Nothing to sync. } - $this->sync->managers['queue']->start_queue(); + $this->plugin->components['sync']->managers['queue']->start_queue(); return $this->call_thread(); @@ -241,18 +202,18 @@ public function rest_push_attachments( \WP_REST_Request $request ) { // Process queue based. if ( ! empty( $last_id ) && ! empty( $last_result ) ) { - $this->sync->managers['queue']->mark( $last_id, $last_result ); + $this->plugin->components['sync']->managers['queue']->mark( $last_id, $last_result ); } - if ( ! $this->sync->managers['queue']->is_running() ) { // Check it wasn't stopped. + if ( ! $this->plugin->components['sync']->managers['queue']->is_running() ) { // Check it wasn't stopped. return $this->rest_get_queue_status(); } - $this->post_id = $this->sync->managers['queue']->get_post(); + $this->post_id = $this->plugin->components['sync']->managers['queue']->get_post(); // No post, end of queue. if ( empty( $this->post_id ) ) { - $this->sync->managers['queue']->stop_queue(); + $this->plugin->components['sync']->managers['queue']->stop_queue(); return $this->rest_get_queue_status(); } @@ -272,7 +233,7 @@ public function resume_queue() { add_filter( 'cloudinary_on_demand_sync_enabled', '__return_false' ); // Disable the on-demand sync since we want the status. define( 'DOING_BULK_SYNC', true ); // Define bulk sync in action. - if ( ! $this->sync->is_synced( $this->post_id ) ) { + if ( ! $this->plugin->components['sync']->is_synced( $this->post_id ) ) { $stat = $this->push_attachments( array( $this->post_id ) ); if ( ! empty( $stat['processed'] ) ) { $result = 'done'; @@ -308,7 +269,7 @@ private function call_thread( $last_id = null, $last_result = null ) { } // Setup background call to continue the queue. - $this->api->background_request( 'process', $params ); + $this->plugin->components['api']->background_request( 'process', $params ); return $this->rest_get_queue_status(); } @@ -343,7 +304,7 @@ private function get_sync_type( $attachment ) { $type = 'upload'; // Check for explicit (has public_id, but no breakpoints). - $attachment_signature = $this->sync->get_signature( $attachment->ID ); + $attachment_signature = $this->plugin->components['sync']->get_signature( $attachment->ID ); if ( empty( $attachment_signature ) ) { if ( ! empty( $attachment->{Sync::META_KEYS['public_id']} ) ) { // Has a public id but no signature, explicit update to complete download. @@ -352,7 +313,7 @@ private function get_sync_type( $attachment ) { // fallback to upload. } else { // Has signature find differences and use specific sync method. - $required_signature = $this->sync->generate_signature( $attachment->ID ); + $required_signature = $this->plugin->components['sync']->generate_signature( $attachment->ID ); foreach ( $required_signature as $key => $signature ) { if ( ( ! isset( $attachment_signature[ $key ] ) || $attachment_signature[ $key ] !== $signature ) && isset( $this->sync_types[ $key ] ) ) { return $this->sync_types[ $key ]; @@ -370,11 +331,11 @@ private function get_sync_type( $attachment ) { * Prepare an attachment for upload. * * @param int|\WP_Post $post The attachment to prepare. - * @param bool $push_sync Flag to determine if this prep is for a sync. True = build for syncing, false = build for validation. + * @param bool $down_sync Flag to determine if a missing file starts a downsync. * * @return array|\WP_Error */ - public function prepare_upload( $post, $push_sync = false ) { + public function prepare_upload( $post, $down_sync = false ) { if ( is_numeric( $post ) ) { $post = get_post( $post ); @@ -390,6 +351,9 @@ public function prepare_upload( $post, $push_sync = false ) { return new \WP_Error( 'attachment_post_expected', __( 'An attachment post was expected.', 'cloudinary' ) ); } + // Get the media component. + $media = $this->plugin->components['media']; + // First check if this has a file and it can be uploaded. $file = get_attached_file( $post->ID ); $file_size = 0; @@ -399,10 +363,10 @@ public function prepare_upload( $post, $push_sync = false ) { } elseif ( ! file_exists( $file ) ) { // May be an old upload type. $src = get_post_meta( $post->ID, '_wp_attached_file', true ); - if ( $this->media->is_cloudinary_url( $src ) ) { + if ( $media->is_cloudinary_url( $src ) ) { // Download first maybe. - if ( true === $push_sync ) { - $download = $this->sync->managers['download']->down_sync( $post->ID ); + if ( true === $down_sync ) { + $download = $this->plugin->components['sync']->managers['download']->down_sync( $post->ID ); if ( is_wp_error( $download ) ) { delete_post_meta( $post->ID, Sync::META_KEYS['downloading'] ); update_post_meta( $post->ID, Sync::META_KEYS['sync_error'], $download->get_error_message() ); @@ -421,12 +385,12 @@ public function prepare_upload( $post, $push_sync = false ) { $resource_type = $this->get_resource_type( $post ); $max_size = ( 'image' === $resource_type ? 'max_image_size' : 'max_video_size' ); - if ( ! empty( $this->connect->usage[ $max_size ] ) && $file_size > $this->connect->usage[ $max_size ] ) { - $max_size_hr = size_format( $this->connect->usage[ $max_size ] ); + if ( ! empty( $this->plugin->components['connect']->usage[ $max_size ] ) && $file_size > $this->plugin->components['connect']->usage[ $max_size ] ) { + $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 ); - $this->media->delete_post_meta( $post->ID, Sync::META_KEYS['pending'] ); // Remove Flag. + $media->delete_post_meta( $post->ID, Sync::META_KEYS['pending'] ); // Remove Flag. // Cleanup flags delete_post_meta( $post->ID, Sync::META_KEYS['syncing'] ); @@ -440,8 +404,8 @@ public function prepare_upload( $post, $push_sync = false ) { $public_id = $post->{Sync::META_KEYS['public_id']}; // use the __get method on the \WP_Post to get post_meta. $cld_folder = trailingslashit( $settings['sync_media']['cloudinary_folder'] ); if ( empty( $public_id ) ) { - // Create a new public_id. - $public_id = $this->sync->generate_public_id( $post->ID ); + $file_info = pathinfo( $file ); + $public_id = $cld_folder . $file_info['filename']; } // Assume that the public_id is a root item. @@ -456,7 +420,7 @@ public function prepare_upload( $post, $push_sync = false ) { $public_id_file = $public_id_info['filename']; } // Check if this asset is a folder sync. - $folder_sync = $this->media->get_post_meta( $post->ID, Sync::META_KEYS['folder_sync'], true ); + $folder_sync = $media->get_post_meta( $post->ID, Sync::META_KEYS['folder_sync'], true ); if ( ! empty( $folder_sync ) && false === $downsync ) { $public_id_folder = $cld_folder; // Ensure the public ID folder is constant. } else { @@ -489,7 +453,7 @@ public function prepare_upload( $post, $push_sync = false ) { $imagesize = getimagesize( $file ); $meta['width'] = $imagesize[0]; } - $max_width = $this->media->get_max_width(); + $max_width = $media->get_max_width(); // Add breakpoints request options. if ( ! empty( $settings['global_transformations']['enable_breakpoints'] ) ) { $options['responsive_breakpoints'] = array( @@ -499,7 +463,7 @@ public function prepare_upload( $post, $push_sync = false ) { 'max_width' => $meta['width'] < $max_width ? $meta['width'] : $max_width, 'min_width' => $settings['global_transformations']['min_width'], ); - $transformations = $this->media->get_transformation_from_meta( $post->ID ); + $transformations = $media->get_transformation_from_meta( $post->ID ); if ( ! empty( $transformations ) ) { $options['responsive_breakpoints']['transformation'] = Api::generate_transformation_string( $transformations ); } @@ -530,39 +494,11 @@ public function prepare_upload( $post, $push_sync = false ) { } // Restructure the path to the filename to allow correct placement in Cloudinary. - $public_id = ltrim( $public_id_folder . $options['public_id'], '/' ); - // If this is a push sync, make sure the ID is allowed and unique. - - // Setup suffix data for unique ids. - $suffix_defaults = array( - 'public_id' => $public_id, - 'suffix' => null, - ); - $suffix_meta = $this->media->get_post_meta( $post->ID, Sync::META_KEYS['suffix'], true ); - $suffix_data = wp_parse_args( $suffix_meta, $suffix_defaults ); - - // Prepare a uniqueness check and get a suffix if needed. - if ( true === $push_sync && true !== $downsync && empty( get_post_meta( $post->ID, Sync::META_KEYS['downloading'], true ) ) ) { - if ( $public_id !== $suffix_data['public_id'] || empty( $suffix_data['suffix'] ) ) { - $suffix_data['suffix'] = $this->sync->add_suffix_maybe( $public_id, $post->ID ); - if ( ! empty( $suffix_data['suffix'] ) ) { - // Only save if there is a suffix to save on metadata. - $this->media->update_post_meta( $post->ID, Sync::META_KEYS['suffix'], $suffix_data ); - } else { - // Clear meta data in case of a unique name on a rename etc. - $this->media->delete_post_meta( $post->ID, Sync::META_KEYS['suffix'] ); - } - } - } - // Add Suffix to public_id. - if ( ! empty( $suffix_data['suffix'] ) ) { - $public_id = $public_id . $suffix_data['suffix']; - } + $public_id = ltrim( $public_id_folder . $options['public_id'], '/' ); $return = array( 'file' => $file, 'folder' => ltrim( $cld_folder, '/' ), 'public_id' => $public_id, - 'suffix' => $suffix_data['suffix'], 'breakpoints' => array(), 'options' => $options, ); @@ -607,6 +543,8 @@ public function push_attachments( $attachments ) { 'total' => count( $attachments ), 'processed' => 0, ); + // Get media component. + $media = $this->plugin->components['media']; // Go over each attachment. foreach ( $attachments as $attachment ) { @@ -660,28 +598,28 @@ public function push_attachments( $attachments ) { if ( ! empty( $upload['options']['context'] ) ) { $args['context'] = $upload['options']['context']; } - $result = $this->connect->api->explicit( $args ); + $result = $this->plugin->components['connect']->api->explicit( $args ); } elseif ( 'rename' === $sync_type ) { // Rename an asset. $args = array( - 'from_public_id' => $this->media->get_post_meta( $attachment->ID, Sync::META_KEYS['public_id'] ), + 'from_public_id' => $media->get_post_meta( $attachment->ID, Sync::META_KEYS['public_id'] ), 'to_public_id' => $upload['public_id'], ); - $result = $this->connect->api->{$upload['options']['resource_type']}( 'rename', 'POST', $args ); + $result = $this->plugin->components['connect']->api->{$upload['options']['resource_type']}( 'rename', 'POST', $args ); } else { // dynamic sync type.. - $result = $this->connect->api->{$sync_type}( $upload['file'], $upload['options'] ); + $result = $this->plugin->components['connect']->api->{$sync_type}( $upload['file'], $upload['options'] ); } } else { // Large Upload. - $result = $this->connect->api->upload_large( $upload['file'], $upload['options'] ); + $result = $this->plugin->components['connect']->api->upload_large( $upload['file'], $upload['options'] ); } // Exceptions are handled by the Upload wrapper class and returned as \WP_Error, so check for it. if ( is_wp_error( $result ) ) { $error = $result->get_error_message(); $stats['fail'][] = $error; - $this->media->update_post_meta( $attachment->ID, Sync::META_KEYS['sync_error'], $error ); + $media->update_post_meta( $attachment->ID, Sync::META_KEYS['sync_error'], $error ); delete_post_meta( $attachment->ID, Sync::META_KEYS['syncing'] ); continue; } @@ -689,20 +627,20 @@ public function push_attachments( $attachments ) { // Successful upload, so lets update meta. if ( is_array( $result ) && ( array_key_exists( 'public_id', $result ) || array_key_exists( 'public_ids', $result ) ) ) { $meta_data = array( - Sync::META_KEYS['signature'] => $this->sync->generate_signature( $attachment->ID ), + Sync::META_KEYS['signature'] => $this->plugin->components['sync']->generate_signature( $attachment->ID ), ); // We only have a version if updating a file or an upload. if ( ! empty( $result['version'] ) ) { $meta_data[ Sync::META_KEYS['version'] ] = $result['version']; } - $this->media->delete_post_meta( $attachment->ID, Sync::META_KEYS['pending'] ); + $media->delete_post_meta( $attachment->ID, Sync::META_KEYS['pending'] ); // Cleanup flags delete_post_meta( $attachment->ID, Sync::META_KEYS['downloading'] ); delete_post_meta( $attachment->ID, Sync::META_KEYS['syncing'] ); - $this->media->delete_post_meta( $attachment->ID, Sync::META_KEYS['sync_error'], false ); + $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']; @@ -711,12 +649,6 @@ public function push_attachments( $attachments ) { delete_post_meta( $attachment->ID, Sync::META_KEYS['breakpoints'] ); } } - - // Reset public_id without suffix. - if ( ! empty( $upload['suffix'] ) ) { - $upload['options']['public_id'] = strstr( $upload['options']['public_id'], $upload['suffix'], true ); - } - // Generate a public_id sync hash. if ( ! empty( $upload['options']['public_id'] ) ) { // a transformation breakpoints only ever happens on a down sync. $sync_key = '_' . md5( $upload['options']['public_id'] ); @@ -729,8 +661,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->media->update_post_meta( $attachment->ID, Sync::META_KEYS['public_id'], $upload['options']['public_id'] ); + $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 ) ) {