【问题标题】:CakePHP: BeforeSave & BeforeValidate with PasswordableBehaviorCakePHP:使用 PasswordableBehavior 的 BeforeSave 和 BeforeValidate
【发布时间】:2014-01-05 22:58:16
【问题描述】:

我正在尝试将 DerEuromark 的 Passwordable 行为与我的 CakePHP 应用程序一起使用,但无法使其正常工作。我按照安装说明 (http://www.dereuromark.de/2011/08/25/working-with-passwords-in-cakephp/),修改了我的控制器和视图,但我一直收到错误消息,说我的 BeforeValidateBeforeSave 与该行为不兼容 - 当然,该行为不工作。

我知道我需要在我的模型中正确设置这两个,但我不知道它们应该是什么样子 - 说明没有涵盖这一点。

基本的普通BeforeValidateBeforeSave 需要什么样的外观才能处理这种行为?

在我的用户控制器下:

public function register() {
if ($this->request->is('post') || $this->request->is('put')) {
    $this->User->Behaviors->attach('Tools.Passwordable');
    if ($this->User->save($this->request->data, true, array('username', 'name', 'email', 'pwd', 'pwd_repeat', 'group_id'))) {
    $this->Session->setFlash(__('The user has been saved'), 'flash/success');
            $this->redirect(array('action' => 'index'));
} else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'), 'flash/error');
        }
   unset($this->request->data['User']['pwd']);
    unset($this->request->data['User']['pwd_repeat']);
}

我的user.php 需要与BeforeValidateBeforeSave 兼容的Passwordable 行为:https://github.com/dereuromark/tools/blob/master/Model/Behavior/PasswordableBehavior.php

错误:

Strict (2048): Declaration of PasswordableBehavior::beforeValidate() should be compatible with ModelBehavior::beforeValidate(Model $model, $options = Array) [APP/Plugin/Tools/Model/Behavior/PasswordableBehavior.php, line 338]
Strict (2048): Declaration of PasswordableBehavior::beforeSave() should be compatible with ModelBehavior::beforeSave(Model $model, $options = Array) [APP/Plugin/Tools/Model/Behavior/PasswordableBehavior.php, line 338]

编辑:用户模型:

<?php
App::uses('AppModel', 'Model');
App::uses('AuthComponent', 'Controller/Component');
App::uses('PasswordableBehavior', 'Tools.Model/Behavior');
/**
 * User Model
 *
 * @property Group $Group
 * @property Post $Post
 */
class User extends AppModel {

    //simplified per-group only permissions- tell ACL to skip checking user AROs and only check group AROs
    public function bindNode($user) {
    return array('model' => 'Group', 'foreign_key' => $user['User']['group_id']);
}

/**
 * Validation rules
 *
 * @var array
 */
public $validate = array(
    'username' => array(
        'notEmpty' => array(
            'rule' => array('notEmpty'),
            //'message' => 'Your custom message here',
            //'allowEmpty' => false,
            //'required' => false,
                //'last' => false, // Stop validation after this rule
                //'on' => 'create', // Limit validation to 'create' or 'update' operations
            ),

                    'username' => array(
            'rule' => 'isUnique',
            'required' => true,
            'allowEmpty' => false,
            'on' => 'create',
            'last' => false,
            'message' => 'That username has already been taken'
    ),
        ),


        'email' => array(
            'email' => array(
                'rule' => array('email'),
                //'message' => 'Your custom message here',
                //'allowEmpty' => false,
                //'required' => false,
                //'last' => false, // Stop validation after this rule
                //'on' => 'create', // Limit validation to 'create' or 'update' operations
            ),
        ),
        'password' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
                //'message' => 'Your custom message here',
                //'allowEmpty' => false,
                //'required' => false,
                //'last' => false, // Stop validation after this rule
                //'on' => 'create', // Limit validation to 'create' or     'update' operations
            ),
        ),
        'group_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
                //'message' => 'Your custom message here',
                //'allowEmpty' => false,
                //'required' => false,
                //'last' => false, // Stop validation after this rule
            //'on' => 'create', // Limit validation to 'create' or 'update' operations
        ),
    ),
);

//The Associations below have been created with all possible keys, those that are         not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */    
    public $belongsTo = array(
        'Group' => array(
            'className' => 'Group',
            'foreignKey' => 'group_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );

    public $actsAs = array('Acl' => array('type' => 'requester'));

    public function parentNode() {
        if (!$this->id && empty($this->data)) {
            return null;
        }
        if (isset($this->data['User']['group_id'])) {
            $groupId = $this->data['User']['group_id'];
        } else {
            $groupId = $this->field('group_id');
        }
        if (!$groupId) {
            return null;
        } else {
            return array('Group' => array('id' => $groupId));
        }
    }

/**
 * hasMany associations
 *
 * @var array
 */
    public $hasMany = array(
        'Post' => array(
            'className' => 'Post',
            'foreignKey' => 'user_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        )
    );

    public function beforeValidate($options = array()) {

    }   


public function beforeSave($options = array()) {

} 

}

【问题讨论】:

  • 请用您的User 模型代码更新您的问题。
  • 我添加了模型。我已经为 BeforeValidate 和 BeforeSave 设置了虚拟函数,但它们还没有做任何事情。据我了解,PasswordableBehavior 应该采用 pwd 和 pwd_repeat,比较它们,如果它们匹配则对它们进行散列 - 这是对的吗?我还需要做些什么来正确路由这些变量吗?

标签: php cakephp cakephp-2.0 cakephp-2.4


【解决方案1】:

确保方法签名匹配。方法的参数必须与父类方法的参数相同。

您可能在您的用户模型中忘记了它们。

如果您确实在使用您发布链接的代码,则方法签名是正确的。也许您使用的是旧版本或您的用户模型有错误。

您还必须更新 $actsAs 属性才能使用该行为。

public $actsAs = array(
    'Acl' => array('type' => 'requester'),
    'Passwordable',
);

此外,beforeSavebeforeValidate 必须返回 true 才能继续保存过程。否则,它将中止。见http://book.cakephp.org/2.0/en/models/callback-methods.html

【讨论】:

  • 确定要加$actsAs吗?当我这样做时,它突然说“未找到行为” - 即使插件已安装并添加到引导程序中。
  • 哦,您使用 Passwordable 作为插件的行为。使用$actsAs'Tools.Passwordable'(使用点语法为插件名称添加前缀)而不是'Passwordable'。你必须使用actsAs,否则你的行为不会附加到你的模型上。
【解决方案2】:

该错误已经非常准确地告诉您必须做什么:使行为的方法签名与 ModelBehavior 方法签名的签名相匹配。

看起来插件没有更新以反映最新 CakePHP 版本中的变化。添加了选项数组。

【讨论】:

  • 谢谢-我假设变量/数组没有正确传递,但我无法通过查看行为来判断我应该如何设置 BeforeValidate 和 BeforeSave。由于 CakePHP 的目标是 DRY,我曾希望我可以只使用存根,但似乎并非如此。我对此很陌生,并且一直在通过分解和修改示例代码来自学。 :)
  • 这并不是真正的 CakePHP 问题,而是 PHP 5.4 的变化。您可以禁用它,但我建议您更新行为并通知作者修复它。参见stackoverflow.com/questions/12229113/…
【解决方案3】:

在您的 PasswordableBehavior 中为您的两种方法(beforeValidate、beforeSave)执行此操作

public function beforeValidate ($options=array()) {
   ...
   ...
}

//or try this if it didn't work
public function beforeValidate (Model $model, $options=array()) {
   ...
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    相关资源
    最近更新 更多