/**
  * 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;
 }