public function checkout($templates)
 {
     $view = wa()->getView();
     $steps = wa()->getConfig()->getCheckoutSettings();
     $cart = new shopCart();
     if (!$cart->count()) {
         return false;
     }
     if (waRequest::method() == 'post') {
         if (waRequest::post('wa_auth_login')) {
             $login_action = new shopLoginAction();
             $login_action->run();
         } else {
             $error = false;
             foreach ($steps as $step_id => $step) {
                 $step_instance = self::getStep($step_id);
                 if (!$step_instance->execute()) {
                     $error = true;
                 }
             }
             if (waRequest::post('confirmation') && !$error && !self::checkCart()) {
                 if (self::createOrder()) {
                     wa()->getResponse()->redirect(wa()->getRouteUrl('/frontend/checkout', array('step' => 'success')));
                 }
             }
         }
     }
     $checkout_tpls = array();
     foreach ($steps as $step_id => $step) {
         $step = self::getStep($step_id);
         $step->initDefault();
         $steps[$step_id]['content'] = $step->display();
         /**
          * @event frontend_checkout
          * @return array[string]string $return[%plugin_id%] html output
          */
         $event_params = array('step' => $step_id);
         $view->assign('frontend_checkout', wa()->event('frontend_checkout', $event_params));
         $step_tpl_path = $templates['checkout.' . $step_id]['template_path'];
         $step_tpl = $view->fetch($step_tpl_path);
         $checkout_tpls[$step_id] = $step_tpl;
     }
     $view->assign('checkout_tpls', $checkout_tpls);
     $view->assign('checkout_steps', $steps);
 }
 public function execute()
 {
     $steps = $this->getConfig()->getCheckoutSettings();
     $current_step = waRequest::param('step', waRequest::request('step'));
     if (!$current_step) {
         $current_step = key($steps);
     }
     $title = _w('Checkout');
     if ($current_step == 'success') {
         $order_id = waRequest::get('order_id');
         if (!$order_id) {
             $order_id = wa()->getStorage()->get('shop/order_id');
             $payment_success = false;
         } else {
             $payment_success = true;
             $this->view->assign('payment_success', true);
         }
         if (!$order_id) {
             wa()->getResponse()->redirect(wa()->getRouteUrl('shop/frontend'));
         }
         $order_model = new shopOrderModel();
         $order = $order_model->getById($order_id);
         if ($order) {
             $order['_id'] = $order['id'];
         }
         if (!$payment_success) {
             $order_params_model = new shopOrderParamsModel();
             $order['params'] = $order_params_model->get($order_id);
             $order_items_model = new shopOrderItemsModel();
             $order['items'] = $order_items_model->getByField('order_id', $order_id, true);
             $payment = '';
             if (!empty($order['params']['payment_id'])) {
                 try {
                     /**
                      * @var waPayment $plugin
                      */
                     $plugin = shopPayment::getPlugin(null, $order['params']['payment_id']);
                     $payment = $plugin->payment(waRequest::post(), shopPayment::getOrderData($order, $plugin), true);
                 } catch (waException $ex) {
                     $payment = $ex->getMessage();
                 }
             }
             $order['id'] = shopHelper::encodeOrderId($order_id);
             $this->getResponse()->addGoogleAnalytics($this->getGoogleAnalytics($order));
         } else {
             $order['id'] = shopHelper::encodeOrderId($order_id);
         }
         $this->view->assign('order', $order);
         if (isset($payment)) {
             $this->view->assign('payment', $payment);
         }
     } else {
         $cart = new shopCart();
         if (!$cart->count() && $current_step != 'error') {
             $current_step = 'error';
             $this->view->assign('error', _w('Your shopping cart is empty. Please add some products to cart, and then proceed to checkout.'));
         }
         if ($current_step != 'error') {
             if (waRequest::method() == 'post') {
                 if (waRequest::post('wa_auth_login')) {
                     $login_action = new shopLoginAction();
                     $login_action->run();
                 } else {
                     $redirect = false;
                     foreach ($steps as $step_id => $step) {
                         if ($step_id == $current_step) {
                             $step_instance = $this->getStep($step_id);
                             if ($step_instance->execute()) {
                                 $redirect = true;
                             }
                         } elseif ($redirect) {
                             $this->redirect(wa()->getRouteUrl('/frontend/checkout', array('step' => $step_id)));
                         }
                     }
                     // last step
                     if ($redirect) {
                         if ($this->createOrder()) {
                             $this->redirect(wa()->getRouteUrl('/frontend/checkout', array('step' => 'success')));
                         }
                     }
                 }
             } else {
                 $this->view->assign('error', '');
             }
             $title .= ' - ' . $steps[$current_step]['name'];
             $steps[$current_step]['content'] = $this->getStep($current_step)->display();
             $this->view->assign('checkout_steps', $steps);
         }
     }
     $this->getResponse()->setTitle($title);
     $this->view->assign('checkout_current_step', $current_step);
     /**
      * @event frontend_checkout
      * @return array[string]string $return[%plugin_id%] html output
      */
     $event_params = array('step' => $current_step);
     $this->view->assign('frontend_checkout', wa()->event('frontend_checkout', $event_params));
     if (waRequest::isXMLHttpRequest()) {
         $this->setThemeTemplate('checkout.' . $current_step . '.html');
     } else {
         $this->setLayout(new shopFrontendLayout());
         $this->setThemeTemplate('checkout.html');
     }
 }