php - formrequest - Formulario de Laravel 5 Pre-manipulación de datos.
laravel validation regex (6)
Estoy procesando un formulario donde un usuario puede actualizar su fecha de nacimiento. El formulario le da al usuario 3 campos separados por day
, month
y year
. En el lado del servidor, por supuesto, quiero tratar estos 3 campos separados como un valor, es decir, yyyy-mm-dd
.
Por lo tanto, antes de validar y actualizar mi base de datos, quiero modificar la solicitud de formulario para crear un campo date_of_birth
al concatenar el year
, el month
y el day
con -
caracteres para crear el formato de fecha que necesito (y posiblemente eliminar los 3 campos originales).
Lograr esto manualmente con mi controlador no es un problema. Simplemente puedo tomar la entrada, unir los campos separados por caracteres y desarmarlos. Entonces puedo validar manualmente antes de pasar a un comando para tratar con el procesamiento.
Sin embargo, preferiría usar un FormRequest
para tratar con la validación y hacer que se inyecte en mi método de controlador. Por lo tanto, necesito una forma de modificar realmente la solicitud de formulario antes de que se ejecute la validación.
Encontré la siguiente pregunta que es similar: Solicitud de Laravel 5 - alteración de datos
Se sugiere anular all
método en la solicitud de formulario para contener la lógica para manipular los datos antes de la validación.
<?php namespace App/Http/Requests;
class UpdateSettingsRequest extends Request {
public function authorize()
{
return true;
}
public function rules()
{
return [];
}
public function all()
{
$data = parent::all();
$data[''date_of_birth''] = ''test'';
return $data;
}
Todo esto está muy bien para la validación, pero anular el método all
no modifica los datos en el objeto de solicitud de formulario. Entonces, cuando se trata de ejecutar el comando, la solicitud de formulario contiene los datos originales no modificados. A menos que use el método ahora anulado all
para extraer los datos.
Estoy buscando una forma más concreta de modificar los datos dentro de mi solicitud de formulario que no requiera la llamada de un método específico.
Aclamaciones
Aún anula el método all()
, pero inténtelo de esta manera
public function all()
{
$input = $this->all();
$input[''date_of_birth''] = $input[''year''].''-''.$input[''month''].''-''.$input[''day''];
$this->replace($input);
return $this->all();
}
Entonces, en realidad, no llama al método usted mismo, el validador lo llamará cuando haga las reglas.
Creo que este es el mejor enfoque para hacerlo: Laravel 5.1 Modificar entrada antes de validar solicitud de formulario
En Laravel 5.4+ hay un método dedicado para este tipo de cosas, así que prepareForValidation
: prepareForValidation
Después de jugar un poco a mi alrededor, se me ocurrió lo siguiente:
app / Http / Requests / Request.php
<?php namespace App/Http/Requests;
use Illuminate/Foundation/Http/FormRequest;
abstract class Request extends FormRequest {
/**
* Override the initialize method called from the constructor to give subclasses
* an opportunity to modify the input before anything happens.
*
* @param array $query
* @param array $request
* @param array $attributes
* @param array $cookies
* @param array $files
* @param array $server
* @param null $content
*/
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content);
// Grab the input
$data = $this->getInputSource()->all();
// Pass it off to modifyInput function
$data = $this->modifyInput($data);
// Replace modified data back into input.
$this->getInputSource()->replace($data);
}
/**
* Function that can be overridden to manipulate the input data before anything
* happens with it.
*
* @param array $data The original data.
* @return array The new modified data.
*/
public function modifyInput(array $data)
{
return $data;
}
}
Luego, al extender las clases, puede anular el método modifyInput
la modifyInput
manera:
app / Http / Requests / TestRequest.php
<?php namespace App/Http/Requests;
class TestRequest extends Request {
public function authorize()
{
return true;
}
public function rules()
{
return [];
}
/**
* Modify the input.
*/
public function modifyInput(array $data)
{
$data[''date_of_birth''] = ''something'';
// Make sure to return it.
return $data;
}
}
Esto parece funcionar para mis necesidades. No estoy seguro de los inconvenientes de hacerlo de esta manera, así que doy la bienvenida a cualquier comentario / crítica.
La respuesta dada por The Shift Exchange anterior también funcionará bien.
Tomé un enfoque similar a Julia Logvina, pero creo que de esta manera es una forma ligeramente más elegante de agregar / modificar campos antes de la validación (Laravel 5.1)
<?php
namespace App/Http/Requests;
use App/Http/Requests/Request;
class UpdateSettingsRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [];
}
/**
* Extend the default getValidatorInstance method
* so fields can be modified or added before validation
*
* @return /Illuminate/Contracts/Validation/Validator
*/
protected function getValidatorInstance()
{
// Add new data field before it gets sent to the validator
$this->merge(array(''date_of_birth'' => ''test''));
// OR: Replace ALL data fields before they''re sent to the validator
// $this->replace(array(''date_of_birth'' => ''test''));
// Fire the parent getValidatorInstance method
return parent::getValidatorInstance();
}
}
Esto ampliará la getValidatorInstance
predeterminada para que podamos modificar los valores de entrada en la solicitud antes de que llegue al validador (evitando que use los datos originales no modificados). Una vez que se han modificado los datos, se dispara la getValidatorInstance
original getValidatorInstance
y todo continúa normalmente.
Puede usar $this->replace(array())
o $this->merge(array())
sus nuevos campos en su solicitud. He incluido un ejemplo de cómo hacer ambas cosas en el fragmento anterior.
replace()
reemplazará todos los campos con la matriz que proporcione.
merge()
agregará un nuevo campo a su solicitud.
Yo también necesitaba una manera rápida y sucia de lograr esto. Quería usar la solución The Shift Exchanges pero no funcionó debido a las llamadas a $this
que crean un bucle recursivo infinito. Un cambio rápido para hacer referencia al método principal solucionará el problema:
public function all()
{
$input = parent::all();
$input[''date_of_birth''] = $input[''year''].''-''.$input[''month''].''-''.$input[''day''];
$this->replace($input);
return parent::all();
}
HTH otros necesitados.
en laravel 5.1 puedes hacer eso
<?php namespace App/Http/Requests;
class UpdateSettingsRequest extends Request {
public function authorize()
{
return true;
}
public function rules()
{
return [];
}
protected function getValidatorInstance()
{
$data = $this->all();
$data[''date_of_birth''] = ''test'';
$this->getInputSource()->replace($data);
/*modify data before send to validator*/
return parent::getValidatorInstance();
}