Murlidhar Fichadia
Murlidhar Fichadia

Reputation: 2609

pass array of emails to Job class Mail::to

I am able to send single email but when it comes to multiple emails jobs class fails to send it to multiple users.

The code below works fine and sends email to one user

$email = new Report($this->user);
Mail::to($this->user->email)->queue($email); 

Even hard-coding the email works too

$email = new Report($this->user);
Mail::to("[email protected]")->queue($email); 

But when I pass multiple or array of emails Job fail:

$email = new Report($this->user);
$all_admin = User::select('email')->where('role',2)->get()->pluck('email')->toArray();
$all_admins = json_encode($all_admin, true);
Mail::to($all_admins )->queue($email); 

This code is written in App\Jobs\ReportAdmin file in handle function.

I have sent before array of emails without using jobs

something like:

Mail::send('emails.report', ['firstname'=>$firstname,'lastname'=>$lastname], function ($message)
        {
            $message->from('[email protected]', 'auto-reply email');
            $message->to($all_admins);
            $message->subject('subject');
        });

Upvotes: 0

Views: 338

Answers (3)

Sandeesh
Sandeesh

Reputation: 11906

From the doc

To send a message, use the to method on the Mail facade. The to method accepts an email address, a user instance, or a collection of users.

So do this.

$email = new Report($this->user);

$admins = User::select('email')->where('role', 2)->get();

Mail::to($admins)->queue($email);

This is what happens under the hood. In case you want to use different ways to load the email list.

public function to($address, $name = null)
{
    return $this->setAddress($address, $name, 'to');
}

protected function setAddress($address, $name = null, $property = 'to')
{
    foreach ($this->addressesToArray($address, $name) as $recipient) {
        $recipient = $this->normalizeRecipient($recipient);

        $this->{$property}[] = [
            'name' => isset($recipient->name) ? $recipient->name : null,
            'address' => $recipient->email,
        ];
    }

    return $this;
}

protected function addressesToArray($address, $name)
{
    if (! is_array($address) && ! $address instanceof Collection) {
        $address = is_string($name) ? [['name' => $name, 'email' => $address]] : [$address];
    }

    return $address;
}

protected function normalizeRecipient($recipient)
{
    if (is_array($recipient)) {
        return (object) $recipient;
    } elseif (is_string($recipient)) {
        return (object) ['email' => $recipient];
    }

    return $recipient;
}

Upvotes: 1

Filip Koblański
Filip Koblański

Reputation: 9988

Try to change this:

$all_admins = json_encode($all_admin, true);

for that:

$all_admins = implode(';', $all_admin);

This should give you a valid string format.

EDIT

You can also give a try with itteration:

$email = new Report($this->user);
$all_admin = User::select('email')->where('role',2)->get()
    ->pluck('email')->toArray();
$all_admins = json_encode($all_admin, true);
foreach ($all_admin as $admin) {
    Mail::to($admin)->queue($email);
}

This is even better solution because each e-mail will be send by a single job.

Upvotes: 1

Murlidhar Fichadia
Murlidhar Fichadia

Reputation: 2609

I used a for loop and it works.

Don't know if its the best way to approach this problem.

/**
  * Execute the job.
  *
  * @return void
  */
public function handle()
{
    $email = new Report($this->user);
    $all_admin = User::select('email')->where('role',2)->get()->pluck('email')->toArray();
    $count = count($all_admin);
    for($i = 0; $i<$count; $i++)
    {
        Mail::to($all_admin[$i])->queue($email);
    }
}

Upvotes: 0

Related Questions