CodeIgniter unable to send email using PHP mail() - email

I'm trying to send an e-mail with Codeigniter like this:
$this->load->library('email');
$this->email->from("myemail#email.com");
$this->email->reply_to("myemail#email.com");
$this->email->to("myemail#email.com");
$this->email->subject("Test mail");
$this->email->message("Email body");
$this->email->set_alt_message("Email body txt");
$this->email->send();
and I got this on the email debugger: Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.
If I do e simple PHP mail() function with the same addresses, it works but when I use CodeIgniter it gives me the error. So why would it work with simple mail() but not with CodeIgniter ? Any ideas ?
Thanks.

Had similar issue.
That's working code from the controller :
$config = array();
$config['useragent'] = "CodeIgniter";
$config['mailpath'] = "/usr/bin/sendmail"; // or "/usr/sbin/sendmail"
$config['protocol'] = "smtp";
$config['smtp_host'] = "localhost";
$config['smtp_port'] = "25";
$config['mailtype'] = 'html';
$config['charset'] = 'utf-8';
$config['newline'] = "\r\n";
$config['wordwrap'] = TRUE;
$this->load->library('email');
$this->email->initialize($config);
$this->email->from($fromEmail, $fromName);
$this->email->to($email);
$this->email->subject('Тест Email');
$this->email->message($this->load->view('email/'.$type.'-html', $data, TRUE));
$this->email->send();

Clearly, there does not seem to be a definitive 'one size fits all' answer. What worked for me was changing
$config['protocol'] = 'smtp';
TO:
$config['protocol'] = 'mail';
Hope this helps...

Do you have an email.php file in your config folder? Maybe there's a problem with your configuration in there.

Nobody seemed to really find a definitive answer, so I did some digging around and found out why.
in system/libraries/Email.php, first look at line 1552:
if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
it seems to send everything all peachy like. I had the exact same symptoms too. To see if I was crazy, i inserted immediately before...
mail($this->_recipients, $this->_subject, $this->_finalbody)
so I basically removed all the headers and let PHP put in the defaults. Bingo! Without CI's headers, it works. With the CI headers, it doesn't. So what is it?
Digging around some more, I looked up to where html is initialized and used. Turns out it doesn't really do anything until around 1046, where it builds the message body.
from line 1048:
if ($this->send_multipart === FALSE)
{
$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
$hdr .= "Content-Transfer-Encoding: quoted-printable";
}
else
{
$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline . $this->newline;
$body .= $this->_get_mime_message() . $this->newline . $this->newline;
$body .= "--" . $this->_alt_boundary . $this->newline;
$body .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
$body .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
$body .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
$body .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
$body .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline;
}
Flipping send_multipart between TRUE and FALSE will make the mail class work or not work.
Looked through the Code Ignitor's email class docs reveals nothing. Going to line 52:
var $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo.
So there you have it. Possibly an error in how CI does multipart messages? The hidden config preference
$config['send_multipart'] = FALSE;
in the email.php seems to do the trick.

Be sure domain name in
$this->email->from("myemail#**email.com**");
match to server domain name

Add a protocol variable to the config array and assign it the value "sendmail". The email.php file in the config folder should read as shown below. Mine works like this:
$config['protocol'] = 'sendmail';
$config['mailtype'] = 'html';
$config['charset'] = 'utf-8';
$config['newline'] = "\r\n";

Ensure that Apache can send emails.
To check your current sendmail status:
sestatus -b | grep httpd_can_sendmail
Change it to this if it is off:
sudo setsebool -P httpd_can_sendmail on

I read a comment in the file email.php :
// most documentation of sendmail using the "-f" flag lacks a space after it, however
// we've encountered servers that seem to require it to be in place.
return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['Return-Path']));
"-f" flag - this problem!!!

Had the same problem,
Make sure your 'from' address is a valid email address.

