Ngu ngơ học làm web (x34) - CakePHP2 - Hàm ràng buộc tại model, hashing, callback

Tiếp theo của: Ngu ngơ học làm web (x33) - CakePHP2 – Đổi mật khẩu, ràng buộc ở controller
-----

Phần x34. CakePHP2 – Hàm ràng buộc tại model, hashing, callback


Xem (clip số 35b – chickenrainshop):

- Viết hàm ràng buộc trong model (1":12)

- Sử dụng saveField để lưu một trường dữ liệu (6":18)

- Hàm callback (10":45)

- Gọi class :: (12":07)

Thay vì sử dụng hàm strcmp() trong controller để so sánh giữa password và confirmPassword, có thể viết hàm để so sánh hai đối tượng này trong model.

Đọc thêm về Adding your own Validation Methods tại đây: https://book.cakephp.org/2.0/en/models/data-validation.html

Ví dụ:

class User extends AppModel {

    public $validate = array(
        'promotion_code' => array(
            'rule' => array('limitDuplicates', 25),
            'message' => 'This code has been used too many times.'
        )
    );

    public function limitDuplicates($check, $limit) {
        // $check will have value: array('promotion_code' => 'some-value')
        // $limit will have value: 25
        $existingPromoCount = $this->find('count', array(
            'conditions' => $check,
            'recursive' => -1
        ));
        return $existingPromoCount < $limit;
    }
}

Viết một ràng buộc trong model:

[Model\User.php]

Hàm matchPassword(): sẽ thực hiện so sánh confirm password với password:

            public function matchPassword($check, $passwordField = 'password') {
                        $password = $this->data['User'][$passwordField];
                        $confirmPassword = $this->data['User']['confirmPassword'];
                        if (strcmp($password, $confirmPassword) == 0) {
                                    return true;
                        } else {
                                    return false;
                        }
            }

Gọi và sử dụng hàm matchPassword():

'confirmPassword' => array(
                                    'notBlank' => array(
                                                'rule' => array('notBlank'),
                                                'message' => 'Xác nhận mật khẩu không được để trống',
                                    ),
                                    'matchPassword' => array(
                                                'rule' => array('matchPassword', 'password'),
                                                'message' => 'Xác nhận mật khẩu không đúng!'
                                    ),
                        ),

Lưu mật khẩu mới vào cơ sở dữ liệu, sử dụng hàm saveField(‘tên trường’, ‘giá trị’). Hàm saveField sẽ lưu dữ liệu vào trường được chỉ định, tuy nhiên, mặc định, nó sẽ tạo một mẩu tin mới, để lưu vào một mẩu tin cũ cần chỉ ra id của mẩu tin đó.

Ví dụ:

if ($this->User->validates()) {
                                                $userInfo = $this->getUser();
                                                $this->User->id = $userInfo['id'];
                                                if ($this->User->saveField('password', $this->Auth->password($this->request->data['User']['password']))) {
                                                            $this->Flash->success('Đã lưu thành công', ['params' => ['class' => 'alert alert-success']]);
                                                } else {
                                                            $this->Flash->error('Đổi mật khẩu chưa thành công, vui lòng thử lại!', ['params' => ['class' => 'alert alert-error']]);
}

Để băm mật khẩu trước khi lưu, sử dụng hàm password của Auth, ví dụ:

if ($this->User->saveField('password', $this->Auth->password($this->request->data['User']['password']))) {

Để không phải viết lại $this->Auth->password, mỗi khi muốn băm mật khẩu, có thể viết một hàm callback trong model.

Hàm callback là gì?

Đọc thêm về hàm callback tại đây: https://book.cakephp.org/2.0/en/models/callback-methods.html

Hàm callback là hàm chạy ngầm được gọi bởi thao tác khác trong model hoặc controller.

Ví dụ, hàm callback beforeSave(), sẽ được gọi và thực thi trước mỗi thao tác lưu dữ liệu vào cơ sở dữ liệu.

// âm thầm băm mật khẩu trước khi lưu
            public function beforeSave($options = array()) {
                        if (isset($this->data['User']['password'])) {
                                    $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
                        }
                        return true;
            }          

Trong model không thể gọi $this->Auth->password mà sử dụng AuthComponent::password

Đã viết hàm callback beforeSave(), nên trong UsersController sẽ sửa lại một chút:

$this->User->id = $userInfo['id'];
            if ($this->User->saveField('password', $this->request->data['User']['password'])) {
            $this->Flash->success('Đã lưu thành công', ['params' => ['class' => 'alert alert-successs']]);

            } else {
-----------
Cập nhật 5/7/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web