I need to set the $rules
array in the Validator Class using a setter method.
I need to set defined the $rules using a setter because the rules are stored in a database. I need to use Eloquent to query the database to figure out what will the rules look like.
I extended the Validator Class and added a method called setCustomRules(). I injected a class into this method which will allow me to use Eloquent to read the database to determine the rules.
But, how would I force the setCustomRules() method to fire when Laravel attempt to validate? This method must take place first to ensure that the rules are set before the validation takes place.
This is what I have done
<?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);
}
}
Edited Based on The Alpha's answer, I created an Event Handler that will let me create the rules. But not sure how to tell Laravel to validate now.
This is my EventHandler class
<?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;
}
}
}
}
You can (IMO) utilize the model events, for example: when saving (Applies to create & Updated) you may call the setCustomRules
method to set and validate rules using something like this:
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
});
}
This should be in the Model and there are other ways to register events but I prefer this way most. For more information, check Laravel Website@Events
late answer
You can also use Model Mutators and validate
e.g.
public function setFirstNameAttribute($value) {
// validate $value e.g.:
if (strlen($value) < 2) {
throw new \Exception('name too short, 2 char minimum');
}
}