Laravel email resulting in view not found error - laravel

I am firing an event that sends an email to the user when he requests a password reset.
Here's the event listener that will send an email
class SendResetPasswordLink {
public function handle(UserForgotPassword $event) {
Mail::to($event->user)
->queue(new SendResetPasswordToken($event->user->passwordResetToken));
}
}
Here's my mail class:
class SendResetPasswordToken extends Mailable {
use Queueable, SerializesModels;
public $token;
public function __construct(PasswordReset $token) {
$this->token = $token;
}
public function build() {
return $this->subject('Reset your MyEngine password')
->markdown('emails.password.reset')
->text('emails.password.reset_text');
}
}
I have email files (both html and text) available at
resources/views/emails/password/reset.blade.php
and
resources/views/emails/password/reset_text.blade.php
It is not working and I am getting the following error:
"View [] not found. (View: /home/vagrant/Laravel/youtube/resources/views/emails/password/reset.blade.php)"
What do I need to do? All my blade files are in place.
Here's my reset.blade.php
#component('mail::message')
<strong>Hello {{ $token->user->getFirstNameOrUserName() }}!</strong>
You are receiving this email because we received a password reset request for your account.
If you did not request a password reset, no further action is required.
#component('mail::button', [
'url' => route('password.reset', ['token' => $token,]) . '?email=' . urlencode($token->user->email)
])
Reset Password
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent
<hr>
If you’re having trouble clicking the <strong>"Reset Password"</strong> button, copy and paste the URL below into your web browser:<br>
<small>{{ route('password.reset', ['token' => $token,]) . '?email=' . urlencode($token->user->email) }}</small>
#endcomponent

I found the answer,
For whatever reason I had closed(ended) the markdown component twice #endcomponent.

Related

Mailtrap does not show the body of the message

The function here is to send a six digit pin to email so as to recover password. Mailtrap inbox does not show the six digit pin, just a "button text". How do you send the recovery code /pin to the recovery mail.
class UserPasswordPin extends Mailable {
use Queueable, SerializesModels;
public $pin;
public function __construct($pin)
{
$this->pin = $pin;
}
public function build()
{
return $this->markdown('emails.userpin')->with([
'pin' => $this->pin,
]);
}
}
The recover password controller send the six digit code. it works in postman but when it send email to mailtrap its blank. And also is there an algorithm for the method unwantedPin, like it selects a six digit conbination and prevents sending digits which are predictable?
class RecoverPasswordController extends Controller{
private $unwantedPins = [
111111,222222,333333,444444,555555,666666,777777,888888,999999
];
private function inUnWanted($pin)
{
return in_array($pin,$this->unwantedPins);
}
public function recover(RecoverPasswordRequest $request){
//check if email exist
$user = DB::table('users')->where([
'email' => $request->email
])->first();
if (is_null($user)){
return response([
'errors'=>'The email entered is not registered'
],404);
}
//send a six digit code/pin to the recovery email
$pin = rand( 111111,999999);
foreach ($this->unwantedPins as $unwantedPin){
if ($pin == $unwantedPin){
$pin = rand(111111,999999);
}
}
Mail::to($user)->queue(new UserPasswordPin($pin));
return response([
'pin'=>$pin,
'message'=>'a six digit code has been sent to your email'
],200);
}
}
the problem was in userpin.blade.php
#component('mail::message')
# Introduction
This is your six digit number.
#component('mail::button', ['url' => ''])
{{$pin}}
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent

How to pass the custom variables from ResetPasswordController to reset blade

How to pass the custom variables from ResetPasswordController to reset blade template.
ResetPasswordController.php
public function showResetForm(Request $request, $token = null)
{
$data = array(
'title'=>'Reset password',
'description'=> 'Reset password to abc.com',
'seo_keywords'=> 'Reset password to abc.com',
);
return view('auth/password/reset',$data);
}
By returning a view(), the second argument can be used to pass variables to the blade template (just like you have done)
public function showResetForm(Request $request, $token = null)
{
return view('auth/password/reset',[
'title' =>'Reset password',
'description' => 'Reset password to abc.com',
'seo_keywords' => 'Reset password to abc.com',
]);
}
These would then be accessable as {{ $title }}, {{ $description}}, {{ $seo_keywords}}.
If you are unable to retrieve these, it may be because you are editting the wrong blade template. The default template is located at auth.passwords.reset (resources/views/auth/passwords/reset.blade.php).
I'd suggest just adding a {{ dd('here) }} at the top of that template to make sure it is in fact the template being used by your application!

Laravel send email to address from database

In my index view I show all the users and there is a button that will change the user status to active and not active. The code looks like this:
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{$user->surname}}</td>
<td>{{$user->email}}</td>
<td>
#if($user->is_active == 0)
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('Activate', ['class'=>'btn btn-primary']) !!}
{!! Form::close() !!}
#else
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('De-Activate', ['class'=>'btn btn-danger']) !!}
{!! Form::close() !!}
#endif
</td>
<td>{{$user->cell}}</td>
<td><button class="btn btn-primary">View Property</button></td>
<td><button class="btn btn-danger">Delete</button></td>
</tr>
#endforeach
So when I click on activate/deactivate button I trigger my activateuser function of the controller. After activation, an email is sent.
The controller looks like this:
public function activateuser(Request $request, $id){
$user = User::findOrFail($id);
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::send(new activateUser());
}
else{
$user->update([$user->is_active = 0]);
}
return redirect()->back();
}
At the moment the email is going to myself and my Mailabçe looks like this:
public function build()
{
return $this->view('emails.activateuser')->to('wosleybago#gmail.com');
}
What I want instead is to send the email to the email address from the user email in the database table.
How can I do that?
So, someho I should get the $user->email
I usually want my emails have all the information in itself, so I pass User instance or whatever instance that holds data required to compose the mail.
So the Mailable has __construct(..) like this:
/**
* #var \App\User
*/
public $user; // since this is a public property its going to be available in view of mailable as $user
__construct(App\User $user) {
$this->user = $user;
// further more I set the to(), this is what you are after
$this->to($user->email, $user->name);
// and subject
$this->subject('You are activated!');
}
...
And now all you need to do in the controller is the following:
Mail::send(new activateUser($user));
As mentioned above, $user is available in the mail-view so you can use it there as well:
Hi, {{ $user->name }},
...
Note: change the activateUser to ActivateUser to follow PSR-2
Class names MUST be declared in StudlyCaps.
I also use queued mails so I set the $timeout and $tries properties right on the Mailable class.
Sending email is described in Doc: https://laravel.com/docs/5.6/mail#sending-mail
Put this code inside activateUser() function
Mail::to($user)->send(new YourMailableName());
Do not forget to import Mail and YourMailableName using "use" keyword.
Or you can use user email instead object
Mail::to($user->email)->send(new YourMailableName());
And remove ->to('wosleybago#gmail.com') from your Mailable/
You should pass User Email in when creating new activateUser instance, like so
Mail::send(new activateUser($user->email));
And then use this attribute later.
Sending Email to particular a person is quite simple. My suggestion would be as follows:
Use Queue to send mail later as it will take some time to respond from controller to view.
In existing code you can get the email of the current user and send it using a helper to() that comes with mail functionality of laravel.
You can code it like this.
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::to($user->email)->send(new MailableClassInstance);
}

Laravel error is not passed to view

