Оформление заказа в один шаг – xslt шаблонизатор
Материал из Umicms
В данной статье будет описан принцип создания формы оформления заказа за один шаг, т.е. все необходимые данные, регистрационные данные покупателя, способ доставки, способ оплаты и т.д. представлены на одной страницы. Для использования информации в данной статье версия вашей системы должна быть не ниже 2.8.4.3, иначе код не будет нормально функционировать при наличии в модуле Интернет-магазин способа доставки Курьером, и способа оплаты "Курьером при получении".
Нам понадобятся дополнительные php-методы для реализации данной задачи, которые необходимо добавить в файл classes/modules/emarket/__custom.php, сами методы следующие:
public function fast_purchasing_xslt(){ $order = $this->getBasketOrder(); $orderId = $order->id; $customer = selector::get('object')->id($order->customer_id); $result = array( 'attribute:id' => ($orderId), 'xlink:href' => ('uobject://' . $orderId)); if(!permissionsCollection::getInstance()->isAuth()){ $result['customer'] = array('full:object' => $customer); } $result['delivery'] = $this->customerDeliveryList('notemplate'); $result['delivery_choose'] = $this->renderDeliveryList($order, 'notemplate'); $result['payment'] = $this->renderPaymentsList_custom($order, 'notemplate'); return $result; } public function renderPaymentsList_custom(order $order, $template) { list($tpl_block, $tpl_item) = def_module::loadTemplates("./tpls/emarket/payment/{$template}.tpl", 'payment_block', 'payment_item'); $payementIds = payment::getList(); $items_arr = array(); $currentPaymentId = $order->getValue('payment_id'); foreach($payementIds as $paymentId) { $payment = payment::get($paymentId); if($payment->validate($order) == false) continue; $paymentObject = $payment->getObject(); $paymentTypeId = $paymentObject->getValue('payment_type_id'); $paymentTypeName = umiObjectsCollection::getInstance()->getObject($paymentTypeId)->getValue('class_name'); if( $paymentTypeName == 'social') continue; $item_arr = array( 'attribute:id' => $paymentObject->id, 'attribute:name' => $paymentObject->name, 'attribute:type-name' => $paymentTypeName, 'xlink:href' => $paymentObject->xlink ); if($paymentId == $currentPaymentId) { $item_arr['attribute:active'] = 'active'; } $items_arr[] = def_module::parseTemplate($tpl_item, $item_arr, false, $paymentObject->id); } return array('items' => array('nodes:item' => $items_arr)); } public function saveinfo(){ $order = $this->getBasketOrder(false); //сохранение регистрационных данных $cmsController = cmsController::getInstance(); $data = $cmsController->getModule('data'); $data->saveEditedObject(customer::get()->id, false, true); //сохранение способа доставки $deliveryId = getRequest('delivery-id'); if($deliveryId){ $delivery = delivery::get($deliveryId); $deliveryPrice = (float) $delivery->getDeliveryPrice($order); $order->setValue('delivery_id', $deliveryId); $order->setValue('delivery_price', $deliveryPrice); } //сохранение адреса доставки $addressId = getRequest('delivery-address'); if($addressId == 'new') { $collection = umiObjectsCollection::getInstance(); $types = umiObjectTypesCollection::getInstance(); $typeId = $types->getBaseType("emarket", "delivery_address"); $customer = customer::get(); $addressId = $collection->addObject("Address for customer #".$customer->id, $typeId); $dataModule = $cmsController->getModule("data"); if($dataModule) { $dataModule->saveEditedObject($addressId, true, true); } $customer->delivery_addresses = array_merge( $customer->delivery_addresses, array($addressId) ); } $order->delivery_address = $addressId; //сохранение способа оплаты и редирект на итоговую страницу, либо страницу подтверждения оплаты. $order->setValue('payment_id', getRequest('payment-id')); $order->refresh(); $paymentId = getRequest('payment-id'); if(!$paymentId) { $this->errorNewMessage(getLabel('error-emarket-choose-payment')); $this->errorPanic(); } $payment = payment::get($paymentId); if($payment instanceof payment) { $paymentName = $payment->getCodeName(); $url = "{$this->pre_lang}/".cmsController::getInstance()->getUrlPrefix()."emarket/purchase/payment/{$paymentName}/"; } else { $url = "{$this->pre_lang}/".cmsController::getInstance()->getUrlPrefix()."emarket/cart/"; } $this->redirect($url); }
также в папку classes/modules/emarket/ необходимо добавить файл permissions.custom.php следующего содержания:
<?php $permissions = array('purchasing' => array('fast_purchasing_xslt', 'saveinfo')); ?>
На системной странице /emarket/cart/, либо какой-либо другой, подобным вызовом: udata://emarket/fast_purchasing_xslt/
мы получим все необходимые данные для составления формы оформления заказа, данные будут примерно в следующем виде:
<?xml version="1.0" encoding="utf-8"?> <udata xmlns:xlink="http://www.w3.org/TR/xlink" id="550931" xlink:href="uobject://550931" module="emarket" method="fast_purchasing_xslt" > <customer> <object id="550930" name="127.0.0.1" type-id="74" type-guid="emarket-customer"/> </customer> <delivery type-id="5" xlink:href="udata://data/getCreateForm/5"> <items/> </delivery> <delivery_choose> <items> <item id="304" name="Самовывоз" price="0" xlink:href="uobject://304"/> <item id="305" name="Курьерская доставка" price="200" xlink:href="uobject://305"/> </items> </delivery_choose> <payment> <items> <item id="344" name="Платежная квитанция" type-name="receipt" xlink:href="uobject://344"/> </items> </payment> </udata>
Action формы для оплаты должен быть = /emarket/saveinfo/.
В случае если вы используете в качестве основы демо-сайт Современный или нет,
примеры шаблонов обработки xml-данных можно найти на этом демо-сайте, в папке:
/xsltTpls/modules/emarket/purchase/
- required.xsl – форма редактирования данных Незарегистрированного покупателя.
- delivery.xsl – добавления адреса доставки и выбор способа доставки.
- payment.xsl – выбор способа оплаты и шаг подтверждения оплаты.
При создании блока добавления адреса доставки, не забывайте указывать input:
<input checked="checked" name="delivery-address" value="new" type="radio">
В формах подтверждения оплаты, можно указать id формы =begin, и добавить скрипт:
<script>setTimeout('document.getElementById("search").submit()', 500);</script>
который автоматически, через пол секунды нажмет кнопку подтверждения перехода на сайт платежной системы.
