Magento Order Confirmation Sent to All Customers – Troubleshooting

order-emailorderstransactional-mail

I see a strange behaviour in one of our shops: when an order is placed, the confirmation email is sent in CC to all registered customers that have an order in state "processing". It happens independent of the payment method (bank transfer and credit card are available) and the shipping method (only magento flat standard available).

The shop-setup is pretty basic with one website/store/store view. Installed extensions include nothing order- or checkout-related except the extension of the credit card's payment provider.

Best Answer

Attention!

What this code does is: every time the magento-cronjob removes all sent messages from the core_email_queue database table, it also removes all recipients of these messages. So, basically, it does not work for you until this cronjob-task has run at least once.

Solution

I found the answer thanks to another question here: the core_email_queue_recipients table was not emptied by the cronjob. The method Mage_Core_Model_Email_Queue::cleanQueue() calls Mage_Core_Model_Resource_Email_Queue::removeSentMessages(), which is pretty simple:

public function removeSentMessages() {
    $this->_getWriteAdapter()->delete($this->getMainTable(), 'processed_at IS NOT NULL');
    return $this;
}

Anyway, this method does not remove the old recipients. Thus, as soon as a new message with message_id n is queued, all old recipients with message_id n will also get the new email. The thing I don't understand is: why has the core team not seen this, and why doesn't this lead to more issues?

I wrote a small module to fix this. It uses a class override for Mage_Core_Model_Resource_Email_Queue, so if anybody can suggest a better (event-based?) solution, I would be glad.

app/code/local/Namespace/EmailQueueFix/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Namespace_EmailQueueFix>
            <version>1.0</version>
        </Namespace_EmailQueueFix>
    </modules>
    <global>
        <models>
            <core_resource>
                <rewrite>
                    <email_queue>Namespace_EmailQueueFix_Model_Resource_Email_Queue</email_queue>
                </rewrite>
            </core_resource>
        </models>
    </global>
</config>

app/code/local/Namespace/EmailQueueFix/Model/Resource/Email/Queue.php

<?php

class Namespace_EmailQueueFix_Model_Resource_Email_Queue extends Mage_Core_Model_Resource_Email_Queue {
    /**
     * Remove already sent messages
     * ADDED: also remove all recipients of sent messages!
     *
     * @return Mage_Core_Model_Resource_Email_Queue
     */
    public function removeSentMessages() {
        $writeAdapter = $this->_getWriteAdapter();
        $readAdapter = $this->_getReadAdapter();
        $select = $readAdapter->select()->from(array("ceqr" => $this->getTable('core/email_recipients')), array('*'))->joinLeft(array('ceq' => $this->getMainTable()), 'ceqr.message_id = ceq.message_id', array('*'))->where('ceq.processed_at IS NOT NULL OR ceq.message_id IS NULL');
        $recipients = $readAdapter->fetchAll($select);
        if ( $recipients ) {
            foreach ( $recipients as $recipient ) {
                $writeAdapter->delete($this->getTable('core/email_recipients'), "recipient_id = " . $recipient['recipient_id']);
            }
        }
        $writeAdapter->delete($this->getMainTable(), 'processed_at IS NOT NULL');
        return $this;
    }

}

app/etc/modules/Namespace_EmailQueueFix.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Namespace_EmailQueueFix>
            <codePool>local</codePool>
            <active>true</active>
        </Namespace_EmailQueueFix>
        <depends>
            <Mage_Core/>
        </depends>
    </modules>
</config>
Related Topic