Magento:cronjobsでのみ新しい注文メールを送信する


11

新しい注文メールを送信するにはどうすればよいですか。

$order->sendNewOrderEmail();

私のカスタムモジュールで使用されるcronjobからのみ。

手伝ってくれてありがとう。

回答:


8

無効にします System > Configuration > Sales Email > Order > Enabled

これにより、通常の実行中には送信されません

public function sendNewOrderEmail()
{
    $storeId = $this->getStore()->getId();

    if (!Mage::helper('sales')->canSendNewOrderEmail($storeId)) {
        return $this;
    }

次に、カスタムモジュールに次のようなものを含めます

    Mage::getConfig()->setNode(
        'default/'.Mage_Sales_Model_Order::XML_PATH_EMAIL_ENABLED, true
    );
    foreach(Mage::app()->getStores() as $storeCode=>$store){
        Mage::getConfig()->setNode(
            "stores/{$storeCode}/".Mage_Sales_Model_Order::XML_PATH_EMAIL_ENABLED, true
        );
    }
    $collection = Mage::getModel('sales/order')->getCollection()->addAttributeToFilter('email_sent', 0);
    foreach ($collection as $order){
        $order->sendNewOrderEmail();
    }

主なアイデアは、実行時に無効化された構成値をオーバーライドすることです。コードはテストされていませんが、開始点を提供するはずです。アランのブログからさらに読むことをお勧めします:http : //alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

発生する可能性のある問題の1つは、上記のキャッシュされた値です。

2番目のオプションは、sendNewOrderEmail()からのコードを複製することです。


天才。純粋で純粋な天才。
philwinkle 2013年

1
お世辞はどこでもあなたを得るでしょう;-)
クリストフはフーマンで2013年

3

この種の(根本的な)変更を行うことの本質は次のとおりです。

  • キューとして機能するようにsendNewOrderEmailを書き換え、キューモードに基づいて条件付きで送信/送信しない(以下のいくつかの疑似コードを参照)
  • 販売注文モデルのキューモードに基づいて、cronジョブから注文を読み込み、手動で電子メールを送信することにより、キューから電子メールを送信します。

販売注文モデルのサンプルコードを書き換えます。

次のコードは、呼び出されたテーブルの存在に依存し、yourmodule_sales_email_queueマジックゲッターでいくつかの列を参照します。これは完全に機能するコードではなく、一種の概念実証であるため、スキーマを提供するつもりはありません。動作モジュールではありません。

これをモジュールのetc / config.xmlに追加します。

<global>
    <model>
        <emailqueue>
            <class>YourCompany_YourModule_Model</class>
            <resourceModel>emailqueue_resource</resourceModel>
        </emailqueue>
        <emailqueue_resource>
            <class>YourCompany_YourModule_Model_Resource</class>
            <entities>
                <queue>
                    <table>yourmodule_sales_email_queue</table>
                </queue>
            </entities>
        </emailqueue_resource>
        <sales>
            <rewrite>
                <order>YourCompany_YourModule_Model_Order</order>
            </rewrite>
        </sales>
    </model>
</global>

app / code / local / YourCompany / YourModule / Model / Order.php

<?php

class YourCompany_YourModule_Model_Order extends Mage_Sales_Model_Order
{
    protected $_isQueueMode = false;

    public function sendNewOrderEmail()
    {       
        //send order email if our custom queue mode is set
        if($this->_isQueueMode){
            parent::sendNewOrderEmail();
            return;
        }

        //not running from queue, let's shove stuff into the queue
        $this->getEmailQueue()->load($this)->save();
    }


    public function getEmailQueue()
    {
        if(!isset($this->queue)){
            $this->queue = $this->_getEmailQueue();
        }
        return $this->queue;
    }

    protected function _getEmailQueue()
    {
        return Mage::getResourceModel('emailqueue/queue');
    }


}

そこから、リソースモデル、コレクション、およびcronワーカーを定義する必要があります。

etc / config.xmlのcron定義は次のようになります。

<crontab>
    <jobs>
        <emailqueue_send_order_emails>
            <schedule>
                <cron_expr>0 0 * * *</cron_expr>
            </schedule>
            <run>
                <model>emailqueue/observer::sendEmailsFromQueue</model>
            </run>
        </emailqueue_send_order_emails>
    </jobs>
</crontab>

これは、クラスからメソッドを呼び出しますYourCompany_YourModule_Model_Observer。キューから過去24時間のメールを読み込み、関連する注文を読み込み、フラグを設定してメールの送信を許可します。次にemail sendメソッドを呼び出します:

<?php

class YourCompany_YourModule_Model_Observer
{
    public function sendEmailsFromQueue($observer)
    {
        //load queue and define the run window
        $queue = Mage::getModel('emailqueue/queue')->getCollection()->getSelect()
                ->where('created_at',array('lt'=>Zend_Db_Expr('NOW()')))
                ->where('created_at',array('gt'=>Zend_Db_Expr('NOW() - INTERVAL 24 HOUR')));

        foreach($queue as $worker){
            //logic to send the email e.g.:
            $order = Mage::getModel('sales/order')->loadByIncrementId($worker->getOrderIncrementId());
            $order->_isQueueMode = true;
            $order->sendNewOrderEmail();
        }

    }
}

免責事項:

上記のコードはテストされておらず、それ自体では機能しないことに注意してください。コレクションのような多くの機能が存在することを期待ています。また、この回答を始めてから1回または2回これを処理する方法について考えが変わったので、私はそれをトップオブマインドで書いており、矛盾があるかもしれません

これは、キックスタートして、これをどのように達成するかについて考えることを意図しています。あなたの質問に喜んでお答えします。また、このタイプのモジュールのオープンソースバージョンにGithubで貢献したいと思っています。

がんばって!


これは@foomanのソリューションと比較して過度に設計されており、私は彼よりも彼の方が好きです:)
philwinkle 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.