我在我们的一家商店中看到一种奇怪的行为:下订单时,确认电子邮件将以抄送方式发送给状态为“处理中”的所有注册客户。它的发生与付款方式(可使用银行转帐和信用卡)和运输方式(仅适用于magento flat标准)无关。
商店设置非常简单,只有一个网站/商店/商店视图。除信用卡付款提供商的扩展名外,已安装的扩展名不包含任何与订单或结帐相关的信息。
我在我们的一家商店中看到一种奇怪的行为:下订单时,确认电子邮件将以抄送方式发送给状态为“处理中”的所有注册客户。它的发生与付款方式(可使用银行转帐和信用卡)和运输方式(仅适用于magento flat标准)无关。
商店设置非常简单,只有一个网站/商店/商店视图。除信用卡付款提供商的扩展名外,已安装的扩展名不包含任何与订单或结帐相关的信息。
Answers:
注意!
这段代码的作用是:每次magento-cronjob从core_email_queue数据库表中删除所有已发送的消息时,它也会同时删除这些消息的所有收件人。因此,基本上,直到此cronjob任务至少运行了一次,它才对您不起作用。
解
由于这里有另一个问题,我找到了答案:cronjob没有清空core_email_queue_recipients表。该方法Mage_Core_Model_Email_Queue::cleanQueue()
调用Mage_Core_Model_Resource_Email_Queue::removeSentMessages()
,非常简单:
public function removeSentMessages() {
$this->_getWriteAdapter()->delete($this->getMainTable(), 'processed_at IS NOT NULL');
return $this;
}
无论如何,此方法不会删除旧的收件人。因此,一旦新邮件以message_id n排队,所有旧邮件以message_id n接收也将收到新电子邮件。我不明白的是:为什么核心团队没有看到这一点,为什么这不会导致更多问题?
我写了一个小模块来解决这个问题。它为使用了一个类重写Mage_Core_Model_Resource_Email_Queue
,因此,如果有人可以提出更好的(基于事件的?)解决方案,我将很高兴。
应用程序/代码/本地/命名空间/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>
应用程序/代码/本地/命名空间/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>
我发布了一个不需要安装新模块的其他修复程序,它可能更清洁一些。
它仅对core_email_queue_recipients表使用外键约束来删除级联上的收件人记录。
通过使用此新的外键,在清理core_email_queue表时,core_email_queue_recipients表上不会留下任何孤立的记录,因此不会将重复的消息进一步发送给错误的收件人。
您可以在此职位上找到详细的解决方案:https : //magento.stackexchange.com/a/87299/23057
这是数据库中索引的问题。您可以使用Magento数据库修复工具对其进行修复。
http://merch.docs.magento.com/ce/user_guide/magento/database-repair-tool.html
这个问题使我很沮丧。就我而言,它源自版本升级。每次进行版本升级以在另一个目录和新的空引用数据库中进行全新安装时,都是一种好的做法,然后使用该工具来比较数据库中的结构和索引是否声明为新的空目录。参考数据库。新版本需要这种结构!请注意,该问题不是索引错误,并且无法通过重新索引解决。我认为更多是缺少索引的问题。运行该工具之前,请始终保留数据库的备份副本!遗憾的是,即使重新安装了Magento,也没有提供数据库的索引和结构验证作为选项,您必须按照上述步骤进行操作。(就我而言,是从1.8版升级到1.9版)。