2015-10-19 111 views
3

我需要使用setter方法在Validator類中設置$rules數組。如何在Laravel中使用setter方法設置驗證規則?

我需要使用setter來定義$規則,因爲規則存儲在數據庫中。我需要使用Eloquent來查詢數據庫以確定規則是什麼樣的。

我擴展了Validator類並添加了一個名爲setCustomRules()的方法。我在這個方法中注入了一個類,它允許我使用Eloquent來讀取數據庫來確定規則。

但是,當Laravel嘗試驗證時,如何強制setCustomRules()方法啓動?該方法必須首先進行,以確保在驗證發生之前設置規則。

這是我做了什麼

<?php namespace Vend\Surveys\Validator\SurveyAnswers; 

use Cartalyst\Support\Validator; 

use Vend\Surveys\Repositories\SurveyAnswers\SurveyAnswerDefinedRepository; 

class SurveyAnswerDefinedValidator extends Validator implements SurveyAnswerDefinedValidatorInterface { 

    /** 
    * {@inheritDoc} 
    */ 
    protected $rules; 

    /** 
    * {@inheritDoc} 
    */ 
    public function onUpdate() 
    { 

    } 


    public function setCustomRules(SurveyAnswerDefinedRepository $rules) 
    { 

     foreach($rules as $rule){ 
      $this->rules[$rule->name] = $rule->spec; 
     } 

     //this should display the rules that will be used to validate the form 
     dd($this->rules); 
    } 


} 

編輯 基於阿爾法的回答,我創建了一個事件處理程序,將讓我創建的規則。但不知道如何告訴Laravel現在驗證。

這是我的EventHandler類

<?php namespace vend\Surveys\Handlers\SurveyAnswers; 

use Illuminate\Events\Dispatcher; 
use vend\Surveys\Models\SurveyAnswerDefined; 
use Cartalyst\Support\Handlers\EventHandler as BaseEventHandler; 

use vend\Surveys\Repositories\SurveyQuestions\SurveyQuestionsRepositoryInterface; 

class SurveyAnswerDefinedEventHandler extends BaseEventHandler implements SurveyAnswerDefinedEventHandlerInterface { 

    protected $rules = []; 
    /** 
    * {@inheritDoc} 
    */ 
    public function subscribe(Dispatcher $dispatcher) 
    { 
     $dispatcher->listen('vend.surveys.surveyanswerdefined.creating', __CLASS__.'@creating'); 
     $dispatcher->listen('vend.surveys.surveyanswerdefined.created', __CLASS__.'@created'); 

     $dispatcher->listen('vend.surveys.surveyanswerdefined.updating', __CLASS__.'@updating'); 
     $dispatcher->listen('vend.surveys.surveyanswerdefined.updated', __CLASS__.'@updated'); 

     $dispatcher->listen('vend.surveys.surveyanswerdefined.deleted', __CLASS__.'@deleted'); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function creating(SurveyQuestionsRepositoryInterface $questions, array $data) 
    { 
     $this->setRules($questions); 
     dd($this->rules); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function created(SurveyAnswerDefined $surveyanswers) 
    { 
     $this->flushCache($surveyanswers); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function updating(SurveyAnswerDefined $surveyanswers, array $data) 
    { 

     $this->setRules($questions); 
     dd($this->rules); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function updated(SurveyAnswerDefined $surveyanswers) 
    { 
     $this->flushCache($surveyanswers); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function deleted(SurveyAnswerDefined $surveyanswers) 
    { 
     $this->flushCache($surveyanswers); 
    } 

    /** 
    * Flush the cache. 
    * 
    * @param \vend\Surveys\Models\Surveyanswers $surveyanswers 
    * @return void 
    */ 
    protected function flushCache(SurveyAnswerDefined $surveyanswers) 
    { 
     $this->app['cache']->forget('vend.surveys.surveyanswerdefined.all'); 

     $this->app['cache']->forget('vend.surveys.surveyanswerdefined.'.$surveyanswers->id); 
    } 


    private function setRules($questions){ 

     foreach($questions as $question){ 

      foreach($questions->controls as $control){ 

       $this->rules['control_' . $control->id] = $this->makeRules($control); 
      } 

     } 
    } 

    private function makeRules($control){ 

     $rules = []; 

     if($control->is_required){ 
      $rules[] = 'required'; 
     } 

     if($control->validation_rule == 'Text'){ 

      if($control->min_length){ 
       $rules[] = 'min:' . $control->max_length; 
      } 

      if($control->max_length){ 
       $rules[] = 'max:' . $control->max_length; 
      } 

     } 


     if($control->validation_rule == 'Number'){ 

      $rules[] = 'numeric'; 

      if($control->min_value){ 
       $rules[] = 'min:' . $control->max_length; 
      } 

      if($control->max_value){ 
       $rules[] = 'max:' . $control->max_length; 
      } 

     } 


    } 
} 

回答

0

可以(IMO)利用模型事件,例如:保存時(適用於創建&更新),您可致電setCustomRules方法來設置和使用驗證規則這樣的事情:

public static function boot() 
{ 
    parent::boot(); 

    // This method will be called on creating and updating 
    // but there are separate events for both methods so you 
    // may use separate handlers for different events like : 
    // static::creating(...) static::updating(...) 
    static::saving(function($user) 
    { 
     // Set rules and validate here 
    }); 
} 

這應該是在模型中,還有其他方式註冊事件,但我更喜歡這種方式最。欲瞭解更多信息,請Laravel [email protected]

+0

如果我理解laravel http://laravel.com/docs/5.1/lifecycle中的請求生命週期,驗證步驟將在任何數據庫操作之前進行。所以如果出現錯誤,Laravel會產生錯誤,然後將用戶發送到視圖或每個返回到控制器的方法。因此,如果驗證發生在任何SQL操作之前,那麼您的建議將導致驗證兩次,一次是默認的Laravel步驟,然後是保存之前的步驟。我在這裏錯過了什麼? –

+0

不,如果你註冊這些事件,那麼它會像這樣工作。例如,在引導方法中,如果您註冊了一個'creating(function(){...})',那麼在新模型創建之前,函數將被執行。如果您從該函數返回false,則創建將會中斷,意味着不會爲無效數據保存新模型。你需要手動捕捉。 –

+0

我想我明白了。然後,我將如何將SurveyAnswerDefinedRepository類注入到save()事件中,以便我可以讀取數據庫中的規則? –

0

末答案

您還可以使用Model Mutators和驗證

例如

public function setFirstNameAttribute($value) { 
    // validate $value e.g.: 
    if (strlen($value) < 2) { 
     throw new \Exception('name too short, 2 char minimum'); 
    } 
}