Оформление заказа в один шаг – xslt шаблонизатор
В данной статье будет описан принцип создания формы оформления заказа за один шаг, т.е. все необходимые данные, регистрационные данные покупателя, способ доставки, способ оплаты и т.д. представлены на одной страницы. Для использования информации в данной статье версия вашей системы должна быть не ниже 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>
который автоматически, через пол секунды нажмет кнопку подтверждения перехода на сайт платежной системы.