Run the command with -vvv to get the full stack trace. It should lead you to where in your code originates. Tracking down the error based strtolower in all of laravel + all dependencies is a needle in a haystack
Sending email via command results in local.ERROR: strtolower(): Passing null to parameter #1 ($string)
I'm coding up a command which runs daily and checks if any courses are taking place on that day. If there is, it grabs the emails of the attendees and sends them an email reminder.
I've coded everything up and run it in a normal view and it runs perfectly, no errors or anything showing up in the error log and I receive the emails.
Now I've built my command, I've dropped my code in (along with dependencies) and logged the output using info(). I can see its pulling the course and attendee emails (which are popped into an array and used in the BCC of the mail message).
When I comment out the info() and use my Mail:: sender, I get a really long error list which starts off with this:
[2022-09-12 16:39:00] local.ERROR: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated {"exception":"[object] (ErrorException(code: 0): strtolower(): Passing null to parameter #1 ($string) of type string is deprecated
I'm not using strtolower() anywhere in my code so I'm guessing this could have something to do with SwiftMailer(?), but I may also have run into something I need to work around as I've not really coded commands before.
Can anyone shed any light onto why this happens?
Hi @sinnbeck, this is what I get when I run php artisan schedule:work -vvv :
[2022-09-12 17:05:00] local.ERROR: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated {"exception":"[object] (ErrorException(code: 0): strtolower(): Passing null to parameter #1 ($string) of type string is deprecated at /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php:144)
[stacktrace]
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8192, 'strtolower(): P...', '/home/USER/p...', 144)
#1 /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(144): strtolower(NULL)
#2 /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php(43): Swift_Transport_EsmtpTransport->setEncryption(NULL)
#3 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(194): Swift_SmtpTransport->__construct('mail.WEBSITE.c...', '465')
#4 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(178): Illuminate\Mail\MailManager->createSmtpTransport(Array)
#5 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(152): Illuminate\Mail\MailManager->createTransport(Array)
#6 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(120): Illuminate\Mail\MailManager->createSwiftMailer(Array)
#7 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(95): Illuminate\Mail\MailManager->resolve('smtp')
#8 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(73): Illuminate\Mail\MailManager->get('smtp')
#9 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(550): Illuminate\Mail\MailManager->mailer()
#10 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\Mail\MailManager->__call('to', Array)
#11 /home/USER/WEBSITE.co.uk/app/Console/Commands/DailyCourseReminder.php(100): Illuminate\Support\Facades\Facade::__callStatic('to', Array)
#12 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\Console\Commands\DailyCourseReminder->handle()
#13 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/Util.php(40): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#14 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#15 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#16 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/Container.php(653): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#17 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Illuminate\Container\Container->call(Array)
#18 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Command/Command.php(299): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#19 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#20 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(978): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(295): Symfony\Component\Console\Application->doRunCommand(Object(App\Console\Commands\DailyCourseReminder), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(167): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Application.php(94): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#24 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#25 /home/USER/WEBSITE.co.uk/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#26 {main}
"}
Does this help?
Oh, there's a reference to
DailyCourseReminder.php(100)
On line 100 its just
Mail::to($email_recipients)
which is an array, but I've changed it to my own email address and the error is the same.
@idcreatv show the code
@Sinnbeck Sure, here you go. I use a generic emailer and just construct the message in the controller (or the command in this case) so I can use the same format when creating new mailers are overkill.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
use Mail;
use App\Models\Course;
use App\Models\Coursesettings;
use App\Mail\GenericEmail;
class DailyCourseReminder extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'daily:reminder';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$email_recipients = [];
$courses = Course::with('bookings')->where('start_date', Carbon::today())->get();
foreach ($courses as $course) {
$bookings = $course->bookings;
// Grab the bookings
foreach ($bookings as $booking) {
// Grab the attendees
foreach (json_decode($booking->attendees) as $attendee) {
$email = $attendee->email;
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
array_push($email_recipients, $email);
}
}
}
}
// Send the emails
if ($email_recipients != null) {
// Grab the Coursesettings key => value pairs
$settings = Coursesettings::orderby('key', 'asc')
->where('key', 'email_attendee_booking_confirmation')
->pluck('value', 'key')->toArray();
// Course type
if ($course->type == 0) {
$course_type = 'physical';
} else {
$course_type = 'virtual';
}
// Set subject
$subject = 'Reminder: You are enrolled on a course for today';
// Intro text
$intro_text = 'Hello, this email is to remind you that you are booked on the following course for today:';
// Message
$message_body = $settings['email_attendee_booking_confirmation'];
// Shortcodes to change
$message_body = str_replace('[COURSENAME_HERE]', $course->coursename->name, $message_body);
$message_body = str_replace('[STARTDATE_HERE]', Carbon::parse($course->start_date)->format('d/m/Y'), $message_body);
$message_body = str_replace('[STARTTIME_HERE]', $course->start_time, $message_body);
$message_body = str_replace('[ENDTIME_HERE]', $course->end_time, $message_body);
$message_body = str_replace('[COURSETYPE_HERE]', $course_type, $message_body);
$message = [
'intro' => $intro_text,
'message_body' => $message_body,
'show_panel' => 'no',
'panel_body' => 'PANEL_BODY',
'show_button' => 'no',
'button_label' => 'BUTTON_LABEL',
'button_url' => url(''),
];
Mail::to($email_recipients)
->send(new GenericEmail($message, $subject)); // End of attendee email
// info($email_recipients);
return 0;
}
}
}
@idcreatv the error could be your mail config. Maybe something is set as null?
@Sinnbeck I did see that earlier but its strange as I have settings for all these…
MAIL_MAILER=smtp
MAIL_HOST=mail.…….co.uk
MAIL_PORT=465
MAIL_USERNAME=…@….co.uk
MAIL_PASSWORD=XXXXXXX
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS="…@….co.uk"
MAIL_FROM_NAME="${APP_NAME}"
I've sent quite a few emails while testing today so I can't see it being those settings in the wrong.
@idcreatv strange. And you hard-coded it like this?
Mail::to('[email protected]')
->send(new GenericEmail($message, $subject));
@Sinnbeck Yep. That was the first thing I did when testing. Baffled.
@idcreatv anything in the GenericEmail?
Can you check the file it throws the error in? The current version has to do with encryption but handles if it's null
@Sinnbeck GenericEmail.php…
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class GenericEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($message, $subject)
{
$this->message = $message;
$this->subject = $subject;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.generic.generic-email')
->with('message', $this->message)
->subject($this->subject);
}
}
Generic-email blade file…
@component('mail::message')
# {!! $message['intro'] !!}
{!! $message['message_body'] !!}
@if ($message['show_panel'] == 'yes')
@component('mail::panel')
{!! $message['panel_body'] !!}
@endcomponent
@endif
@if ($message['show_button'] == 'yes')
@component('mail::button', ['url' => $message['button_url']])
{{ $message['button_label'] }}
@endcomponent
@endif
@if (isset($message['attachments']))
@foreach ($message['attachments'] as $attachment)
@component('mail::button', ['url' => url($attachment['URL'])])
{{ $attachment['button_name'] }}
@endcomponent
@endforeach
@endif
@endcomponent
@idcreatv think it has to do with encryption. Check my past post :)
@Sinnbeck I copied the code from that file and dropped it into my file in vendor/swiftmailer… etc.
I've cleared the caches.
There's no long error any more, however the result of the command is this…
[2022-09-12T19:25:00+01:00] Execution #1 output:
No scheduled commands are ready to run.
I've tried commenting my mailer out and just running a simple log('TEST'); but its not hitting the log file now. :/
@idcreatv ok that sounds like a bad idea. Better to actually solve the problem (like updating your depencies to get the newest version)
That there is no scheduled tasks isn't related to the problem
@Sinnbeck Okay, I’ll revert it and update composer in the morning to see if that solves it. Will update this thread as soon as I’ve tried it. 👍
@sinnbeck Morning. I replaced the original vendor files with my backup version and ran composer update. That seemed to fix things and I was able to fire off a reminder email :).
I stopped the schedule and then restarted it (its set to run every minute) just to make sure its working but then I get the 'No scheduled commands are ready to run' message in console, even though it should still run (ultimately it will run once per day, its just every minute for testing).
Is there anything which needs to be reset to make it run the same command?
@idcreatv Sounds good! Please mark this thread as solved, and create a new one in regards to your schedule. That it failed to send due to that package, isnt really related to scheduling :)
Please or to participate in this conversation.