0

[CakePHP] Tìm hiểu Uploader plugin (P3)

Tiếp tục phần thứ 2 về tìm hiểu Uploader plugin, trong phần cuối này chúng ta sẽ đi vào code demo cho các nội dung bên dưới :

  • Chỉnh sửa tên file khi upload.
  • Sử dụng tranform : flip, scale, fit.
  • Lưu trữ meta data của file.
  • Upload nhiều file cùng lúc.
  • Upload thông qua URL

1) Chỉnh sửa tên file khi upload

Uploader cung cấp cho chúng ta 3 cài đặt dùng cho việc sửa lại tên file theo format của người dùng, đó là :

  • nameCallback : cài đặt này cho phép gọi đến phương thức chỉnh sửa tên file có trong model hiện tại. Phương thức này sẽ trả về tên file mới, nó cần 2 tham số là tên file hiện tại và object File thông qua Transit. Object này có thể lấy thông tin như kích cỡ, đuôi mở rộng... của file upload.
  • append : cài đặt này cho phép thêm vào cuối file một chuỗi nào đó.
  • prepend : giống với append nhưng sẽ thêm vào đầu file một chuỗi.

Hãy viết một phương thức để chỉnh sửa tên file như dưới đây và sau đó gọi đến nó bằng 'nameCallback ' => 'formatName' trong khai báo $actAs :

public function formatName($name, $file) {
    return sprintf('%s-%s', $name, $file->size());
}

Và cũng thử thêm cài đặt append, prepend vào $actAs để xem kết ủa trả về như nào :

    'append' => '-test',
    'prepend' => 'demo-',
    // bạn sẽ có file name dạng : demo-money-732466-test.jpg

2) Sử dụng transform : flip, scale, fit

2.1) flip

Trong cài đặt 'transform' ở phần 2, bạn đã có crop để crop ảnh làm thumbail. Giờ bạn hãy thêm vào code dưới, cài đặt flip sẽ lật bức ảnh theo chiều ngang, dọc hoặc cả 2 chiều.

	array('method' => 'flip',
	   	'quality' => 80, // chất lượng tấm ảnh flip, nhưng chỉ áp dụng cho jpg
	    'direction' => 'horizontal' // bạn có thể để vertical hoặc both
	)
	// tên file của ảnh flip có dạng,
	// 1 là số đếm, nếu đã có trùng tên file thì sẽ tăng lên 2 ...  :
	// "tên file-flip-horizontal-1".jpg

2.2) scale

Tiếp tục với scale sẽ cho phép bạn set cho bức ảnh tăng hay gỉam kích cỡ dựa vào 'percent', chú ý là gía trị bạn gán cho 'percent' là một số kiểu float, 1 tương đương 100% nên bạn muốn gỉam 50% bức ảnh thì bạn sẽ set 'percent' => 0.5. Hãy thử với đoạn code, thêm vào cài đặt 'transform' trong $actAs :

	array('method' => 'scale',
	      'quality' => 100, // chỉ dành cho ảnh jpg
	      'percent' => 1.2
	)

2.3) fit

Với cài đặt fit bạn sẽ có thể set ảnh với độ rộng, chiều cao nào đó. Bức ảnh sẽ được căn cả theo trục ngang và đứng dựa vào 'vertical''horizontal'. Còn 'fill' sẽ cho phép setup một màu nào đó cho phần bị trống do fit ảnh, nó nhận một mảng gía trị màu RGB như ví dụ dưới tôi để màu trắng. Nếu để tr

    array('method' => 'fit',
        'width' => 1980,
    	'height' => 1280,
    	'quality' => 100,
    	'fill' => array('255','255','255' ),
    	'vertical' => 'center',
    	'horizontal' => 'left'
    )

3) Lưu trữ meta data

Trong những trường hợp nhất định nào đó, chắc hẳn bạn sẽ quan tâm đến những thông số meta data của bức ảnh như các thông tin có trong exif (máy nào đã chụp bức hình đó, độ phơi sáng bức ảnh, ngày chụp, iso khi chụp ...). Để phục vụ nhu cầu đó Uploader cung cấp cài đặt 'metaColumns', với các lựa chọn : basename (có đuôi mở rộng ), ext, name (không có đuôi mở rộng), size, type (mime type), width, height, exif.make, exif.model, exif.exposure, exif.orientation, exif.fnumber, exif.date, exif.iso, and exif.focal. Hãy thử lấy ra một vài thông tin bằng cách khai báo trong $actAs :

    'metaColumns' => array(
        'name' => 'file_name', // đuôi mở rộng
        'size' => 'file_size', // kích cỡ filee
        'exif.model' => 'camera' // loại camera đã chụp
        'exif.date' => 'taken_date' // ngày chụp
    )

