Jump to:

22972 Posts in 11596 Topics by 2824 members

General Questions

SilverStripe Forums » General Questions » [SOLVED kind of] Email corruption from inside loop

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1073 Views
  • StuM
    Avatar
    Community Member
    56 Posts

    [SOLVED kind of] Email corruption from inside loop Link to this post

    I've been pulling my hair out with this.

    I have some code that sends bulk emails. They have customised messages to each recipient and generates the message on the fly.

    Sometimes it can do 20, sometimes 50, but never reach 100 without the subject and plaintext version fields turning into the 'from' field. Running the same script under the same conditions will yield different results(i.e. send a different number of emails before stuffing up). The 'CC' field also gets set to the sender along the way I've just noticed as well.

    I'm running a trunk version from September, I did a WinMerge between the email classes in the latest version and the trunk version, and they're the same. Upgrading not an option at this time, and probably won't help in this situation.

    Any ideas at all

  • StuM
    Avatar
    Community Member
    56 Posts

    Re: [SOLVED kind of] Email corruption from inside loop Link to this post

    I've done more tests on another server which is running 2.3.0-rc2. Test code below:

    for ($i = 0; $i < 100; $i++)
    {
    $email = new Email();
    $email->to = 'mail@example.com';
    $email->from = 'mail2@example.com';
    $email->subject = 'This is a test';
    echo $email->debug();
    }

    No body is added in this case, but makes no difference anyway. This code will sometimes get through 10, one test got to 34, before the 'subject' and 'to' are changed to the 'from' address, and cc and bcc headers added with the from address.

    * Instantiating email object outside of loop makes no difference
    * Unsetting email object makes no difference
    * adding a usleep appears(although still random) to allow you to send more emails before it stuffs up
    * adding echo $email->to after send will also have the from address set
    * once it stuffs up, all emails afterwards are stuffed - it's like it's setting a global switch to mess up all of the emails

    I'd also like to note that instantiating the email object outside of the loop causes even weirder behaviour when there is content, such as the subject getting set as the html body, and cc and bcc headers getting added with the html body

    This is nuts!!!

  • StuM
    Avatar
    Community Member
    56 Posts

    Re: [SOLVED kind of] Email corruption from inside loop Link to this post

    Ok, I submitted this issue to the bug tracker and it was dismissed as a non-issue. I then updated my versions Email.php. Mailer.php and SS_Viewer.php to the latest trunk versions, and it still is an issue.

    In the end, I created a basic class wrapper on Email, and replaced the processVariables function. There is a suspicious looking for loop in there that does alter all of the headers that are getting changed, so now I have:

    class GFEmail extends Email
    {
       
       /**
        * Load all the template variables into the internal variables, including
        * the template into body. Called before send() or debugSend()
        * $isPlain=true will cause the template to be ignored, otherwise the GenericEmail template will be used
        * and it won't be plain email
        */
       protected function parseVariables($isPlain = false) {
          if(!$this->parseVariables_done) {
             $this->parseVariables_done = true;

             // Parse $ variables in the base parameters
             $data = $this->templateData();
             
             /* nuked this
             foreach(array('from','to','subject','body', 'plaintext_body', 'cc', 'bcc') as $param) {
                $template = SSViewer::fromString($this->$param);
                $this->$param = $template->process($data);
             }
             */
             
             // Process a .SS template file
             $fullBody = $this->body;
             if($this->ss_template && !$isPlain) {
                // Requery data so that updated versions of To, From, Subject, etc are included
                $data = $this->templateData();
                
                $template = new SSViewer($this->ss_template);
                
                if($template->exists()) {
                   $fullBody = $template->process($data);
                }
             }
             
             // Rewrite relative URLs
             $this->body = HTTP::absoluteURLs($fullBody);
          }
       }
    }

    and all seems to be working fine for my needs, hopefully this can help somebody else if they experience the same issue.

    1073 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.