Skip to content

Instantly share code, notes, and snippets.

@rmrhz
Last active Jul 11, 2016
Embed
What would you like to do?
Making Requests and validation easier and less redundant.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
abstract class Request extends FormRequest
{
/**
* Validation rules
*
* @var array
*/
protected $rules = [];
/**
* Get the parsed method
*
* @return string
*/
public function parsedMethod()
{
return strtolower($this->method());
}
/**
* OVERRIDE!
*
* This will call `$this->resolveValidationRules` depending on the request method,
* returns all of the rules by default
* --
* Get the validator instance for the request.
*
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function getValidatorInstance()
{
$factory = $this->container->make(\Illuminate\Contracts\Validation\Factory::class); // Originally as ValidationFactory
if (method_exists($this, 'validator')) {
return $this->container->call([$this, 'validator'], compact('factory'));
}
return $factory->make(
$this->validationData(), $this->container->call([$this, 'rules'], [$this->getRuleKeys()]), $this->messages(), $this->attributes()
);
}
/**
* Return the validation rule set from a pre-set
*
* @param array $params
* @return array
*/
public function rules(array $params = [], $command = 'only') : array
{
return count($params) > 0 ?
call_user_func($this->getCommand($command), [$this->rules, $params]):
$this->rules;
}
/**
* Return the validation rules depending on the request method
*
* @return array
*/
public function getRuleKeys() : array
{
return array_key_exists($this->parsedMethod(), $this->rules) ? array_keys($this->rules[$this->method()]): [];
}
/**
* Gets the appropriate command to run
*
* @param string $command
* @return string
*/
public function getCommand(string $command) : string
{
$commands = [
'only' => 'array_only',
'pluck' => 'array_pluck'
];
if ( ! array_key_exists($command, $commands) ) {
throw \Exception('Command not found');
}
return $command;
}
/**
* @param array $errors
* @return \Illuminate\Http\JsonResponse
*/
public function response(array $errors)
{
$errors = array_merge(['code' => 422, 'data' => $errors]);
return response()->json($errors);
}
}
<?php
namespace App\Http\Requests;
class PostRequest extends Request
{
protected $rules = [
'post' => [
'username' => 'required'
],
'put' => [
'id' => 'required',
'username' => 'required'
]
];
public function authorize()
{
return true;
}
}
@srph
Copy link

srph commented Jul 11, 2016

Does it handle cases where only a validation rule is omitted for some methods? For example,

password is required only on POST, but not on PUT. Of course, I still want my 20 max characters (HAHAHAHAHA) validation rule.

@awkwardusername
Copy link

awkwardusername commented Jul 11, 2016

Checking the code, it doesn't. Lol. Should be more useful if we get,

protected $rules = [
   [
        'method' => 'get'
        'fields' => [
            'username' => 'required'
        ],
   ],
   [
        'method' => 'put'
        'fields' => [
            'username' => 'max:5'
        ],
   ]
];

@srph
Copy link

srph commented Jul 11, 2016

The original API (getRules, if I'm right) looks much more flexible to me, although not declarative as this.

@awkwardusername
Copy link

awkwardusername commented Jul 11, 2016

Or is it valid if we make the method as a key so,

protected $rules = [
   [
       'get' => [
            'username' => 'required'
        ],
   ],
   [
       'put' => [
            'username' => 'max:5'
        ],
   ]
];

Looks hackish, but we can do,

/**
     * Return the validation rule set from a pre-set
     *
     * @param array $params
     * @return array
     */
    public function rules(array $params = [], $command = 'only') : array
    {   
        return count($params) > 0 ? call_user_func($this->getCommand($command), [$this->rules[$this->method()], $params]) : [];
    }

    /**
     * Return the validation rules depending on the request method
     *
     * @return array
     */
    public function getRuleKeys() : array
    {
        return array_keys($this->rules[$this->method()]);
    }

@rmrhz
Copy link
Author

rmrhz commented Jul 11, 2016

I'll leave that in mind. I'll be creating a repository for this if you want to use it as a component.

@awkwardusername
Copy link

awkwardusername commented Jul 11, 2016

Go repo. Ahaha. I might be using this pattern for all my future forms.

@rmrhz
Copy link
Author

rmrhz commented Jul 11, 2016

Addressed.

protected $rules = [
    'get' => [
        'username' => 'required'
    ],

    'put' => [
        'username' => 'max:5'
    ]
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment