Loading .gitmodules 0 → 100644 +3 −0 Original line number Diff line number Diff line [submodule "inc/aws-sdk"] path = inc/aws-sdk url = git@github.com:humanmade/aws-sdk-php.git inc/.DS_Store 0 → 100644 +6 KiB File added.No diff preview for this file type. View file aws-sdk @ d5583425 Original line number Diff line number Diff line Subproject commit d558342507cd2c333ac58e3ae8f5e21577129f47 inc/class-s3-uploads-uploader.php 0 → 100644 +83 −0 Original line number Diff line number Diff line <?php class S3_Uploads_Uploader { private $bucket; private $key; private $secret; /** * @param string $bucket * @param string $key * @param string $secret */ function __construct( $bucket, $key, $secret ) { $this->bucket = $bucket; $this->key = $key; $this->secret = $secret; } public function get_s3_url() { return 'https://' . $this->bucket . '.s3.amazonaws.com'; } /** * Upload a file to S3 * * @param string $file_path The file system path * @return string The path to the uploaded file */ public function upload_file_to_s3( $file_path ) { $relative = str_replace( ABSPATH, '', $file_path ); try { $this->s3()->putObject(array( 'Bucket' => $this->bucket, 'Key' => $relative, 'Body' => fopen( $file_path, 'r' ), 'ACL' => Aws\S3\Enum\CannedAcl::PUBLIC_READ )); } catch( Exception $e ) { return new WP_Error( 's3-upload-error', $e->getMessage() ); } return $relative; } /** * Delete a file from S3 * * @param string $file_path s3 path to file * @return bool|WP_Error */ public function delete_file_from_s3( $file_path ) { try { $this->s3()->deleteObject( array( "Bucket" => $this->bucket, "Key" => $file_path )); } catch( Exception $e ) { return new WP_Error( 's3-delete-error' ); } return true; } /** * @return Aws\S3\S3Client */ private function s3() { require_once dirname( __FILE__ ) . '/aws-sdk/aws-autoloader.php'; if ( ! empty( $this->s3 ) ) return $this->s3; $this->s3 = Aws\Common\Aws::factory( array( 'key' => $this->key, 'secret' => $this->secret ) )->get( 's3' ); return $this->s3; } } No newline at end of file inc/class-s3-uploads-wordpress-uploads-uploader.php 0 → 100644 +126 −0 Original line number Diff line number Diff line <?php /** * Upload all images to S3 * Adapted from Neeki Patel's "Uploads S3" plugin */ class S3_Uploads_WordPress_Uploads_Uploader extends S3_Uploads_Uploader { public function __construct( $bucket, $key, $secret ) { parent::__construct( $bucket, $key, $secret ); add_filter( 'wp_update_attachment_metadata', array( $this, 'filter_upload_images' ), 10, 2 ); add_filter( 'update_attached_file', array( $this, 'filter_upload_attachment' ), 10, 2 ); add_filter( 'wp_get_attachment_url', array( $this, 'filter_get_attachment_url' ), 9, 2 ); add_action( 'delete_attachment', array( $this, 'filter_delete_attachment' ) ); } /** * Upload an image to S3 when it's uploaded to WP */ public function filter_upload_images( $file, $attachment_id ) { if ( empty( $file ) ) return $file; $original_file = get_attached_file( $attachment_id ); foreach ( $file['sizes'] as $size => $image ) { $thumbnail = dirname( $original_file ) . '/' . $image['file']; if ( ! file_exists( $thumbnail ) ) continue; $response = $this->upload_file_to_s3( $thumbnail ); if ( is_wp_error( $response ) ) { echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html( $_FILES['async-upload']['name'] ) ) . '</strong><br />' . esc_html( $response->get_error_message() ) . '</div>'; } unlink( $thumbnail ); } unlink( $original_file ); return $file; } /** * Upload an attachment to S3 when it's uploaded to WP * * @param string $file * @param int $attachment_id */ public function filter_upload_attachment( $file, $attachment_id ) { if ( ! file_exists( $file ) ) return $file; $relative = str_replace( WP_CONTENT_DIR, '', $file ); $response = wp_remote_head( $this->get_s3_url() .'/'. $relative ); if ( wp_remote_retrieve_response_code( $response ) == 200 ) { wp_delete_attachment( $attachment_id, true ); unlink( $file ); echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html($_FILES['async-upload']['name']) ) . '</strong><br />' . esc_html( 'Duplicate file name' ) . '</div>'; exit; } $uploaded_file = $this->upload_file_to_s3( $file ); if ( is_wp_error( $uploaded_file ) ) { wp_delete_attachment( $attachment_id, true ); unlink( $file ); echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html( $_FILES['async-upload']['name'] ) ) . '</strong><br />' . esc_html( $uploaded_file->get_error_message() ) . '</div>'; exit; } update_post_meta( $attachment_id, 's3_path', $relative ); unlink( $file ); return $file; } /** * Replace the saved attachment URL with the bucket URL */ public function filter_get_attachment_url( $url, $attachment_id ) { if ( ! $path = get_post_meta( $attachment_id, 's3_path', true ) ) return $url; return $this->get_s3_url() . $path; } /** * Delete the attachment on S3 when it's deleted locally */ public function filter_delete_attachment( $attachment_id ) { $meta = wp_get_attachment_metadata( $attachment_id ); $file = get_attached_file( $attachment_id ); $this->delete_file_from_s3( $file ); if ( isset( $meta['sizes'] ) ) { foreach ( $meta['sizes'] as $size => $image ) { $thumbnail = dirname( $file ) . '/' . $image['file']; $this->delete_file_from_s3( $thumbnail ); } } } } Loading
.gitmodules 0 → 100644 +3 −0 Original line number Diff line number Diff line [submodule "inc/aws-sdk"] path = inc/aws-sdk url = git@github.com:humanmade/aws-sdk-php.git
aws-sdk @ d5583425 Original line number Diff line number Diff line Subproject commit d558342507cd2c333ac58e3ae8f5e21577129f47
inc/class-s3-uploads-uploader.php 0 → 100644 +83 −0 Original line number Diff line number Diff line <?php class S3_Uploads_Uploader { private $bucket; private $key; private $secret; /** * @param string $bucket * @param string $key * @param string $secret */ function __construct( $bucket, $key, $secret ) { $this->bucket = $bucket; $this->key = $key; $this->secret = $secret; } public function get_s3_url() { return 'https://' . $this->bucket . '.s3.amazonaws.com'; } /** * Upload a file to S3 * * @param string $file_path The file system path * @return string The path to the uploaded file */ public function upload_file_to_s3( $file_path ) { $relative = str_replace( ABSPATH, '', $file_path ); try { $this->s3()->putObject(array( 'Bucket' => $this->bucket, 'Key' => $relative, 'Body' => fopen( $file_path, 'r' ), 'ACL' => Aws\S3\Enum\CannedAcl::PUBLIC_READ )); } catch( Exception $e ) { return new WP_Error( 's3-upload-error', $e->getMessage() ); } return $relative; } /** * Delete a file from S3 * * @param string $file_path s3 path to file * @return bool|WP_Error */ public function delete_file_from_s3( $file_path ) { try { $this->s3()->deleteObject( array( "Bucket" => $this->bucket, "Key" => $file_path )); } catch( Exception $e ) { return new WP_Error( 's3-delete-error' ); } return true; } /** * @return Aws\S3\S3Client */ private function s3() { require_once dirname( __FILE__ ) . '/aws-sdk/aws-autoloader.php'; if ( ! empty( $this->s3 ) ) return $this->s3; $this->s3 = Aws\Common\Aws::factory( array( 'key' => $this->key, 'secret' => $this->secret ) )->get( 's3' ); return $this->s3; } } No newline at end of file
inc/class-s3-uploads-wordpress-uploads-uploader.php 0 → 100644 +126 −0 Original line number Diff line number Diff line <?php /** * Upload all images to S3 * Adapted from Neeki Patel's "Uploads S3" plugin */ class S3_Uploads_WordPress_Uploads_Uploader extends S3_Uploads_Uploader { public function __construct( $bucket, $key, $secret ) { parent::__construct( $bucket, $key, $secret ); add_filter( 'wp_update_attachment_metadata', array( $this, 'filter_upload_images' ), 10, 2 ); add_filter( 'update_attached_file', array( $this, 'filter_upload_attachment' ), 10, 2 ); add_filter( 'wp_get_attachment_url', array( $this, 'filter_get_attachment_url' ), 9, 2 ); add_action( 'delete_attachment', array( $this, 'filter_delete_attachment' ) ); } /** * Upload an image to S3 when it's uploaded to WP */ public function filter_upload_images( $file, $attachment_id ) { if ( empty( $file ) ) return $file; $original_file = get_attached_file( $attachment_id ); foreach ( $file['sizes'] as $size => $image ) { $thumbnail = dirname( $original_file ) . '/' . $image['file']; if ( ! file_exists( $thumbnail ) ) continue; $response = $this->upload_file_to_s3( $thumbnail ); if ( is_wp_error( $response ) ) { echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html( $_FILES['async-upload']['name'] ) ) . '</strong><br />' . esc_html( $response->get_error_message() ) . '</div>'; } unlink( $thumbnail ); } unlink( $original_file ); return $file; } /** * Upload an attachment to S3 when it's uploaded to WP * * @param string $file * @param int $attachment_id */ public function filter_upload_attachment( $file, $attachment_id ) { if ( ! file_exists( $file ) ) return $file; $relative = str_replace( WP_CONTENT_DIR, '', $file ); $response = wp_remote_head( $this->get_s3_url() .'/'. $relative ); if ( wp_remote_retrieve_response_code( $response ) == 200 ) { wp_delete_attachment( $attachment_id, true ); unlink( $file ); echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html($_FILES['async-upload']['name']) ) . '</strong><br />' . esc_html( 'Duplicate file name' ) . '</div>'; exit; } $uploaded_file = $this->upload_file_to_s3( $file ); if ( is_wp_error( $uploaded_file ) ) { wp_delete_attachment( $attachment_id, true ); unlink( $file ); echo '<div class="error-div"> <a class="dismiss" href="#" onclick="jQuery(this).parents(\'div.media-item\').slideUp(200, function(){jQuery(this).remove();});">' . __( 'Dismiss' ) . '</a> <strong>' . sprintf(__('“%s” has failed to upload due to an error'), esc_html( $_FILES['async-upload']['name'] ) ) . '</strong><br />' . esc_html( $uploaded_file->get_error_message() ) . '</div>'; exit; } update_post_meta( $attachment_id, 's3_path', $relative ); unlink( $file ); return $file; } /** * Replace the saved attachment URL with the bucket URL */ public function filter_get_attachment_url( $url, $attachment_id ) { if ( ! $path = get_post_meta( $attachment_id, 's3_path', true ) ) return $url; return $this->get_s3_url() . $path; } /** * Delete the attachment on S3 when it's deleted locally */ public function filter_delete_attachment( $attachment_id ) { $meta = wp_get_attachment_metadata( $attachment_id ); $file = get_attached_file( $attachment_id ); $this->delete_file_from_s3( $file ); if ( isset( $meta['sizes'] ) ) { foreach ( $meta['sizes'] as $size => $image ) { $thumbnail = dirname( $file ) . '/' . $image['file']; $this->delete_file_from_s3( $thumbnail ); } } } }