Оформление заказа в один шаг – tpl шаблонизатор
Актуально для 2.9.5
В данной статье будет описан принцип создания формы оформления заказа за один шаг, т.е. все необходимые данные, регистрационные данные покупателя, способ доставки, способ оплаты и т.д. представлены на одной страницы. Для использования информации в данной статье версия вашей системы должна быть не ниже 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) {
if(!$dataModule->saveEditedObject($addressId, true, true))
$dataModule->saveEditedObjectWithIgnorePermissions($addressId, true, true); // начиная с версии 2.9.5
}
$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">
</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().