0

[CakePHP] Tìm hiểu Uploader plugin

Trong khi tìm kiếm một plugin phục vụ cho việc upload file mà có thể chỉnh sửa file sẽ upload đó được, tôi tìm thấy plugin có tên Uploader khá hay. Nên trong bài này tôi sẽ cùng các bạn tìm hiểu xem Uploader có thể làm được những gì. Mặc dù người viết ra nó chỉ còn support một cách hạn chế nếu có các issues phát sinh, nhưng với CakePHP 2.x thì nó vẫn chạy tốt.

1) Làm sao để cài Uploader ?

Hiện tại bản mới nhất của Uploader là 4.5.4, với các bản 4.x thì tác giả có hỗ trợ sử dụng Composer để get tự động những gói phụ thuộc khi chạy Uploader nên tôi cũng sẽ dùng bản 4.x cho các bài viết. Bạn có thể download/clone từ GitHub.

Uploader yêu cầu PHP 5.3CakePHP 2.3 trở lên và Composer. Composer sẽ đảm bảo các gói phụ thuộc được cài đặt tự động và dễ dàng hơn khi làm thủ công, như gói Transit, AWS SDK mà Uploader có dùng đến.

1.1) Tạo composer.json

Trước tiên, bạn hãy tạo một file composer.json ở trong thư mục "app/", với nội dung :

    {
    	"config": {
    		"vendor-dir": "Vendor"
    	},
    	"require": {
    		"mjohnson/uploader": "4.*"
    	}
    }

1.2) Clone Composer về

Tiếp đó, hãy vào thư mục "app/Plugin" để clone plugin Composer về local.

    git clone git://github.com/uzyn/cakephp-composer.git Composer

1.3)Sửa bootstrap.php

Thêm dòng code dưới đây vào cuối file "Config/bootstrap.php"

    CakePlugin::load('Composer', array('bootstrap' => true));

1.4) Cài Composer

Back về thư mục app và chạy câu lệnh dưới để install Uploader

    Console/cake composer.c install
Chú ý : Nếu bạn làm trên windows và gặp lỗi "php is not recognized as an internal or external command" như tôi thì bạn cần thêm biến môi trường Path để có thể chạy được lệnh trên. Ví dụ : C:\xampp\php. Nhưng khuyên bạn nên dùng Linux như Ubuntu sẽ gỉam thiểu rủi ro gặp lỗi hơn, như dấu \ trên windows còn Linux lại dùng / chẳng hạn.

Đến bước này bạn sẽ thấy Uploader được down về app/Plugin, còn các gói phụ thuộc của nó sẽ có mặt trong app/Vendor.

Để chắc chắn, bạn cần thêm dòng code sau vào file Config/core.php :

require_once dirname(__DIR__) . '/Vendor/autoload.php';

2) Uploader có thể làm được gì?

  • Bằng cách sử dụng AttachmentBehavior trong Uploader thì file sẽ được upload một cách tự động thông qua hàm save() của Model.
  • Có thể validate file một cách tự động khi dùng save() trong Model bằng FileValidationBehavior.
  • Có nhiểu rules cho việc validate như : size, ext, type, height, width...
  • Có thể chỉnh sửa file đã upload hoặc tạo mới : crop, scale, rotate, flip...
  • Tự động xóa file khi bản ghi tương ứng trong DB bị xóa hoặc cập nhật.
  • Hỗ trợ việc transport file tới một hệ thống lưu trữ như AWS.

3) Làm sao để khi gọi save() thì file sẽ được validate và upload.

Tất cả các file upload thông qua model và được thiết lập với AttachmentBehavior. Để khi một cột trong DB lưu trữ đường dẫn của file ( có thể tương đối hay tuyệt đối) thì cần thiết lập attachment. Khi đã có thiết lập này, bạn gọi save() của Model thì file sẽ được upload, nếu có chỉnh sửa thì cũng sẽ được tiến hành và cuối dùng sẽ lưu đường dẫn của file vào DB. Mặc định chúng ta có những thiết lập khả dụng như đoạn code dưới.

    public $actsAs = array(
    	'Uploader.Attachment' => array(
    		/*
    		Bên dưới là ví dụ, do đó bạn cần tham khảo cách dùng chi tiết của từng option khi đưa vào thực tế
    		*/
    		'image' => array(
    			'nameCallback' => '',
    			'append' => '',
    			'prepend' => '',
    			'tempDir' => TMP,
    			'uploadDir' => '',
    			'transportDir' => '',
    			'finalPath' => '',
    			'dbColumn' => '',
    			'metaColumns' => array(),
    			'defaultPath' => '',
    			'overwrite' => false,
    			'stopSave' => true,
    			'allowEmpty' => true,
    			'transforms' => array(),
    			'transformers' => array(),
    			'transport' => array(),
    			'transporters' => array(),
    			'curl' => array()
    		)
    	)
    );

Chi tiết của từng thiết lập cụ thể chúng ta sẽ đi vào chi tiết sau. Trước mắt, bạn để ý thấy từ khóa "image" trong thiết lập trên, đó chính là tên trường trong DB dùng để lưu trữ đường dẫn của file, đường dẫn đó sẽ tìm thấy trong "finalPath".

Sau khi đã có thiết lập như trên, thì bạn cần có một form cùng với input có type là file, ví dụ :

    echo $this->Form->create('Model', array('type' => 'file'));
    echo $this->Form->end('Submit');

Bước cuối cùng, bạn chỉ cần gọi đến hàm save() khi submit form trên và file của bạn sẽ được upload. Đương nhiên, bạn cần thêm vào những validate cần thiết khi upload bằng FileValidationBehavior (trong bài tới chúng ta sẽ cùng code một ví dụ để rõ hơn cách dùng).

