looping phpmailer - php

when i send email i get two emails but it should send email to respective emails.
Lopoping problem ?
$array_values = Array
(
[0] => Array
(
[0] => uname1
[1] => fullname1
[2] => email 1
)
[1] => Array
(
[0] => uname2
[1] => fullname2
[2] => email 2
)
)
$f=0;
foreach($array_values as $mail_vars)
{
//$mail->AddReplyTo($mail_vars[2],'RED');
$mail->AddAddress($mail_vars[2], 'sss');
$body .="<br>";
$body .= 'Username: '. $mail_vars[0];
$body .="<br>";
$body .= 'Password: '.$mail_vars[1];
$body .="<br>";
$mail->SetFrom('email', 'FULLNAME');
$mail->Subject = "NEW";
$mail->MsgHTML($body);
//$mail->Send();
$f++;
}

Looking through the source of PHP Mailer, you will need to clear the fields. At least the address, maybe more. Here is the section of code from the PHPMailer class that has the clear functions. You are more than welcomed to look through them and try them etc. This is obviously an alternative to re-instantiating a new object, which may or may not cause a memory leak (depending on how many calls you make to it).
So implementing the clearAddresses code:
$mail->Subject = "NEW";
$mail->MsgHTML($body);
$mail->Send();
$mail->ClearAddresses(); // should reset the To address and remove the first one from it.
I removed the actual code as you just need the description and function name.
/////////////////////////////////////////////////
// CLASS METHODS, MESSAGE RESET
/////////////////////////////////////////////////
/**
* Clears all recipients assigned in the TO array. Returns void.
* #return void
*/
public function ClearAddresses() {
}
/**
* Clears all recipients assigned in the CC array. Returns void.
* #return void
*/
public function ClearCCs() {
}
/**
* Clears all recipients assigned in the BCC array. Returns void.
* #return void
*/
public function ClearBCCs() {
}
/**
* Clears all recipients assigned in the ReplyTo array. Returns void.
* #return void
*/
public function ClearReplyTos() {
}
/**
* Clears all recipients assigned in the TO, CC and BCC
* array. Returns void.
* #return void
*/
public function ClearAllRecipients() {
}
/**
* Clears all previously set filesystem, string, and binary
* attachments. Returns void.
* #return void
*/
public function ClearAttachments() {
}
/**
* Clears all custom headers. Returns void.
* #return void
*/
public function ClearCustomHeaders() {
}

if you look through the php mailer code, there is this useful method ClearAllRecipients() if you want to clear to, cc, and bcc all at once.

You need a:
$mail=new PHPMailer()
in the beginning of your for loop -as it is, the second time through it just messes around with the first email (since a new one isn't created).
As you pointed out body also needs to be reset - in fact using a separated var like that isn't very helpful - better to just supply directly to MsgHTML. Since the content of your email is trivial you may also want to send a plain-text version of the data (depends on your target recipient I guess).
So the updated script:
foreach($array_values as $mail_vars)
{
$mail=new PHPMailer();
$mail->SetFrom('email', 'FULLNAME');
$mail->AddAddress($mail_vars[2], 'sss');
$mail->Subject = "NEW";
$mail->MsgHTML("<br>\nUsername: ".$mail_vars[0]."<br>\nPassword: ".$mail_vars[1]."<br>");
//$mail->Send();
$f++;
}

Related

Email configuration dynamically not changing from database in loop

I apply a foreach loop in the email configuration SMTP settings dynamically from database.there are multiple SMTP servers in the SMTP server table. I am selecting the SMTP information dynamically from the table according to smtp_server_id from processing table and storing it in an email configuration before sending the email on the fly. But on the first iteration, the SMTP servers that come from dB are stored on email configuration like as config('mail.smtp.host') but on the second iteration till the end of loop, the SMTP information do not change. The SMTP information remains the same and Mail Configuration variables remains same when they are on the first iteration. What should I do to change the SMTP configuration dynamically one one by one according to the smtp_id in foreach loop.
My cron job to send emails.
namespace App\Console\Commands;
use App\Mail\SendEmail;
use App\Models\CronjobSetting;
use App\Models\ProcessingEmail;
use App\Models\SmtpServer;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
class SendEmailsBasedonDate extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'sendemailviadate:cron';
/**
* 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()
{
$cronJob = CronjobSetting::whereDate('created_at', Carbon::today())->first();
if ($cronJob->email_group_type == 1) {
$processingEmails = ProcessingEmail::all();
foreach ($processingEmails as $processingEmail) {
$smtpServer = SmtpServer::where('id', $processingEmail->smtp_id)->first();
Config::set('mail.mailers.smtp.host', $smtpServer->hostname);
Config::set('mail.mailers.smtp.port', $smtpServer->port);
Config::set('mail.mailers.smtp.username', $smtpServer->username);
Config::set('mail.mailers.smtp.password', $smtpServer->password);
$email = new SendEmail($processingEmail);
Mail::to($processingEmail->recipient_email)->send($email);
if (Mail::failures()) {
ProcessingEmail::where('id', $processingEmail->id)->update(
['status' => 3]
);
} else {
ProcessingEmail::destroy($processingEmail->id);
}
}
} else {
$processingEmails = ProcessingEmail::where('email_group_id', $cronJob->email_group_id)->get();
foreach ($processingEmails as $processingEmail) {
$smtpServer = SmtpServer::where('id', $processingEmail->smtp_id)->first();
Config::set('mail.mailers.smtp.host', $smtpServer->hostname);
Config::set('mail.mailers.smtp.port', $smtpServer->port);
Config::set('mail.mailers.smtp.username', $smtpServer->username);
Config::set('mail.mailers.smtp.password', $smtpServer->password);
$email = new SendEmail($processingEmail);
Mail::to($processingEmail->recipient_email)->send($email);
if (Mail::failures()) {
ProcessingEmail::where('email_leads_id', $processingEmail->email_lead_id)->update(
['status' => 3]
);
} else {
ProcessingEmail::where('email_leads_id', $processingEmail->email_lead_id)->delete();
}
}
return Command::SUCCESS;
}
}
}
SO I will give you two options
one: register the MailServiceProvider after new config.
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
two: creating a new Instance of swift mailer
<?php
$transport = (new \Swift_SmtpTransport('host', 'port'))
->setEncryption(null)
->setUsername('username')
->setPassword('secret')
->setPort($port);
$mailer = app(\Illuminate\Mail\Mailer::class);
$mailer->setSwiftMailer(new \Swift_Mailer($transport));
$mail = $mailer
->to('user#laravel.com')
->send(new SendEmail($processingEmail));
Basically, you are creating a new Instance of swift mailer here and adding providing to laravel mailer.

How to create a logic hook in SuiteCRM based a custom module 'ProductInvestigation' subpanel of Cases

I'm using a custom module called ProductInvestigation and Cases module; when the user adds/deletes a case from the subpanel; I would like to send an email. It has a one to many relationship. The logic I'm thinking of is that if the cases status is new and ProductInvestigation status is InvestigationClosed then it should send out an email. Function createPIEmailwithCases is what I would like to use to send the email. But how do I get the data from the relationship to be send in the email. Is it that function before_add and after_add should be in this function createPIEmailwithCases? This is what I have so far.
function before_add($bean, $event, $arguments)
{
if ($arguments['related_module'] =='Cases')
{
$bean->new_case_c =$arguments['related_id'];
$case_bean = BeanFactory::getBean('Cases', $arguments['related_id']);
/* Get PI Status */
$pi_status=trim($bean->getFieldValue('status_c'));
if ($case_bean->status_c = "New" && $pi_status='Investigation_Closed' )
{
}
}
}
function after_add($bean, $event, $arguments)
{
if ($arguments['related_module'] =='Cases'){
$bean->new_case_c =$arguments['related_id'];
$bean->save();
}
}
*function createPIEmailwithCases(&$email,$action_array,$bean,$xtpl){
/* Get PI Number */
$xtpl->assign('PI_Number', $bean->pinum_c);
/* Get PI Subject */
$xtpl->assign('PI_Subject', $bean->name);
/* Get Product Name */
$xtpl->assign('Product_Name', $bean->product_name_c);
/* Get Product Type */
$xtpl->assign('Product_Type', $bean->type_of_product_c);
/* Get Batch # */
$xtpl->assign('Batch_Number', $bean->batch_c);
/* Get Size(s) */
$xtpl->assign('Size', $bean->size_c);
/* Get Fill Date */
$xtpl->assign('Fill_Date', $bean->filldate_c);
/* Get Batch # */
$xtpl->assign('BestBefore', $bean->bestbefore_c);
/* Get PI Description */
$xtpl->assign('PI_Desc', $bean->description);
/* Get Reviewer Name */
$xtpl->assign('Reviewed_By',$bean->reviewer_c);
$xtpl->assign('Review_Date',$bean->reviewdate_c);
/* Create email message using email template and data above */
$xtpl->parse('block');
$email->Body = from_html($xtpl->text('block'));
return $email;
}
SuiteCRM provides different types of hook and in this case, you can use following relationship hooks.
after_relationship_add
after_relationship_delete
Support URL: https://docs.suitecrm.com/developer/logic-hooks/

Laravel: Get bad_domains from Mailable

I am sending mails with Laravel like this:
foreach ($users as $user) {
\Mail::to($user())->send(new Newsletter($user));
}
I would like to have an array of all the users who had a bad_domain response. I found in the docs that Laravel uses Swiftmailer which has a way to find bad_domain respones:
// Pass a variable name to the send() method
if (!$mailer->send($message, $failures))
{
echo "Failures:";
print_r($failures);
}
/*
Failures:
Array (
0 => receiver#bad-domain.org,
1 => other-receiver#bad-domain.org
)
*/
However, I want to use the a Mailable class. I am not sure how I can do this with the Swiftmailer (which I can access through \Mail::getSwiftMailer()).
Is there any easy way of getting the bad_domains when using Mailable from Laravel?
You may only access bad_domains, but not bounces with Swiftmailer (Swiftmailer 4 does not retrieve bounces as $failedRecipients).
One can get bad_domains it with
\Mail::to($user)->send(new \App\Mail\Hi());
dd(\Mail::failures());
See Illuminate\Mail\Mailer.php
/**
* Send a Swift Message instance.
*
* #param \Swift_Message $message
* #return void
*/
protected function sendSwiftMessage($message)
{
try {
return $this->swift->send($message, $this->failedRecipients);
} finally {
$this->forceReconnection();
}
}

How to use SetCC in Yii

Hi I am trying to send an email using the code below, It works as expected until and unless I use setCC function. On using setCC function mailer is not sending mail ( no errors). Could someone help with this code, thanks
use Yii;
class Email {
/**
* #param unknown $template
* #param unknown $to
* #param unknown $subject
* #param array $data
* #return boolean
*/
public static function sendEmail($template, $to, $cc='my#email.com', $subject, $data = [], $proforma = false) {
$mail = Yii::$app->mailer
->compose($template, $data)
->setFrom([Yii::$app->params['adminEmail'] => 'MyDomains.com'])
->setTo($to)
->setCc($cc)
->setSubject($subject);`
Third Parameter of your function sendEmail i.e $cc must be an email but you are passing "Payment ok" in it a regular string. which is causing the error and you are not receiving email.

issues with return-path in zend_mail

Could you please tell me why I set returnPath using zend_mail received email has to return-path headers (I view them in gmail) using smtp trasport:
Return-Path: <bounce#domain.com> //I think this is added by server
.....
Return-Path: bounce#domain.com //I think this is cause by returnPath
I set return-path like this:
$mailer->setReturnPath('bounce#domain.com');
I set transport like this:
$emailConfig = $this->getOption('email');
$transport = new Zend_Mail_Transport_Smtp($emailConfig['server'], $emailConfig);
Zend_Mail::setDefaultTransport($transport);
If I don't set returnPath server add returnPath the same as I set From header.
Is it a bug in Zend_Mail or what? What I understand it right that server will add return-path header the same as it's use in MAIL_FROM and setReturnPath shouldn't add header menually, but only save it to use for MAIL_FROM?
It in Zend_Mail_Transport_Smtp change code comment line:
/**
* Sets the Return-Path header of the message
*
* #param string $email
* #return Zend_Mail Provides fluent interface
* #throws Zend_Mail_Exception if set multiple times
*/
public function setReturnPath($email)
{
if ($this->_returnPath === null) {
$email = $this->_filterEmail($email);
$this->_returnPath = $email;
//This line presents in Zend_Framework
//I comment this like I get only one return-path the same as
//set using setReturnPath method of Zend_Mail
//$this->_storeHeader('Return-Path', $email, false);
} else {
/**
* #see Zend_Mail_Exception
*/
require_once 'Zend/Mail/Exception.php';
throw new Zend_Mail_Exception('Return-Path Header set twice');
}
return $this;
}
In Zend you can pass the necessary additional parameter to sendmail by explicitly choosing the transport:
$tr = new Zend_Mail_Transport_Sendmail('-fmail#example.com');
$_mail = new Zend_Mail();
$_mail->setDefaultTransport($tr);
try this:
$mail->addHeader('Return-path', 'email#address.com');

Categories