【问题标题】:Laravel/Ardent/User model editing + savingLaravel/Ardent/用户模型编辑+保存
【发布时间】:2014-02-14 08:27:51
【问题描述】:

在 laravel/ardent 中使用密码编辑用户模型的预期方法是什么?我的问题是,我不想在正确验证用户输入之前从数据库加载实际用户模型。当我将密码字段留空时,验证显然会失败,因为需要密码。这是我目前的后期编辑操作:

public function postEdit($id)
{
    // ardent autohydrates this model
    $newUser = new User;

    // validation fails
    if(!$newUser->validate())
        return Redirect::action('UsersController@getEdit', $id)
            ->with('error', Lang::get('Bitte Eingabe überprüfen'))
            ->withErrors($newUser->errors())
            ->withInput(Input::except('password'));

    // load model from db
    $exUser = User::find($id);
    if(!$exUser->exists)
        return Response::make('No such user', 500);

    // save model, ardent autohydrates again?
    if($exUser->save())
        return Redirect::action('UsersController@getShow', $id)
            ->with('success', Lang::get('Änderungen gespeichert'));
    else
        return Redirect::action('UsersController@getEdit', $id)
            ->with('error', Lang::get('Bitte Eingabe überprüfen'))
            ->withErrors($newUser->errors())
            ->withInput(Input::except('password'));
}

这似乎是一大堆代码(+ 它不起作用),我无法找到这种情况的示例

【问题讨论】:

    标签: php laravel ardent


    【解决方案1】:

    我遇到了和你一样的问题。在永远搜索之后,我通读了 Ardent 代码并想出了这个。它允许您使用一组规则、自动补水、自动哈希密码和 Ardent 的 updateUnique() 函数。我知道它可以被清理,而且我确信有更好的方法来解决这个问题,但我已经在这个问题上花费了很多时间。

    这使用控制器中的动态 beforeSave() 闭包(documented here)。由于我们正在更新,我们会检查是否发送了密码。如果没有密码,则将 $rules 数组中的密码验证设置为空白,从验证中排除密码。由于自动散列密码发生在验证之后和 beforeSave() 之前,我们需要将其关闭(设置为 false)。该模型在通过验证后第二次传播,因此提交的空白密码字段将在 beforeSave() 之前发出一个哈希,使其不再为空白,并且将无法通过我们的第二次检查。当运行 updateUniques() '或 Save()' 时,我们通过 beforeSave 闭包再次检查是否有密码被提交,如果没有,则将其从更新中删除。

    tl;dr 使用最少的代码防止 Ardent 自动补水要求和/或删除管理更新的密码。

    型号:

    class User extends Ardent implements UserInterface, RemindableInterface {
    
    use UserTrait, RemindableTrait;
    
    // Auto Hydrate
    public $autoHydrateEntityFromInput   = true;
    public $forceEntityHydrationFromInput   = true;
    public $autoPurgeRedundantAttributes    = true;
    // Auto hash passwords
    public static $passwordAttributes  = array('password');
    public $autoHashPasswordAttributes = true;
    
    protected $table  = 'users';
    protected $guarded  = array('id','created_at','updated_at');
    protected $hidden = array('password');
    protected $fillable = array('first_name','last_name','employee_id','position','email','password');
    
    public static $rules = array(
        'first_name'            => 'required',
        'last_name'             => 'required',
        'employee_id'           => 'required|max:10',
        'position'              => 'required',
        'email'                 => 'required|email|unique',
        'password'              => 'required|alpha_num|min:6',
    );
    

    控制器:

    public function update($id)
    {
        $user = User::find($id);
        // Check if a password has been submitted
        if(!Input::has('password')){
        // If so remove the validation rule
          $user::$rules['password'] = '';
        // Also set autoHash to false;
          $user->autoHashPasswordAttributes = false;
        }
        // Run the update passing a Dynamic beforeSave() closure as the fourth argument
        if($user->updateUniques(
          array(),
          array(),
          array(),
          function($user){
        // Check for the presence of a blank password field again
            if(empty($user->password)){
        // If present remove it from the update
              unset($user->password);
              return true;
            }
          })
        ){
          Alert::success('User Updated')->flash();
          return Redirect::route('admin.users.index');
        }
            Alert::add('form','true')->flash();
        return Redirect::back()
          ->withInput(Input::except('password'))
          ->withErrors($user->errors());
    }
    

    【讨论】:

      【解决方案2】:

      好的,我自己解决了,因为这不是一个很活跃的话题。

      问题在于结合了 ardents 的自动补水功能和保留旧密码(如果没有提供新密码)的独特要求。因为 argent 在 validate()save() 上自动水合,所以也无法防止空密码自动水合。首先,我尝试更改输入数组并用旧密码覆盖它,但随后我只是关闭了用户模型的自动水合:

      class User extends Ardent implements UserInterface, RemindableInterface {
      
          public $forceEntityHydrationFromInput = false;
          public $autoHydrateEntityFromInput = false;
      

      这是 POST 上的编辑操作:

      public function postEdit($id)
      {
          // manually insert the input
          $user = new User(Input::all());
      
          // validate the user with special rules (password not required)
          if($user->validate(User::$updateRules)) {
      
              // get user from database and fill with input except password
              $user = User::find($id);
              $user->fill(Input::except('password'));
      
              // fill in password if it is not empty
              // will flag the pw as dirty, which will trigger rehashing on save()
              if(!empty(Input::get('password')))
                  $user->password = Input::get('password');
      
              if($user->save())
                  return Redirect::action('UsersController@getIndex')
                      ->with('success', Lang::get('Änderungen gespeichert'));
          }
      
          return Redirect::action('UsersController@getEdit', $id)
              ->with('error', Lang::get('Bitte Eingaben überprüfen'))
              ->withErrors($user->errors())
              ->withInput(Input::except('password'));
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-27
        • 1970-01-01
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-13
        相关资源
        最近更新 更多