Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.3
* Author: Cloudinary Ltd., XWP
* Author URI: https://cloudinary.com/
* License: GPLv2+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
Expand Down Expand Up @@ -1243,7 +1242,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;
}
Expand All @@ -1266,6 +1267,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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,20 @@ 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.
$logged_cookie = wp_parse_auth_cookie( '', 'logged_in' );
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,
Expand All @@ -85,8 +86,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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class Sync implements Setup, Assets {
'transformation' => '_transformations',
'sync_error' => '_sync_error',
'cloudinary' => '_cloudinary_v2',
'attempts' => '_sync_attempts',
);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,8 @@ 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 {
} elseif ( ! empty( $public_id ) ) {
// Has public ID, but not fully down synced.
$cloudinary_id = $public_id;
}
}
Expand Down Expand Up @@ -117,19 +106,7 @@ 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 );
// 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(
'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;
}
Expand All @@ -138,7 +115,7 @@ 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() ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,22 @@ 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.
// 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 );
}
Expand All @@ -117,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';
Expand All @@ -128,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.
Expand All @@ -145,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' );
Expand All @@ -154,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.
Expand All @@ -165,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 );
Expand All @@ -189,10 +245,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 );
return $response;
}
}
Loading