Validation request with Laravel 5 - validation

I am trying to make validation with Laravel 5 on right way:
Here is my working code in model:
public function apiAddNewComment() {
if (Input::get("task") == 'addComment') {
$user = Auth::id();
$inputs = array(
'comment' => Input::get('comment'),
'projectID' => Input::get('projectID'),
'order' => Input::get("order"),
'level' => Input::get("level"),
);
$rules = array(
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
);
$validator = Validator::make($inputs, $rules);
if ($validator->fails()) {
return json_encode(array('err' => true, 'errors' => $validator->messages()->all()));
} else {
return $this->createNewComment();
}
}
}
here is my controller:
public function update($id, Comment $update)
{
return $update->apiUpdateComment();
}
How can I make validation with request?
And can someone explain me how this method works inside request:
public function authorize()
{
return false;
}
?

The Request has to basic functions: rules() and authorize()
rules returns an array that is used for the validation.
The authorize method can for example check if the user is allowed to do this request.
public function authorize() {
return Auth::check();
}
So you don't have to check it each time when you use the request in a controller.
If you need no check just return true.
UPDATE:
Generate a request File with artisan
php artisan make:request CommandRequest
then edit the generate file like this:
class CommandRequest extends FormRequest
{
public function rules()
{
return [
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
];
}
public function authorize()
{
return true;
}
}
Also update the controller method:
public function update($id, Comment $update, CommandRequest $request)
{
// create your comment here like:
return Comment::create($request->all());
}

You are using a Laravel 4 code I guess, you need to translate it to L5 where Input::get('var') turns into $request->input('var') for instance:
public function apiAddNewComment(Illuminate\Http\Request $request) { //Remember to add the Request as a parameter of the method
if ($request->input("task") == 'addComment') {
...
Then the validation part looks fine

Related

Howto reusing Form Request inside loop

I am making a "/bulk" endpoint for my API/REST made in Laravel 8.
My problem is that I don't know how to reuse the same FormRequest that I have for the create or update
json post to: /cars/bulk
{
"cars": [{"model": "A", "year": 2021, "plate": "AA11BB"},{"model": "B", "year": 2021, "plate": "AA12BB"},{"model": "C", "plate": "AA13BB"}]
}
// CarController.php
public function store(CarRequest $request)
{
$car = $this->carService->store($request, Car::class);
}
public function update(CarRequest $request, Car $car)
{
$this->carService->update($request, $car);
}
public function bulk(Request $request)
{
$this->carService->bulk($request);
}
// CarService.php
public function store($request, $modelClass)
{
# My code....
}
public function update($request, $model)
{
# My code....
}
public function bulk($request)
{
foreach ($request->cars AS $carData )
{
$car = Car::where('plate','=',$carData->plate)->first()
# here is the problem,
# howto validate each $car by reusing CarRequest
if ($car){
$this->update($carData, $car);
} else {
$this->store($carData, Car::class);
}
}
}
This is de form request for each item, i have use to for bulk or one request
class CarRequest extends BaseRequest
{
public function authorize()
{
$this->setModel(Car::class);
return $this->isAuthorized();
}
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'model' => 'required',
'year' => 'required|numeric',
'plate' => 'required'
];
return $rules;
}
public function messages()
{
# multiples messages
}
}
I need reuse my request
Edit: add form request
So I wouldn't suggest using it within a loop how you have in your example, what would be better would be to create a second, bulk request that valiates an array like this.
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'cars' => ['required', 'array'],
'cars.*.model' => 'required',
'cars.*.year' => 'required|numeric',
'cars.*.plate' => 'required'
];
return $rules;
}
You can do it with same CarRequest form request class as follows.
public function rules()
{
return[
'cars.*.model' => 'required',
'cars.*.year' => 'required',
'cars.*.plate' => 'required',
];
}
Laravel will expect that you are sending nested array. If you dont want to mix it up with CarRequest you can do it with creating another FormRequest class.

Laravel resource empty request parameters

When calling API route the data from query doesn't get passed to resource and the request doesn't contain any data from the query.
Route
Route::get('rooms', 'RoomController#index');
Controller
public function index() {
$rooms = Room::get();
return RoomCollection::collection($rooms);
}
Resource
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}
Maybe you need Room::all() instead of Room::get()?
In controller
use App\Room;
use App\Http\Resources\Room as RoomResource;
public function index() {
$rooms = Room::all();
return RoomResource::collection($rooms);
}
In App\Http\Resources\Room.php
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}

Laravel 302 redirect issue

I am trying to get info from action, but when click, just page refresh and in console I get code 302 and stay on current page.
I read a lot of similar topics here but found nothing.
I am trying to execute http://laravel2.lo/getUserChannels?user_id=2
Laravel 5.7.16
route:
Auth::routes();
Route::group(['middleware' => ['auth']], function () {
Route::view('createUser', 'createuser');
Route::view('createChannel', 'createchannel');
Route::view('joinChannel', 'joinchannel');
Route::get('profile', 'UserController#profile');
Route::get('users', 'UserController#users');
Route::get('getChannelUsers', 'UserController#getChannelUsers');
Route::get('getUserChannels', 'ChannelController#getUserChannels');
});
ChannelController:
class ChannelController extends Controller
{
public function getUserChannels(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
]);
/** #var User $user */
$user = User::find($request->user_id);
return view('singleuser', ['channels' => $user->channels, 'username' => $user->name]);
}
}
In the log file no errors.
Thanks for any help and advise.
I don't think you'll receive query params as anything other than strings, so your integer validation fails.
To improve your error handling you could customize your App\Exceptions\Handler, catch your ValidationException errors with something like get_class() or instanceOf and do some neat stuff there
And of course you could not use query params at all by using Route::get('getUserChannels/{id}', 'controller#show'); and access it /getUserChannels/2 - then you could probably validate it as an integer
You could go with
Route::get('getUserChannels/{id}', ...
public function getUserChannels($id)
{
$user = User::findOrFail($id);
return view('singleuser', [
'channels' => $user->channels,
'username' => $user->name
]);
}
Then it would just throw a 404 if string, not found etc...
class ChannelController extends Controller
{
public function getUserChannels(Request $request)
{
$validator = \Validator::make($request->all(), ['user_id' => 'required|integer']);
if($validator->fails())
{
$error = $validator->errors()->first();
dd($error);
}
/** #var User $user */
$user = User::find($request->user_id);
return view('singleuser', ['channels' => $user->channels, 'username' => $user->name]);
}
}

Laravel Form Request Add Custom Variable After Validation

This is my form request code, i want to add new variable after validation success, so i can access that variable at my controller :
class CouponRequest extends Request
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'start_year' => 'required',
'start_month' => 'required',
'start_day' => 'required',
'start_time' => 'required',
'finish_year' => 'required',
'finish_month' => 'required',
'finish_day' => 'required',
'finish_time' => 'required',
];
}
public function afterValidation()
{
$this->start_date = Carbon::create( $this->start_year, $this->start_month, $this->start_day );
}
}
So after validation has no error, i can call this instance at my controller :
$request->start_date;
Could i do this?
All above methods work but in my opinion I would override the passedValidation method in the form request class. This method is called after the validation checks are passed and hence keep the data clean.
Ex.
public function passedValidation()
{
$this->merge([
'start_date' => Carbon::create( $this->start_year, $this->start_month, $this->start_day )
]);
}
If you dump the data now you should see your new start_date value as well.
You could do this
public function afterValidation()
{
$this->request->add([
'start_date' => Carbon::create($this->start_year, $this->start_month, $this->start_day)
]);
}
public function validate()
{
parent::validate();
$this->afterValidation();
}
And then access the attribute in your controller as
$request->get('start_date');
In your form request use function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'start_date' => Carbon::now()
]);
}
Cheers!
I am using this method after success request for manipulations.
Source: 50116187/1101038
public function withValidator(Validator $validator)
{
if ( $validator->fails() ) {
\Log::info('Error! No Manipulation!');
}else{
$this->merge([
'custom' => 'Test Manipulation!'
]);
\Log::info('Success Manipulation!');
}
}
I made the validation in the Controller. The method has a "Request $request" parameter. I have a I do this:
$input = $request->all();
$input['my_new_field] = 'the_data';

Problems creating users in laravel

I am creating the traditional register of users with Laravel and I have a problem to send specific value.
public function postUserRegister(){
$input = Input::all();
$rules = array(
'name' => 'required',
);
$v = Validator::make($input, $rules);
if($v->passes() ) {
$user = User::create(Input::all());
} else {
Session::flash('msg', 'The information is wrong');
return Redirect::back();
}
}
This code works correctly , but I need to send always the same value into table users and this column doesn't appear in the form. How can I send the value of the table if the value doesn't appear?
You can just supply the value manually. There are several ways to do this, here is one:
$user = new User(Input::all());
$user->yourcolumn = $yourdata;
$user->save();
You can use input merge to add extra fields.
Input::merge(array('val_key' => $val_name));
$input = Input::all();
Firstly, I think it would be ideal to clean a bit the method, something like that:
public function postUserRegister(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($v->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
And now you can simply assign a data to a specific column by using:
$request->merge(['column_name' => 'data']);
The data can be null, or variable etc. And now the whole code would look something like:
public function postUserRegister(Request $request)
{
$request->merge(['column_name' => 'data']);
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($validator->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
You can add whatever data you want directly into the create method:
public function postUserRegister()
{
$input = request()->all();
if (validator($input, ['name' => 'required'])->fails()) {
return back()->with('msg', 'The information is wrong');
}
$user = User::create($input + ['custom' => 'data']);
//
}
P.S. Merging that data into the request itself is a bad idea.
You can do this in the User model by adding the boot() method.
class User extends Model
{
public static function boot()
{
parent::boot();
static::creating(function ($user) {
$user->newColumn = 'some-value';
});
}
...
}
Reference: https://laravel.com/docs/5.2/eloquent#events

Resources