I want to have 2 notifications when new user registered:
inform admin that we have new user for moderation
send welcome email to new user
I created 2 events, put them in EventServiceProvider, but as result I have 2 emails to admin. I already tried to register 4 users with different emails, but none of them receive welcome email. It is always sent to admin config('mail.to.address')
For some reason welcome email sent to admin, instead of new user. What's wrong?
My code is below.
EventServiceProvider
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
SendWelcomeEmail::class,
SendNewUserRegisteredEmail::class,
],
];
SendWelcomeEmail
<?php
namespace App\Listeners;
use Mail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Auth\Events\Registered;
class SendWelcomeEmail
{
public function __construct()
{
}
public function handle(Registered $event)
{
$data = array(
'name' => $event->user->name,
'email' => $event->user->email
);
Mail::send('emails.welcome', $data, function($message) use ($data) {
$message->to($data['email'])
->subject('Добро пожаловать на сайт '.config('app.name'). '.');
$message->from(config('mail.from.address'));
});
}
}
SendNewUserRegisteredEmail
<?php
namespace App\Listeners;
use Mail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Auth\Events\Registered;
class SendNewUserRegisteredEmail
{
public function __construct()
{
}
public function handle(Registered $event)
{
$data = array(
'name' => $event->user->name,
'email' => $event->user->email
);
Mail::send('emails.registered', $data, function($message) use ($data) {
$message->to(config('mail.to.address'))
->subject('Новый пользователь на сайте '.config('app.name'). '.');
$message->from(config('mail.from.address'));
});
}
}
Related
I want to send two different emails with two different view blade files for submitting a single form.
My Controller
<?php
namespace App\Http\Controllers\Frontend;
use App\Mail\quickQuoteMail;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\sysmaster;
use App\Mail\contactEmail;
use Illuminate\Support\Facades\Mail;
class EmailController extends Controller
{
public function contactEmail(Request $request)
{
$data = array(
'ContactPerson'=> $request->FullName,
'ContactEmail'=> $request->Email,
'ContactNumber'=> $request->Number,
'ContactMessage'=> $request->Enquiry,
);
$token = $request->input('g-recaptcha-response');
if(strlen($token)>0)
{
$quickQuoteemail = sysmaster::where('sysm_val_type', 'Contact_Email')->where('sysm_def_id', 'to')->first();
$quickQuote = sysmaster::where('sysm_val_type', 'Contact_Email')->where('sysm_def_id', 'Cc')->first();
if ($quickQuote->sysm_value!=null) {
Mail::to($quickQuoteemail->sysm_value)->cc([$quickQuote->sysm_value, $request->Email])->send(new contactEmail($data));
} else {
Mail::to($quickQuoteemail->sysm_value)->cc($request->Email)->send(new contactEmail($data));
}
return redirect()->back()->with('message','Thank you for contact us.');
}else{
return redirect()->back()->with('message','Please make sure your not a robot');
}
}
}
Mail Function
<?php
namespace App\Mail;
use App\sysmaster;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class contactEmail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$quickQuoteemail = sysmaster::where('sysm_val_type','Contact_Email')->where('sysm_def_id','from')->first();
return $this->from($quickQuoteemail->sysm_value,$this->data['ContactPerson'])
->subject('Contact Us Enquiry')->view('email_contact_quote')->with('data',$this->data);
}
}
I have another view blade file there (contact_email_company) How can I include that view with this function and this UI only will send for the company top one have to go for the only client please help how to do this.
You can use dynamic view name You can pass view name in $data Mail class
Change below in your controller function:
if ($quickQuote->sysm_value!=null) {
$data['view_name'] = 'email_contact_quote';
Mail::to($quickQuoteemail->sysm_value)->cc([$quickQuote->sysm_value, $request->Email])->send(new contactEmail($data));
}
else {
$data['view_name'] = 'contact_email_company';
Mail::to($quickQuoteemail->sysm_value)->cc($request->Email)->send(new contactEmail($data));
}
And in mail class change as below: take view name from $data,
return $this->from($quickQuoteemail->sysm_value,$this->data['ContactPerson'])
->subject('Contact Us Enquiry')->view($this->data['view_name'])->with('data',$this->data);
I would like to send email notifications using the queue.
I have created the queue table and tracked all the documentation related to this topic but the notifications are sent without going through the queue.
In my controller :
Notification::send(User::role('team')->get(), new NewExchangeToCollaboratorNotification($user, $exchange, $firstMessage));
And my notification code is :
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Setting;
class NewExchangeToCollaboratorNotification extends Notification implements ShouldQueue
{
use Queueable;
protected $user; protected $exchange; protected $exchangeMessage; protected $replyToAddress;
public function __construct($user, $exchange, $exchangeMessage)
{
$this->user = $user;
$this->exchange = $exchange;
$this->exchangeMessage = $exchangeMessage;
$this->replyToAddress = Setting::get('MAIL_REPLY_TO_ADDRESS', env('MAIL_FROM_ADDRESS'));
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)->view(
'emails.exchanges.new',
[
'user' => $this->user,
'exchangeMessage' => $this->exchangeMessage,
'exchange' => $this->exchange
]
) ->subject('New exchange: ' . $this->exchange->title)
->from(env('MAIL_FROM_ADDRESS'))
->replyTo($this->replyToAddress);
}
}
Are the notifications queueable ? Is there something I'm doing wrong ?
Thank you for your answers :)
EDIT :
Add delay does not work too.
$when = now()->addMinutes(10);
Notification::send(User::role('team')->get(), (new NewExchangeToCollaboratorNotification($user, $exchange, $firstMessage))->delay($when));
EDIT 2 :
No failed job
Make sure your .env is:
QUEUE_CONNECTION=database
So I am trying to implement a command that notifies all users that are subscribes to an event with command that does an check every day. I was reading Laravel mail docs 7.x so there example is about order system where they send the mail with this peace of code
foreach (['taylor#example.com', 'dries#example.com'] as $recipient) {
Mail::to($recipient)->send(new OrderShipped($order));
}
what as it looks takes the email of of the loop and then send an email toward that adress.
So I made a mail class php artisan make:mail NotifyUserOfEvents
and where I made this code
<?php
namespace App\Mail;
use App\Event;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NotifyUserOfEvents extends Mailable
{
use Queueable, SerializesModels;
protected $event;
public function __construct(Event $event)
{
$this->event = $event;
}
public function build()
{
return $this->view('mails.NotifyUserOfEvents')
->with([
'name' => $this->event->name,
'date' => $this->event->settings->start_date,
]);
}
}
but when I try to call this class with this function
<?php
namespace App\Console\Commands;
use App\Event;
use App\RegistrationEvents;
use App\User;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class NotifyUsersForEvents extends Command
{
protected $signature = 'NotifyUsersForEvents';
protected $description = 'Notify the user for the event. test run with -> php artisan schedule:run';
public function __construct()
{
parent::__construct();
}
public function handle()
{
Log::debug('this works every minute');
$events = Event::query()
->with('settings')
->has('settings')
->get();
foreach ($events as $event) {
$week = Carbon::now()->addWeek();
$sixDays = $week->copy()->subDay();
if (Carbon::create($event->settings->date_start)->between($week, $sixDays)) {
$subscriptions = RegistrationEvents::query()
->where('event_id', $event->id)
->get();
foreach ($subscriptions as $subscription) {
var_dump($subscription->user_id);
$user = User::findOrFail($subscription->user_id);
Mail::to($user->email)->send($event);
var_dump($user->email);
}
}
}
}
}
it returns this error: Argument 1 passed to Illuminate\Database\Eloquent\Model::__construct() must be of the type array, object given, called in so do I need to change the way I call the mail class or do I need to add something to the Event Model?
also the event.php
use Illuminate\Contracts\Mail\Mailable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Event extends Model implements Mailable
{
use SoftDeletes;
public function settings(){
return $this->hasOne('App\EventSettings', 'event_id');
}
}
You must pass to send function an object of your NotifyUserOfEvents, not an Event object.
Try this:
Mail::to($user->email)->send(new NotifyUserOfEvents($event));
Referring to this line:
Mail::to($user->email)->send(new Event($event));
you are creating a new Event passing to the constructor another Event... you probably never define a constructor that accept as first parameter an Event...
But despite that, what's the sense of doing this? To Mail::send you have to pass a Mailable, not an event, and i'm pretty sure you don't need a new event, so i believe you would want to do something like this:
use App\Mail\NotifyUserOfEvents; // or whatever namespace you have to the mail
Mail::to($user->email)->send(new NotifyUserOfEvents($event));
$user = User::find($id);
$email = $user->email;
if(Helper::isValidEmail($email))
{
Mail::send('emails.applicant_reference',
$emailParameters, function($message) use ($email, $name, $subject){
$message->to($email, $name)
->subject($subject);
});
$applicantName = null;
$subject = " Application received for ".$applicantName;
$emailParameters = ["applicantName" => $applicantName, "proposerName" => $proposerName, "seconderName" => $seconderName];
try
{
Mail::send('emails.application', $emailParameters, function($message) use ($applicantName, $subject){
$message->to(['test#gmail.com','test#gamil.com'], " Test Email Function ")
->subject($subject);
});
} catch (Exception $ex){ Log::error("UserController".$ex->getMessage());
}
I have an Event that fires off a Welcome email whenever someone registers a new account on my website.
My problem is, I needed to create a "Create User" page on my admin section. Now every time I create a user from the admin section the email still fires off an email welcoming the new user.
This would be fine, but I need that email to say something else.
I don't want the Welcome email to fire when creating a user from the admin panel.
How can I control this Event from sending the email?
Code pretty much goes in this order:
1. Event code: NewUser.php
namespace App\Events;
... irrelevant classes
use Illuminate\Foundation\Events\Dispatchable;
use App\User;
class NewUser
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
2. Listener: SendWelcomeEmail.php
namespace App\Listeners;
use App\Events\NewUser;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;
use App\Mail\NewUserWelcome;
class SendWelcomeEmail
{
public function __construct()
{
//
}
public function handle(NewUser $event)
{
Mail::to($event->user->email)->send(new NewUserWelcome($event->user));
}
}
3. Mail: NewUserWelcome.php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
class NewUserWelcome extends Mailable
{
use Queueable, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function build()
{
return $this->subject('Welcome To The Website')->markdown('emails.user.newuserwelcome');
}
}
4. Markdown email would be next.
#component('mail::message')
# Greetings bla bla bla
5. EventServiceProvider: is making the call like this:
protected $listen = [
'App\Events\NewUser' => [
'App\Listeners\SendWelcomeEmail',
],
];
6. User model I have the following relevant code:
class User extends Authenticatable {
use Notifiable;
protected $dispatchesEvents = [
'created' => Events\NewUser::class
];
In my ADMIN SAVE USER FUNCTION | UserController This is what I'm using to SAVE the New User From Admin Panel: (No Event classes)
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function adminUserStore(Request $request){
$newsupporter = User::create([
'name'=> $request->name,
'email' => $request->email,
'password' => Hash::make($quickpass),
]);
return back()->with('success','The user has been created and a password reset email has been sent to them.');
}
Any help would be appreciated, I've been battling this one for quite some time.
You can try by adding a new nullable column for your user model, which would check if the user was added by admin or someone else;
$newsupporter = User::create([
'name'=> $request->name,
'email' => $request->email,
'password' => Hash::make($quickpass),
'added_by' => 'admin',
]);
And then create a check and send email only when the user was not added my admin,
public function handle(NewUser $event)
{
if(!$event->user->added_by == 'admin'){
Mail::to($event->user->email)->send(new NewUserWelcome($event->user));
}
}
Personally I would introduce two events instead of the one. Something along the lines of AccountCreatedByUser and AccountCreatedByAdmin. These events can then be handled by separate listeners, which will send separate e-mails. This will mean you'll have to fire these events manually instead of depending on the built-in created event. This can be done like so:
event(new AccountCreatedByUser($user));
Documentation for firing events manually can be found here
Hey guys I'm trying to learn PHP frameworks as well as OOP and I'm using Laravel 5.1 LTS.
I have the following code in my AuthController
<?php
namespace App\Http\Controllers\Auth;
use App\Verification;
use Mail;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
private $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
protected function create(array $data){
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
// generate our UUID confirmation_code
mt_srand((double)microtime()*15000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$uuid = substr($charid, 0, 8)
.substr($charid, 8, 4)
.substr($charid,12, 4)
.substr($charid,16, 4)
.substr($charid,20,12);
$data['confirmation_code'] = $uuid;
// pass everything to the model here
$setVerification = new Verification();
$setVerification->setVerificationCode($data['email'], $data['confirmation_code']);
// send email for confirmation
Mail::send('email.test', $data, function ($m) use ($data){
$m->from('test#test.com', 'Your Application');
$m->to($data['email'])->subject('Thanks for register! Dont forget to confirm your email address');
});
return $user;
}
}
my error message Class 'Models\Verification' not found is coming from this piece of code here
// pass everything to the model here
$setVerification = new Verification();
$setVerification->setVerificationCode($data['email'], $data['confirmation_code']);
which looks right to my beginner's eyes, but it's clearly wrong.
Here is my Verification class that has the setVerificationCode method
<?php
namespace App\Http\Controllers;
use App\User;
use DB;
use App\Http\Controllers\Controller;
class Verification {
/**
* This method will update the confirmation_code column with the UUID
* return boolean
**/
protected function setVerificationCode($email, $uuid) {
$this->email = $email;
$this->uuid = $uuid;
// check to see if $email & $uuid is set
if (isset($email) && isset($uuid)) {
DB::table('users')
->where('email', $email)
->update(['confirmation_code' => $uuid]);
return TRUE;
} else {
return FALSE;
}
}
/**
* This method will validate if the UUID sent in the email matches with the one stored in the DB
* return boolean
**/
protected function verifyConfirmationCode() {
}
}
Please give the following in AuthController
use App\Http\Controllers\Verification;
instead of
use App\Verification;
If we give use App\Verification , it will check if there is any model named Verification.
its seems that, you are missing something, which, Extend your Model with eloquent model
use Illuminate\Database\Eloquent\Model;
class Verification extends Model
{
and the rest is seems fine.
also share your verification model code
Updated
instead of your this line
use App\Verification;
do this
use App\Models\Verification;
as you created custom directory for your Models then its better to auto load it in your composer.json file. add this line "app/Models" in your "autoload" section. follow this
"autoload": {
"classmap": [
"database",
"app/Models"
],
and after that, run this command in your project repo composer dump-autoload