send mail returns null - php

When trying to send a message, In my view verifyEmail.blade.php $agent is null and $agent->name says trying to get property of non object.
verifyEmail.blade.php
<body>
<h2> Welcome to our website{{ $agent->name }} </h2>
click here to verify your email
</body>
This is how I am using the Mail class. In my Mail folder in verifyEmail file I have a construct function which collects the $agent model.
verifyEmail.php
class verifyEmail extends Mailable
{
public $agent;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($agent)
{
$this->$agent = $agent;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.verifyEmail');
}
}
And in my admin controller which does the registration for the user looks like this. The send method passes the agent model to the verifyEmail.php which was working in the tutorial I watched. How can I make agent model available in verifyEmail.blade.php
AdminController
$agent = new agent($data);
$agent->name = $data["name"];
$agent->email = $data["email"];
$agent->nrc = $data["nrc"];
$agent->resident = $data["residents"];
$agent->password = Hash::make($data["password"]);
$agent->save();
verifyUser::create(
[
'token' => Str::random(60),
'agent_id' => $agent->id,
]
);
Mail::to($agent->email)->send(new verifyEmail($agent));

I think there can be a slight modification in the code provided to solve this.
Inside the file verifyEmail.php, the line
$this->$agent = $agent;
should be
$this->agent = $agent;
Because $this->$agent might not be able to find the class level variable 'agent' and update its value that is provided in the constructor so it will have the default value null which is shown afterwards.

Configuring The Sender
Using The from Method
First, let's explore configuring the sender of the email. Or, in other words, who the email is going to be "from". There are two ways to configure the sender. First, you may use the from method within your mailable class' build method:
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('example#example.com')
->view('emails.orders.shipped');
}
Using A Global from Address
However, if your application uses the same "from" address for all of its emails, it can become cumbersome to call the from method in each mailable class you generate. Instead, you may specify a global "from" address in your config/mail.phpconfiguration file. This address will be used if no other"from" address is specified within the mailable class:
'from' => ['address' => 'example#example.com', 'name' => 'App Name'],
In addition, you may define a global "reply_to" address within your config/mail.php configuration file:
'reply_to' => ['address' => 'example#example.com', 'name' => 'App Name'],
So you can try this In verifyEmail.php Change this
public function build()
{
return $this->view('emails.verifyEmail');
}
To this
public function build()
{
return $this->from('info#domain.com')->view('emails.verifyEmail');
}

Related

Laravel : send email to other_emails

I'm trying to send an email to other_emails, so that when the user 1 already book for his friends, the user 1 got email and his friends also got an email, i tried to use foreach for sending the email the other_emails but i got this error message Undefined variable: isi_email1
How can i fix it?
The Controller :
$isi_email1 = [
'title'=>'Thank you for your purchase',
'body'=>'Please give us your review about your experience using Pintunuswantara Travel. Link : https://pintunuswantara.com/review'
];
$subject = [$booking->email];
Mail::to($subject)->send(new OthersEmail($isi_email1));
$others = Booking::select('other_emails');
foreach($others as $other){
Mail::to($other)->send(new OthersEmail($isi_email1));
}
The OthersEmail :
public $isi_email1;
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
$this->isi_email1 = $isi_email1;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('admin#pinnuss.com')
->subject('Thank you')
->view('other_email');
}
The problem seems to be the variable scope/context. In order for you to access a variable in a function within a class, you must pass it in as a parameter; it doesn't inherit the context of where its called.
IE: in this example, your OthersEmail::construct function must accept the $isi_email1 parameter in order to then assign it to its property.
Change the constructor function to look like this in order to then assign and be able to pass through the variable:
public function __construct(array $isi_email1) {
$this->isi_email1 = $isi_email1;
}
If you don't intend on using typed parameters, you can remove the array from the parameter definition.
public function __construct($isi_email1) {
// etc.
}
Your controller class is already trying to pass the variable in, so there shouldn't have to be any changes there in order for this to work.

How do I create a hasMany relationship with non-standard foreign keys

