Cron job doesn't send email [duplicate] - php

This question already has answers here:
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 5 years ago.
I have a cron job set up on my hostgator server that returns a value of 1 (email sent), but doesn't actually send the email. When I call the php file manually in the browser, the email gets sent. It doesn't if run via cron.
Earlier this month, I moved my site from one server on hostgator to another server (on hostgator) so I could get SSL and a dedicated IP address. Since moving the site, the cron jobs work OK except for the part that sends the email (ie, database functions work fine). I've contacted hostgator tech support, but he thinks the problem is in my code.
Thinking that maybe my server info was incorrect, I switched to using smtp.gmail.com and using a gmail account to send the mail, but that didn't work either. Please help!
The cron job is set up like this:
* 7 * * * /opt/php56/bin/php /home/user/public_html/somefolder/sendmailcron.php
(While testing, I changed it to run every 2 minutes: */2 * * * * )
Here's the sendmailcron.php script:
<?php
$now = date("Y-m-d H:i:s");
$msgcontent = [];
$msgcontent['email'] = "recipient#example.com";
$msgcontent['name'] = "Recipient Name";
$msgcontent['textpart'] = "This is the text version of the email body.";
$msgcontent['htmlpart'] = "<p>This is the <strong>HTML</strong> version of the email body.</p>";
$msgcontent['subject'] = "Test email sent at " . $now;
$result = sendMyMail($msgcontent, "HTML");
exit();
function sendMyMail($msgcontent, $format="HTML") {
require_once '/home/user/public_html/somefolder/swiftmailer/lib/swift_required.php';
$result = 0;
$subject = $msgcontent['subject'];
$email = $msgcontent['email'];
if (strlen($email) == 0) {
return 0;
}
$name = $msgcontent['name'];
$emailbody = $msgcontent['textpart'];
$emailpart = $msgcontent['htmlpart'];
switch($format) {
case "TEXT":
$msgformat = 'text/plain';
break;
case "HTML":
$msgformat = 'text/html; charset=UTF-8';
break;
default:
$msgformat = 'text/html';
break;
}
$adminemailaddress = "me#mydomain.com";
$adminemailpwd = 'myadminpwd';
$sendername = 'My Real Name';
$transport = Swift_SmtpTransport::newInstance('mygator1234.hostgator.com', 465, "ssl")
->setUsername($adminemailaddress)
->setPassword($adminemailpwd)
;
$mailer = Swift_Mailer::newInstance($transport);
// Create the message
if($format == "TEXT") {
$message = Swift_Message::newInstance($subject)
->setFrom(array($adminemailaddress => $sendername))
->setTo(array($email => $name))
->setBody($emailbody)
->setContentType($msgformat)
;
}
else {
$message = Swift_Message::newInstance($subject)
->setFrom(array($adminemailaddress => $sendername))
->setTo(array($email => $name))
->setBody($emailpart)
->setContentType($msgformat)
;
}
//This is where we send the email
try {
$result = $mailer->send($message); //returns the number of messages sent
} catch(\Swift_TransportException $e){
$response = $e->getMessage() ;
}
return $result; //will be 1 if success or 0 if fail
}
?>
The return value is always 1, but no email is sent.
Any suggestions would be greatly appreciated!

Your cron job uses a different php.ini configuration file, than your browser uses.
Try running the cron job by disabling safe_mode, like this:
/opt/php56/bin/php -d safe_mode=Off /home/user/public_html/somefolder/sendmailcron.php
And check if the email is now sent.

Related

PHP strange behaviour on IF statement when sending email via phpmailer (having output of IF and ELSE together)

The script im going to present is quite dificult to understand, but I will explain the basic idea bellow.
<?php
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
require_once 'apps/PHPMailer/src/Exception.php';
require_once 'apps/PHPMailer/src/PHPMailer.php';
require_once 'apps/PHPMailer/src/SMTP.php';
include_once('apps/HTMLDOMParser/simple_html_dom.php');
require_once("../db.php");
function clear($var) {
$var = NULL;
unset($var);
}
// Time when emails were sent last time
$result_laststamp = $conn->prepare("SELECT sent FROM nl_campaigns_emails ORDER BY sent DESC LIMIT 1", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_laststamp->execute();
if($result_laststamp->rowCount() > 0) {
while($row_laststamp = $result_laststamp->fetch(PDO::FETCH_ASSOC)) {
// data for first qeued campaign
$result_campaign = $conn->prepare("SELECT id,name,text,amount,period,smtp,user FROM nl_campaigns WHERE status='1' ORDER BY id ASC LIMIT 1", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_campaign->execute();
if($result_campaign->rowCount() > 0) {
while($row_campaign = $result_campaign->fetch(PDO::FETCH_ASSOC)) {
// SMTP Data
if($row_campaign['smtp']==1 && $row_campaign['user']>0) {
$result_smtp = $conn->prepare("SELECT * FROM admin_logins WHERE id=:id LIMIT 1", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_smtp->execute(array(":id"=>$row_campaign['user']));
if($result_smtp->rowCount() > 0) {
while($row_smtp = $result_smtp->fetch(PDO::FETCH_ASSOC)) {
// Check if its time to send next group of emails
if($row_laststamp['sent'] < (time()-($row_campaign['period']*3600))) {
// get email addresses, send, and edit timestmap in db when they were sent
$result_emails = $conn->prepare("SELECT id,email FROM nl_campaigns_emails WHERE (id_campaign=:id_campaign AND sent='0') ORDER BY id ASC LIMIT ".$row_campaign['amount'], array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_emails->execute(array(":id_campaign"=>$row_campaign['id']));
if($result_emails->rowCount() > 0) {
$array_email_ids = array();
while($row_emails = $result_emails->fetch(PDO::FETCH_ASSOC)) {
try {
$mail = new PHPMailer(true);
$mail->CharSet = 'UTF-8'; // UTF8 Encoding
$mail->Encoding = 'base64'; // Needs to be set with UTF8
//$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = "smtp.somedomain.com"; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = "noreply#somedomain.cz"; // SMTP username
$mail->Password = "somepassword"; // SMTP password
$mail->SMTPSecure = "tls";
$mail->Port = 587; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
//Sender
$mail->setFrom($row_smtp['email'], 'somename');
$mail->addReplyTo('info#somedomain.cz', 'somename');
$mail->Sender = 'noreply#somedomain.cz';
// Recipient
$mail->addAddress($row_emails['email']);
// Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
$bottom_text = "<p align=center style=\"font-size:11px; font-family:Arial; color:#8b8b8b;\">This email was sent to address ".$row_emails['email'].".<br>";
$bottom_text .= "To unsubscribe you can click to unsubscribe.</p>";
$bottom_text .= "<img src=\"http://www.somedomain.cz/view.php?id_campaign=".$row_campaign['id']."&id_email=".$row_emails['id']."\" style=\"visibility: hidden;\">";
// YOUTUBE LINK
$text = new simple_html_dom();
$text->load($row_campaign['text']);
foreach($text->find('iframe') as $element) {
$youtubeid = substr($element->src, strrpos($element->src, "/")+1);
// Create image instances
$video = imagecreatefromjpeg('https://img.youtube.com/vi/'.$youtubeid.'/maxresdefault.jpg');
$button = imagecreatefrompng('../images/youtube_play.png');
$video = imagescale($video, $element->width, $element->height);
$button = imagescale($button, imagesx($video)/7.5);
imagecopy($video, $button, imagesx($video)/2-imagesx($button)/2, imagesy($video)/2-imagesy($button)/2, 0, 0, imagesx($button), imagesy($button));
// Output and free from memory
imagejpeg($video, "../images/campaigns/videos/".$youtubeid.".jpg", 95);
imagedestroy($video);
imagedestroy($button);
unset($video);
unset($button);
$element->outertext = '<img src="http://www.somedomain.cz/images/campaigns/videos/'.$youtubeid.'.jpg" width="'.$element->width.'" height="'.$element->height.'">';
}
$row_campaign['text'] = (string)$text;
$text->clear();
clear($text);
// URL LINK FOR CLICKER ANALYZER
$doc = new simple_html_dom();
$doc->load($row_campaign['text']);
foreach ($doc->find('a') as $a) {
$a->href = 'http://www.somedomain.cz/clicker.php?id_campaign='.$row_campaign["id"].'&id_email='.$row_emails["id"].'&url='.urlencode($a->href);
}
$row_campaign['text'] = (string)$doc;
$doc->clear();
clear($doc);
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $row_campaign['name'];
$mail->Body = $row_campaign['text'].$bottom_text;
$mail->AltBody = strip_tags($row_campaign['text']);
// MessageID
$data = array(
'campaign_id' => str_pad($row_campaign['id'], 6, '0', STR_PAD_LEFT),
'email_id' => str_pad($row_emails['id'], 11, '0', STR_PAD_LEFT),
'sent' => time(),
);
$messageId = '<'.base64_encode(json_encode($data)).'#www.somedomain.cz>';
$mail->MessageID = $messageId;
$mail->addCustomHeader('In-Reply-To', $messageId);
clear($data);
// SEND Email
$mail->send();
}
catch (Exception $e) {
echo "Emails were not send because: {$mail->ErrorInfo}";
die();
}
// ADD sent email to array
array_push($array_email_ids, $row_emails['id']);
// UPDATE the "sent" stamp
$update = $conn->prepare("UPDATE nl_campaigns_emails SET sent=:sent WHERE id=:id");
try { $update->execute(array(":id"=>$row_emails['id'], ":sent"=>time())); }
catch(Exception $error) { die($error->getMessage()); }
clear($update);
clear($mail);
}
clear($result_emails);
// CHECK IF STATUS COULD BE CLOSED
$result_emails_sent = $conn->prepare("SELECT id FROM nl_campaigns_emails WHERE (id_campaign=:id_campaign AND sent='0') ORDER BY id", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_emails_sent->execute(array(":id_campaign"=>$row_campaign['id']));
if($result_emails_sent->rowCount() == 0) {
$update = $conn->prepare("UPDATE nl_campaigns SET status=:status WHERE id=:id");
try { $update->execute(array(":status"=>3, ":id"=>$row_campaign['id'])); }
catch(Exception $error) { die($error->getMessage()); }
clear($update);
}
clear($result_emails_sent);
// Print the result
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">Sent total: ".count($array_email_ids)." emails.</div>";
echo "<center>REFRESH</center>";
}
}
else {
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">Next emails can be send at: ".date("j.n.Y H:i:s", $row_laststamp['sent']+($row_campaign['period']*3600))."</div>";
echo "<center>REFRESH</center>";
die();
}
}
}
else { die("error resolving SMTP"); }
clear($result_smtp);
}
}
clear($result_campaign);
}
else {
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">No campaign is running</div>";
echo "<center>REFRESH</center>";
die();
}
}
}
clear($result_laststamp);
clear($conn);
?>
the script looks quite huge, but at the end its simple logic:
get the last time emails were sent (for example $lastTimeSent)
get the data of the opened queued campaign (for example $dataCampaign)
get SMTP data to be used for sending emails (for example $SMTP)
checks if current timestamp time() is bigger then $lastTimeSent+allowed_period (because Im allowed to send 200 emails every 20mins)
loop the phpmailer, send emails separately (each time add one email to send)
and the problem is, that if I run the script inside nonallowed time period (so im not following rule of 200 emails in 20 mins), all works fine and script will evaluate this as false:
if($row_laststamp['sent'] < (time()-($row_campaign['period']*3600)))
$row_laststamp['sent'] is the timestmap of last email sent ($lastTimeSent)
$row_campaign['period'] is allowed period to send the email (value is actually 0.33 as in hours its 20 minutes), and im multiplying it by 3600 to recalculate to seconds so I can compare
so basicaly will jump and do stuff only from ELSE statement as its logical and its OK behaviour
However, when im outsode of the period so the same statement would evaluate as TRUE, the very strange behaviour happens.
The script will be looping and sending emails as it should, however instead of sending 200 emails as its the value of $row_campaign['amount'], it actually sends 64 (sometimes 65 emails) and then it wont echo Sent total: ".count($array_email_ids)." emails as it should logicaly, but also shows again the ELSE output *Next emails can be send at: ".date("j.n.Y H:i:s", $row_laststamp['sent']+($row_campaign['period']3600))..
So Im dealing with the problem that its shows the IF and ELSE output at once...
In other words, when statement *if($row_laststamp['sent'] < (time()-($row_campaign['period']3600))) is TRUE, it will partialy run the loop of try {} (only 65 times out of 200) and then shows the ELSE {} anyway...
BUT !!! if I remove/comment the line $mail->send(); then ALL works as expected !!!!! (unless emails are sent of course).
I was checking the memory status if im not getting out of memory and found out the maximum in final loop is about 24MB (when limnit is set to 256MB), also execution time is around 10second when I have set 120s.
so basicaly PHPMailer wont send more then 200 emails in loop when sending just one each time?
I wouldnt mind to send them all together and not looping it, however i dont want them to be seen in "TO" header of email, and if I use BCC instead, then (at least in gmail) it jumps to spam.
Any ideas?
EDIT:
I have simplified the script, made the adjustment according to https://github.com/PHPMailer/PHPMailer/wiki/Sending-to-lists
also i did place the debugger $mail->SMTPDebug = SMTP::DEBUG_SERVER; to see whats happening, and its interesting that the message from client to server suddently stop in the middle... no responce from the server, so the transfer just stops in the middle...
the very last line is not even finished and it just:
2020-09-02 17:06:40 CLIENT -> SERVER: NTI1MjUyNTNGaWRfY2FtcGFpZ24lMjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjU
so the comunication just stops from no reason, no server reply that its sent or not, nothing...
anyone has an idea?
so the error at the end was realy that I was not clearing recipients after each send(),
therefore first email was send to 1 recipient and each loop was 1 added but previous was not cleared...
clearing recipients after each loop fixed the problem

Executing email sending php script with cron

I have a php script that sends an email with an attachment. When I manually execute the php script below via a web browser, everything works well and the email is sent instantly. However, when I try to execute the php file using a crontab command, the email is not sent. Any idea why this is? The cron command isn't generating any errors...
Further, the email_output.log shows success but the email doesn't come through, as if it is piling up in the outgoing box but never actually sent.
Crontab command:
/Applications/MAMP/bin/php/php5.6.10/bin/php /my/path/emailApp.php > /my/path/email_console.log 2> /my/path/email_error.log
Thanks in advance.
<?php
include_once(__DIR__ . '/mailer/swift_required.php');
$transport = Swift_SmtpTransport::newInstance('mail.myhost.com', 25)
->setUsername('name#myhost.com')
->setPassword('password');
// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
$mailTo = Array('testemail#gmail.com');
$subject ="report";
$attach = 'report.pdf';
$message = Swift_Message::newInstance($subject)
->setFrom(array('name#mydomain.com' => 'Bob Dole' ))
->attach(Swift_Attachment::fromPath($attach)->setFilename($attach))
->setTo($mailTo);
$message->setBody("attached",'text/html');
// Send the message
$result = $mailer->send($message);
if($result == 0){
echo 'Error';
} else {
echo 'Success';
}

Can not send email threw SwiftMailer with Mandrill

Since today, many of my php applications can not send email using SwiftMailer and different Mandrill accounts.
I've got this code, and the send function in the last if stop the script..
// Instance message
$message = Swift_Message::newInstance();
$message->setSubject("subject")
->setFrom(array('noreply#email.test' => 'test'))
->setTo(array('a_valid_email' => 'name'))
->setBody("test", 'text/html')
->setPriority(2);
$smtp_host = 'smtp.mandrillapp.com';
$smtp_port = 587;
$smtp_username = 'valid_username';
$smtp_password = 'valid_password';
// SMTP
$smtp_param = Swift_SmtpTransport::newInstance($smtp_host , $smtp_port)
->setUsername($smtp_username)
->setPassword($smtp_password);
// Instance Swiftmailer
$instance_swiftmailer = Swift_Mailer::newInstance($smtp_param);
$type = $message->getHeaders()->get('Content-Type');
$type->setValue('text/html');
$type->setParameter('charset', 'iso-8859-1');
//Here the send function stop event and I did not go inside the if
if ($instance_swiftmailer->send($message, $fail)) {
echo 'OK ';
}else{
echo 'NOT OK : ';
print_r($fail);
}
Thank you in advance to help me to solve this problem..
If your code used to work, and now doesn't work, and you didn't change your code, then it's probably not a problem with your code. Check your Mandrill account validity - sometimes they suspend accounts for suspicious-appearing usage.

Why is this script sending blank emails without using template in SugarCRM?

This is my code to send emails in SugarCRM CE 6.5.x version,
<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid EntryPoint');
require_once('include/SugarPHPMailer.php');
$msg = new SugarPHPMailer();
$emailObj = new Email();
$defaults = $emailObj->getSystemDefaultEmail();
//Setup template
require_once('XTemplate/xtpl.php');
$xtpl = new XTemplate('custom/modules/Users/ChangePassword.html');
//assign recipients email and name
$rcpt_email = 'sohan.tirpude#mphasis.com';
$rcpt_name = 'Sohan';
//Set RECIPIENT's address
$email = $msg->AddAddress($rcpt_email, $rcpt_name);
//Send msg to users
$template_name = 'User';
//Assign values to variables in template
$xtpl->assign('EMAIL_NAME', $rcpt_name);
$xtpl->parse();
//$body = "Hello Sohan, It's been 80 days that you haven't changed your password. Please take some time out to change password first before it expires.";
$msg->From = $defaults['email'];
$msg->FromName = $defaults['name'];
$msg->Body = from_html(trim($xtpl->text($template_name)));
//$msg->Body = $body;
$msg->Subject = 'Change Password Request';
$msg->prepForOutbound();
$msg->AddAddress($email);
$msg->setMailerForSystem();
//Send the message, log if error occurs
if (!$msg->Send()){
$GLOBALS['log']->fatal('Error sending e-mail: ' . $msg->ErrorInfo);
}
?>
Now this script send blanks emails, and when I hardcoded body part then it is takes those message written in body, and sends an email. So, please help me here.

bcc multiple addresses with swiftmailer

Im using the below php code to send an email to one address and bcc 2 other addresses. It sends to the recipient fine but I can only get it to send to one of the 2 bcc addresses. (see comments in code for what ive tried)
Oddly enough though, $result comes back as 3 so it seems that its trying to send the second bcc email but it never comes through.
<?php
$tracker='tracking#pnrbuilder.com';
$subject = $_POST['subject'];
$sender = $_POST['sender'];
$toEmail=$_POST['toEmail'];
$passedInEmail=stripslashes($_POST['message']);
$passedInEmail=preg_replace('/ /',' ',$passedInEmail);
require_once('swiftLib/simple_html_dom.php');
require_once('swiftLib/swift_required.php');
$transport = Swift_MailTransport::newInstance();
$mailer = Swift_Mailer::newInstance($transport);
// Create the message
$message = Swift_Message::newInstance();
//turn the meesage into an object using simple_html_dom
//so we can iterate through and embed each image
$content = str_get_html($passedInEmail);
// Retrieve all img src tags and replace them with embedded images
foreach($content->find('img') as $e)
{
if($e->src != "")
{
$value = $e->src;
$newValue = $message->embed(Swift_Image::fromPath($value));
$e->src = $newValue;
}
}
$message->setSubject($subject);
$message->setFrom($sender);
$message->setTo($toEmail);
//this is my problem
$message->setBcc(array('tracking#pnrbuilder.com',$sender));
//as it is above only "sender" gets the email
//if I change it like this:
//$message->setBcc($tracker,$sender);
//only "tracker" gets the email
//same if I change it like this:
//$message->setBcc($sender);
//$message->addBcc($tracker);
$message->setReplyTo(array('flights#pnrbuilder.com'));
$message->setBody($content,'text/html');
$result = $mailer->send($message);
if ($result=3) {
echo 'Email Sent!';
}
else {
echo 'Error!';
}
?>
What is the proper way to do this?
You can find the swiftmailer tutorial here
example:
$message->setBcc(array(array('some#address.tld' => 'The Name'),array('another#address.tld' => 'Another Name')));
Try setting the names for the email addresses and see if it makes any difference.
This ended up being an issue on the server side, I contacted my hosting provider (GoDaddy) who were able to make some changes on their end fixing the problem. Thank you to all those who tried to help!

Categories