I can't figure put why laravel blade doesn't catch my error validation and doesn't pass it to my view.
In detail
I do have error snippet in my blade template
below is my validation which works correctly
What I'm missing?
Thank you
This is json message I see instead of message in blade template
{
message: "The given data was invalid.",
status_code: 500
}
This snippet I use to let user know about error
#if(count($errors))
<div class="form-group">
<div class="alert alert-danger">
<ul>
#if($errors->all())
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
#endif
</ul>
</div>
</div> #endif
And finally this is my correctly working validation
$request->validate([
'email' => 'required|email|unique:subscribers|max:255',
]);
EDIT:
This is the rout in web.php
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
And this is the method
namespace App\Http\Controllers;
use App\subscriber;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Ramsey\Uuid\Uuid;
class SaveSubscriberEmailController extends Controller
{
public function saveEmail(Request $request)
{
$request->validate([
'email' => 'required|email|unique:subscribers|max:255',
]);
$uuid = Uuid::uuid4();
$subscriber = new subscriber();
$subscriber->email = $request->email;
$subscriber->uuid = $uuid->toString();
$subscriber->created_at = Carbon::now();
$subscriber->save();
flash('Registration conformation email has been sent. Please check your mailbox. Thank you!')->success();
return redirect()->back();
}
}
I've had this problem before and the way I was able to fix it was to wrap the routes with a middleware group that includes the middleware \Illuminate\View\Middleware\ShareErrorsFromSession::class. It adds the session's errors to the view.
In your Kernel.php class's protected $middlewareGroups array it can look something like:
'web' => [
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// other middleware
],
Then where you declare your routes you can do:
Route::group(['middleware' => ['web']], function () {
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
};
Request validation only send error of 422 not 500 if you are getting this error it's because of something else and the formRequest error bag won't catch this error .
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
Put this route into web middleware. you can do this like
Route::middleware(['web'])->group(function () {
Route::post('saveemail', 'SaveSubscriberEmailController#saveEmail');
});
Change your controller to this.
class SaveSubscriberEmailController extends Controller
{
public function saveEmail(Request $request)
{
$validator = validate($request->all(),[
'email' => 'required|email|unique:subscribers|max:255',
]);
if($validator->fails()){
return back()->withErrors($validator);
}
$uuid = Uuid::uuid4();
$subscriber = new subscriber();
$subscriber->email = $request->email;
$subscriber->uuid = $uuid->toString();
$subscriber->created_at = Carbon::now();
$subscriber->save();
flash('Registration conformation email has been sent. Please check your mailbox. Thank you!')->success();
return redirect()->back();
}
}
Hope this helps

Passing data with login redirect - Laravel 4

The scenario is, a user must be logged in to be able to 'book an event'. My ideal process is:
User wishes to attend an event, clicks the attend button.
Auth filter realises user isn't logged in and so redirects to the login page
Once user is authenticated, the event ID and user ID is passed to the 'PostCreate' function within the 'Events' controller to book them on.
Currently, the user is redirected if not logged in, to the login page. Once the user is logged in, it attempts to call the 'events/create' controller method which is postCreate, but an error message is presented.
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
Controller method not found.
However, as I am now authenticated, I can go back to the event, click attend, and it will process the booking. I am a little stumped as to why this won't work! Any help would be appreciated.
Is it down to the event ID not being passed with the login data? If so, it still should be able to find the controller method?
Event Controller:
<?php
class EventsController extends BaseController {
protected $layout = "layouts.main";
public function __construct(){
$this->beforeFilter('csrf', array('on'=>'post'));
$this->beforeFilter('auth', array('only'=>array('postCreate')));
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function postCreate(){
$user_id = Auth::user()->id;
$user = myApp\User::find($user_id);
$event_id = Input::get('event_id');
$event_name = myApp\Event::find($event_id)->title;
$user->event()->attach($event_id);
return Redirect::back()->with('message-success', 'You are now attending '.$event_name.' !');
}
Users Controller
public function postSignin(){
if (Auth::attempt(array('email'=>Input::get('email'), 'password'=>Input::get('password')))) {
$title = Auth::user()->title;
$surname = Auth::user()->surname;
return Redirect::intended('users/dashboard')->with('message-success', 'You are now logged in, '.$title.' '.$surname.'. ');
} else {
return Redirect::to('users/login')
->with('message-danger', 'Your username/password combination was incorrect')
->withInput();
}
}
Show.blade.php
<div class="col-md-3">
#if (Auth::user())
<br>
#if (!in_array($events->id, $attending))
{{ Form::open(array('url'=>'events/create', 'class'=>'form-signup', 'role'=>'form')) }}
{{ Form::hidden('event_id', $events->id) }}
{{ Form::submit('Attend Event', array('class'=>'btn btn-success'))}}
{{ Form::close() }}
#else
{{ Form::open(array('url'=>'events/cancel', 'class'=>'form-cancel', 'role'=>'form')) }}
{{ Form::hidden('event_id', $events->id) }}
{{ Form::submit('Cancel Booking', array('class'=>'btn btn-warning'))}}
{{ Form::close() }}
#endif
#else
{{ Form::open(array('url'=>'events/create', 'class'=>'form-signup', 'role'=>'form')) }}
{{ Form::hidden('event_id', $events->id) }}
{{ Form::submit('Attend Event', array('class'=>'btn btn-success'))}}
{{ Form::close() }}
#endif
</div>
Routes
/* Event Route */
Route::get('events/{id}/{slug}', 'EventsController#show');
Route::controller('events', 'EventsController');
/* User Route */
Route::controller('users', 'UsersController');
/* Home Route */
Route::get('/', 'HomeController#getHome');
Route::controller('/', 'HomeController');
All Redirect responses will create a GET request. Your route and controller setup would then be looking for getCreate() instead of postCreate(), hence the error.

Resources