I have a function that sends an email when a form is submitted. This function contains the following if-statement:
if ($guestDetails)
{
$mailer->addRecipient($guestDetails->email);
$mailer->addCC( $config->get('emails_admin_email'));
$mailer->setSubject( $subject );
$mailer->setBody($template_layout);
$mailer->IsHTML($mode);
$mailer->setSender(array( $mailfrom, $fromname ));
$sent = $mailer->send();
}
Recently, this function has stopped working (i.e. the emails are no longer being sent). To investigate what is going on I have modified the code to log some of the variables as there was nothing being recorded in the PHP Error log. Here is how the if-statement looks now:
$testArr = array();
ClassName::_log_r("guestdetails", $guestDetails);
if ($guestDetails)
{
ClassName::_log_r("got into if", $testArr);
$mailer->addRecipient($guestDetails->email);
$mailer->addCC( $config->get('emails_admin_email'));
$mailer->setSubject( $subject );
$mailer->setBody($template_layout);
$mailer->IsHTML($mode);
$mailer->setSender(array( $mailfrom, $fromname ));
$sent = $mailer->send();
ClassName::_log_r("mailer", $mailer);
ClassName::_log_r("sent", $sent);
} else
ClassName::_log_r("got into else", $testArr);
The _log_r is just a function that writes to a text file the contents of the given variable. Once I added this "debug" code, the emails started being sent once again and the log correctly records "got into if".
Removing the afore mentioned debug code stops the emails from being sent once again.
I am puzzled at what could be possibly going on here. Has anyone ever came across anything like this?
Why are emails not being sent when the debug code is removed?
Please let me know if more information is needed. Thanks!
PS the code is written in PHP and the server is running PHP 5.3.10
The only likely answer that comes to mind is that, for whatever reason, $guestDetails is not defined anymore (e.g., it got renamed into $guestDetail somewhere else).
This also would need the _log_r function to redefine the argument if it does not exist.
If you check the mails being sent to the CC: only, they will arrive - an invalid $guestDetails will probably not stop the process from completing. Actually ONLY the emails to the admin will get generated.
Try something like
if (!defined($guestDetails))
ClassName::_log_r("mailer", "Not defined");
if (empty($guestDetails))
ClassName::_log_r("mailer", "empty");
and see whether some more detail can be worried out.
Instead of logging with _log_r, try to catch mail exceptions and check if you get better info on whats going on:
if ($guestDetails)
{
try
{
$mailer->addRecipient($guestDetails->email);
$mailer->addCC( $config->get('emails_admin_email'));
$mailer->setSubject( $subject );
$mailer->setBody($template_layout);
$mailer->IsHTML($mode);
$mailer->setSender(array( $mailfrom, $fromname ));
$sent = $mailer->send();
}
catch (phpmailerException $e)
{
echo $e->errorMessage(); //you could do a _log_r here..
}
catch (Exception $e)
{
echo $e->getMessage(); //or here..
}
}
else
{
echo "guestDetails empty!"; //or here..
}
Related
In my contact.php page, I am sending emails to admin and user after passing the validation. The code looks something below:
// If any validation error occurs
if(count($errors) > 0)
{
// show error messages
}
else
{
// sending emails to admin and user
set_flash_msg('msg', 'Thank you for contacting us.', 'success');
redirect_to('contact');
}
But the code in else part related flash message doesn't work. If I put this code in if part then it works without any issue. The function set_flash_msg() is responsible to create session based flash message. Its code is below:
// Set flash message
function set_flash_msg($name, $msg, $class)
{
global $name;
if(empty($_SESSION[$name]) && empty($_SESSION[$name . '_class']))
{
$_SESSION[$name] = $msg;
$_SESSION[$name . '_class'] = $class;
}
}
To display this message, another function is called below the above code as:
// Show flash message
get_flash_msg();
There is no issue regarding session setting because in if part, it works fine. The same logic and coding flow is used in my backend too where I set flash message when a new page is added and show the flash message on page listing page.php. If it works at there then why it doesn't work on my front-end contact.php page? Any idea?
In my contact.php page, I am grabbing the form values particularly "name" as:
// Preparing form variables
$name = isset($_POST['txtname']) ? $db_obj->sanitize_input($_POST['txtname']) : '';
The local variable $name conflicts with global variable $name in set_flash_msg() function. Changing $name to $uname in above code solved the problem.
I've posted this question twice in the last two days and I have really run dry of solutions. I'm creating a very simple comment box that when filled out sends the comment in an email to my company's safety department. I have been receiving this 5.5.4 Invalid Domain Error for the last couple days.
It's SMTP and TLS. The port and server name is correct. The server allows for anonymous emails, and does not validate. I'm using the Swiftmailer library so I shouldn't need to script a ELHO/HELO. The only property of the email that's not defined/hard coded is the body of the message. This is the code for my controller (index.php).
// Initialize Swiftmailer Library
require_once("./swiftmailer/lib/swift_required.php");
// Class that contains the information of the email that will be sent (from, to, etc.)
require_once("./classes/EmailParts.php");
// The class that "breaks" the data sent with the HTML form to a more "usable" format.
require_once("./classes/ContactForm.php");
// =====================
// Main Configuration
// =====================
define("EMAIL_SUBJECT", "Safety Concerns");
define("EMAIL_TO", "safetydepartment#company.com");
define("EMAIL_FROM", "safetydepartment#company.com");
// SMTP Configuration
define("SMTP_SERVER", 'exchange.company.local');
define("SMTP_PORT", 25);
function main($contactForm) {
// Checks if something was sent to the contact form, if not, do nothing
if (!$contactForm->isDataSent()) {
return;
}
// Validates the contact form and checks for errors
$contactForm->validate();
$errors = array();
// If the contact form is not valid:
if (!$contactForm->isValid()) {
// gets the error in the array $errors
$errors = $contactForm->getErrors();
} else {
// If the contact form is valid:
try {
// send the email created with the contact form
$result = sendEmail($contactForm);
// after the email is sent, redirect and "die".
// We redirect to prevent refreshing the page which would resend the form
header("Location: ./success.php");
die();
} catch (Exception $e) {
// an error occured while sending the email.
// Log the error and add an error message to display to the user.
error_log('An error happened while sending email contact form: ' . $e->getMessage());
$errors['oops'] = 'Ooops! an error occured while sending your email! Please try again later!';
}
}
return $errors;
}
// Sends the email based on the information contained in the contact form
function sendEmail($contactForm) {
// Email part will create the email information needed to send an email based on
// what was inserted inside the contact form
$emailParts = new EmailParts($contactForm);
// This is the part where we initialize Swiftmailer with
// all the info initialized by the EmailParts class
$emailMessage = Swift_Message::newInstance()
->setSubject($emailParts->getSubject())
->setFrom($emailParts->getFrom())
->setTo($emailParts->getTo())
->setBody($emailParts->getBodyMessage());
// Another Swiftmailer configuration..
$transport = Swift_SmtpTransport::newInstance(SMTP_SERVER, SMTP_PORT, 'tls');
$mailer = Swift_Mailer::newInstance($transport);
$result = $mailer->send($emailMessage);
return $result;
}
// Initialize the ContactForm with the information of the form and the possible uploaded file.
$contactForm = new ContactForm($_POST, $_FILES);
// Call the "main" method. It will return a list of errors.
$errors = main($contactForm);
// Call the "contactForm" view to display the HTML contact form.
require_once("./views/contactForm.php");
I've posted the entirety of my code at Dropbox. There's not much, but I think the problem must lie in the Index.
I would like my form (based on Swift Mailer) to redirect to a link by using header();
Problem is I just can't seem to find out where to place the header(); part so that the form is successfully sent and the person is redirect. This is the current code:
<?php
if(isset($_POST['email'])) {
// Require the Swift Mailer library
require_once 'lib/swift_required.php';
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl' )
->setUsername('xxxx')
->setPassword('xxxx')
;
$mailer = Swift_Mailer::newInstance($transport);
foreach ($_POST as $key => $value)
$messageText .= ucfirst($key).": ".$value."\n\n";
$message = Swift_Message::newInstance('A message from Pivot Template Form')
->setFrom(array($_POST['email'] => $_POST['name']))
->setTo(array('email#email.com' => 'John Doe'))->setBody($messageText);
try{
echo($mailer->send($message));
}
catch(Exception $e){
echo($e->getMessage());
}
exit;
}
?>
Anybody have an idea as to where to add the line?
You're likely having issues figuring this out because of this portion of your code:
try{
echo($mailer->send($message));
}
catch(Exception $e){
echo($e->getMessage());
}
// This is where you're probably trying to put header()
exit;
The issue is that by using echo, PHP automatically sends headers to the browser, rendering any other header function useless as the headers have already been sent along with the output. From the docs:
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
So you must use a different strategy to convey the message back to the user. Likely something like:
try{
$mailer->send($message);
header('Location: mydesiredpage.php?success=1');
}
catch(Exception $e){
echo($e->getMessage());
}
exit;
And then checking the $_GET['success'] variable in the next page to convey the message to the user.
I am using PHPmailer to send mails. However, the mail is being sent to each user twice. Below is the screen-shot of a test mail.
The following is my code :
<?php
##REQUIRED FUNCTION
function send_mail_to($receiver, $msg)
{
$subject="[ TNP Update ] - Do you like the new look ?";
#Grab the PHPmailer class
require_once('./lib/phpmailer/phpmailer.inc.php');
#Create object
$mailer = new PHPmailer(); //Instantiate class
$mailer->From="tnp#aakashbhowmick.in";
$mailer->FromName="TNP Mailer";
$mailer->IsHTML(true);
$mailer->Subject = $subject;
$mailer->Body = $msg;
$mailer->AddAddress($receiver);
#Send the email
set_time_limit(300);
$mailer->Send();
} //End of send_mail_to()
###### THE WORKING CODE ######
#Only authorised access is allowed.
if($_POST['signature']=="some-secret-signature-here"){
$msg1=urldecode($_POST['text']);
# Formatting the message a little
$msg1=str_replace("#c0c0c0","#EAE99A",$msg1);
$msg1=str_replace("<td","<td style='font-family:Trebuchet MS,Verdana,arial'; ",$msg1);
#Start sending mails. Some lines commented for testing purpose
//include("connection.php");
//$result=mysql_query("SELECT * FROM subscribers");
$subscriber=array('id'=>'1','email'=>'aakashrocks#gmail.com','active'=>'1');
//while($subscriber=mysql_fetch_array($result)){
if($subscriber['active']==1){
$body="Some text";
send_mail_to($subscriber['email'], $body);
} #End-of-if
//} #End-of-while
} ##End of if
?>
I had the same problem, for me solution was to change
$mailer->isSMTP();
to
$mailer->Mailer = 'smtp';
So, try to use $mailer->Mailer.
May be there is a page refresh and hence multiple execution - Make sure the mail method is called only once by the browser for each reciever. To make sure, you could set a session variable upon sending and go into the send part only if session is not set.
if(!isset($_SESSION[$reciever]))
{
$_SESSION[$reciever] = 1;
\\mail code here
}
else{
echo "doing it more than once";
}
Also you can set $mailer->$SingleTo to true, so you would know if its multiple execution or single. You could also send the timestamp with the email for more debugging.
I had the same problem but using the SMTP connection.
I still don't know why but it happens when your recipient doesn't have a name.
So, instead of
$mailer->AddAddress($receiver);
Do
$mailer->AddAddress($receiver, 'Receiver name');
I hope it helps.
I was experiencing the same problem. In my case changing mail systems did the trick.
By default, phpMailer sends out email using Mail. Once I told it to use Sendmail instead, I stopped getting the duplicate address.
$email = new phpmailer;
$email->mailer = "sendmail";
The CI Email send() function only returns true or false. Is there a way to get a more detailed reason as to why a sending failed? I'm using SMTP.
You can further inspect what happened by using the email debugger:
$r = $this->send(FALSE);
if (!$r)
$this->email->print_debugger()
;
From the Codeigniter Email Class Reference.
If you need the debugger output as a string, you can just catch the output with an output buffer:
$errors = array();
... # Loop
$r = $this->send(FALSE);
if (!$r) {
ob_start();
$this->email->print_debugger();
$error = ob_end_clean();
$errors[] = $error;
}
... # Loop end
Codeigniter in more recent versions requires an explicit FALSE for the $auto_clear parameter of the email->send() function in order to not clear the message and the debugging, effectively killing the debugger function if you fail to pass the FALSE.
The print_debugger() function will work but it appends the e-mail header and message at the bottom. If all you want is an array of the debug message (which include both success and error messages), you could consider extending the functionality of the Email class as follows:
<?php
class MY_Email extends CI_Email
{
public function clear_debugger_messages()
{
$this->_debug_msg = array();
}
public function get_debugger_messages()
{
return $this->_debug_msg;
}
}
You'd want to place this in a file named MY_Email.php in your ./application/libraries folder. CodeIgniter will automatically recognize the existence of this class and use it instead of it's default one.
When you want to get a list (array) of debug messages, you can then do this:
$this->email->get_debugger_messages();
If you're looping through messages and don't want to include debugger messages from previous attempts, you can do this:
foreach ($email_addresses as $email_address)
{
$this->email->to($email_address);
if (! $this->email->send())
{
echo 'Failed';
// Loop through the debugger messages.
foreach ($this->email->get_debugger_messages() as $debugger_message)
echo $debugger_message;
// Remove the debugger messages as they're not necessary for the next attempt.
$this->email->clear_debugger_messages();
}
else
echo 'Sent';
}
Reference: "Extending Native Libraries" section of https://www.codeigniter.com/user_guide/general/creating_libraries.html.
Codeigniter 3:
if ( $this->email->send() ) {
echo 'Your Email has successfully been sent.';
} else {
$errors = $this->email->print_debugger();
print_r($errors);
}
You could check your mail logs. If the mail errors out then you should have a record saying why in there.
I'm not sure where they will be located though it depends on your system.