Changing sender name and email laravel - php

For each user, I change the email configuration in laravel project, when user login i use this:
\Config::set(['mail.mailers.smtp.host' => $user->smtp_mail_host]);
\Config::set(['mail.mailers.smtp.port' => $user->smtp_mail_port]);
\Config::set(['mail.mailers.smtp.username' => $user->smtp_mail_username]);
\Config::set(['mail.mailers.smtp.password' => $user->smtp_mail_password]);
\Config::set(['mail.from.address' => $user->mail_address]);
\Config::set(['mail.from.name' => $user->mail_from_name]);
when I did config() it is showing my change, but when I send, the mail is sent from the .env configuration mail address, there is a missing part I'm not finding it.
thanks for help

This is not optimal solution but can help! Pass the Configuration to your Mail::send before call send method such like this:
First import these classes in your Controller
use Mail;
use \Swift_Mailer;
use \Swift_SmtpTransport as SmtpTransport;
Then in your send function:
$from_email = \Config::get('mail.from.address');
$email_name = \Config::get('mail.from.name');
$to_email = "test#test.com";
$transport = (new SmtpTransport(\Config::get('mail.mailers.smtp.host'), \Config::get('mail.mailers.smtp.port'), null))->setUsername(\Config::get('mail.mailers.smtp.username'))->setPassword(\Config::get('mail.mailers.smtp.password'));
$mailer = new Swift_Mailer($transport);
Mail::setSwiftMailer($mailer);
Mail::send('emails.emailhtmlpage', [], function ($m) use ($from_email,$email_name,$to_email) {
$m->from($from_email, $email_name);
$m->to($to_email, 'TEST')->subject("Your Email Subject");
});

The settings applied using Config::set do not persist across different requests: if you only run them when the user logins, the changes with not apply to the following requests.
You should modify your Authenticate middleware adding:
public function handle($request, Closure $next, ...$guards)
{
$authReturned = parent::handle($request, $next, $guards);
$user = Auth::user();
\Config::set(['mail.mailers.smtp.host' => $user->smtp_mail_host]);
\Config::set(['mail.mailers.smtp.port' => $user->smtp_mail_port]);
\Config::set(['mail.mailers.smtp.username' => $user->smtp_mail_username]);
\Config::set(['mail.mailers.smtp.password' => $user->smtp_mail_password]);
\Config::set(['mail.from.address' => $user->mail_address]);
\Config::set(['mail.from.name' => $user->mail_from_name]);
return $authReturned;
}

if you using Queue and Jobs make sure to
stop the php artisan queue:work first (its seems to have it own cache where it store the configs)
check background process to make sure queue:work already stop (for linux you can use top -c -p $(pgrep -d',' -f php) and search for php artisan queue:work in COMMAND column )
do the change you want in .env or configs
config:clear
redo php artisan queue:work

Related

How can I run my php script in background to send email notification

I can send email to all users after submitting the form but it takes some time. What I want to achieve is to skip that task(sending email) and run it in background after submitting the form. So, users can do other things asides waiting to finish the task(sending email).
I tried to look at https://laravel.com/docs/4.2/queues but I'm beginner in Laravel and I don't understand well the documentaion. by the way I'm using old laravel version which is laravel 4.2.
APKFileController.php
$users = User::All();
foreach($users as $user) {
$data = array(
'apk_name' => Input::get('name'),
'version' => $apk->version,
'download_link' => Input::get('remarks'),
'subject' => 'v' . $apk->version . ' is now available.',
'message' => 'A new version of APK has been released!',
);
$this->userMailer->sendToApp($user, compact('data'));
}
}
UserMailer.php
<?php namespace Sample\Mailers;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use User;
class UserMailer extends Mailer
{
public function sendToApp(User $user, $data)
{
$subject = $data['data']['subject'];
$view = 'emails.clients.apkInfo';
return $this->sendTo($user, $subject, $view, $data);
}
}
Mailer.php
<?php namespace Sample\Mailers;
use Illuminate\Mail\Mailer as Mail;
abstract class Mailer {
private $mail;
function __construct(Mail $mail) {
$this->mail = $mail;
}
public function sendTo($user, $subject, $view, $data = [] )
{
$this->mail->queue($view, $data, function ($message) use ($user, $subject) {
$message->to($user->email)->subject($subject);
});
}
}
You can create a artisan command, just as described here:
Building A Command
Generating The Class
To create a new command, you may use the command:make Artisan command, which will generate a command stub to help you get started:
Generate A New Command Class
php artisan command:make FooCommand
By default, generated commands will be stored in the app/commands
directory; however, you may specify custom path or namespace:
php artisan command:make FooCommand --path=app/classes --namespace=Classes
When creating the command, the --command option may be used to assign
the terminal command name:
php artisan command:make AssignUsers --command=users:assign
Then you create a crontab schedule to run your command as described here:
Add a Cron JobPermalink
Open a crontab for your user in a text editor (vi in most distributions):
crontab -e
Note:
To change the text editor used, add the environment variable to your ~/.bashrc file, exchanging vim for nano, or whatever other
terminal-based editor you prefer.
export EDITOR=vim
Add the Cron job, save, and exit. The crontab will be saved in /var/spool/cron/crontabsas a crontab specific to the user who created
it. To later remove a Cron job from it, delete the line from the
user’s crontab file.
Or you can simple put it in a Queuing system. Refer to this https://laravel.com/docs/4.2/queues

Laravel Config::set() does not seem to work with Queued Jobs

I need to modify the mail SMTP parameters such as MAIL_HOST and MAIL_USERNAME dynamically.
For, this I am using Config::set() to set these values dynamically.
# This code works
Config::set('mail.host', 'smtp.gmail.com');
Mail::to('user#example.com')->send(new myMailable());
The above code works if I do not queue the mail.
The moment I queue it, it appears that Config::set() fails to set the values.
Test to confirm Config::set() not working with queued jobs -
I created a simple job and put the below code in the handler.
public function handle()
{
# set the config
Config::set('mail.host', 'smtp.gmail.com');
# confirm config has been set correctly
logger('Setting host to = [' . config('mail.host') . ']');
}
The above code creates the below log entry.
Setting host to = []
Why can I not change the Config on-the-fly for queued jobs? And how to solve this?
This is because the Queue worker doesn't use the current request. It is a stand-alone process, not being interferred by config settings.
To let this work, you need to use a Job. The dispatch function takes your data and sends it through to the job itself. From your controller, call:
JobName::dispatch($user, $settings);
In the job you set the variables accordingly:
public function __construct($user, $settings)
{
$this->user = $user;
$this->settings = $settings;
}
Then in the handle method:
\Notification::sendNow($this->user, new Notification($this->settings));
You can use a normal notification for this.
Do not for get to add implements ShouldQueue to your job!

Recover password mail dosen't send to user laravel

the password recovery email in laravel is not sent to the user
and this is my function in controller :
public function recover(Request $request)
{
$validator = Validator::make($request->only('email'), [
'email' => 'required'
]);
if($validator->fails()) {
throw new ValidationHttpException($validator->errors()->all());
}
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject(Config::get('boilerplate.recovery_email_subject'));
});
switch ($response) {
case Password::RESET_LINK_SENT:
// return $this->response->noContent();
return response()->json(['success' => true, 'data' => $response], 200);
case Password::INVALID_USER:
// return $this->response->errorNotFound();
return response()->json(['success' => false, 'data' => $response], 200);
}
}
and I configure my .env and mail.php
I use laravel 5.6
if you are using gmail address to sent mail. then you need to on less secure app.
go to https://myaccount.google.com/lesssecureapps
then allow by turning it on.
and also use
php artisan config:clear
sometimes google blocks when you try to send email through some code. In that case you got a alert mail. click on that mail(Check Activity) and mark as yes (Do you recognize this activity?)
Or you can try
MAIL_DRIVER=sendmail
and also use
php artisan config:clear
First of all, try to locate the problem.
I would suggest to try to setup MAIL_DRIVER=log and check laravel.log after executing this function. If nothing is found in the log - then you're not trying to send it. Most common problem, in this case, is using queues, so, check the QUEUE_CONNECTIONvariable in .env, it should be equal to "sync" (or set up your driver, like Redis if required).
By using "log" driver you should see your message in the log. If it works fine with "log" and doesn't work with smtp then you should get an error about it. If an error is present - please post it. If not - say so as well.
P.S. please note that if you're using php artisan serve, all variables from .env are updates only after restarting the php server.

Updating config on runtime for a user

I am using Laravel 5.1
I created a function to get smtp info from db for a user $mail_config=STMPDetails::where('user_id',36)->first() and then I can just call config helper function and pass the array to set config value config($mail_config). and then I call Mail::queue function.
but before it reaches createSmtpDriver#vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php where it reads the configuration again to send the mail, mail config are changed to the one specified in .env file.
Another thing to note is Mail sending function is in a Listener
I am not able to figure out where can I call the function such that configuration changes are retained before mail is sent.
Thanks,
K
This should work:
// Set your new config
Config::set('mail.driver', $driver);
Config::set('mail.from', ['address' => $address, 'name' => $name]);
// Re execute the MailServiceProvider that should use your new config
(new Illuminate\Mail\MailServiceProvider(app()))->register();
Since the default MailServiceProvider is a deferred provider, you should be able to change config details before the service is actually created.
Could you show the contents of $mail_config? I'm guessing that's the problem. It should be something like
config(['mail.port' => 587]);
Update - tested in 5.1 app:
Mail::queue('emails.hello', $data, function ($mail) use ($address) {
$mail->to($address);
});
->> Sent normally to recipient.
config(['mail.driver' => 'log']);
Mail::queue('emails.hello', $data, function ($mail) use ($address) {
$mail->to($address);
});
->> Not sent; message logged.

Delay laravel push notification for 5 second

I am using ""davibennun/laravel-push-notification": "dev-laravel5" " for sending push notification. What i want is delay in sending notification after hit but dont want to stop the process. Is there any idea how can i do this or is this possible?
Following is the code to send push notification:
$pushNotification = PushNotification::app('appNameAndroid')->to($token);
$pushNotification->adapter->setAdapterParameters(['sslverifypeer' => false]);
$pushNotification->send($message);
Thanks in advance.
I found how to do this.
Following are the steps.
Run the following command
php artisan queue:table
php artisan migrate
Change .env
QUEUE_DRIVER=database
Create a job
php artisan make:job JobName
//In Job file
I have mentioned 2 protected variable in my job file
$message,$deviceToken
In _construct i assigned a value to the above variables.
public function __construct($deviceToken, $message)
{
$this->deviceToken = $deviceToken;
$this->message = $message;
}
In handle method
$pushNotification = PushNotification::app('appNameAndroid')->to($this->deviceToken);
$pushNotification->adapter->setAdapterParameters(['sslverifypeer' => false]);
$pushNotification->send($this->message);
//In my controller
$job = (new JobName($deviceToken, $message))->delay(10);
$this->dispatch($job);

Categories