4) Chỉnh ảnh : crop, rotate, resize.

Đây có lẽ là phấn hay nhất mà plugin này có, bạn có thể dùng chức năng chỉnh sửa để sửa ảnh đã được upload hoặc dùng nó để tạo ra thumbnail cho ảnh. Để thiết lập, bạn sẽ dùng "transforms". Mỗi transform chấp nhận các thiết lập sau : nameCallback, append, prepend, uploadDir, transportDir, finalPath, defaultPath và overwrite. Có 2 thiết lập chỉ định tới các transforms là "class" và "self". Thiết lập "class" để chỉ loại chỉnh sửa nào sẽ được làm, còn "self" sẽ quyết định việc chỉnh sửa sẽ ảnh hưởng tới file đã upload hay sẽ tạo thêm file, mặc định sẽ "false" để không chỉnh file cũ mà tạo ra cái mới. Có tất cả 7 lựa chọn loại "class" là resize, crop, flip, scale, rotate, fit, và exif. Mỗi loại lại có những cái có thể thiết lập riêng. Nhưng trong bài này, chúng ta sẽ chỉ tìm hiểu về crop, rotate, resize.

4.1) Resize

  • width (int) - độ rộng resize
  • height (int) - chiều cao resize
  • quality (int:100) - chất lượng của bức ảnh sau resize (nhưng chỉ dùng cho ảnh jpg)
  • expand (boolean:false) - Bạn set false thì sẽ không cho phép ảnh được resize lớn hơn ảnh gốc.
  • aspect (boolean:true) - Thiết lập true thì ảnh sẽ duy trì ratio khi scale ảnh theo chiều lên hoặc xuống
  • mode (string:width) - dùng để tính ratio (có thể set width hoặc height)

4.2 ) Crop

Loại này có thể thiết lập các thông số sau để crop vùng nào đó của một bức ảnh.

  • width (int) - độ rộng ảnh để crop
  • height (int) - chiều cao để crop
  • quality (int:100) - chất lượng ảnh sau crop (nhưng chỉ dùng được cho jpg)
  • location (string:center) - quyết định vùng nào sẽ được crop (bạn có thể set : center, top, right, bottom, left)

4.3) Rotate

Cho phép bạn xoay bức ảnh của mình.

  • quality (int:100) - chất lượng ảnh sau rotate (nhưng chỉ dùng được cho jpg)
  • degrees (int:180) - góc xoay bức ảnh của bạn sẽ là bao nhiêu độ

5) Tự động xóa file

Mặc định thì Uploader sẽ xóa tự động các file đã upload sau khi bản ghi lưu trữ path của nó bị xóa hoặc bị update thành path khác. Tuy nhiên, đôi khi bạn sẽ muốn xóa file đơn lẻ mà không có liên quan đến record, bạn sẽ cần dùng đến hàm deleteFiles(). Hãy xem code ví dụ sau, gỉa sử bạn có 3 file cho 1 bức ảnh với kích cỡ khác nhau small, medium, large :

    // Khi gọi như này tất cả 3 bức ảnh của bạn sẽ bị xóa
    $this->Image->deleteFiles($id);

    // còn khi đã chỉ định rõ xóa bức nào thì chỉ đối tượng đó bị xóa, trường hợp dưới là bức có kích cỡ medium bị xóa
    $this->Image->deleteFiles($id, array('medium'));

6) Validate file sẽ upload như nào?

Cũng giống như khi bạn validate nội dung các item trong form, bạn cũng sẽ muốn validate được file mà bạn chuẩn bị upload, bạn sẽ dùng FileValidationBehavior để làm điều đó. Uploader hỗ trợ bạn những validate sau : width, height, minWidth, minHeight, maxWidth, maxHeight, filesize, extension, type, mimeType và required. Việc của bạn chỉ là thiết lập các thông số đó như nào trong $actAs, bên dưới là một ví dụ.

    public $actsAs = array(
    	'Uploader.FileValidation' => array(
    		'image' => array(
    			'maxWidth' => 100, // rộng tối đa 100px
    			'minHeight' => 100, // cao tối đa 100px
    			'extension' => array('gif', 'jpg', 'png', 'jpeg'), // chỉ chấp nhận ảnh có đuôi gif, jpg, png hay jpeg
    			'type' => 'image', // loại file upload phải là ảnh
    			'mimeType' => array('image/gif'), // file sẽ upload phải có loại mime là image/gif
    			'filesize' => 5242880, // file của bạn ko được qúa 5242880kb
    			'required' => true // file cần được chọn mới có thể upload
    		)
    	)
    );

Bên trên chỉ là những thiết lập cơ bản, nếu bạn muốn thì có thể chi tiết hơn, ví dụ file "required" nhưng bạn muốn có thông báo ra nếu user không chỉ định file nào cả :

    'required' => array(
    	'value' => true,
    	'error' => 'Bạn chưa chỉ định file sẽ upload.'
    	)

Hơn nữa, Uploader cũng chấp nhận những thiết lập options giống CakePHP, điều này cho phép chúng ta sử dụng chúng để phù hợp những hoàn cảnh khác nhau. Như là khi tạo mới thì required nhưng lúc cập nhật lại không cần phải upload file lên.

    'required' => array(
    	'value' => false,
    	'on' => 'update',
    	'allowEmpty' => true
            // khi update sẽ không require chỉ định file, và cho phép empty
    	)

Uploader còn có rất nhiều thiết lập khác mà bạn có thể set, nhưng trong phạm vi bài này tôi chỉ đề cập đến một vài điều cơ bản, để đến phần tiếp sẽ có thể sử dụng những kiến thức trên xây dựng một chức năng nhỏ có dùng đến Uploader.

To be continued ... (phần 2)


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.