마 젠토 : cronjobs로만 새 주문 이메일 보내기 주문 이메일을 보내려면 어떻게해야합니까? $order->sendNewOrderEmail(); 내 사용자 정의 모듈에서

다음을 사용하여 새 주문 이메일을 보내려면 어떻게해야합니까?

$order->sendNewOrderEmail();

내 사용자 정의 모듈에서 사용되는 크론 작업에서만.

도움에 감사드립니다.



답변

나는 비활성화 할 것이다 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();
    }

주요 아이디어는 런타임에 비활성화 된 구성 값을 재정의하는 것입니다. 코드는 테스트되지 않았지만 시작점을 제공해야합니다. Alan의 블로그 ( http://alanstorm.com/magento_loading_config_variables
http://alanstorm.com/magento_config_a_critique_and_caching) 에서 읽을 것을 권장합니다.

발생할 수있는 한 가지 문제는 위의 캐시 된 값입니다.

두 번째 옵션은 sendNewOrderEmail ()에서 코드를 복제하는 것입니다.


답변

이런 종류의 (급진적) 변화를 만드는 본질은 다음과 같습니다.

  • sendNewOrderEmail을 대기열로 사용하고 대기열 모드를 기반으로 조건에 따라 전송 / 비 전송을 재 작성하십시오 (아래의 의사 코드 참조).
  • 판매 주문 모델의 대기열 모드에 따라 크론 작업에서 주문을로드하고 수동으로 전자 메일을 보내 대기열에서 전자 메일을 보냅니다.

판매 주문 모델 재 작성에 대한 일부 샘플 코드 :

다음 코드는 테이블의 존재 여부에 따라 다르며 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();
        }

    }
}

기권:

위 코드는 테스트 되지 않았 으며 자체적으로 작동하지 않습니다 . 컬렉션과 같은 많은 기능이 존재할 것으로 기대 합니다. 또한 이 답변을 시작한 후이 문제를 한 번 또는 두 번 처리하는 방법에 대한 내 생각을 바꿨 으므로 마음에 그것을 썼고 불일치 가있을 수 있습니다 .

이것은 당신이 킥 스타트하고 당신이 이것을 달성 할 방법에 대해 생각하게하기위한 것입니다. 궁금한 점이 있으면 기꺼이 답변 해 드리겠습니다. 또한이 유형의 모듈의 오픈 소스 버전에 Github에 기꺼이 기여할 것입니다.

행운을 빕니다!


답변