I had the same problem and though it seems silly to me now, I had some of the config array options capitalized when they all need to be lowercase:
was:
$mail_config['smtp_host'] = 'mail.example.com';
$mail_config['smtp_port'] = '587';
$mail_config['smtp_user'] = 'email#example.com';
$mail_config['smtp_pass'] = 'password';
$mail_config['smtp_crypto'] = 'TLS'; //ERROR
$mail_config['protocol'] = 'SMTP'; //ERROR
$mail_config['mailtype'] = 'HTML'; //ERROR
$mail_config['send_multipart'] = FALSE;
$this->email->initialize($mail_config);
Fixed:
$mail_config['smtp_host'] = 'mail.example.com';
$mail_config['smtp_port'] = '587';
$mail_config['smtp_user'] = 'email#example.com';
$mail_config['smtp_pass'] = 'password';
$mail_config['smtp_crypto'] = 'tls'; //FIXED
$mail_config['protocol'] = 'smtp'; //FIXED
$mail_config['mailtype'] = 'html'; //FIXED
$mail_config['send_multipart'] = FALSE;
$this->email->initialize($mail_config);
That worked for me

Its worth saying that if you're on WAMP (Windows) you will need to have sendmail installed otherwise there is no default SMTP method of sending. I wanted to use Gmail but couldn't because there is simply no default mail mechanism.

$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'ssl://smtp.googlemail.com',
'smtp_port' => 465,
'smtp_user' => 'email',
'smtp_pass' => 'pass',
'mailtype' => 'html',
'charset' => 'iso-8859-1'
);
$this->load->library('email',$config);
**$this->email->set_newline("\r\n");** <- add this line
this code worked for me.

Related

How to reset user password by wordpress rest api

Any one of you know know to send a reset link for lost password by wordpress rest api ? I have been looking into wordpress rest api documentation but I haven't find out anything about it. Maybe someone has done a custom function for that.
I found out a way to do that:
function runRetrivePassword($data)
{
global $wpdb, $wp_hasher;
$user_data = get_user_by('email', $data['email']);
if (!$user_data) return array('result' => false);
do_action('lostpassword_post');
$user_login = $user_data->user_login;
$user_email = $user_data->user_email;
$key = get_password_reset_key($user_data);
$message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
$message .= network_home_url('/') . "\r\n\r\n";
$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
$message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
$message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
$message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
if (is_multisite())
$blogname = $GLOBALS['current_site']->site_name;
else
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$title = sprintf(__('[%s] Password Reset'), $blogname);
$title = apply_filters('retrieve_password_title', $title);
$message = apply_filters('retrieve_password_message', $message, $key);
if ($message && !wp_mail($user_email, $title, $message))
wp_die(__('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...'));
return array('result' => true);
}
add_action('rest_api_init', function () {
register_rest_route('apiuser/v1', '/forgotpwd/(?P<email>\S+)', array(
'methods' => 'GET',
'callback' => 'runRetrivePassword'
));
});

FPDF PDF file cannot be opened after email using PHPMailer

I am trying to create a PDF file using FPDF and send it via e-mail using PHPMailer. It did send the file, but for some reasons I cannot open the file, either from my email or using Adobe Reader (which gives me something like the file is damaged).
This is my code
require('fpdf.php');
require 'PHPMailerAutoload.php';
header("Access-Control-Allow-Origin: *");
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','UB',28);
$pdf->Cell(0,10,"My Profile",0,1,'C');
$pdf->Ln();
$mail = new PHPMailer();
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'example#gmail.com'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;
// a random hash will be necessary to send mixed content
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// main header
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"";
// no more headers after this, we start the body! //
$body = "--".$separator.$eol;
$body .= "Content-Transfer-Encoding: 7bit".$eol.$eol;
$body .= "This is a MIME encoded message.".$eol;
// message
$body .= "--".$separator.$eol;
$body .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$body .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$body .= $message.$eol;
// attachment
$body .= "--".$separator.$eol;
$body .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$body .= "Content-Transfer-Encoding: base64".$eol;
$body .= "Content-Disposition: attachment".$eol.$eol;
$body .= $attachment.$eol;
$body .= "--".$separator."--";
$pdfdoc = $pdf->Output('','S');
$attachment = chunk_split(base64_encode($pdfdoc));
//Set who the message is to be sent from
$mail->setFrom('example#gmail.com', 'Baby Diary');
//Set who the message is to be sent to
$mail->addAddress('example2#gmail.com', 'haha');
//Set the subject line
$mail->Subject = 'PHPMailer mail() test';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AddStringAttachment($attachment, 'doc.pdf', 'base64', 'application/pdf');
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
It does give me output when I use $pdf->Output(), which hints to me that the problem should not be in FPDF side. Any suggestion will be much appreciated.
Your problem is with phpmailer and not with fpdf. Try using the standard PHPMailer class methods.
If I was you I'd try to rework your code from the attachement example included in the PHPMailer doc samples. And particularly I'd stick to using the PHPMailer methods rather that doing my own smtp formating.
So first save your pdf to file, and then try attaching the file with $mail->addAttachment() . And let PHPMailer handle the formating of the mail.
So you might end up with something like this code below (I haven't run it, you'll probably need to fine tune it) :
require('fpdf.php');
require 'PHPMailerAutoload.php';
header("Access-Control-Allow-Origin: *");
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','UB',28);
$pdf->Cell(0,10,"My Profile",0,1,'C');
$pdf->Ln();
$pdfoutputfile = '/some-tmp-dir/temp-file.pdf';
$pdfdoc = $pdf->Output($pdfoutputfile, 'F');
// We're done with the pdf generation
// now onto the email generation
$mail = new PHPMailer();
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'example#gmail.com'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;
$separator = md5(time()); // a random hash will be necessary to send mixed content
//Set who the message is to be sent from
$mail->setFrom('example#gmail.com', 'From Test address');
//Set who the message is to be sent to
$mail->addAddress('example2#gmail.com', 'to test address');
//Set the subject line
$mail->Subject = 'Test message with attachement';
$mail->Body = 'Test message with attached files.';
$mail->AddAttachment($pdfoutputfile, 'my-doc.pdf');
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}

