diff --git a/README.md b/README.md index 4c3da245..9f6e8fb4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ **Tags:** uploads, amazon, s3, mirror, admin, media, cdn, cloudfront **Requires at least:** 3.7 **Tested up to:** 4.3 -**Stable tag:** 0.9.4 +**Stable tag:** 0.9.5 **License:** GPLv3 Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery. @@ -67,6 +67,9 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin ## Changelog ## +### 0.9.5 - 2015-09-01 ### +* Bug fix: Fatal error: Cannot use object of type WP_Error as array + ### 0.9.4 - 2015-08-27 ### * New: Update all existing attachments with missing file sizes when the 'Remove Files From Server' option is enabled (automatically runs in the background) * Improvement: Show when constants are used to set bucket and region options diff --git a/classes/amazon-s3-and-cloudfront.php b/classes/amazon-s3-and-cloudfront.php index 134abbb0..7845e1f6 100644 --- a/classes/amazon-s3-and-cloudfront.php +++ b/classes/amazon-s3-and-cloudfront.php @@ -86,6 +86,7 @@ function init( $plugin_file_path ) { new AS3CF_Upgrade_Region_Meta( $this ); new AS3CF_Upgrade_File_Sizes( $this ); + new AS3CF_Upgrade_Meta_WP_Error( $this ); add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) ); add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) ); @@ -489,7 +490,7 @@ function wp_update_attachment_metadata( $data, $post_id ) { } // upload attachment to S3 - $data = $this->upload_attachment_to_s3( $post_id, $data ); + $this->upload_attachment_to_s3( $post_id, $data ); return $data; } @@ -507,9 +508,7 @@ function wp_update_attachment_metadata( $data, $post_id ) { * @return array|WP_Error $s3object|$meta If meta is supplied, return it. Else return S3 meta */ function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $force_new_s3_client = false, $remove_local_files = true ) { - $return_metadata = true; if ( is_null( $data ) ) { - $return_metadata = false; $data = wp_get_attachment_metadata( $post_id, true ); } @@ -628,11 +627,8 @@ function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $fo // Store in the attachment meta data for use by WP $data['filesize'] = $bytes; - if ( ! $return_metadata ) { - // Upload happening outside of 'wp_update_attachment_metadata' filter, - // So update metadata manually - update_post_meta( $post_id, '_wp_attachment_metadata', $data ); - } + // Update metadata with filesize + update_post_meta( $post_id, '_wp_attachment_metadata', $data ); // Add to the file size total $filesize_total += $bytes; @@ -692,21 +688,13 @@ function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $fo // Make sure we don't have a cached file sizes in the meta unset( $data['filesize'] ); - if ( ! $return_metadata ) { - // Upload happening outside of 'wp_update_attachment_metadata' filter, - // So update metadata manually - update_post_meta( $post_id, '_wp_attachment_metadata', $data ); - } + // Remove the filesize from the metadata + update_post_meta( $post_id, '_wp_attachment_metadata', $data ); delete_post_meta( $post_id, 'wpos3_filesize_total' ); } } - if ( $return_metadata ) { - // If the attachment metadata is supplied, return it - return $data; - } - return $s3object; } diff --git a/classes/upgrades/as3cf-meta-wp-error.php b/classes/upgrades/as3cf-meta-wp-error.php new file mode 100644 index 00000000..2b23d725 --- /dev/null +++ b/classes/upgrades/as3cf-meta-wp-error.php @@ -0,0 +1,156 @@ +upgrade_id = 3; + $this->upgrade_name = 'meta_error'; + $this->upgrade_type = 'attachments'; + + $this->running_update_text = __( 'and rebuilding the metadata for attachments that may have been corrupted.', 'as3cf' ); + + parent::__construct( $as3cf ); + } + + /** + * Rebuild the attachment metadata for an attachment + * + * @param $attachment + * + * @return bool + */ + function upgrade_attachment( $attachment ) { + $s3object = unserialize( $attachment->s3object ); + if ( false === $s3object ) { + error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object ); + $this->error_count++; + + return false; + } + + $file = get_attached_file( $attachment->ID, true ); + + if ( ! file_exists( $file ) ) { + // Copy back the file to the server if doesn't exist so we can successfully + // regenerate the attachment metadata + try { + $args = array( + 'Bucket' => $s3object['bucket'], + 'Key' => $s3object['key'], + 'SaveAs' => $file, + ); + $this->as3cf->get_s3client( $s3object['region'], true )->getObject( $args ); + } catch ( Exception $e ) { + error_log( sprintf( __( 'There was an error attempting to download the file %s from S3: %s', 'as3cf' ), $s3object['key'], $e->getMessage() ) ); + + return false; + } + } + + // Remove corrupted meta + delete_post_meta( $attachment->ID, '_wp_attachment_metadata' ); + + require_once ABSPATH . '/wp-admin/includes/image.php'; + // Generate new attachment meta + wp_update_attachment_metadata( $attachment->ID, wp_generate_attachment_metadata( $attachment->ID, $file ) ); + + return true; + } + + /** + * Get a count of all attachments without region in their S3 metadata + * for the whole site + * + * @return int + */ + function count_attachments_to_process() { + // get the table prefixes for all the blogs + $table_prefixes = $this->as3cf->get_all_blog_table_prefixes(); + $all_count = 0; + + foreach ( $table_prefixes as $blog_id => $table_prefix ) { + $count = $this->get_attachments_with_error_metadata( $table_prefix, true ); + $all_count += $count; + } + + return $all_count; + } + + /** + * Get all attachments that don't have region in their S3 meta data for a blog + * + * @param string $prefix + * @param int $limit + * + * @return mixed + */ + function get_attachments_to_process( $prefix, $limit ) { + $attachments = $this->get_attachments_with_error_metadata( $prefix, false, $limit ); + + return $attachments; + } + + /** + * Get S3 attachments that have had their _wp_attachment_metadata corrupted + * + * @param string $prefix + * @param bool|false $count + * @param null|int $limit + * + * @return array|int + */ + function get_attachments_with_error_metadata( $prefix, $count = false, $limit = null ) { + global $wpdb; + + $sql = "FROM `{$prefix}postmeta` pm1 + LEFT OUTER JOIN `{$prefix}postmeta` pm2 + ON pm1.`post_id` = pm2.`post_id` + AND pm2.`meta_key` = '_wp_attachment_metadata' + WHERE pm1.`meta_key` = 'amazonS3_info' + AND pm2.`meta_value` like '%%WP_Error%%'"; + + if ( $count ) { + $sql = 'SELECT COUNT(*)' . $sql; + + return $wpdb->get_var( $sql ); + } + + $sql = "SELECT pm1.`post_id` as `ID`, pm1.`meta_value` AS 's3object'" . $sql; + + if ( ! is_null( $limit ) ) { + $sql .= ' LIMIT %d'; + + $sql = $wpdb->prepare( $sql, $limit ); + } + + return $wpdb->get_results( $sql, OBJECT ); + } +} \ No newline at end of file diff --git a/languages/amazon-s3-and-cloudfront-en.pot b/languages/amazon-s3-and-cloudfront-en.pot index 0291c033..4844d90f 100644 --- a/languages/amazon-s3-and-cloudfront-en.pot +++ b/languages/amazon-s3-and-cloudfront-en.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: amazon-s3-and-cloudfront\n" "Report-Msgid-Bugs-To: nom@deliciousbrains.com\n" -"POT-Creation-Date: 2015-08-27 20:17+0100\n" +"POT-Creation-Date: 2015-09-01 09:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,112 +25,112 @@ msgstr "" msgid "S3 and CloudFront" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:522 +#: classes/amazon-s3-and-cloudfront.php:521 #, php-format msgid "File %s does not exist" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:531 +#: classes/amazon-s3-and-cloudfront.php:530 #, php-format msgid "Mime type %s is not allowed" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:608 +#: classes/amazon-s3-and-cloudfront.php:607 #, php-format msgid "Error uploading %s to S3: %s" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1259 +#: classes/amazon-s3-and-cloudfront.php:1247 msgid "Cheatin’ eh?" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1263 +#: classes/amazon-s3-and-cloudfront.php:1251 msgid "You do not have sufficient permissions to access this page." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1269 +#: classes/amazon-s3-and-cloudfront.php:1257 msgid "No bucket name provided." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1544 +#: classes/amazon-s3-and-cloudfront.php:1532 msgid "Error Getting Bucket Region" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1545 +#: classes/amazon-s3-and-cloudfront.php:1533 #, php-format msgid "There was an error attempting to get the region of the bucket %s: %s" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1665 +#: classes/amazon-s3-and-cloudfront.php:1653 msgid "" "This is a test file to check if the user has write permission to S3. Delete " "me if found." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1697 +#: classes/amazon-s3-and-cloudfront.php:1685 #, php-format msgid "" "There was an error attempting to check the permissions of the bucket %s: %s" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1755 +#: classes/amazon-s3-and-cloudfront.php:1743 msgid "Error creating bucket" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1756 +#: classes/amazon-s3-and-cloudfront.php:1744 msgid "Bucket name too short." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1757 +#: classes/amazon-s3-and-cloudfront.php:1745 msgid "Bucket name too long." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1758 +#: classes/amazon-s3-and-cloudfront.php:1746 msgid "" "Invalid character. Bucket names can contain lowercase letters, numbers, " "periods and hyphens." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1759 +#: classes/amazon-s3-and-cloudfront.php:1747 msgid "Error saving bucket" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1760 +#: classes/amazon-s3-and-cloudfront.php:1748 msgid "Error fetching buckets" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1761 +#: classes/amazon-s3-and-cloudfront.php:1749 msgid "Error getting URL preview: " msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1762 +#: classes/amazon-s3-and-cloudfront.php:1750 msgid "The changes you made will be lost if you navigate away from this page" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1820 +#: classes/amazon-s3-and-cloudfront.php:1808 msgid "Cheatin' eh?" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1923 +#: classes/amazon-s3-and-cloudfront.php:1911 msgctxt "Show the media library tab" msgid "Media Library" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:1924 +#: classes/amazon-s3-and-cloudfront.php:1912 msgctxt "Show the support tab" msgid "Support" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:2060 +#: classes/amazon-s3-and-cloudfront.php:2048 #, php-format msgid "The file %s has been given %s permissions on Amazon S3." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:2561 +#: classes/amazon-s3-and-cloudfront.php:2549 msgid "Quick Start Guide" msgstr "" -#: classes/amazon-s3-and-cloudfront.php:2563 +#: classes/amazon-s3-and-cloudfront.php:2551 #, php-format msgid "" "Looks like we don't have write access to this bucket. It's likely that the " @@ -139,7 +139,7 @@ msgid "" "correctly." msgstr "" -#: classes/amazon-s3-and-cloudfront.php:2565 +#: classes/amazon-s3-and-cloudfront.php:2553 #, php-format msgid "" "Looks like we don't have access to the buckets. It's likely that the user " @@ -148,6 +148,7 @@ msgid "" msgstr "" #: classes/as3cf-plugin-compatibility.php:357 +#: classes/upgrades/as3cf-meta-wp-error.php:72 #, php-format msgid "There was an error attempting to download the file %s from S3: %s" msgstr "" @@ -201,6 +202,11 @@ msgid "" "items and the total space used in Multisite subsites." msgstr "" +#: classes/upgrades/as3cf-meta-wp-error.php:38 +msgid "" +"and rebuilding the metadata for attachments that may have been corrupted." +msgstr "" + #: classes/upgrades/as3cf-region-meta.php:36 msgid "" "and updating the metadata with the bucket region it is served from. This " diff --git a/readme.txt b/readme.txt index 29dfeb95..565d7562 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: bradt, deliciousbrains Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront Requires at least: 3.7 Tested up to: 4.3 -Stable tag: 0.9.4 +Stable tag: 0.9.5 License: GPLv3 Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery. @@ -63,6 +63,9 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin == Changelog == += 0.9.5 - 2015-09-01 = +* Bug fix: Fatal error: Cannot use object of type WP_Error as array + = 0.9.4 - 2015-08-27 = * New: Update all existing attachments with missing file sizes when the 'Remove Files From Server' option is enabled (automatically runs in the background) * Improvement: Show when constants are used to set bucket and region options diff --git a/wordpress-s3.php b/wordpress-s3.php index a7030707..b1147032 100644 --- a/wordpress-s3.php +++ b/wordpress-s3.php @@ -4,7 +4,7 @@ Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/ Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery. Author: Delicious Brains -Version: 0.9.4 +Version: 0.9.5 Author URI: http://deliciousbrains.com/ Network: True Text Domain: as3cf @@ -26,7 +26,7 @@ // Then completely rewritten. */ -$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.4'; +$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.5'; $GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['supported_addon_versions'] = array( 'amazon-s3-and-cloudfront-pro' => '1.0b1', @@ -57,6 +57,7 @@ function as3cf_init( $aws ) { require_once $abspath . '/classes/as3cf-upgrade.php'; require_once $abspath . '/classes/upgrades/as3cf-region-meta.php'; require_once $abspath . '/classes/upgrades/as3cf-file-sizes.php'; + require_once $abspath . '/classes/upgrades/as3cf-meta-wp-error.php'; require_once $abspath . '/classes/as3cf-plugin-compatibility.php'; require_once $abspath . '/classes/amazon-s3-and-cloudfront.php'; $as3cf = new Amazon_S3_And_CloudFront( __FILE__, $aws );