Расширение класса проверки Magento OnePage - PullRequest
4 голосов
/ 21 мая 2011

Я добавляю дополнительное поле флажка к оформлению подписки на рассылку через новый модуль Magento.

Пока что я добавил код в файл макета (billing.phtml):

<p>Please untick this box if you do not wish to receive infrequent email updates and newsletters from us. <input type="checkbox" name="billing[is_subscribed]" title="" value="1" id="billing:is_subscribed" class="checkbox" checked="checked" /></p>

Я расширил класс (app/code/local/Clientname/Checkout/Model/Type/Onepage.php) - я расширил только метод сохранения:

<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     Mage_Checkout
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

/**
 * One page checkout processing model
 */

class Eatyourwords_Checkout_Model_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{

    public function saveBilling($data, $customerAddressId)
    {
        if (empty($data)) {
            return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
        }

        $address = $this->getQuote()->getBillingAddress();

        if (!empty($customerAddressId)) {
            $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
            if ($customerAddress->getId()) {
                if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
                    return array('error' => 1,
                        'message' => $this->_helper->__('Customer Address is not valid.')
                    );
                }
                $address->importCustomerAddress($customerAddress);
            }
        } else {
            // process billing address and validate form
            /* @var $addressForm Mage_Customer_Model_Form */
            $addressForm    = Mage::getModel('customer/form');
            $addressForm->setFormCode('customer_address_edit')
                ->setEntity($address)
                ->setEntityType('customer_address')
                ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
            // emulate request object
            $addressData    = $addressForm->extractData($addressForm->prepareRequest($data));
            $addressErrors  = $addressForm->validateData($addressData);
            if ($addressErrors !== true) {
                return array('error' => 1, 'message' => $addressErrors);
            }
            $addressForm->compactData($addressData);

            if (!empty($data['save_in_address_book'])) {
                $address->setSaveInAddressBook(1);
            }
        }

        // validate billing address
        if (($validateRes = $address->validate()) !== true) {
            return array('error' => 1, 'message' => $validateRes);
        }

        $address->implodeStreetAddress();

        if (true !== ($result = $this->_validateCustomerData($data))) {
            return $result;
        }

        if (!$this->getQuote()->getCustomerId() && self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
            if ($this->_customerEmailExists($address->getEmail(), Mage::app()->getWebsite()->getId())) {
                return array('error' => 1, 'message' => $this->_customerEmailExistsMessage);
            }
        }

        if (!$this->getQuote()->isVirtual()) {
            /**
             * Billing address using otions
             */
            $usingCase = isset($data['use_for_shipping']) ? (int)$data['use_for_shipping'] : 0;

            switch($usingCase) {
                case 0:
                    $shipping = $this->getQuote()->getShippingAddress();
                    $shipping->setSameAsBilling(0);
                    break;
                case 1:
                    $billing = clone $address;
                    $billing->unsAddressId()->unsAddressType();
                    $shipping = $this->getQuote()->getShippingAddress();
                    $shippingMethod = $shipping->getShippingMethod();
                    $shipping->addData($billing->getData())
                        ->setSameAsBilling(1)
                        ->setShippingMethod($shippingMethod)
                        ->setCollectShippingRates(true);
                    $this->getCheckout()->setStepData('shipping', 'complete', true);
                    break;
            }
        }

        $this->getQuote()->collectTotals();

        if (isset($data['is_subscribed'])) {
            $status = Mage::getModel(‘newsletter/subscriber’)->subscribe($data['email']);
        }

        $this->getQuote()->save();

        $this->getCheckout()
            ->setStepData('billing', 'allow', true)
            ->setStepData('billing', 'complete', true)
            ->setStepData('shipping', 'allow', true);

        return array();
    }

}

Специально к нижней части класса, который я вставил:

if (isset($data['is_subscribed'])) {
            $status = Mage::getModel(‘newsletter/subscriber’)->subscribe($data['email']);
        }

Я добавил файл, чтобы сообщить Magento о модуле (app/etc/modules/Clientname_Checkout.xml):

<?xml version="1.0"?>

<config>
    <modules>
        <Clientname_Checkout>
            <active>true</active>
            <codePool>local</codePool>
        </Clientname_Checkout>
    </modules>
</config>

Однако сейчас я застрял на последнем этапе того, как заставить Magento распознавать и использовать метод оповещения save_billing, который я расширил. Я думаю, что мне нужно добавить файл /app/code/local/Clientname/config.xml.

Но я не понимаю, как я настроил это так, чтобы новый класс сохранения использовался вместо оригинала.

Может кто-нибудь помочь с этим последним шагом?

Спасибо

Simon

1 Ответ

6 голосов
/ 23 мая 2011

Это учебный пример переопределений классов в Magento.Как вы, вероятно, знаете, Magento использует форму абстракции для загрузки классов, основанных на содержимом файлов конфигурации XML, разбитых вокруг кодовой базы.Это означает, что мы можем загрузить модель Mage_Checkout_Model_Type_Onepage, вызвав Mage::getModel('checkout/type_onepage') с конфигурацией по умолчанию.Довольно интересная функция - это возможность изменить отображение ссылки на модель, checkout/type_onepage на фактическое имя класса.

Структура каталогов

Итак, вы проделали тяжелую работу: редактированиешаблон и изменение метода модели.Далее вам нужно собрать небольшой модуль для переписывания классов.Основываясь на имени вашего класса, вам понадобится структура каталогов в форме:

/app
  /etc
    /modules
      /Eatyourwords_Checkout.xml
  /code
    /local
      /Eatyourwords
        /Checkout
          /etc
            /config.xml
          /Model
            /Type
              /Onepage.php

Выполнение перезаписи

Перезапись обрабатывается в файле конфигурации вашего модуля, config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <eyw_c>
            <version>1.0</version>
        </eyw_c>
    </modules>
    <global>
        <models>
            <eyw_c>Eatyourwords_Checkout_Model</eyw_c>
            <checkout>
                <rewrite>
                    <type_onepage>Eatyourwords_Checkout_Model_Type_Onepage</type_onepage>
                </rewrite>
            </checkout>
        </models>
    </global>
</config>

Материал в группе тегов <modules /> - это просто стандартная начальная загрузка модуля.

В разделе <models /> мы определяем пространство имен , которое будет использоваться при загрузке любого из наших классов Model.Подобно checkout/type_onepage, мы можем получить доступ к любым моделям, которые у нас есть в каталоге /Model, добавив eyw_c/*.

Затем мы откроем пространство имен модели Mage_Checkout, <checkout /> и выполнимпереписать класс checkout/type_onepage.Теперь, когда Magento пытается загрузить checkout/type_onepage, он будет искать наш класс.Все остальные классы checkout/* не будут затронуты.Имя класса для них будет построено обычным способом.

Включите модуль

Далее нам нужно указать Magento на новый модуль, который мы создали.Ваша попытка была почти правильной.Вы должны назвать это Eatyourwords_Checkout.xml и поместить его в /app/etc/modules:

<?xml version="1.0"?>
<config>
    <modules>
        <Eatyourwords_Checkout>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Checkout />
            </depends>
        </Eatyourwords_Checkout>
    </modules>
</config>

.. и все готово.Класс переопределен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...