Оформление заказа в один шаг – tpl шаблонизатор
Материал из Umicms
В данной статье будет описан принцип создания формы оформления заказа за один шаг, т.е. все необходимые данные, регистрационные данные покупателя, способ доставки, способ оплаты и т.д. представлены на одной страницы. Для использования информации в данной статье версия вашей системы должна быть не ниже 2.8.4.3, иначе код не будет нормально функционировать при наличии в модуле Интернет-магазин способа доставки Курьером, и способа оплаты "Курьером при получении".
Нам понадобятся дополнительные php-методы для реализации данной задачи, которые необходимо добавить в файл classes/modules/emarket/__custom.php, сами методы следующие:
public function deliveryAddressesList($template = 'default'){ $order = $this->getBasketOrder(false); list($tpl_block, $tpl_item) = def_module::loadTemplates("./tpls/emarket/delivery/{$template}.tpl", 'delivery_address_block', 'delivery_address_item'); $customer = customer::get(); $addresses = $customer->delivery_addresses; $items_arr = array(); $currentDeliveryId = $order->getValue('delivery_address'); $collection = umiObjectsCollection::getInstance(); if(is_array($addresses)) foreach($addresses as $address) { $addressObject = $collection->getObject($address); $item_arr = array( 'attribute:id' => $address, 'attribute:name' => $addressObject->name ); if($address == $currentDeliveryId) $item_arr['attribute:active'] = 'active'; $items_arr[] = def_module::parseTemplate($tpl_item, $item_arr, false, $address); } $types = umiObjectTypesCollection::getInstance(); $typeId = $types->getBaseType("emarket", "delivery_address"); if($tpl_block) { return def_module::parseTemplate($tpl_block, array('items' => $items_arr, 'type_id' => $typeId)); } } public function deliveryList($template = 'default') { $order = $this->getBasketOrder(false); list($tpl_block, $tpl_item_free, $tpl_item_priced) = def_module::loadTemplates("./tpls/emarket/delivery/{$template}.tpl", 'delivery_block', 'delivery_item_free', 'delivery_item_priced'); if(!isset($_SESSION['emarket'])) $_SESSION['emarket'] = array(); if(!isset($_SESSION['emarket']['delivery'])) $_SESSION['emarket']['delivery'] = array(); $deliveryIds = delivery::getList(); $items_arr = array(); $currentDeliveryId = $order->getValue('delivery_id'); foreach($deliveryIds as $delivery) { $delivery = delivery::get($delivery); if($delivery->validate($order) == false) { continue; } $deliveryObject = $delivery->getObject(); $deliveryPrice = $delivery->getDeliveryPrice($order); $_SESSION['emarket']['delivery'][$delivery->id] = (float)$deliveryPrice; $item_arr = array( 'attribute:id' => $deliveryObject->id, 'attribute:name' => $deliveryObject->name, 'attribute:price' => $deliveryPrice.'', 'xlink:href' => $deliveryObject->xlink ); if($delivery->id == $currentDeliveryId) $item_arr['attribute:active'] = 'active'; $tpl_item = $deliveryPrice ? $tpl_item_priced : $tpl_item_free; $items_arr[] = def_module::parseTemplate($tpl_item, $item_arr, false, $deliveryObject->id); } if($tpl_block) { return def_module::parseTemplate($tpl_block, array('items' => $items_arr)); } else { return array('items' => array('nodes:item' => $items_arr)); } } public function paymentsList($template = 'default') { $order = $this->getBasketOrder(false); 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); } if($tpl_block) { return def_module::parseTemplate($tpl_block, array('items' => $items_arr)); } else { return array('items' => array('nodes:item' => $items_arr)); } } public function personalInfo($template = 'default') { if (!permissionsCollection::getInstance()->isAuth()){ $customerId = customer::get()->id; $cmsController = cmsController::getInstance(); $data = $cmsController->getModule('data'); return $data->getEditForm($customerId, $template); }else return ''; } 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('deliveryList', 'deliveryAddressesList', 'paymentsList', 'personalInfo', 'saveinfo')); ?>
Необходимо создать шаблон tpls/emarket/delivery/onestep.tpl:
<?php $FORMS = Array(); $FORMS['delivery_block'] = <<<END <h3 class="dost">Выберите подходящий вам способ доставки:</h3> <ul> %items% </ul> END; $FORMS['delivery_item_free'] = <<<END <li><input type="radio" name="delivery-id" value="%id%" checked="checked" /> %name% - бесплатно</li> END; $FORMS['delivery_item_priced'] = <<<END <li><input type="radio" name="delivery-id" value="%id%" /> %name% - %price%</li> END; $FORMS['delivery_address_block'] = <<<END <div class="adrest"> <h3 class="dost">Выберите подходящий вам адрес доставки:</h3> <ul> %items% <li> <input type="radio" name="delivery-address" value="new" /> <b>Новый адрес доставки:</b> <table cellspacing="1" cellpadding="1" width="100%" border="0"> %data getCreateForm(%type_id%, 'onestep')% </table> </li> </ul> </div> END; $FORMS['delivery_address_item'] = <<<END <li><input type="radio" name="delivery-address" value="%id%" />%index%, %city%, %street%, д. %house%, кв. %flat%</li> END; ?>
Шаблон tpls/emarket/payment/onestep.tpl:
<?php $FORMS = Array(); $FORMS['payment_block'] = <<<END Выберите подходящий вам способ оплаты: <ul> %items% </ul> END; $FORMS['payment_item'] = <<<END <li><input type="radio" name="payment-id" value="%id%" /> %name%</li> END; ?>
Шаблон tpls/data/reflection/onestep.tpl:
<?php $FORMS = Array(); $FORMS['reflection_block'] = <<<END %groups% END; $FORMS['reflection_group'] = <<<END <tr> <td colspan="2"> <br/><br /><b>%title%</b><br /><br /> </td> </tr> %fields% END; $FORMS['reflection_field_string'] = <<<END <tr> <td> %title%%required_asteriks%: </td> <td> <input type="text" name="%input_name%" value="%value%" class="textinputs" /> </td> </tr> END; $FORMS['reflection_field_text'] = <<<END <tr> <td> %title%%required_asteriks%: </td> <td> <textarea name="%input_name%" class="textinputs">%value%</textarea> </td> </tr> END; $FORMS['reflection_field_int'] = <<<END <tr> <td> %title%%required_asteriks%: </td> <td> <input type="text" name="%input_name%" value="%value%" class="textinputs" /> </td> </tr> END; $FORMS['reflection_field_relation'] = <<<END <tr> <td> %title%%required_asteriks%: </td> <td> <select name="%input_name%" style="width: 205px" class="textinputs"> <option /> %options% </select> </td> </tr> END; $FORMS['reflection_field_relation_option'] = <<<END <option value="%id%">%name%</option> END; $FORMS['reflection_field_relation_option_a'] = <<<END <option value="%id%" selected="selected">%name%</option> END; ?>
В шаблоне tpls/emarket/default.tpl, в блоке order_block, форма должна быть примерно следующая:
<form action="%pre_lang%/emarket/saveinfo/"> %emarket deliveryList('onestep')% %emarket deliveryAddressesList('onestep')% <p></p> <table cellspacing="1" cellpadding="1" width="100%" border="0"> %data getCreateForm(5, 'onestep')% </table> <br/> %emarket paymentsList('onestep')% <br/> <table cellspacing="1" cellpadding="1" width="100%" border="0"> %emarket personalInfo('onestep')% </table> <br/> <input type="submit" value="Оформить заказ" /> </form>
В макросе data getCreateForm(), первый параметр это id типа данных "Адрес доставки" в модуле "Шаблоны данных", первая вкладка, раздел "Справочники", этот id вы должны для вашей системы определить самостоятельно и подставить в макрос data getCreateForm().