I have a Laravel 8 application where a User hasMany Notifications. The notifications table has two required keys: sender_id and recipient_id. These are both instances of User. Here's how I setup the relationship in the model:
App\Models\User
public function recievedNotifications()
{
return $this->hasMany(Notification::class, 'recipient_id');
}
public function sentNotifications()
{
return $this->hasMany(Notification::class, 'sender_id');
}
App\Models\Notification
public function recipient()
{
return $this->belongsTo(User::class);
}
public function sender()
{
return $this->belongsTo(User::class);
}
I want to create two users and properly associate a Notification instance for those two users. I can't quite get the syntax.
I wanted to try something like this but it assigns the incorrect user ids when I manually look at the database entries:
$sender = User::factory()->create();
$recipient = User::factory()->create();
$notification = App\Models\Notification::factory()->hasSender($sender)->hasRecipient($recipient)->create();
I am not certain if this is a function of:
1: Not having the relationships set up in the PHP Models
2: Not creating the factory the correct way
The Notification factory is defined as the following:
<?php
namespace Database\Factories;
use App\Models\Notification;
use Illuminate\Database\Eloquent\Factories\Factory;
class NotificationFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Notification::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
//
'message' => $this->faker->sentence,
'is_read' => rand(0, 1),
];
}
}
How do I properly create Notifications with a recipient and sender using factories?
Why just not use it like this, by assigning the ids from the factory?
$sender = User::factory()->create();
$recipient = User::factory()->create();
$notification = App\Models\Notification::factory()->create([
'recipient_id' => $recipient->id,
'sender_id' => $sender->id
]);
The relationships look good, so I'm leaning towards not using the factory properly. Factories simply provide default values to use when instantiating new models if you don't provide the attributes explicitly.
You can set these values by supplying an array in the create() or make() method:
$sender = User::factory()->create();
$recipient = User::factory()->create();
$notification = Notification::factory()->create([
'sender_id' => $sender->getKey(),
'recipient_id' => $recipient->getKey(),
]);

Call to a member function notify() on null in Laravel 8