Nhưng trước khi chạy demo thì các bạn cần chỉnh lại bảng images để có các trường dùng để lưu trữ các thông tin meta tương ứng. Lần trước tôi đã có tạo ra trường file_name, file_size nên bài này hãy add thêm trường camerataken_date.

// câu dưới có thể khác, tùy vào bảng imges của bạn đang như nào
ALTER TABLE `demo`.`images`
ADD COLUMN `camera` VARCHAR(45) NULL AFTER `modified`,
ADD COLUMN `taken_date` VARCHAR(45) NULL AFTER `camera`;

Và đồng thời chỗ lấy tên file, kích cỡ file trong code của controller lần trước cũng không cần nữa, hãy xóa chúng đi 😃

Đơn vị được kích cỡ ảnh đưa vào DB là bytes nên hãy chỉnh chút trên View (index.ctp) để hiển thị đơn vị kB.

<?php echo round($image['Image']['file_size'] / 1000, 1); ?>
Chú ý : bạn chỉ có thể lấy được meta data của file gốc, với những file mà bạn crop hay scale ... là không thể.

4) Upload thông qua URL

Trong thực tế có thể bạn đã gặp trường hợp mà trang web cho phép chọn ảnh để upload thông qua một đường dẫn URL, như trong diễn đàn nào đó cho phép đăng kí avatar qua URL. Uploader cũng cung cấp cho bạn khả năng làm điều đó. Bạn chỉ cần chú ý 2 điều :

  • Một là bạn hãy để loại input từ file sang dạng textbox bình thường.
  • Hai là URL phải bắt đầu bằng http thì mới được, nên hãy tạo một validation trong model Image.php. VD :
	public $validate = array(
	    'file_path' => array(
	        'rule' => '/http+/',
	        'message' => 'Bạn cần nhập URL bắt đầu bằng http'
	    )
	);

Trong upload.ctp hãy chuyển echo $this->Form->file('file_path'); thành echo $this->Form->input('file_path');

Chỉ có vậy, hãy thử upload với URL bên dưới :

http://dantri4.vcmedia.vn/PhxhlPHvyGGAAypd6w1oNmUElJgqw/Image/2015/03/DSC09365-70214.JPG

5) Upload nhiều file cùng lúc

Khi bạn muốn upload nhiều file cùng lúc (cùng model) thì đầu tiên cần khai báo nhiều input có type là _file _, tôi sẽ tạo file View mới multiple_upload.ctp (code chi tiết có trong file đó). Bạn sẽ thấy ở đây khai báo mảng Image cho trường file_path1, mỗi phần tử sẽ là một input cho một file.

    echo $this->Form->input('Image.0.file_path1', array('type' => 'file'));
    echo $this->Form->input('Image.1.file_path1', array('type' => 'file'));

Oki, chúng ta đã có view vậy hãy xây dựng phương thức tương ứng trong Controller. Điều khác so với phương thức upload() là nó dùng SaveMany() thay vì save(), và đối số truyền vào là $this->Image->data['Image']

	public function multiple_upload() {
		// Check user đã submit chưa
		if($this->request->is('post')) {

			$this->Image->create();
			// nếu lưu thành công sẽ quay về list
			if($this->Image->saveMany($this->request->data['Image'])) {
				$this->Session->setFlash(__('Đã upload thành công.'));
				return $this->redirect(array('action' => 'index'));
			}

		    /*
		     * lược bỏ đoạn code show lỗi
		     */
		}
	}

Phần còn lại là trong model Image.php, cũng giống như trường file_path khi upload một file, bạn cần đặt ra các luật bắt validation cũng nhưng các cài đặt như crop, lưu vào cột nào trong bảng, đường dẫn lưu ảnh sẽ upload ( chi tiết tham khảo file trên github)

Tổng kết

Qua 3 phần tìm hiểu về Uploader plugin cho CakePHP, chúng ta đã hiểu được cơ bản những chức năng chính mà Uploader cung cấp. Hy vọng chúng sẽ gíup ích được cho các bạn ít nhiều trong các dự án. Tuy nhiên, với nhược điểm là phiên bản 3.x của CakePHP thì Uploader không còn support nữa nên cần tìm một gỉai pháp thay thế khác.

>>> github source của demo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí