PageRenderTime 81ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/controllers/front/ParentOrderController.php

https://bitbucket.org/enurkov/prestashop
PHP | 565 lines | 420 code | 64 blank | 81 comment | 101 complexity | 3383a88febff31e9ddecb77bd73bf668 MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2012 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2012 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. /**
  27. * Class FreeOrder to use PaymentModule (abstract class, cannot be instancied)
  28. */
  29. class FreeOrder extends PaymentModule
  30. {
  31. public $active = 1;
  32. }
  33. class ParentOrderControllerCore extends FrontController
  34. {
  35. public $ssl = true;
  36. public $php_self = 'order';
  37. public $nbProducts;
  38. /**
  39. * Initialize parent order controller
  40. * @see FrontController::init()
  41. */
  42. public function init()
  43. {
  44. $this->isLogged = (bool)($this->context->customer->id && Customer::customerIdExistsStatic((int)$this->context->cookie->id_customer));
  45. parent::init();
  46. /* Disable some cache related bugs on the cart/order */
  47. header('Cache-Control: no-cache, must-revalidate');
  48. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
  49. $this->nbProducts = $this->context->cart->nbProducts();
  50. global $isVirtualCart;
  51. if (!$this->context->customer->isLogged(true) && $this->context->getMobileDevice() && Tools::getValue('step'))
  52. Tools::redirect($this->context->link->getPageLink('authentication', true, (int)$this->context->language->id, $params));
  53. // Redirect to the good order process
  54. if (Configuration::get('PS_ORDER_PROCESS_TYPE') == 0 && Dispatcher::getInstance()->getController() != 'order')
  55. Tools::redirect('index.php?controller=order');
  56. if (Configuration::get('PS_ORDER_PROCESS_TYPE') == 1 && Dispatcher::getInstance()->getController() != 'orderopc')
  57. {
  58. if (isset($_GET['step']) && $_GET['step'] == 3)
  59. Tools::redirect('index.php?controller=order-opc&isPaymentStep=true');
  60. Tools::redirect('index.php?controller=order-opc');
  61. }
  62. if (Configuration::get('PS_CATALOG_MODE'))
  63. $this->errors[] = Tools::displayError('This store has not accepted your new order.');
  64. if (Tools::isSubmit('submitReorder') && $id_order = (int)Tools::getValue('id_order'))
  65. {
  66. $oldCart = new Cart(Order::getCartIdStatic($id_order, $this->context->customer->id));
  67. $duplication = $oldCart->duplicate();
  68. if (!$duplication || !Validate::isLoadedObject($duplication['cart']))
  69. $this->errors[] = Tools::displayError('Sorry, we cannot renew your order.');
  70. else if (!$duplication['success'])
  71. $this->errors[] = Tools::displayError('Some items are not available, we are unable to renew your order');
  72. else
  73. {
  74. $this->context->cookie->id_cart = $duplication['cart']->id;
  75. $this->context->cookie->write();
  76. if (Configuration::get('PS_ORDER_PROCESS_TYPE') == 1)
  77. Tools::redirect('index.php?controller=order-opc');
  78. Tools::redirect('index.php?controller=order');
  79. }
  80. }
  81. if ($this->nbProducts)
  82. {
  83. if (CartRule::isFeatureActive())
  84. {
  85. if (Tools::isSubmit('submitAddDiscount'))
  86. {
  87. if (!($code = trim(Tools::getValue('discount_name'))))
  88. $this->errors[] = Tools::displayError('You must enter a voucher code');
  89. elseif (!Validate::isCleanHtml($code))
  90. $this->errors[] = Tools::displayError('Voucher code invalid');
  91. else
  92. {
  93. if (($cartRule = new CartRule(CartRule::getIdByCode($code))) && Validate::isLoadedObject($cartRule))
  94. {
  95. if ($error = $cartRule->checkValidity($this->context, false, true))
  96. $this->errors[] = $error;
  97. else
  98. {
  99. $this->context->cart->addCartRule($cartRule->id);
  100. Tools::redirect('index.php?controller=order-opc');
  101. }
  102. }
  103. else
  104. $this->errors[] = Tools::displayError('This voucher does not exists');
  105. }
  106. $this->context->smarty->assign(array(
  107. 'errors' => $this->errors,
  108. 'discount_name' => Tools::safeOutput($code)
  109. ));
  110. }
  111. elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) && Validate::isUnsignedId($id_cart_rule))
  112. {
  113. $this->context->cart->removeCartRule($id_cart_rule);
  114. Tools::redirect('index.php?controller=order-opc');
  115. }
  116. }
  117. /* Is there only virtual product in cart */
  118. if ($isVirtualCart = $this->context->cart->isVirtualCart())
  119. $this->setNoCarrier();
  120. }
  121. $this->context->smarty->assign('back', Tools::safeOutput(Tools::getValue('back')));
  122. }
  123. public function setMedia()
  124. {
  125. parent::setMedia();
  126. if ($this->context->getMobileDevice() == false)
  127. {
  128. // Adding CSS style sheet
  129. $this->addCSS(_THEME_CSS_DIR_.'addresses.css');
  130. // Adding JS files
  131. $this->addJS(_THEME_JS_DIR_.'tools.js');
  132. if ((Configuration::get('PS_ORDER_PROCESS_TYPE') == 0 && Tools::getValue('step') == 1) || Configuration::get('PS_ORDER_PROCESS_TYPE') == 1)
  133. $this->addJS(_THEME_JS_DIR_.'order-address.js');
  134. $this->addJqueryPlugin('fancybox');
  135. if ((int)(Configuration::get('PS_BLOCK_CART_AJAX')) || Configuration::get('PS_ORDER_PROCESS_TYPE') == 1)
  136. {
  137. $this->addJS(_THEME_JS_DIR_.'cart-summary.js');
  138. $this->addJqueryPlugin('typewatch');
  139. }
  140. }
  141. }
  142. /**
  143. * Check if order is free
  144. * @return boolean
  145. */
  146. protected function _checkFreeOrder()
  147. {
  148. if ($this->context->cart->getOrderTotal() <= 0)
  149. {
  150. $order = new FreeOrder();
  151. $order->free_order_class = true;
  152. $order->validateOrder($this->context->cart->id, Configuration::get('PS_OS_PAYMENT'), 0, Tools::displayError('Free order', false), null, array(), null, false, $this->context->cart->secure_key);
  153. return (int)Order::getOrderByCartId($this->context->cart->id);
  154. }
  155. return false;
  156. }
  157. protected function _updateMessage($messageContent)
  158. {
  159. if ($messageContent)
  160. {
  161. if (!Validate::isMessage($messageContent))
  162. $this->errors[] = Tools::displayError('Invalid message');
  163. else if ($oldMessage = Message::getMessageByCartId((int)($this->context->cart->id)))
  164. {
  165. $message = new Message((int)($oldMessage['id_message']));
  166. $message->message = htmlentities($messageContent, ENT_COMPAT, 'UTF-8');
  167. $message->update();
  168. }
  169. else
  170. {
  171. $message = new Message();
  172. $message->message = htmlentities($messageContent, ENT_COMPAT, 'UTF-8');
  173. $message->id_cart = (int)($this->context->cart->id);
  174. $message->id_customer = (int)($this->context->cart->id_customer);
  175. $message->add();
  176. }
  177. }
  178. else
  179. {
  180. if ($oldMessage = Message::getMessageByCartId($this->context->cart->id))
  181. {
  182. $message = new Message($oldMessage['id_message']);
  183. $message->delete();
  184. }
  185. }
  186. return true;
  187. }
  188. protected function _processCarrier()
  189. {
  190. $this->context->cart->recyclable = (int)(Tools::getValue('recyclable'));
  191. $this->context->cart->gift = (int)(Tools::getValue('gift'));
  192. if ((int)(Tools::getValue('gift')))
  193. {
  194. if (!Validate::isMessage($_POST['gift_message']))
  195. $this->errors[] = Tools::displayError('Invalid gift message');
  196. else
  197. $this->context->cart->gift_message = strip_tags($_POST['gift_message']);
  198. }
  199. if (isset($this->context->customer->id) && $this->context->customer->id)
  200. {
  201. $address = new Address((int)($this->context->cart->id_address_delivery));
  202. if (!($id_zone = Address::getZoneById($address->id)))
  203. $this->errors[] = Tools::displayError('No zone matches your address');
  204. }
  205. else
  206. $id_zone = Country::getIdZone((int)Configuration::get('PS_COUNTRY_DEFAULT'));
  207. if (Tools::getIsset('delivery_option'))
  208. {
  209. if ($this->validateDeliveryOption(Tools::getValue('delivery_option')))
  210. $this->context->cart->setDeliveryOption(Tools::getValue('delivery_option'));
  211. }
  212. elseif (Tools::getIsset('id_carrier'))
  213. {
  214. // For retrocompatibility reason, try to transform carrier to an delivery option list
  215. $delivery_option_list = $this->context->cart->getDeliveryOptionList();
  216. if (count($delivery_option_list) == 1)
  217. {
  218. $delivery_option = reset($delivery_option_list);
  219. $key = Cart::desintifier(Tools::getValue('id_carrier'));
  220. foreach ($delivery_option_list as $id_address => $options)
  221. if (isset($options[$key]))
  222. $this->context->cart->setDeliveryOption(array($id_address => $key));
  223. }
  224. }
  225. Hook::exec('actionCarrierProcess', array('cart' => $this->context->cart));
  226. if (!$this->context->cart->update())
  227. return false;
  228. // Carrier has changed, so we check if the cart rules still apply
  229. CartRule::autoRemoveFromCart($this->context);
  230. CartRule::autoAddToCart($this->context);
  231. return true;
  232. }
  233. /**
  234. * Validate get/post param delivery option
  235. * @param array $delivery_option
  236. */
  237. protected function validateDeliveryOption($delivery_option)
  238. {
  239. if (!is_array($delivery_option))
  240. return false;
  241. foreach ($delivery_option as $option)
  242. if (!preg_match('/(\d+,)?\d+/', $option))
  243. return false;
  244. return true;
  245. }
  246. protected function _assignSummaryInformations()
  247. {
  248. $summary = $this->context->cart->getSummaryDetails();
  249. $customizedDatas = Product::getAllCustomizedDatas($this->context->cart->id);
  250. // override customization tax rate with real tax (tax rules)
  251. if ($customizedDatas)
  252. {
  253. foreach ($summary['products'] as &$productUpdate)
  254. {
  255. $productId = (int)(isset($productUpdate['id_product']) ? $productUpdate['id_product'] : $productUpdate['product_id']);
  256. $productAttributeId = (int)(isset($productUpdate['id_product_attribute']) ? $productUpdate['id_product_attribute'] : $productUpdate['product_attribute_id']);
  257. if (isset($customizedDatas[$productId][$productAttributeId]))
  258. $productUpdate['tax_rate'] = Tax::getProductTaxRate($productId, $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
  259. }
  260. Product::addCustomizationPrice($summary['products'], $customizedDatas);
  261. }
  262. $cart_product_context = Context::getContext()->cloneContext();
  263. foreach ($summary['products'] as $key => &$product)
  264. {
  265. $product['quantity'] = $product['cart_quantity'];// for compatibility with 1.2 themes
  266. if ($cart_product_context->shop->id != $product['id_shop'])
  267. $cart_product_context->shop = new Shop((int)$product['id_shop']);
  268. $product['price_without_specific_price'] = Product::getPriceStatic(
  269. $product['id_product'],
  270. !Product::getTaxCalculationMethod(),
  271. $product['id_product_attribute'],
  272. 2,
  273. null,
  274. false,
  275. false,
  276. 1,
  277. false,
  278. null,
  279. null,
  280. null,
  281. $null,
  282. true,
  283. true,
  284. $cart_product_context);
  285. if (Product::getTaxCalculationMethod())
  286. $product['is_discounted'] = $product['price_without_specific_price'] != $product['price'];
  287. else
  288. $product['is_discounted'] = $product['price_without_specific_price'] != $product['price_wt'];
  289. }
  290. // Get available cart rules and unset the cart rules already in the cart
  291. $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart);
  292. $cart_cart_rules = $this->context->cart->getCartRules();
  293. foreach ($available_cart_rules as $key => $available_cart_rule)
  294. {
  295. if (strpos($available_cart_rule['code'], 'BO_ORDER_') === 0)
  296. {
  297. unset($available_cart_rules[$key]);
  298. continue;
  299. }
  300. foreach ($cart_cart_rules as $cart_cart_rule)
  301. if ($available_cart_rule['id_cart_rule'] == $cart_cart_rule['id_cart_rule'])
  302. {
  303. unset($available_cart_rules[$key]);
  304. continue 2;
  305. }
  306. }
  307. $show_option_allow_separate_package = (!$this->context->cart->isAllProductsInStock(true) && Configuration::get('PS_SHIP_WHEN_AVAILABLE'));
  308. $this->context->smarty->assign($summary);
  309. $this->context->smarty->assign(array(
  310. 'token_cart' => Tools::getToken(false),
  311. 'isLogged' => $this->isLogged,
  312. 'isVirtualCart' => $this->context->cart->isVirtualCart(),
  313. 'productNumber' => $this->context->cart->nbProducts(),
  314. 'voucherAllowed' => CartRule::isFeatureActive(),
  315. 'shippingCost' => $this->context->cart->getOrderTotal(true, Cart::ONLY_SHIPPING),
  316. 'shippingCostTaxExc' => $this->context->cart->getOrderTotal(false, Cart::ONLY_SHIPPING),
  317. 'customizedDatas' => $customizedDatas,
  318. 'CUSTOMIZE_FILE' => Product::CUSTOMIZE_FILE,
  319. 'CUSTOMIZE_TEXTFIELD' => Product::CUSTOMIZE_TEXTFIELD,
  320. 'lastProductAdded' => $this->context->cart->getLastProduct(),
  321. 'displayVouchers' => $available_cart_rules,
  322. 'currencySign' => $this->context->currency->sign,
  323. 'currencyRate' => $this->context->currency->conversion_rate,
  324. 'currencyFormat' => $this->context->currency->format,
  325. 'currencyBlank' => $this->context->currency->blank,
  326. 'show_option_allow_separate_package' => $show_option_allow_separate_package,
  327. ));
  328. $this->context->smarty->assign(array(
  329. 'HOOK_SHOPPING_CART' => Hook::exec('displayShoppingCartFooter', $summary),
  330. 'HOOK_SHOPPING_CART_EXTRA' => Hook::exec('displayShoppingCart', $summary)
  331. ));
  332. }
  333. protected function _assignAddress()
  334. {
  335. //if guest checkout disabled and flag is_guest in cookies is actived
  336. if (Configuration::get('PS_GUEST_CHECKOUT_ENABLED') == 0 && ((int)$this->context->customer->is_guest != Configuration::get('PS_GUEST_CHECKOUT_ENABLED')))
  337. {
  338. $this->context->customer->logout();
  339. Tools::redirect('');
  340. }
  341. else if (!Customer::getAddressesTotalById($this->context->customer->id))
  342. Tools::redirect('index.php?controller=address&back='.urlencode('order.php?step=1&multi-shipping='.(int)Tools::getValue('multi-shipping')));
  343. $customer = $this->context->customer;
  344. if (Validate::isLoadedObject($customer))
  345. {
  346. /* Getting customer addresses */
  347. $customerAddresses = $customer->getAddresses($this->context->language->id);
  348. // Getting a list of formated address fields with associated values
  349. $formatedAddressFieldsValuesList = array();
  350. foreach ($customerAddresses as $address)
  351. {
  352. $tmpAddress = new Address($address['id_address']);
  353. $formatedAddressFieldsValuesList[$address['id_address']]['ordered_fields'] = AddressFormat::getOrderedAddressFields($address['id_country']);
  354. $formatedAddressFieldsValuesList[$address['id_address']]['formated_fields_values'] = AddressFormat::getFormattedAddressFieldsValues(
  355. $tmpAddress,
  356. $formatedAddressFieldsValuesList[$address['id_address']]['ordered_fields']);
  357. unset($tmpAddress);
  358. }
  359. $this->context->smarty->assign(array(
  360. 'addresses' => $customerAddresses,
  361. 'formatedAddressFieldsValuesList' => $formatedAddressFieldsValuesList));
  362. /* Setting default addresses for cart */
  363. if ((!isset($this->context->cart->id_address_delivery) || empty($this->context->cart->id_address_delivery)) && count($customerAddresses))
  364. {
  365. $this->context->cart->id_address_delivery = (int)($customerAddresses[0]['id_address']);
  366. $update = 1;
  367. }
  368. if ((!isset($this->context->cart->id_address_invoice) || empty($this->context->cart->id_address_invoice)) && count($customerAddresses))
  369. {
  370. $this->context->cart->id_address_invoice = (int)($customerAddresses[0]['id_address']);
  371. $update = 1;
  372. }
  373. /* Update cart addresses only if needed */
  374. if (isset($update) && $update)
  375. {
  376. $this->context->cart->update();
  377. // Address has changed, so we check if the cart rules still apply
  378. CartRule::autoRemoveFromCart($this->context);
  379. CartRule::autoAddToCart($this->context);
  380. }
  381. /* If delivery address is valid in cart, assign it to Smarty */
  382. if (isset($this->context->cart->id_address_delivery))
  383. {
  384. $deliveryAddress = new Address((int)($this->context->cart->id_address_delivery));
  385. if (Validate::isLoadedObject($deliveryAddress) && ($deliveryAddress->id_customer == $customer->id))
  386. $this->context->smarty->assign('delivery', $deliveryAddress);
  387. }
  388. /* If invoice address is valid in cart, assign it to Smarty */
  389. if (isset($this->context->cart->id_address_invoice))
  390. {
  391. $invoiceAddress = new Address((int)($this->context->cart->id_address_invoice));
  392. if (Validate::isLoadedObject($invoiceAddress) && ($invoiceAddress->id_customer == $customer->id))
  393. $this->context->smarty->assign('invoice', $invoiceAddress);
  394. }
  395. }
  396. if ($oldMessage = Message::getMessageByCartId((int)($this->context->cart->id)))
  397. $this->context->smarty->assign('oldMessage', $oldMessage['message']);
  398. }
  399. protected function _assignCarrier()
  400. {
  401. $address = new Address($this->context->cart->id_address_delivery);
  402. $id_zone = Address::getZoneById($address->id);
  403. $carriers = $this->context->cart->simulateCarriersOutput();
  404. $checked = $this->context->cart->simulateCarrierSelectedOutput();
  405. $delivery_option_list = $this->context->cart->getDeliveryOptionList();
  406. $this->setDefaultCarrierSelection($this->context->cart->getDeliveryOptionList());
  407. $this->context->smarty->assign(array(
  408. 'address_collection' => $this->context->cart->getAddressCollection(),
  409. 'delivery_option_list' => $delivery_option_list,
  410. 'carriers' => $carriers,
  411. 'checked' => $checked,
  412. 'delivery_option' => $this->context->cart->getDeliveryOption(null, false)
  413. ));
  414. $vars = array(
  415. 'HOOK_BEFORECARRIER' => Hook::exec('displayBeforeCarrier', array(
  416. 'carriers' => $carriers,
  417. 'checked' => $checked,
  418. 'delivery_option_list' => $delivery_option_list,
  419. 'delivery_option' => $this->context->cart->getDeliveryOption(null, false)
  420. ))
  421. );
  422. Cart::addExtraCarriers($vars);
  423. $this->context->smarty->assign($vars);
  424. }
  425. protected function _assignWrappingAndTOS()
  426. {
  427. // Wrapping fees
  428. $wrapping_fees = $this->context->cart->getGiftWrappingPrice(false);
  429. $wrapping_fees_tax_inc = $wrapping_fees = $this->context->cart->getGiftWrappingPrice();
  430. // TOS
  431. $cms = new CMS(Configuration::get('PS_CONDITIONS_CMS_ID'), $this->context->language->id);
  432. $this->link_conditions = $this->context->link->getCMSLink($cms, $cms->link_rewrite, true);
  433. if (!strpos($this->link_conditions, '?'))
  434. $this->link_conditions .= '?content_only=1';
  435. else
  436. $this->link_conditions .= '&content_only=1';
  437. $this->context->smarty->assign(array(
  438. 'checkedTOS' => (int)($this->context->cookie->checkedTOS),
  439. 'recyclablePackAllowed' => (int)(Configuration::get('PS_RECYCLABLE_PACK')),
  440. 'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')),
  441. 'cms_id' => (int)(Configuration::get('PS_CONDITIONS_CMS_ID')),
  442. 'conditions' => (int)(Configuration::get('PS_CONDITIONS')),
  443. 'link_conditions' => $this->link_conditions,
  444. 'recyclable' => (int)($this->context->cart->recyclable),
  445. 'delivery_option_list' => $this->context->cart->getDeliveryOptionList(),
  446. 'carriers' => $this->context->cart->simulateCarriersOutput(),
  447. 'checked' => $this->context->cart->simulateCarrierSelectedOutput(),
  448. 'address_collection' => $this->context->cart->getAddressCollection(),
  449. 'delivery_option' => $this->context->cart->getDeliveryOption(null, false),
  450. 'gift_wrapping_price' => (float)$wrapping_fees,
  451. 'total_wrapping_cost' => Tools::convertPrice($wrapping_fees_tax_inc, $this->context->currency),
  452. 'total_wrapping_tax_exc_cost' => Tools::convertPrice($wrapping_fees, $this->context->currency)));
  453. }
  454. protected function _assignPayment()
  455. {
  456. $this->context->smarty->assign(array(
  457. 'HOOK_TOP_PAYMENT' => Hook::exec('displayPaymentTop'),
  458. 'HOOK_PAYMENT' => Hook::exec('displayPayment'),
  459. ));
  460. }
  461. /**
  462. * Set id_carrier to 0 (no shipping price)
  463. */
  464. protected function setNoCarrier()
  465. {
  466. $this->context->cart->setDeliveryOption(null);
  467. $this->context->cart->update();
  468. }
  469. /**
  470. * Decides what the default carrier is and update the cart with it
  471. *
  472. * @todo this function must be modified - id_carrier is now delivery_option
  473. *
  474. * @param array $carriers
  475. *
  476. * @deprecated since 1.5.0
  477. *
  478. * @return number the id of the default carrier
  479. */
  480. protected function setDefaultCarrierSelection($carriers)
  481. {
  482. if (!$this->context->cart->getDeliveryOption(null, true))
  483. $this->context->cart->setDeliveryOption($this->context->cart->getDeliveryOption());
  484. }
  485. /**
  486. * Decides what the default carrier is and update the cart with it
  487. *
  488. * @param array $carriers
  489. *
  490. * @deprecated since 1.5.0
  491. *
  492. * @return number the id of the default carrier
  493. */
  494. protected function _setDefaultCarrierSelection($carriers)
  495. {
  496. $this->context->cart->id_carrier = Carrier::getDefaultCarrierSelection($carriers, (int)$this->context->cart->id_carrier);
  497. if ($this->context->cart->update())
  498. return $this->context->cart->id_carrier;
  499. return 0;
  500. }
  501. }