I want to send an SMS to a mobile phone (if he had already turned on the two-factor authentication system).
So at LoginController I added this method:
protected function authenticated(Request $request, $user)
{
return $this->loggendin($request , $user);
}
And this loggendin method is inside of a trait called TwoFactorAuthentication, which goes like this:
trait TwoFactorAuthenticate
{
public function loggendin(Request $request , $user)
{
if($user->hasTwoFactorAuthenticatedEnabled()) {
auth()->logout();
$request->session()->flash('auth' , [
'user_id' => $user->id,
'using_sms' => false,
'remember' => $request->has('remember')
]);
if($user->two_factor_type == 'sms') {
$code = ActiveCode::generateCode($user);
// Todo Send Sms
$request->user()->notify(new ActiveCodeNotification($code , $user->phone_number));
$request->session()->push('auth.using_sms' , true);
}
return redirect(route('twofa.token'));
}
return false;
}
}
Now the problem is when I want to log in, this message appears on the screen which is saying:
Error Call to a member function notify() on null
Which is referring to this line:
$request->user()->notify(new ActiveCodeNotification($code , $user->phone_number));
And this ActiveCodeNotification holds some settings for sending the SMS.
If you would like to visit that, here it is:
class ActiveCodeNotification extends Notification
{
use Queueable;
public $code;
public $phoneNumber;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($code , $phoneNumber)
{
$this->code = $code;
$this->phoneNumber = $phoneNumber;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return [GhasedakChannel::class];
}
public function toGhasedakSms($notifiable)
{
return [
'text' => "{$this->code}",
'number' => $this->phoneNumber
];
}
}
So what's going wrong here that I get Call to a member function notify() on null while it's two parameters have value.
So if you know, please let me know. I would really appreciate any idea from you guys...
Thanks.
Try this:
First, make sure your User model has the Notifiable trait.
Top of the User Model class:
use Illuminate\Notifications\Notifiable;
After that:
class User extends Model{
use Notifiable; // ....
And then...
Instead of
$request->user()->notify(new ActiveCodeNotification($code , $user->phone_number));
Use this
$user->notify(new ActiveCodeNotification($code, $user->phone_number));
Or
Before calling auth()->logout();
use it at first:
auth()->user()->notify(new ActiveCodeNotification($code, $user->phone_number));
then, you can call auth()->logout();
Worked for me recently
The $request->user() would be null at that point on LoginController because the request was not authenticated and the user is not set on the request instance yet.
You have to use the $user argument instead:
$user->notify(new ActiveCodeNotification($code , $user->phone_number));
Note: make sure that your User model has Illuminate\Notifications\Notifiable trait in order to be able to use notify().

How to Set Session Variable when User Login in Laravel

Invoice app development is going on using Laravel. I store date and amount format for every users in settings table.
When user login to their account how to set Session variable? Please give any suggestions. I am using Laravel 5.3.
Of course the docs tell us how to store session data*, but they don't address the OP's question regarding storing session data at login. You have a couple options but I think the clearest way is to override the AuthenticatesUsers trait's authenticated method.
Add the override to your LoginController:
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
$this->setUserSession($user);
}
Then you can set your session up as:
protected function setUserSession($user)
{
session(
[
'last_invoiced_at' => $user->settings->last_invoiced_at,
'total_amount_due' => $user->settings->total_amount_due
]
);
}
If you want to be a bit more clever you can create a listener for the Login or Authenticated events and set up the session when one of those events* fires.
Create a listener such as SetUpUserSession:
<?php
namespace app\Listeners;
use Illuminate\Auth\Events\Login;
class SetUserSession
{
/**
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
session(
[
'last_invoiced_at' => $event->user->settings->last_invoiced_at,
'total_amount_due' => $event->user->settings->total_amount_due
]
);
}
}
*Links go to 5.4 but this hasn't changed from 5.3.
I've used the Auth class to manage user data, like this:
public function index(){
$user_id = Auth::user()->id;
}
But you have to add 'use Auth;' before class declaration. Then you can add any data to session variable.
Laravel fires an event when a new login is made to the application.
When an event fires you may add a listener for it, then add a session .
This is the content of a listener I made.
<?php
namespace App\Listeners\Auth;
use Illuminate\Auth\Events\Login;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class UserLoggedIn
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
public function handle(Login $event)
{
if ($event->user->hasRole('subsidiary_admin')) {
\Session::put('subsidiary_admin', $event->user->subsidiaryBoUser->subsidiary_id);
\Session::put('subsidiary', $event->user->subsidiaryBoUser->subsidiary);
}
}
}
and I register it on the eventServiceProvider like this
'Illuminate\Auth\Events\Login' => [
'App\Listeners\Auth\UserLoggedIn',
],
You can store data in the session using two different methods either a Request instance or using the global helper/function provided.
Request Instance
public function methodA(Request $request) {
$request->session()->put('KEY', 'VALUE');
}
Global Helper
public function methodB() {
session(['key' => 'value']);
}
You can find more details on both methods in the documentation.
Here's what I am doing:
I have this on my helper file:
\App\Helpers\helpers.php:
function signedUser()
{
return [
'id' => Auth::id(),
'group_id' => Auth::user()->group_id,
'group_name' => Auth::user()->group->name,
'avatar' => Auth::user()->avatar,
'first_name' => Auth::user()->first_name,
'full_name' => Auth::user()->full_name,
];
}
On my User Model:
public function group()
{
return $this->belongsTo('App\Models\Group');
}
public function getFullNameAttribute()
{
$full_name = ucfirst($this->first_name) . ' ' . ucfirst($this->middle_name[0]) . '. ' . ucfirst($this->last_name);
return $full_name;
}
Then I can accessed the variables on both controllers and blade files like so:
dump(signedUser()['full_name']);
{{ signedUser()['full_name'] }}

Passing Argument to Lumen Job

I am building an app in Lumen that sends text messages with Twilio. I am in the process of creating the Job that actually handles the sending of the message. I dispatch the Job directly from the routes file. Eventually, the "To" phone number will be entered in a form so I'm having it passed into the job as an argument.
Here is my Job class:
<?php
namespace App\Jobs;
class FiveMessageJob extends Job
{
protected $number;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($number)
{
$this->number = $number;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//dd($this->number);
// this line loads the library
require base_path('twilio-php-master/Services/Twilio.php');
$account_sid = 'xxxxxxxxxxxx';
$auth_token = 'xxxxxxxxxxxx';
$client = new \Services_Twilio($account_sid, $auth_token);
$client->account->messages->create(array(
'To' => $this->number,
'From' => "xxxxxxxxxxx",
'Body' => "What's up Stackoverflow?"
));
}
}
Here is the route that dispatches the job:
$app->get('/', function () use ($app) {
$number = "+15555555555";
dispatch(new \App\Jobs\FiveMessageJob($number));
return view('index');
});
I am getting the Twilio error: A 'To' phone number is required.
When I dd($this->number) inside of the handle function, it returns null.
Obviously the $number argument isn't being passed through. I'm sure I'm missing something obvious so I could use a second set of eyes and any help y'all can offer.
Thanks.

Categories