Cách hook core upload file lên s3 trong Wordpress

Lưu trữ file trên Amazon S3 thay vì trên server truyền thống mang lại nhiều lợi ích vượt trội. S3 cung cấp khả năng mở rộng không giới hạn, đảm bảo hiệu suất và tốc độ tải trang luôn ổn định ngay cả khi lượng truy cập tăng cao. Đặc biệt, S3 đảm bảo độ tin cậy và bảo mật cao, giúp dữ liệu của bạn luôn an toàn và dễ dàng quản lý. Hơn nữa, việc tích hợp dễ dàng với các dịch vụ khác của AWS giúp bạn tối ưu hóa hệ thống một cách linh hoạt và hiệu quả.

Dù có nhiều plugin đã hỗ trợ việc này, nhưng phí sử dụng cao và plugin thường đi kèm với nhiều tính năng không cần thiết. Việc tự code sẽ hiệu quả hơn, dễ kiểm soát hơn và giúp tiết kiệm chi phí.

Dưới đây là các bước để làm điều này

Bước 1 : Chuẩn bị môi trường

Tạo bucket trên S3 và lấy những thông tin sau dán vào wp-config.php theo hình bên dưới

Install thư viện SDK của S3 bằng lệnh bên dưới

composer require aws/aws-sdk-php

Bước 2 : Viết code

Viết hàm để upload lên s3

function upload_to_s3($file_path) {
    try {
        // chuẩn bị config s3
        $bucket = S3_UPLOADS_BUCKET;
        $s3 = new Aws\S3\S3Client([
            'version' => 'latest',
            'region' => S3_UPLOADS_REGION,
            'credentials' => [
                'key' => S3_UPLOADS_KEY,
                'secret' => S3_UPLOADS_SECRET,
            ]
        ]);

        // sửa lại đường dẫn
        $file_url = str_replace(UPLOAD_DIR, UPLOAD_URI, $file_path);
        $file_name = str_replace(home_url('/'), '', $file_url);

        // Thực hiện upload file lên S3
        $result = $s3->putObject([
            'Bucket' => $bucket,
            'Key' => $file_name,
            'Body' => fopen($file_path, 'r'),
            'ACL' => 'public-read'
        ]);
        return true;
    } catch (Aws\Exception\S3Exception $e) {
        // Xử lý ngoại lệ S3Exception
        error_log("Error uploading file to S3: " . $e->getMessage());
        return false;
    } catch (Exception $e) {
        // Xử lý ngoại lệ khác
        error_log("An unexpected error occurred: " . $e->getMessage());
        return false;
    }
}

Sử dụng hook của wordpress để upload lên S3

add_filter('wp_generate_attachment_metadata', 'upload_image_to_s3', 10, 2);
function upload_image_to_s3($metadata, $attachment_id) {
    try {
        $file = get_attached_file($attachment_id);
        upload_to_s3($file);

        $path_parts = pathinfo($file);
        $path = $path_parts['dirname'];

        $mime_type = get_post_mime_type($attachment_id);
        if (strpos($mime_type, 'image') !== false) {
            if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
                foreach ($metadata['sizes'] as $size => $data) {
                    $file_size_path = $path.'/'.$data['file'];
                    upload_to_s3($file_size_path);
                }
            }
        }
    } catch (Exception $e) {
        // Xử lý ngoại lệ ở đây nếu cần
        error_log('Error: ' . $e->getMessage());
    }
    
    return $metadata;
}

Tới đây khi upload trong media của WordPress thì nó sẽ tự động lên s3 tất cả phiên bản của hình theo đúng đường dẫn uploads

Viết hàm xoá hình trên S3

function delete_from_s3($file_path) {
    try {
        // Chuẩn bị config S3
        $bucket = S3_UPLOADS_BUCKET;
        $s3 = new Aws\S3\S3Client([
            'version' => 'latest',
            'region' => S3_UPLOADS_REGION,
            'credentials' => [
                'key' => S3_UPLOADS_KEY,
                'secret' => S3_UPLOADS_SECRET,
            ]
        ]);

        $file_path = str_replace(UPLOAD_DIR, 'wp-content/uploads', $file_path);
        
        // Thực hiện xoá file trên S3
        $result = $s3->deleteObject([
            'Bucket' => $bucket,
            'Key' => $file_path,
        ]);

        // Kiểm tra kết quả
        if ($result['@metadata']['statusCode'] === 204) {
            // Xoá thành công
            return true;
        } else {
            // Xoá không thành công
            return false;
        }
    } catch (Aws\S3\Exception\S3Exception $e) {
        // Xử lý ngoại lệ
        // Log lỗi hoặc thông báo cho người dùng
        error_log('Error deleting file from S3: ' . $e->getMessage());
        return false;
    }
}

Sử dụng hook của wordpress để xoá hình

Hook này để báo cho WordPress biết khi xoá hình trên media thì cũng xoá luôn trên S3

add_action('delete_attachment', 'delete_image_to_s3');
function delete_image_to_s3($attachment_id) {
    try {
        $file = get_attached_file($attachment_id);
        delete_from_s3($file);

        $path_parts = pathinfo($file);
        $path = $path_parts['dirname'];

        $metadata = wp_get_attachment_metadata($attachment_id);

        $mime_type = get_post_mime_type($attachment_id);
        if (strpos($mime_type, 'image') !== false) {
            if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
                foreach ($metadata['sizes'] as $size => $data) {
                    $file_size_path = $path.'/'.$data['file'];
                    delete_from_s3($file_size_path);
                }
            }
        }
    } catch (Exception $e) {
        // Xử lý ngoại lệ ở đây
        error_log('Error deleting attachment: ' . $e->getMessage());
    }
}

Sử dụng hook để replace lại đường dẫn hình mặc định của WordPress

Lúc này WordPress vẫn sử dụng đường dẫn cũ, nên cần replace qua đường dẫn S3, trường hợp có sài cloudfront thì bỏ qua bước này. Vì đường dẫn cloudfront sẽ giống với domain.

add_filter('upload_dir', 'custom_upload_dir');
function custom_upload_dir($upload) {
    try {
        $upload['baseurl'] = 'https://' . S3_UPLOADS_BUCKET . '.s3.'. S3_UPLOADS_REGION .'.amazonaws.com/wp-content/uploads';
    } catch (Exception $e) {
        // Xử lý ngoại lệ ở đây
        error_log('Error setting custom upload directory: ' . $e->getMessage());
    }
    return $upload;
}

Tới đây mọi thứ đã xong, lưu ý là để chức năng chạy tốt thì khi lấy hình ra phải dùng hàm chuẩn của WordPress thì mới hook dc.

Tư vấn - Báo giá
Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
Mọi thông tin tư vấn và báo giá đều miễn phí.

    「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
    Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
    Tư vấn - Báo giá
    Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
    Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
    Mọi thông tin tư vấn và báo giá đều miễn phí.

      「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
      Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
      liên hệ