Оформление заказа в один шаг – tpl шаблонизатор

Материал из Umicms
Перейти к:навигация, поиск

В данной статье будет описан принцип создания формы оформления заказа за один шаг, т.е. все необходимые данные, регистрационные данные покупателя, способ доставки, способ оплаты и т.д. представлены на одной страницы. Для использования информации в данной статье версия вашей системы должна быть не ниже 2.8.4.3, иначе код не будет нормально функционировать при наличии в модуле Интернет-магазин способа доставки Курьером, и способа оплаты "Курьером при получении".


Нам понадобятся дополнительные php-методы для реализации данной задачи, которые необходимо добавить в файл classes/modules/emarket/__custom.php, сами методы следующие:

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', 'paymentsList', 'personalInfo', 'saveinfo'));
?>

Необходимо создать шаблон tpls/emarket/delivery/onestep.tpl:

<?php
$FORMS = Array();

$FORMS['delivery_block'] = <<<END
	Выберите подходящий вам способ доставки:
	<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;

?>


Шаблон 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')%
        <input type="radio" name="delivery-address" value="new" /> Новый адрес доставки:
	<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().