/** * Rebuild the attachment metadata for an attachment * * @param mixed $attachment * * @return bool */ protected function upgrade_item($attachment) { $s3object = unserialize($attachment->s3object); if (false === $s3object) { AS3CF_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) { AS3CF_Error::log(sprintf(__('There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront'), $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 the region for the bucket where an attachment is located, update the S3 meta. * * @param mixed $attachment * * @return bool */ protected function upgrade_item($attachment) { $s3object = unserialize($attachment->s3object); if (false === $s3object) { AS3CF_Error::log('Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object); $this->error_count++; return false; } // retrieve region and update the attachment metadata $region = $this->as3cf->get_s3object_region($s3object, $attachment->ID); if (is_wp_error($region)) { AS3CF_Error::log('Error updating region: ' . $region->get_error_message()); $this->error_count++; return false; } return true; }
/** * Apply ACL to an attachment and associated files * * @param int $post_id * @param array $s3object * @param string $acl * * @return array|bool|WP_Error */ function set_attachment_acl_on_s3($post_id, $s3object, $acl) { // Return early if already set to the desired ACL if (isset($s3object['acl']) && $acl === $s3object['acl']) { return false; } $args = array('ACL' => $acl, 'Bucket' => $s3object['bucket'], 'Key' => $s3object['key']); $region = isset($s3object['region']) ? $s3object['region'] : false; $s3client = $this->get_s3client($region, true); try { $s3client->PutObjectAcl($args); $s3object['acl'] = $acl; // update S3 meta data if ($acl == self::DEFAULT_ACL) { unset($s3object['acl']); } update_post_meta($post_id, 'amazonS3_info', $s3object); } catch (Exception $e) { $msg = 'Error setting ACL to ' . $acl . ' for ' . $s3object['key'] . ': ' . $e->getMessage(); AS3CF_Error::log($msg); return new WP_Error('acl_exception', $msg); } return $s3object; }
/** * Get the total file sizes for an attachment and associated files. * * @param mixed $attachment * * @return bool */ protected function upgrade_item($attachment) { $s3object = unserialize($attachment->s3object); if (false === $s3object) { AS3CF_Error::log('Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object); $this->error_count++; return false; } $region = $this->as3cf->get_s3object_region($s3object); if (is_wp_error($region)) { AS3CF_Error::log('Failed to get the region for the bucket of the attachment ' . $attachment->ID); $this->error_count++; return false; } $s3client = $this->as3cf->get_s3client($region, true); $main_file = $s3object['key']; $path_parts = pathinfo($main_file); $prefix = trailingslashit(dirname($s3object['key'])); // Used to search S3 for all files related to an attachment $search_prefix = $prefix . basename($main_file, '.' . $path_parts['extension']); $args = array('Bucket' => $s3object['bucket'], 'Prefix' => $search_prefix); try { // List objects for the attachment $result = $s3client->ListObjects($args); } catch (Exception $e) { AS3CF_Error::log('Error listing objects of prefix ' . $search_prefix . ' for attachment ' . $attachment->ID . ' from S3: ' . $e->getMessage()); $this->error_count++; return false; } $file_size_total = 0; $main_file_size = 0; foreach ($result->get('Contents') as $object) { if (!isset($object['Size'])) { continue; } $size = $object['Size']; // Increment the total size of files for the attachment $file_size_total += $size; if ($object['Key'] === $main_file) { // Record the size of the main file $main_file_size = $size; } } if (0 === $file_size_total) { AS3CF_Error::log('Total file size for the attachment is 0: ' . $attachment->ID); $this->error_count++; return false; } // Update the main file size for the attachment $meta = get_post_meta($attachment->ID, '_wp_attachment_metadata', true); $meta['filesize'] = $main_file_size; update_post_meta($attachment->ID, '_wp_attachment_metadata', $meta); // Add the total file size for all image sizes update_post_meta($attachment->ID, 'wpos3_filesize_total', $file_size_total); return true; }
/** * Download a file from S3 if the file does not exist locally and places it where * the attachment's file should be. * * @param array $s3_object * @param string $file * * @return string|bool File if downloaded, false on failure */ public function copy_s3_file_to_server($s3_object, $file) { // Make sure the directory exists $dir = dirname($file); if (!wp_mkdir_p($dir)) { $error_message = sprintf(__('The local directory %s does not exist and could not be created.', 'amazon-s3-and-cloudfront'), $dir); AS3CF_Error::log(sprintf(__('There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront'), $s3_object['key'], $error_message)); return false; } try { $this->as3cf->get_s3client($s3_object['region'], true)->getObject(array('Bucket' => $s3_object['bucket'], 'Key' => $s3_object['key'], 'SaveAs' => $file)); } catch (Exception $e) { AS3CF_Error::log(sprintf(__('There was an error attempting to download the file %s from S3: %s', 'amazon-s3-and-cloudfront'), $s3_object['key'], $e->getMessage())); return false; } return $file; }