Welcome Guest, Not a member yet? Register   Sign In
Codeigniter sending blank emails when more then one email is sent in a single request
#1

(This post was last modified: 09-16-2015, 09:13 PM by webdev25.)

Hello,

Long time CI developer here, been with CI since v1.7.1 and it's still my framework of choice for personal and client projects. A big thank you to the CI Team, it's been an indispensable tool for me.

I have recently been building a few projects with v3.0 and everything so far has been great but i've ran into a strange issue.

When using the email library, if i send out a single email in a single HTTP request to the server everything works fine, however if try to send out two emails within that single HTTP request the second email comes through blank. The subject and all the headers are fine but the body of the email is empty.

I have tried sending out emails via my local server (hosting on my LAN) and my production server (hosted in a datacenter) in a few different ways and i get the same issues.

I have tried sending out via SMTP using Gmail,
SMTP via Amazon AWS
php's mail() via sendmail

I have tried introducing 60+ second delays between each email being sent for each of the methods listed above in case it was a throttling issue and it makes no difference. I have tried to upgrade CI to v 3.0.1 and have the same issues.

I do not get the blank emails when sending to multiple addresses via BCC and this works for cases where i need to send two copies of an email, but if i need to send two different emails to two different addresses the BCC method does not work.

i changed the $_body variable of the email class to public and echo'd it out via the model sending the email and when the first email is sent, the $_body variable contains the HTML for the email, but the variable is empty when the second email is being sent. This happens when sending the same email, running the same code twice, and also happens when sending two different emails as well.

The emailer model:

PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

class 
Emailer extends CI_Model {

 function 
__construct() {

 
parent::__construct();

 
$this->load->library('email');

 
$config = array(
 
'mailtype'  => 'html',
 
'useragent' => $this->config->item('app_email_useragent'),
 
'protocol'  => $this->config->item('app_email_protocol'),
 
   'smtp_host' => $this->config->item('app_email_smtp_host'),
 
   'smtp_port' => $this->config->item('app_email_smtp_port'),
 
   'smtp_user' => $this->config->item('app_email_smtp_user'),
 
   'smtp_pass' => $this->config->item('app_email_smtp_pass'),
 
   'smtp_crypto'=>'tls'
 
);

 
$this->email->initialize($config);

 
$this->email->set_newline("\r\n");

 }

 public function 
send_email($email,$to,$data=array()) {

 
$func '_email_'.$email;

 if( 
method_exists($this,$func) ) {
 
 
$email $this->$func($data);

 if( 
$email ) {

 
$this->email->to($to); 

 
$this->email->from($this->config->item('app_email_from'), $this->config->item('app_email_from_name'));
 
 
$this->email->subject($email['subject']);
 
 
$this->email->message$this->load->view('emails/_wrapper',array('body'=>$email['body']),true) );
 
 
$result $this->email->send();

 }

 }

 }

 private function 
_email_contact_form($data=array()) {

 
$result = array();

 
$result['subject'] = 'Enquiry from '.$this->config->item('app_name').' website';
 
$result['body'] = $this->load->view('emails/contact_form',$data,true);

 return 
$result;

 } 

The controller:

PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Contactus extends MY_Controller {

 function 
__construct() {

 
parent::__construct();


 }

 public function 
index() {

 
$this->load->library('recaptcha');

 if( 
$this->input->post('act') == 'submit' ) {

 
$this->recaptcha->recaptcha_check_answer();

 if( 
$this->recaptcha->getIsValid() !== true ) {

 
$this->data['errors'][]='Invalid Captcha';

 } else {

 
$postdata $this->_build_postdata( array('name','telephone','email','message') );

 
$this->data['errors'] = $this->Sys->contact_form_validate($postdata);

 if( !
$this->data['errors'] ) {

 
$result $this->Sys->contact_form($postdata); 

 if( 
$result ) {

 
$this->data['successes'][]='Your message was sent, we will be in contact shortly';

 } else {

 
$this->data['errors'][] = 'There was a problem sending your message, please try again later';

 }

 }

 }

 }

 
$this->_render();

 }



The 'Sys' model:

PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

class 
Sys extends CI_Model {

 function 
__construct() {

 
parent::__construct();

 

 }

 public function 
contact_form_validate($data) {

 
$errors = array();

 if( !isset(
$data['name']) || !$this->form_validation->required($data['name']) )
 
$errors[] = 'You must enter a name';

 if( !isset(
$data['telephone']) || !$this->form_validation->required($data['telephone']) )
 
$errors[] = 'You must enter a telephone number';

 if( !isset(
$data['email']) || !$this->form_validation->valid_email($data['email']) )
 
$errors[] = 'You must enter a valid email address';

 if( !isset(
$data['message']) || !$this->form_validation->required($data['message']) )
 
$errors[] = 'You must enter a message';

 return 
$errors;

 }

 public function 
contact_form($data) {

 if( !
$this->contact_form_validate($data) ) {

 foreach( 
$this->config->item('app_contact_form_emails') as $addr )
 
$this->Emailer->send_email('contact_form',$addr,$data);

 return 
true;

 }

 return 
false;

 }



the _wrapper.php view for the email:

Code:
<div style="background:#FFFFFF;">
<div style="padding: 28px 15px 28px 15px; background:#0065ad; color:#FFF;"><?= $this->config->item('app_name'); ?></div>
<div style="padding:15px 15px 15px 15px; color:#000000;"><?= $body ?></div>
</div>

the contact_form.php view for the email:

Code:
<p>You have received a new message from the <?= $this->config->item('app_name'); ?> website.</p>
<p><b>Name:</b> <?= htmlspecialchars($name); ?></p>
<p><b>Telephone:</b> <?= htmlspecialchars($telephone); ?></p>
<p><b>Email:</b> <?= htmlspecialchars($email); ?></p>
<p><b>Message:</b></p>
<p><?= nl2br(htmlspecialchars($message)); ?></p>

The email headers and source code from the first of the two emails i'm sending out in one request, this example is being sent out via gmail (i've removed some information specific to the client's project as well as some IP addresses and actual email addresses) The timestamps are wrong because i've used a test i did later in the day for the first example, but the results are the same with emails sent in order.

Code:
Return-Path: <[email protected]>
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
server111-111-111-111.live-servers.net
X-Spam-Level: ****
X-Spam-Status: No, score=4.2 required=7.0 tests=DKIM_SIGNED,DKIM_VALID,
FREEMAIL_FROM,HTML_MESSAGE,MISSING_HEADERS,REPLYTO_WITHOUT_TO_CC,XPRIO
autolearn=no version=3.3.1
X-Original-To: [email protected]
Delivered-To: [email protected]
Received: from server111-111-111-111.live-servers.net (localhost [127.0.0.1])
by server111-111-111-111.live-servers.net (Postfix) with ESMTP id 2D08C9D8062;
Wed, 16 Sep 2015 21:42:03 +0100 (BST)
Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177])
by server111-111-111-111.live-servers.net (Postfix) with ESMTPS;
Wed, 16 Sep 2015 21:42:03 +0100 (BST)
Received: by wicfx3 with SMTP id fx3so90115582wic.1;
       Wed, 16 Sep 2015 13:42:07 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
       d=gmail.com; s=20120113;
       h=sender:user-agent:date:from:subject:reply-to:message-id
        :mime-version:content-type;
       bh=9H3uCFQALQMdnXvQCisA+TZORrNYNjfjZD7smXGCadw=;
       b=bU76OKrqxw8pHAZhrL0UedfS6C4K9GwEVEigAaq1uOCsim760lwUfLARA7pO1KBwGP
        3npwoabI3IqS4XK+fgOLyna8ZAT+oAUSRxNA+6s3OaKQD5ABxzFNtywAFZv/lp5R/j1u
        EEiiRnxvLI3GGfpJQUFvL0o4vYtmUMMPLBFybPMt9N2EAOZFK/dvjCub6jsGPvJNFwed
        62yEHbMvNN3Y26SXSUTToCvsaEL5X9CG8qCaP6gM74D+dks5lyH8VIaCwAk8gPg+4yBn
        JLi8ifjw9Oc7tbEqJPwOMSo9EUFgGOpJYB6/CmYJc4BVmL1kj6ZPv3CCqeVhpmjNdhLp
        ZIoQ==
X-Received: by 10.194.113.101 with SMTP id ix5mr26977590wjb.66.1442436127521;
       Wed, 16 Sep 2015 13:42:07 -0700 (PDT)
Received: from localhost (host-111-111-111-111.static.as13285.net. [111.111.111.111])
       by smtp.gmail.com with ESMTPSA id r9sm28277519wjz.35.2015.09.16.13.42.06
       (version=TLS1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
       Wed, 16 Sep 2015 13:42:06 -0700 (PDT)
Sender: Removed <[email protected]>
User-Agent: Removed
Date: Wed, 16 Sep 2015 21:41:26 +0100
From: "Removed" <[email protected]>
Subject: Enquiry from Removed website
Reply-To: "[email protected]" <[email protected]>
X-Sender: [email protected]
X-Mailer: Removed
X-Priority: 3 (Normal)
Message-ID: <[email protected]>
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="B_ALT_55f9d3f6dd895"

This is a multi-part message in MIME format.
Your email application may not support this format.

--B_ALT_55f9d3f6dd895
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Removed
You have received a new message from the Removed website.
Name: ghjghjg
Telephone: ghjghj
Email: [email protected]
Message:
dfsgdfgdfgdf


--B_ALT_55f9d3f6dd895
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div style=3D"background:#FFFFFF;">
<div style=3D"padding: 28px 15px 28px 15px; background:#0065ad; color:#FFF;=
">Removed</div>
<div style=3D"padding:15px 15px 15px 15px; color:#000000;"><p>You have rece=
ived a new message from the removed website.</p>
<p><b>Name:</b> ghjghjg</p>
<p><b>Telephone:</b> ghjghj</p>
<p><b>Email:</b> [email protected]</p>
<p><b>Message:</b></p>
<p>dfsgdfgdfgdf</p></div>
</div>

--B_ALT_55f9d3f6dd895--

and this is the email headers and source code from the second email sent out in the same HTTP request

Code:
Return-Path: <[email protected]>
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
server111-111-111-111.live-servers.net
X-Spam-Level: ****
X-Spam-Status: No, score=4.2 required=7.0 tests=DKIM_SIGNED,DKIM_VALID,
FREEMAIL_FROM,HTML_MESSAGE,MISSING_HEADERS,REPLYTO_WITHOUT_TO_CC,XPRIO
autolearn=no version=3.3.1
X-Original-To: [email protected]
Delivered-To: [email protected]
Received: from server111-111-111-111.live-servers.net (localhost [127.0.0.1])
by server111-111-111-111.live-servers.net (Postfix) with ESMTP id A82579D8062
for <[email protected]>; Wed, 16 Sep 2015 21:40:41 +0100 (BST)
Received: from mail-wi0-f180.google.com (mail-wi0-f180.google.com [111.111.111.111])
by server111-111-111-111.live-servers.net (Postfix) with ESMTPS
for <[email protected]>; Wed, 16 Sep 2015 21:40:41 +0100 (BST)
Received: by wicfx3 with SMTP id fx3so1546625wic.0
       for <[email protected]>; Wed, 16 Sep 2015 13:40:46 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
       d=gmail.com; s=20120113;
       h=sender:user-agent:date:from:subject:reply-to:message-id
        :mime-version:content-type;
       bh=b5ftjI8mFViAjS2jc/b+UsrzJQ58XKfb2kbqjBXLKBg=;
       b=jTsa7666wCrwGfQigJc9azLY+CA+AnSyueFV4x3BS46fDUAJxX1hCcjflXRsDxe7nx
        c6zIoVs3bPJD1qnz+FC/JEga2unin9JKF8NsXRte3WuUrr6cwLwLPOS0fx5bznSMJVVP
        OIMRHlMrT094zJOzZ1zdNokyH/OZOar9ryy+kwsLyqp+i5TLO+riyQSxFe6nS/1gYKA0
        jwAmGwUU7FOQ6hu1kBKoKKpw+rBaxyOF9h3YbisHpUuFOFWid03DmfDlrHkoE7MrJxrp
        BTmxeZe33cNGl1In0/BXqxwKjiJS/r3siV+m8X8RhaaO7wZiq6XwQLCXkL0rgwwNL5lM
        FZpQ==
X-Received: by 10.194.78.34 with SMTP id y2mr55343644wjw.91.1442436045906;
       Wed, 16 Sep 2015 13:40:45 -0700 (PDT)
Received: from localhost (host-111-111-111-111.static.as13285.net. [111.111.111.111])
       by smtp.gmail.com with ESMTPSA id m4sm28327989wje.5.2015.09.16.13.40.44
       for <[email protected]>
       (version=TLS1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
       Wed, 16 Sep 2015 13:40:44 -0700 (PDT)
Sender: Removed <[email protected]>
User-Agent: Removed
Date: Wed, 16 Sep 2015 21:40:01 +0100
From: "Removed" <[email protected]>
Subject: Enquiry from Removed website
Reply-To: "[email protected]" <[email protected]>
X-Sender: [email protected]
X-Mailer: Removed
X-Priority: 3 (Normal)
Message-ID: <[email protected]>
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="B_ALT_55f9d3a47afdd"

This is a multi-part message in MIME format.
Your email application may not support this format.

--B_ALT_55f9d3a47afdd
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit




--B_ALT_55f9d3a47afdd
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



--B_ALT_55f9d3a47afdd--

as you can see from the above both parts of the multipart email are blank in the second email being sent out. I also get the blank email issue when sending the email out as a 'non-multipart' email and if i send the emails out as plain-text instead of HTML

I have a CI app i've written in CI v2.2.0 which sends out different emails to different user's by processing an 'email queue' from a database, and is sending up to 30 emails with a single request in some cases and i'm using similar code that i've shown above and i have no issues with blank emails. I have tried using the Email class from the 2.2.0 codebase in the v3.0.1 codebase and i still get the blank email issue.

So this is where i'm getting lost:

Same issue on two different servers both of which send out multiple emails with a single HTTP request fine in v.2.2.0 but not in v3.0.1 or v3.0.1 with the v2.2.0 email class.

Sending via two different SMTP hosts (Gmail and AWS) and sending out via mail() on two different servers causes the same issue.

Adding delay's to between sending emails makes no difference so i don't think it's a throttling issue.

the print_debugger() function show's everything being sent ok, although it's still showing the second email as being sent to the SMTP server as blank.

Single or Multipart emails have the same issue.

Sending out as HTML or Plain-text only also has the same issue.

I have also tried manually issuing the clear() method for the email class before and after sending the email, and i have also set the 'auto clear' to false when issuing the send() method for the email class, neither makes any difference.

There are no errors what so ever in the apache error logs when sending out via SMTP (both gmail and AWS) or via mail() on either server i'm testing with.


Hopefully i've listed enough information here to give you guys a good idea of what i'm doing and how i'm doing it. If anything is un-clear let me know and i'll try to provide you with some more information.

Thanks again Smile
Reply
#2

Have you tried clearing before the second send to reset everything?
http://www.codeigniter.com/user_guide/li...ail::clear

Or perhaps try using php's native mail() and see if it still happens. That would at least rule out a CI issue, and perhaps give more clues?

That might not be much help as it seems you are doing everything perfectly well, sorry.

Paul.
Reply
#3

(This post was last modified: 09-17-2015, 07:54 AM by webdev25.)

(09-17-2015, 07:05 AM)PaulD Wrote: Have you tried clearing before the second send to reset everything?
http://www.codeigniter.com/user_guide/li...ail::clear

Or perhaps try using php's native mail() and see if it still happens. That would at least rule out a CI issue, and perhaps give more clues?

That might not be much help as it seems you are doing everything perfectly well, sorry.

Paul.

Hello Paul,

Thank you for your response, i have tried both of your suggestions already with no success, the mail() function works when called directly, but using it via the Email class has the same issues as using SMTP via the Email class Sad
Reply
#4

Try moving the calls to initialize()/set_newline() into your send_email() method (you should probably store the $config array in a property, just don't name the property $config, for hopefully obvious reasons).
Reply
#5

(09-17-2015, 10:03 AM)mwhitney Wrote: Try moving the calls to initialize()/set_newline() into your send_email() method (you should probably store the $config array in a property, just don't name the property $config, for hopefully obvious reasons).

Already tried this too, soz should have mentioned it in my initial post. I've tried moving the initialize() & set_newline() along with the config array in to the send_email() method with no luck, I've also tried destroying the email class via unset() and re-initialising / re-loading it right before I start sending the email too, so each time an email is sent everything should be starting from scratch again, no luck. 

The problem with making the $config array a property of my emailer class is it needs to call to the config class which I don't think is possible in the property, I've run into errors when trying that, so I'd still need to set the values for the $config array property in the construct or send_email method, neither of which makes a difference either. Sad

What I can't get my head around is why the $_body property of the email class is blank when I'm calling $this->email->message() the second time round, looking at the code in the email class for the message() method I can't see anything there there that could possibly cause it not to be set only on the second time it's called.
Reply
#6

I was thinking something like this:
PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

class 
Emailer extends CI_Model {

    private 
$emailConfig;

    public function 
__construct() {

        
parent::__construct();

        
$this->load->library('email');

        
$this->emailConfig = array(
            
'mailtype'  => 'html',
            
'useragent' => $this->config->item('app_email_useragent'),
            
'protocol'  => $this->config->item('app_email_protocol'),
            
'smtp_host' => $this->config->item('app_email_smtp_host'),
            
'smtp_port' => $this->config->item('app_email_smtp_port'),
            
'smtp_user' => $this->config->item('app_email_smtp_user'),
            
'smtp_pass' => $this->config->item('app_email_smtp_pass'),
            
'smtp_crypto'=>'tls'
        
);
    }

    public function 
send_email($email$to$data = array()) {
        
$func '_email_'.$email;
        if (
method_exists($this$func)) {
            
$email $this->$func($data);
            if (
$email) {
                
$this->email->initialize($this->emailConfig);
                
$this->email->set_newline("\r\n");
                
$this->email->to($to); 
                
$this->email->from($this->config->item('app_email_from'), $this->config->item('app_email_from_name'));
                
$this->email->subject($email['subject']);
                
$this->email->message($this->load->view('emails/_wrapper', array('body' => $email['body']), true));
                
$result $this->email->send();
            }
        }
    }

    private function 
_email_contact_form($data = array()) {
        
$result = array();
        
$result['subject'] = 'Enquiry from '.$this->config->item('app_name').' website';
        
$result['body'] = $this->load->view('emails/contact_form'$datatrue);

        return 
$result;
    } 


However, I have a feeling there's something else wrong, and I'm just not seeing it for some reason.
Reply
#7

Thanks for the feedback mwhitney, I tried your code and still get the same issues Sad . Not sure what's happening, I'm going to do some tests with a clean CI install and see what happens.
Reply
#8

So, I am even more confused then I was before, using the following code on a fresh install all the emails send fine.

PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Welcome extends CI_Controller {

    public function 
index() {

        
$this->load->library('email');

        
$config = array(
            
'mailtype'  => 'html',
            
'useragent' => 'Codeigniter Test',
            
'protocol'  => 'smtp',
            
'smtp_host' => '173.194.67.108',
            
'smtp_port' => 587,
            
'smtp_user' => '[email protected]',
            
'smtp_pass' => 'mypassword',
            
'smtp_crypto'=>'tls'
        
);
    
        
$this->email->initialize($config);

        
$this->email->set_newline("\r\n");

        
$emails = array(
            
'[email protected]',
            
'[email protected]',
            
'[email protected]'
        
);

        foreach(
$emails as $to) {

            
$this->email->to($to); 

            
$this->email->from('[email protected]''My Name');
            
            
$this->email->subject('Codeigniter Email Test');
            
            
$this->email->message$this->load->view('welcome_message',array(),true) );
            
            
$result $this->email->send();

        }
        
    }

Reply
#9

So, I changed my code for the send_email() method to this:

PHP Code:
public function send_email($email,$to,$data=array()) {

        
$func '_email_'.$email;

        if( 
method_exists($this,$func) ) {
            
            
$email $this->$func($data);

            if( 
$email ) {

                    
$this->email->to($to); 

                    
$this->email->from($this->config->item('app_email_from'), $this->config->item('app_email_from_name'));
                    
                    
$this->email->subject($email['subject']);

                    
$message $this->load->view('emails/_wrapper',array('body'=>$email['body']),true);

                    
var_dump($message);

                    echo 
'<hr>';
                    
                    
$this->email->message$message );
                    
                    
$result $this->email->send();

            }

        }

    } 

and it turns out $message is loaded properly the first time, but on subsequent attempts to set the value of $message I just get an empty string? So for whatever reason CI isn't loading the _wrapper view properly after the first time.
Reply
#10

(This post was last modified: 09-21-2015, 10:00 PM by webdev25.)

So.... I figured it out... I should have provided more information about how my application(s) were setup.

Because this particular system has multiple 'applications' within it, I have the codebase setup something like this:

admin
-- index.php
merchants
-- index.php
applications
-- admin
-- common
---- views
------ emails
-------- _wrapper.php
-- merchants
-- public
---- views
------ emails
-------- _wrapper.php
-------- contact_form.php
system
index.php

Because i want to share some files and code across applications, the email wrapper being one of them the file in applications/common/views/emails/_wrapper.php contained the HTML code for the email wrapper. The file in applications/public/views/emails/_wrapper.php contained the following code:

PHP Code:
<?php require_once BASEPATH.'../applications/common/views/emails/_wrapper.php'

I changed it to

PHP Code:
<?php require BASEPATH.'../applications/common/views/emails/_wrapper.php'

Problem solved. Sorry guy's, school boy error Tongue Thanks for your help and feedback though.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB