Advertisement
Guest User

OnepageController.php

a guest
Mar 19th, 2015
749
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 22.26 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Magento
  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@magento.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 Magento to newer
  18.  * versions in the future. If you wish to customize Magento for your
  19.  * needs please refer to http://www.magento.com for more information.
  20.  *
  21.  * @category    Mage
  22.  * @package     Mage_Checkout
  23.  * @copyright  Copyright (c) 2006-2014 X.commerce, Inc. (http://www.magento.com)
  24.  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  25.  */
  26.  
  27. /**
  28.  * Onepage controller for checkout
  29.  *
  30.  * @category    Mage
  31.  * @package     Mage_Checkout
  32.  * @author      Magento Core Team <core@magentocommerce.com>
  33.  */
  34. class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
  35. {
  36.     /**
  37.      * List of functions for section update
  38.      *
  39.      * @var array
  40.      */
  41.     protected $_sectionUpdateFunctions = array(
  42.         'payment-method'  => '_getPaymentMethodsHtml',
  43.         'shipping-method' => '_getShippingMethodsHtml',
  44.         'review'          => '_getReviewHtml',
  45.     );
  46.  
  47.     /**
  48.      * @var Mage_Sales_Model_Order
  49.      */
  50.     protected $_order;
  51.  
  52.     /**
  53.      * Predispatch: should set layout area
  54.      *
  55.      * @return Mage_Checkout_OnepageController
  56.      */
  57.     public function preDispatch()
  58.     {
  59.         parent::preDispatch();
  60.         $this->_preDispatchValidateCustomer();
  61.  
  62.         $checkoutSessionQuote = Mage::getSingleton('checkout/session')->getQuote();
  63.         if ($checkoutSessionQuote->getIsMultiShipping()) {
  64.             $checkoutSessionQuote->setIsMultiShipping(false);
  65.             $checkoutSessionQuote->removeAllAddresses();
  66.         }
  67.  
  68.         if (!$this->_canShowForUnregisteredUsers()) {
  69.             $this->norouteAction();
  70.             $this->setFlag('',self::FLAG_NO_DISPATCH,true);
  71.             return;
  72.         }
  73.  
  74.         return $this;
  75.     }
  76.  
  77.     /**
  78.      * Send Ajax redirect response
  79.      *
  80.      * @return Mage_Checkout_OnepageController
  81.      */
  82.     protected function _ajaxRedirectResponse()
  83.     {
  84.         $this->getResponse()
  85.             ->setHeader('HTTP/1.1', '403 Session Expired')
  86.             ->setHeader('Login-Required', 'true')
  87.             ->sendResponse();
  88.         return $this;
  89.     }
  90.  
  91.     /**
  92.      * Validate ajax request and redirect on failure
  93.      *
  94.      * @return bool
  95.      */
  96.     protected function _expireAjax()
  97.     {
  98.         if (!$this->getOnepage()->getQuote()->hasItems()
  99.             || $this->getOnepage()->getQuote()->getHasError()
  100.             || $this->getOnepage()->getQuote()->getIsMultiShipping()
  101.         ) {
  102.             $this->_ajaxRedirectResponse();
  103.             return true;
  104.         }
  105.         $action = $this->getRequest()->getActionName();
  106.         if (Mage::getSingleton('checkout/session')->getCartWasUpdated(true)
  107.             && !in_array($action, array('index', 'progress'))
  108.         ) {
  109.             $this->_ajaxRedirectResponse();
  110.             return true;
  111.         }
  112.         return false;
  113.     }
  114.  
  115.     /**
  116.      * Get shipping method step html
  117.      *
  118.      * @return string
  119.      */
  120.     protected function _getShippingMethodsHtml()
  121.     {
  122.         $layout = $this->getLayout();
  123.         $update = $layout->getUpdate();
  124.         $update->load('checkout_onepage_shippingmethod');
  125.         $layout->generateXml();
  126.         $layout->generateBlocks();
  127.         $output = $layout->getOutput();
  128.         return $output;
  129.     }
  130.  
  131.     /**
  132.      * Get payment method step html
  133.      *
  134.      * @return string
  135.      */
  136.     protected function _getPaymentMethodsHtml()
  137.     {
  138.         $layout = $this->getLayout();
  139.         $update = $layout->getUpdate();
  140.         $update->load('checkout_onepage_paymentmethod');
  141.         $layout->generateXml();
  142.         $layout->generateBlocks();
  143.         $output = $layout->getOutput();
  144.         return $output;
  145.     }
  146.  
  147.     /**
  148.      * Return block content from the 'checkout_onepage_additional'
  149.      * This is the additional content for shipping method
  150.      *
  151.      * @return string
  152.      */
  153.     protected function _getAdditionalHtml()
  154.     {
  155.         $layout = $this->getLayout();
  156.         $update = $layout->getUpdate();
  157.         $update->load('checkout_onepage_additional');
  158.         $layout->generateXml();
  159.         $layout->generateBlocks();
  160.         $output = $layout->getOutput();
  161.         Mage::getSingleton('core/translate_inline')->processResponseBody($output);
  162.         return $output;
  163.     }
  164.  
  165.     /**
  166.      * Get order review step html
  167.      *
  168.      * @return string
  169.      */
  170.     protected function _getReviewHtml()
  171.     {
  172.         return $this->getLayout()->getBlock('root')->toHtml();
  173.     }
  174.  
  175.     /**
  176.      * Get one page checkout model
  177.      *
  178.      * @return Mage_Checkout_Model_Type_Onepage
  179.      */
  180.     public function getOnepage()
  181.     {
  182.         return Mage::getSingleton('checkout/type_onepage');
  183.     }
  184.  
  185.     /**
  186.      * Checkout page
  187.      */
  188.     public function indexAction()
  189.     {
  190.         if (!Mage::helper('checkout')->canOnepageCheckout()) {
  191.             Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
  192.             $this->_redirect('checkout/cart');
  193.             return;
  194.         }
  195.         $quote = $this->getOnepage()->getQuote();
  196.         if (!$quote->hasItems() || $quote->getHasError()) {
  197.             $this->_redirect('checkout/cart');
  198.             return;
  199.         }
  200.         if (!$quote->validateMinimumAmount()) {
  201.             $error = Mage::getStoreConfig('sales/minimum_order/error_message') ?
  202.                 Mage::getStoreConfig('sales/minimum_order/error_message') :
  203.                 Mage::helper('checkout')->__('Subtotal must exceed minimum order amount');
  204.  
  205.             Mage::getSingleton('checkout/session')->addError($error);
  206.             $this->_redirect('checkout/cart');
  207.             return;
  208.         }
  209.         Mage::getSingleton('checkout/session')->setCartWasUpdated(false);
  210.         Mage::getSingleton('customer/session')->setBeforeAuthUrl(Mage::getUrl('*/*/*', array('_secure' => true)));
  211.         $this->getOnepage()->initCheckout();
  212.         $this->loadLayout();
  213.         $this->_initLayoutMessages('customer/session');
  214.         $this->getLayout()->getBlock('head')->setTitle($this->__('Checkout'));
  215.         $this->renderLayout();
  216.     }
  217.  
  218.     /**
  219.      * Refreshes the previous step
  220.      * Loads the block corresponding to the current step and sets it
  221.      * in to the response body
  222.      *
  223.      * This function is called from the reloadProgessBlock
  224.      * function from the javascript
  225.      *
  226.      * @return string|null
  227.      */
  228.     public function progressAction()
  229.     {
  230.         // previous step should never be null. We always start with billing and go forward
  231.         $prevStep = $this->getRequest()->getParam('prevStep', false);
  232.  
  233.         if ($this->_expireAjax() || !$prevStep) {
  234.             return null;
  235.         }
  236.  
  237.         $layout = $this->getLayout();
  238.         $update = $layout->getUpdate();
  239.         /* Load the block belonging to the current step*/
  240.         $update->load('checkout_onepage_progress_' . $prevStep);
  241.         $layout->generateXml();
  242.         $layout->generateBlocks();
  243.         $output = $layout->getOutput();
  244.         $this->getResponse()->setBody($output);
  245.         return $output;
  246.     }
  247.  
  248.     /**
  249.      * Shipping method action
  250.      */
  251.     public function shippingMethodAction()
  252.     {
  253.         if ($this->_expireAjax()) {
  254.             return;
  255.         }
  256.         $this->loadLayout(false);
  257.         $this->renderLayout();
  258.     }
  259.  
  260.     /**
  261.      * Review page action
  262.      */
  263.     public function reviewAction()
  264.     {
  265.         if ($this->_expireAjax()) {
  266.             return;
  267.         }
  268.         $this->loadLayout(false);
  269.         $this->renderLayout();
  270.     }
  271.  
  272.     /**
  273.      * Order success action
  274.      */
  275.     public function successAction()
  276.     {
  277.         $session = $this->getOnepage()->getCheckout();
  278.         if (!$session->getLastSuccessQuoteId()) {
  279.             $this->_redirect('checkout/cart');
  280.             return;
  281.         }
  282.  
  283.         $lastQuoteId = $session->getLastQuoteId();
  284.         $lastOrderId = $session->getLastOrderId();
  285.         $lastRecurringProfiles = $session->getLastRecurringProfileIds();
  286.         if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
  287.             $this->_redirect('checkout/cart');
  288.             return;
  289.         }
  290.  
  291.         $session->clear();
  292.         $this->loadLayout();
  293.         $this->_initLayoutMessages('checkout/session');
  294.         Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
  295.         $this->renderLayout();
  296.     }
  297.  
  298.     /**
  299.      * Failure action
  300.      */
  301.     public function failureAction()
  302.     {
  303.         $lastQuoteId = $this->getOnepage()->getCheckout()->getLastQuoteId();
  304.         $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
  305.  
  306.         if (!$lastQuoteId || !$lastOrderId) {
  307.             $this->_redirect('checkout/cart');
  308.             return;
  309.         }
  310.  
  311.         $this->loadLayout();
  312.         $this->renderLayout();
  313.     }
  314.  
  315.  
  316.     /**
  317.      * Get additional info action
  318.      */
  319.     public function getAdditionalAction()
  320.     {
  321.         $this->getResponse()->setBody($this->_getAdditionalHtml());
  322.     }
  323.  
  324.     /**
  325.      * Address JSON
  326.      */
  327.     public function getAddressAction()
  328.     {
  329.         if ($this->_expireAjax()) {
  330.             return;
  331.         }
  332.         $addressId = $this->getRequest()->getParam('address', false);
  333.         if ($addressId) {
  334.             $address = $this->getOnepage()->getAddress($addressId);
  335.  
  336.             if (Mage::getSingleton('customer/session')->getCustomer()->getId() == $address->getCustomerId()) {
  337.                 $this->getResponse()->setHeader('Content-type', 'application/x-json');
  338.                 $this->getResponse()->setBody($address->toJson());
  339.             } else {
  340.                 $this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
  341.             }
  342.         }
  343.     }
  344.  
  345.     /**
  346.      * Save checkout method
  347.      */
  348.     public function saveMethodAction()
  349.     {
  350.         if ($this->_expireAjax()) {
  351.             return;
  352.         }
  353.         if ($this->getRequest()->isPost()) {
  354.             $method = $this->getRequest()->getPost('method');
  355.             $result = $this->getOnepage()->saveCheckoutMethod($method);
  356.             $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  357.         }
  358.     }
  359.  
  360.     /**
  361.      * Save checkout billing address
  362.      */
  363.     public function saveBillingAction()
  364.     {
  365.         if ($this->_expireAjax()) {
  366.             return;
  367.         }
  368.         if ($this->getRequest()->isPost()) {
  369.             $data = $this->getRequest()->getPost('billing', array());
  370.             $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
  371.  
  372.             if (isset($data['email'])) {
  373.                 $data['email'] = trim($data['email']);
  374.             }
  375.             $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
  376.  
  377.             if (!isset($result['error'])) {
  378.                 if ($this->getOnepage()->getQuote()->isVirtual()) {
  379.                     $result['goto_section'] = 'payment';
  380.                     $result['update_section'] = array(
  381.                         'name' => 'payment-method',
  382.                         'html' => $this->_getPaymentMethodsHtml()
  383.                     );
  384.                 } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
  385.                     $result['goto_section'] = 'shipping_method';
  386.                     $result['update_section'] = array(
  387.                         'name' => 'shipping-method',
  388.                         'html' => $this->_getShippingMethodsHtml()
  389.                     );
  390.  
  391.                     $result['allow_sections'] = array('shipping');
  392.                     $result['duplicateBillingInfo'] = 'true';
  393.                 } else {
  394.                     $result['goto_section'] = 'shipping';
  395.                 }
  396.             }
  397.  
  398.             $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  399.         }
  400.     }
  401.  
  402.     /**
  403.      * Shipping address save action
  404.      */
  405.     public function saveShippingAction()
  406.     {
  407.         if ($this->_expireAjax()) {
  408.             return;
  409.         }
  410.         if ($this->getRequest()->isPost()) {
  411.             $data = $this->getRequest()->getPost('shipping', array());
  412.             $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
  413.             $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
  414.  
  415.             if (!isset($result['error'])) {
  416.                 $result['goto_section'] = 'shipping_method';
  417.                 $result['update_section'] = array(
  418.                     'name' => 'shipping-method',
  419.                     'html' => $this->_getShippingMethodsHtml()
  420.                 );
  421.             }
  422.             $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  423.         }
  424.     }
  425.  
  426.     /**
  427.      * Shipping method save action
  428.      */
  429.     public function saveShippingMethodAction()
  430.     {
  431.         if ($this->_expireAjax()) {
  432.             return;
  433.         }
  434.         if ($this->getRequest()->isPost()) {
  435.             $data = $this->getRequest()->getPost('shipping_method', '');
  436.             $result = $this->getOnepage()->saveShippingMethod($data);
  437.             // $result will contain error data if shipping method is empty
  438.             if (!$result) {
  439.                 Mage::dispatchEvent(
  440.                     'checkout_controller_onepage_save_shipping_method',
  441.                      array(
  442.                           'request' => $this->getRequest(),
  443.                           'quote'   => $this->getOnepage()->getQuote()));
  444.                 $this->getOnepage()->getQuote()->collectTotals();
  445.                 $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  446.  
  447.                 $result['goto_section'] = 'payment';
  448.                 $result['update_section'] = array(
  449.                     'name' => 'payment-method',
  450.                     'html' => $this->_getPaymentMethodsHtml()
  451.                 );
  452.             }
  453.             $this->getOnepage()->getQuote()->collectTotals()->save();
  454.             $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  455.         }
  456.     }
  457.  
  458.     /**
  459.      * Save payment ajax action
  460.      *
  461.      * Sets either redirect or a JSON response
  462.      */
  463.     public function savePaymentAction()
  464.     {
  465.         if ($this->_expireAjax()) {
  466.             return;
  467.         }
  468.         try {
  469.             if (!$this->getRequest()->isPost()) {
  470.                 $this->_ajaxRedirectResponse();
  471.                 return;
  472.             }
  473.  
  474.             $data = $this->getRequest()->getPost('payment', array());
  475.             $result = $this->getOnepage()->savePayment($data);
  476.  
  477.             // get section and redirect data
  478.             $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
  479.             if (empty($result['error']) && !$redirectUrl) {
  480.                 $this->loadLayout('checkout_onepage_review');
  481.                 $result['goto_section'] = 'review';
  482.                 $result['update_section'] = array(
  483.                     'name' => 'review',
  484.                     'html' => $this->_getReviewHtml()
  485.                 );
  486.             }
  487.             if ($redirectUrl) {
  488.                 $result['redirect'] = $redirectUrl;
  489.             }
  490.         } catch (Mage_Payment_Exception $e) {
  491.             if ($e->getFields()) {
  492.                 $result['fields'] = $e->getFields();
  493.             }
  494.             $result['error'] = $e->getMessage();
  495.         } catch (Mage_Core_Exception $e) {
  496.             $result['error'] = $e->getMessage();
  497.         } catch (Exception $e) {
  498.             Mage::logException($e);
  499.             $result['error'] = $this->__('Unable to set Payment Method.');
  500.         }
  501.         $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  502.     }
  503.  
  504.     /**
  505.      * Get Order by quoteId
  506.      *
  507.      * @throws Mage_Payment_Model_Info_Exception
  508.      * @return Mage_Sales_Model_Order
  509.      */
  510.     protected function _getOrder()
  511.     {
  512.         if (is_null($this->_order)) {
  513.             $this->_order = Mage::getModel('sales/order')->load($this->getOnepage()->getQuote()->getId(), 'quote_id');
  514.             if (!$this->_order->getId()) {
  515.                 throw new Mage_Payment_Model_Info_Exception(Mage::helper('core')->__("Can not create invoice. Order was not found."));
  516.             }
  517.         }
  518.         return $this->_order;
  519.     }
  520.  
  521.     /**
  522.      * Create invoice
  523.      *
  524.      * @return Mage_Sales_Model_Order_Invoice
  525.      */
  526.     protected function _initInvoice()
  527.     {
  528.         $items = array();
  529.         foreach ($this->_getOrder()->getAllItems() as $item) {
  530.             $items[$item->getId()] = $item->getQtyOrdered();
  531.         }
  532.         /* @var $invoice Mage_Sales_Model_Service_Order */
  533.         $invoice = Mage::getModel('sales/service_order', $this->_getOrder())->prepareInvoice($items);
  534.         $invoice->setEmailSent(true)->register();
  535.  
  536.         Mage::register('current_invoice', $invoice);
  537.         return $invoice;
  538.     }
  539.  
  540.     /**
  541.      * Create order action
  542.      */
  543.     public function saveOrderAction()
  544.     {
  545.         if (!$this->_validateFormKey()) {
  546.             $this->_redirect('*/*');
  547.             return;
  548.         }
  549.  
  550.         if ($this->_expireAjax()) {
  551.             return;
  552.         }
  553.  
  554.         $result = array();
  555.         try {
  556.             $requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds();
  557.             if ($requiredAgreements) {
  558.                 $postedAgreements = array_keys($this->getRequest()->getPost('agreement', array()));
  559.                 $diff = array_diff($requiredAgreements, $postedAgreements);
  560.                 if ($diff) {
  561.                     $result['success'] = false;
  562.                     $result['error'] = true;
  563.                     $result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
  564.                     $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  565.                     return;
  566.                 }
  567.             }
  568.  
  569.             $data = $this->getRequest()->getPost('payment', array());
  570.             if ($data) {
  571.                 $data['checks'] = Mage_Payment_Model_Method_Abstract::CHECK_USE_CHECKOUT
  572.                     | Mage_Payment_Model_Method_Abstract::CHECK_USE_FOR_COUNTRY
  573.                     | Mage_Payment_Model_Method_Abstract::CHECK_USE_FOR_CURRENCY
  574.                     | Mage_Payment_Model_Method_Abstract::CHECK_ORDER_TOTAL_MIN_MAX
  575.                     | Mage_Payment_Model_Method_Abstract::CHECK_ZERO_TOTAL;
  576.                 $this->getOnepage()->getQuote()->getPayment()->importData($data);
  577.             }
  578.  
  579.             $this->getOnepage()->saveOrder();
  580.  
  581.             $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
  582.             $result['success'] = true;
  583.             $result['error']   = false;
  584.         } catch (Mage_Payment_Model_Info_Exception $e) {
  585.             $message = $e->getMessage();
  586.             if (!empty($message)) {
  587.                 $result['error_messages'] = $message;
  588.             }
  589.             $result['goto_section'] = 'payment';
  590.             $result['update_section'] = array(
  591.                 'name' => 'payment-method',
  592.                 'html' => $this->_getPaymentMethodsHtml()
  593.             );
  594.         } catch (Mage_Core_Exception $e) {
  595.             Mage::logException($e);
  596.             Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
  597.             $result['success'] = false;
  598.             $result['error'] = true;
  599.             $result['error_messages'] = $e->getMessage();
  600.  
  601.             $gotoSection = $this->getOnepage()->getCheckout()->getGotoSection();
  602.             if ($gotoSection) {
  603.                 $result['goto_section'] = $gotoSection;
  604.                 $this->getOnepage()->getCheckout()->setGotoSection(null);
  605.             }
  606.             $updateSection = $this->getOnepage()->getCheckout()->getUpdateSection();
  607.             if ($updateSection) {
  608.                 if (isset($this->_sectionUpdateFunctions[$updateSection])) {
  609.                     $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
  610.                     $result['update_section'] = array(
  611.                         'name' => $updateSection,
  612.                         'html' => $this->$updateSectionFunction()
  613.                     );
  614.                 }
  615.                 $this->getOnepage()->getCheckout()->setUpdateSection(null);
  616.             }
  617.         } catch (Exception $e) {
  618.             Mage::logException($e);
  619.             Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
  620.             $result['success']  = false;
  621.             $result['error']    = true;
  622.             $result['error_messages'] = $this->__('There was an error processing your order. Please contact us or try again later.');
  623.         }
  624.         $this->getOnepage()->getQuote()->save();
  625.         /**
  626.          * when there is redirect to third party, we don't want to save order yet.
  627.          * we will save the order in return action.
  628.          */
  629.         if (isset($redirectUrl)) {
  630.             $result['redirect'] = $redirectUrl;
  631.         }
  632.  
  633.         $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
  634.     }
  635.  
  636.     /**
  637.      * Filtering posted data. Converting localized data if needed
  638.      *
  639.      * @param array
  640.      * @return array
  641.      */
  642.     protected function _filterPostData($data)
  643.     {
  644.         $data = $this->_filterDates($data, array('dob'));
  645.         return $data;
  646.     }
  647.  
  648.     /**
  649.      * Check can page show for unregistered users
  650.      *
  651.      * @return boolean
  652.      */
  653.     protected function _canShowForUnregisteredUsers()
  654.     {
  655.         return Mage::getSingleton('customer/session')->isLoggedIn()
  656.             || $this->getRequest()->getActionName() == 'index'
  657.             || Mage::helper('checkout')->isAllowedGuestCheckout($this->getOnepage()->getQuote())
  658.             || !Mage::helper('checkout')->isCustomerMustBeLogged();
  659.     }
  660. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement