Laravel return flash message - laravel

I am trying to return a flash message depending on the outcome of an function however I don't really know how to do this properly, can someone help me with fixing this?
Controller:
public function postDB(Requests\NameRequest $request) {
$newName = trim($request->input('newName'));
$newLat = $request->input('newCode');
$websites = new Website();
$websites->name = $newName;
$websites->html = $newLat;
$websites->save();
if ($websites->save())
{
$message = 'success';
}else{
$message = 'error';
}
return redirect()->back()->withInput()->with('message', 'Profile updated!');
}
Request:
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'img' => 'file|image',
];
}
public function messages()
{
return [
'img.image' => 'File type is not supported! Use files with extension .jpg/.jpeg/.gif',
];
}
Template:
#if (session('status'))
#if (session('status')=="success")
<div class="alert alert-success">
{{ session('message') }}
</div>
#else
<div class="alert alert-error">
{{ session('message') }}
</div>
#endif
#endif
Route:
Route::group(['middleware' => ['web']], function () {
Route::get('home', 'BuilderController#homepage');
Route::get('pages', 'BuilderController#websites');
Route::get('template', 'BuilderController#templates');
Route::post('template2', 'BuilderController#postDB');
Route::post('template', 'BuilderController#testing');
Route::get('logout', 'BuilderController#getLogout');
Route::get('/website/{name}', 'BuilderController#website');
});

Solution :
There could be only one reason for this issue.
The laravel will pass the flash messages only if it's registered inside the middleware web
i.e.,
Route::group(['middleware' => ['web']], function () {
//The back()'s url should be registered here
});
Update :
It seems you need to redirect back with message and inputs
So, You can do like this
if ($request->hasFile('img')) {
$message = 'success';
} else {
$message = 'error';
}
return redirect()->back()->withInput()->->with('message', $message);
Update 2 :
#if (session('status'))
#if (session('status')=="success")
<div class="alert alert-success">
Congrats! Everything was fine
</div>
#else
<div class="alert alert-error">
Oops! Something went wrong
</div>
#endif
#endif
Note : You can pass the status param to your wish

If you pass message as a flash parameter name, use it, not status.
#if (session('message'))
#if (session('message')=="success")
<div class="alert alert-success">
Congrats! Everything was fine
</div>
#else
<div class="alert alert-error">
Oops! Something went wrong
</div>
#endif
#endif

Related

How to restrict edit only on data display in the index in laravel

I have a problem with my edit.blade.php. In the show view, I have restricted it only on the users' logged in as you can see in my controller
public function index()
{
$animal = Auth::user()->animals;
return view('farms.index', compact('animal'));
}
And my index view
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Farm Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
You are logged in! {{ Auth::user()->name }}
<br>
Add animal
#foreach( $animal as $animal)
<div class="row">
<div class="col-2">{{ $animal->id }}</div>
<div class="col-4">{{ $animal->type->category }}</div>
<div class="col-4">{{ $animal->created_at }}</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
</div>
#endsection
But I still have a problem if I change in my url the id number of an object of another user I can still edit and update.
What can I change in my controller to prevent that
public function show($id)
{
$animal = Animal::query()->findOrFail($id);
return view('farms.show', compact('animal'));
}
/**
* Show the form for editing the specified resource.
*
* #param $id
* #return void
*/
public function edit($id)
{
$type = Type::all();
$user = Auth::user();
$animal = Animal::query()->findOrFail($id);
return view('farms.edit', compact('animal', 'type', 'user'));
}
/**
* Update the specified resource in storage.
*
* #param $id
* #return void
*/
public function update($id)
{
$animal = Animal::query()->findOrFail($id);
$animal->update($this->validateRequest());
return redirect('farms/' . $animal->id)->with('message', 'Animal Details Updated');
}
You can follow this basic/easy method
For Show
public function show($id)
{
try {
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
return view('farms.show', compact('animal'));
} catch(\Exception $ex) {
//return exception or any other page
abort(404, 'Not allowed');
//or return back()->withErrors(['Not allowed']);
}
}
For edit
public function edit($id)
{
try {
$type = Type::all();
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
return view('farms.edit', compact('animal', 'type', 'user'));
} catch(\Exception $ex) {
//return exception or any other page
}
}
For update
public function update($id)
{
try {
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
$animal->update($this->validateRequest());
return redirect('farms/' . $animal->id)->with('message', 'Animal Details Updated'); //use route for redirect instead of url
} catch(\Exception $ex) {
//return exception or any other page
}
}
Use try catch for exception
Make sure you defined that animal has user_id
or
You can also manage this functionality with relationship
Larave Eloquent relationship
For standard practice, you can use laravel gate policy
Laravel policy via model

Call to a member function has() on string in laravel

I am working on user authentication. When a user provides invalid email or password, I want to redirect him to login.blade.php with a flash error message.
// Auth/LoginController:
public function login(Request $request)
{
$user=User::where('email',$request->email)->first();
if(!is_null($user))
{
if($user->status==1)
{
if(Auth::guard('web')->attempt(['email'=>$request->email,'password'=>$request->password],$request->remember))
return redirect()->intended(route('index'));
}
}
else
{
if(Auth::guard('web')->attempt(['email'=>$request->email,'password'=>$request->password],$request->remember))
{
if(Auth::check())
{
Auth::logout();
}
$user->notify(new VerifyRegistration($user));
session()->flash('success','A new confirmation mail has sent to you...Please check and confirm your email');
return redirect('/');
}
else
{
session()->flash('errors','Password is incorrect!!');
return redirect()->route('login');
}
}
}
else
{
session()->flash('errors','Email or Password is incorrect!!');
return redirect('/login');
}
}
I am using the default laravel login.blade.php.
When user enter's wrong password rather than setting up session flash message please use below given code to redirect user in else condition.
return redirect()->route('login')->with('error','Invalid password.');
On login template you can display errors like
#if (session('success'))
<div class="alert alert-success">
<p>{{ session('success') }}</p>
</div>
#endif
#if (session('warning'))
<div class="alert alert-warning">
<p>{{ session('warning') }}</p>
</div>
#endif
#if (session('error'))
<div class="alert alert-error">
<p>{{ session('error') }}</p>
</div>
#endif

Laravel 5.8: Validation multiple inputs

What I have
I have a form with 3 inputs and I want to check the following conditions:
All inputs are integers and they are required.
We do a math operation with all the numbers and we get if the operation was successfull or not.
Success: we redirect the user to a success page.
No success: we show a error message to the user with a message explaining him that the numbers aren't valid.
I resolved this with the following lines.
Controller:
function formAction(Request $request) {
$this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if($isValid) {
return redirect()->route('success');
} else {
$request->session()->flash('error', 'The numbers are not valid.');
return back();
}
}
View (using Bootstrap):
<form method="POST" action="{{ route('form-action') }}">
#csrf
<div class="form-group">
<label for="number1">number1</label>
<input id="number1" name="number1" class="form-control {{ $errors->has('number1') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number2">number2</label>
<input id="number2" name="number2" class="form-control {{ $errors->has('number2') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number3">number3</label>
<input id="number3" name="number3" class="form-control {{ $errors->has('number3') ? ' is-invalid' : '' }}" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
What I looking for
When MyOwnClass::checkMathOperation($numbers) is false:
To highlight number1, number2 and number3 inputs.
To show an unique custom error message
To hide the number1, number2 and number3 input error messages.
How can I do that with validators?
Solution
Create a Form Request Validation called, for example, NumbersForm using:
php artisan make:request NumbersForm
The previous command creates a App/Http/Requests/NumbersForm.php file. Make authorize() returns true, put the validation rules into rules() and create a withValidatior() function.
class NumbersForm extends FormRequest
{
public function authorize() {
return true;
}
public function rules() {
return [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
];
}
public function withValidator($validator) {
$validator->after(function ($validator) {
$numbers = $this->except('_token'); // Get all inputs except '_token'
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', ' ');
$validator->errors()->add('number2', ' ');
$validator->errors()->add('number3', ' ');
$validator->errors()->add('globalError', 'The numbers are not valid.');
}
});
}
}
Note: It's not important the text in the second param of $validator->errors()->add('number1', ' ');, but it can't be empty. If it is an empty string, $errors->has('number1') returns false, and the field won't be hightlighted.
Set the controller like this:
use App\Http\Requests\NumbersForm;
function formAction(NumbersForm $request) {
$this->validated();
return redirect()->route('success');
}
And, finally, if we want to print an unique error message, we must remove the following lines from view:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
and replace them with:
#if ($errors->has('globalError'))
<div class="alert alert-danger">
{{ $errors->first('globalError') }}
</div>
#else
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#endif
I haven't tested this but I think it can get you going in the right direction.
1 // Highlight the inputs
You can do this by accessing the error object within your view. This object is an instance of the MessageBag object.
Here is the docs: https://laravel.com/docs/5.7/validation#working-with-error-messages
Example:
// if the error exists for the input the class will be added
<input class=" {{ $error->has('number1') ? 'highlight' : '' }}" name="number1">
<input class=" {{ $error->has('number2') ? 'highlight' : '' }}" name="number2">
<input class=" {{ $error->has('number3') ? 'highlight' : '' }}" name="number3">
2 & 3 // Show a unique custom error message and hide the default messages
See the validator docs: https://laravel.com/docs/5.8/validation#custom-error-messages && https://laravel.com/docs/5.7/validation#working-with-error-messages -- this should solve both of these.
There is a validator callback and I think you can pass your second validation into that. If these numbers aren't valid then you can add your custom error messages and access them the same way as I did above.
function formAction(Request $request) {
$validator = $this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$validator->after(function ($validator) {
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', 'Unique message');
$validator->errors()->add('number2', 'Unique message');
$validator->errors()->add('number3', 'Unique message');
}
});
}
Custom Validation Rules:
To add custom messages and validation you can also write a custom validation rule
Example:
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Custom Error Messages:
You could also add custom error messages for rules within a Request:
public function messages()
{
return [
'number1.required' => 'My custom message telling the user he needs to fill in the number1 field.',
'number1.integer' => 'My custom message telling the user he needs to use an integer.',
];
}

How to Set & Get Session Data in Laravel Package Development

I am developing a package with a contact form in Laravel. I'm trying to set & get session data, but it's not working with the following.
View
#if(session('success'))
<div class="alert alert-success alert-dismissible">
×
{{session('success')}}
</div>
#endif
Controller
public function store(Request $request)
{
//Validation
$request->validate([
'email'=>'required|max:50|unique:contact_forms,email'
]);
//Data
$contact_form = new ContactForm();
$contact_form->full_name = $request->full_name;
$contact_form->mobile = $request->mobile;
$contact_form->email = $request->email;
//Save
$contact_form->save();
//Return back
return back()->with('success','Record inserted successfully');
}
Route
Route::group(['namespace' => 'W3public\ContactForm\Http\Controllers'], function () {
Route::get('contact-us', 'ContactFormController#index');
Route::post('contact-us', 'ContactFormController#store')->name('contact-us');
});
How can I set/get session data in package development in Laravel?Thanks in advance.
Best way of doing this is flash session messages
Redirect as
$request->session()->flash('alert-success', 'Record inserted successfully!');
and in your view file
<div class="flash-message">
#foreach (['danger', 'warning', 'success', 'info'] as $msg)
#if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} ×</p>
#endif
#endforeach

Laravel 5 Pass and get a flash data not working

i want to pass a flash data from store function to add function but i cant get it to work, i always get null;
here is my controller
public function add()
{
return view('cars.add');
}
public function store(CarFormRequest $request)
{
$car = new Cars(array(
'name' => $request->get('name'),
'color_id' => $request->get('color')
));
$car->save();
$car->position_id = $car->id;
$car->save();
return redirect('/cars/add')->with('status', 'A Car has been added');
}
here is my view:
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif
Add in your controller
session()->flash('status', 'Task was successful!');
and in View:
#if (session->has('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif

Resources