php - calling a function to send email in loop

170 Views Asked by At

I'm using PHPMailer to send multiple emails to different recipients.

To summarize what I'm trying to do here is to send emails to all the persons concerned telling them they have a task/action to do.

In this case $actions contains exactly 2 arrays with 2 different recipients indexed as "action_owner". So I'm looping through $actions to get both recipients

Output of $actions

The problem is in my testing inbox (Mailtrap) I'm only getting 1 email instead of 2. The email content I'm getting in my inbox is from the first iteration of the loop.

As you will see in the code I tried to output the recipients I'm getting and my function to sending the emails. There's no problem with the outputs, I'm getting the recipients I want and the function sendEmail() is being called twice as intended.

case 'action':
      $actions = $_POST['action']; 
      foreach($actions as $key=>$val){
        $emailParams = [
          'to'      => [$val['action_owner']],
          'bcc'     => ['[email protected]'],
          'subject' => _('Subject'),
          'nc_actions'   => $val['nc_actions']
        ];
        // dump($emailParams);
        $test = $mail->sendEmail('nc/action_email', $emailParams);
        // dump($test);
      }
      die;
private function generateEmailBody(string $templateFile, array $params)
{
    // error_reporting(0);
    ob_start();
    require_once $_SERVER['DOCUMENT_ROOT'] . '/layouts/emails/header.php';
    require_once $_SERVER['DOCUMENT_ROOT'] . '/layouts/emails/' . $templateFile . '.php';
    require_once $_SERVER['DOCUMENT_ROOT'] . '/layouts/emails/footer.php';
    return ob_get_clean();
}

public function sendEmail(string $templateFile, array $emailParams)
{
    if (empty($emailParams['to']) || empty($emailParams['subject'])) {
        throw new Exception('Missing required parameters for sending email');
    }

    $this->Subject = $emailParams['subject'];
    $this->Body    = $this->generateEmailBody($templateFile, $emailParams);

    foreach ($emailParams['to'] as $to) {
        $this->addAddress($to);

        if (!empty($emailParams['bcc'])) {
            foreach ($emailParams['bcc'] as $bcc) {
                $this->AddBCC($bcc);
            }
        }

        $this->send();
        $this->ClearAllRecipients();
    }
    return true;
}
1

There are 1 best solutions below

1
InvstIA On

It seems that the issue is that you are adding the recipients using the addAddress() method within the loop, but you are not clearing the recipients after each iteration.

To fix this, you should move the addAddress() method outside of the loop and use the ClearAllRecipients() method to clear the recipients after each iteration.

Here's the updated code:


case 'action':
    $actions = $_POST['action']; 
    foreach($actions as $key=>$val){
        $emailParams = [
            'to'      => [$val['action_owner']],
            'bcc'     => ['[email protected]'],
            'subject' => _('Subject'),
            'nc_actions'   => $val['nc_actions']
        ];
        // Add recipients outside of the loop
        $mail->addAddress($val['action_owner']);
        $test = $mail->sendEmail('nc/action_email', $emailParams);
        // Clear recipients after each iteration
        $mail->ClearAllRecipients();
    }
    die;

public function sendEmail(string $templateFile, array $emailParams)
{
    //...
    foreach ($emailParams['to'] as $to)
    {
        // Remove addAddress() method from here
        if (!empty($emailParams['bcc']))
        {
            foreach ($emailParams['bcc'] as $bcc)
            {
                $this->AddBCC($bcc);
            }
        }
        $this->send();
    }
    //...
}