Reply-To header not picking the php variable

I am creating a page that sends the response from contact form within mail but reply-to is not working (the variable i am using is having value, but is not added within headers)
here's my code:
<?php
//$uname=$_REQUEST['uname'];
if(isset($_REQUEST['name']))
{
$name=$_REQUEST['name'];
}
if(isset($_REQUEST['email']))
{
$email=$_REQUEST['email'];
}
if(isset($_REQUEST['phone']))
{
$phone=$_REQUEST['phone'];
}
if(isset($_REQUEST['message']))
{
$message=$_REQUEST['message'];
}
// TESTING IF VARIABLES HAVE VALUES
echo "$name $email $phone $message";
// RESULT: TRUE TILL HERE
if($name=="" || $email=="" || $phone=="" || $message=="")
{
header("location:../?inst=invalid");
}
else
{
// ---------------- SEND MAIL FORM ----------------
// send e-mail to ...
$to="mail#example.com";
// Your subject
$subject="$name Contacted you via Contact Form";
// From
$headers = "From: ME <no-reply#example.com>\r\n";
$headers .= 'Reply-To:' . $email . "\r\n";
$headers .= "Return-Path: info#example.com\r\n";
$headers .= "X-Mailer: PHP\n";
$headers .= 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
print $message;
// send email
$sentmail = mail($to,$subject,$message,$headers);
//$sentmail = mail($to1,$subject,$message,$header);
}
// if your email succesfully sent
if($sentmail){
echo "Mail Sent.";
}
else {
header("location:../landing/?status=verification-pending");
}
?>
Now when i checked headers in my gmail, the value for $email doesn't appear in header information, Also no message is received. All I get is a blank message or may be $message is not printing anything like the same case i am facing with reply-to.
please help me a little with this. Thanks in advance.
Check that you have php warnings and notices enabled. When you are echoing out $name, $email, etc you are doing a redirect using headers after that. If your php notices etc aren't turned on, your header redirect will fail due to having already echoed something, and you won't know that you had invalid input. This is part of the reason you shouldn't echo things out during logic, but should store and out put values later.
Actually there was a little mistake with the above code. I mistakenly added = instead of == while comparison.
This line:
if($name=="" || $email="" || $phone="" || $message="")
Should read as:
if($name=="" || $email=="" || $phone=="" || $message=="")
Since = is for equation and not a condition for comparison ==
Fixed it in the Question

Zend_Mail error 500 > postfix/sendmail fatal: -n option not supported

I'm working on a Zend project in a very specific server configuration, our production environment is made of two dedicated servers, one for the company's email which host a postfix server and an other server for our web-application which is running on Apache2/Zend.
Those servers have two different IPs, but works on the same website domain.
Now when i try to send an email with an email from the mail server as a sender, i get an error 500 from Zend_Mail and the email.err log tells me :
postfix/sendmail[15782]: fatal: -n option not supported
But when i put a local adresse or a blank email as a sender it works, so i guess i get kicked out by the postfix of the webserver because it doesn't manage localy those emails.
So my question is: is there any way to use a domain email as sender from a distant server without merging the two servers?
Edit: i forgot to add: i can't use the distant server SMTP, i only can use a local sendmail.
I haven't find any solution or explanations so i ended up by writing a custom action helper based on the mail command of PHP.
I hope it can help someone:
class Zend_Controller_Action_SentEmail extends Zend_Controller_Action_Helper_Abstract{
public function sendEmail($from, array $to, $subject, $message){
//Header set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
$headers .= "From: ".$from."<email#domain.com>\r\n";
$headers .= "X-Mailer: PHP/".phpversion();
//To
$stringTo = "";
foreach($to as $k => $v) {
$stringTo .= $k." <".$v.">, ";
}
$stringTo = trim($stringTo, ", ");
//Send the email
if(mail($stringTo, $subject, $message, $headers, "-f bounce#domain.com")){
return true;
}
else{
//Oh! Noes!
return false;
}
}
}

CodeIgniter: Cannot redirect after $this->email->send()

i have the following code which sends an email from a posted form:
$this->load->library('email');
$config['charset'] = 'iso-8859-1';
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('info#mysite.com', 'Scarabee');
$this->email->to('info#mysite.com');
$this->email->subject('Message via website');
$data['msg'] = nl2br($this->input->post('msg'));
$data['msg'] .= '<br><br><b>Verstuurd door:</b><br>';
if($this->input->post('bedrijf')){
$data['msg'] .= $this->input->post('bedrijf').'<br>';
}
$data['msg'] .= $this->input->post('naam').'<br>';
$data['msg'] .= $this->input->post('adres').' - '.$this->input->post('postcode').', '.$this->input->post('gemeente').'<br>';
$data['msg'] .= $this->input->post('tel').'<br>';
$data['msg'] .= $this->input->post('email');
$message = $this->load->view('email', $data, TRUE);
$this->email->message($message);
if($this->email->send()){
$success = 'Message has been sent';
$this->session->set_flashdata('msg', $success);
redirect('contact/'.$this->input->post('lang'));
}
else{
show_error('Email could not be sent.');
}
Problem: the email gets sent with proper formatting (from the email view template), but the page then goes blank. For instance, if I try to echo out $message just below the $this->email->send() call, nothing shows up. Redirecting, as I’m attempting above, obviously doesn’t work either. Am I missing something? Thanks for any help…
Update
Traced the problem down to a function inside /system/libraries/Email.php (CI's default email library). Commenting out the code inside this function allows the mail to get sent, as well as a proper redirect:
protected function _set_error_message($msg, $val = '')
{
$CI =& get_instance();
$CI->lang->load('email');
if (substr($msg, 0, 5) != 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5))))
{
$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
}
else
{
$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
}
}
The line that caused the error is: $CI->lang->load('email');
Go figure...
UPDATE 2: SOLVED
I had this in my controller's construct:
function __construct() {
parent::__construct();
$this->lang = $this->uri->segment(2, 'nl');
}
I guess there was a conflict between $this->lang and the _set_error_message function which also returns a "lang" variable (see var_dump further down).
Solution: changed $this->lang to $this->language, and everything's hunky dory!
Thought I'd post the answer here in case anyone else is ever losing hair with a similar problem :-)
It's likely that an error is occurring when you attempt to send an e-mail which is then killing your script during execution. Check your apache and PHP error logs ( /var/log/apache/ ) and enable full error reporting.
You could, for debugging purposes, try doing this:
...
$this->email->message($message);
$this->email->send();
redirect('contact/'.$this->input->post('lang'));
This should redirect you, regardless of your mail being sent or not (if you still recieve it, you can assume that the redirect would be the next thing that happens).
My own solution looks like this:
...
if ( $this->email->send() )
{
log_message('debug', 'mail library sent mail');
redirect('contact/thankyou');
exit;
}
log_message('error', 'mail library failed to send');
show_error('E-mail could not be send');
$ref2 = $this->input->server('HTTP_REFERER', TRUE);
redirect($ref);
By using the above code you can redirect to the current page itself
and you can set your flash message above the redirect function.