View source
<?php
namespace Drupal\uc_cart\Controller;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Url;
use Drupal\uc_cart\CartInterface;
use Drupal\uc_cart\CartManagerInterface;
use Drupal\uc_cart\Plugin\CheckoutPaneManager;
use Drupal\uc_cart\Event\CheckoutReviewOrderEvent;
use Drupal\uc_cart\Event\CheckoutStartEvent;
use Drupal\uc_order\Entity\Order;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class CheckoutController extends ControllerBase implements ContainerInjectionInterface {
protected $checkoutPaneManager;
protected $cartManager;
protected $session;
protected $dateTime;
public function __construct(CheckoutPaneManager $checkout_pane_manager, CartManagerInterface $cart_manager, SessionInterface $session, TimeInterface $date_time) {
$this->checkoutPaneManager = $checkout_pane_manager;
$this->cartManager = $cart_manager;
$this->session = $session;
$this->dateTime = $date_time;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.uc_cart.checkout_pane'), $container
->get('uc_cart.manager'), $container
->get('session'), $container
->get('datetime.time'));
}
public function checkout() {
$cart_config = $this
->config('uc_cart.settings');
$items = $this->cartManager
->get()
->getContents();
if (count($items) == 0 || !$cart_config
->get('checkout_enabled')) {
return $this
->redirect('uc_cart.cart');
}
if ($this
->currentUser()
->isAnonymous() && !$cart_config
->get('checkout_anonymous')) {
$this
->messenger()
->addMessage($this
->t('You must login before you can proceed to checkout.'));
if ($this
->config('user.settings')
->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
$this
->messenger()
->addMessage($this
->t('If you do not have an account yet, you should <a href=":url">register now</a>.', [
':url' => Url::fromRoute('user.register', [], [
'query' => $this
->getDestinationArray(),
])
->toString(),
]));
}
return $this
->redirect('user.login', [], [
'query' => $this
->getDestinationArray(),
]);
}
if ($this->session
->has('cart_order')) {
$order = $this
->loadOrder();
if ($order) {
$request_time = $this->dateTime
->getRequestTime();
if ($order
->getStateId() != 'in_checkout' || $this
->currentUser()
->isAuthenticated() && $this
->currentUser()
->id() != $order
->getOwnerId() || $order
->getChangedTime() < $request_time - CartInterface::CHECKOUT_TIMEOUT) {
if ($order
->getStateId() == 'in_checkout' && $order
->getChangedTime() < $request_time - CartInterface::CHECKOUT_TIMEOUT) {
$order
->setStatusId('abandoned')
->save();
}
unset($order);
}
}
else {
$this->session
->remove('cart_order');
$this
->messenger()
->addMessage($this
->t('Your session has expired or is no longer valid. Please review your order and try again.'));
return $this
->redirect('uc_cart.cart');
}
}
if (isset($_POST['form_id']) && $_POST['form_id'] == 'uc_cart_checkout_form') {
if (!isset($order)) {
$this
->messenger()
->addMessage($this
->t('Your session has expired or is no longer valid. Please review your order and try again.'));
return $this
->redirect('uc_cart.cart');
}
elseif ($this->session
->has('uc_cart_order_rebuild')) {
$this
->messenger()
->addMessage($this
->t('Your shopping cart contents have changed. Please review your order and try again.'));
return $this
->redirect('uc_cart.cart');
}
}
else {
$rebuild = FALSE;
if (!isset($order)) {
$order = Order::create([
'uid' => $this
->currentUser()
->id(),
]);
$order
->save();
$this->session
->set('cart_order', $order
->id());
$rebuild = TRUE;
}
elseif ($this->session
->has('uc_cart_order_rebuild')) {
$result = \Drupal::entityQuery('uc_order_product')
->condition('order_id', $order
->id())
->execute();
if (!empty($result)) {
$storage = $this
->entityTypeManager()
->getStorage('uc_order_product');
$entities = $storage
->loadMultiple(array_keys($result));
$storage
->delete($entities);
}
uc_order_delete_line_item($order
->id(), TRUE);
$rebuild = TRUE;
}
if ($rebuild) {
$order->products = [];
foreach ($items as $item) {
$order->products[] = $item
->toOrderProduct();
}
$this->session
->remove('uc_cart_order_rebuild');
}
elseif (!uc_order_product_revive($order->products)) {
$this
->messenger()
->addError($this
->t('Some of the products in this order are no longer available.'));
return $this
->redirect('uc_cart.cart');
}
}
$min = $cart_config
->get('minimum_subtotal');
if ($min > 0 && $order
->getSubtotal() < $min) {
$this
->messenger()
->addError($this
->t('The minimum order subtotal for checkout is @min.', [
'@min' => uc_currency_format($min),
]));
return $this
->redirect('uc_cart.cart');
}
$this
->moduleHandler()
->invokeAll('uc_cart_checkout_start', [
$order,
]);
$event = new CheckoutStartEvent($order);
\Drupal::service('event_dispatcher')
->dispatch($event::EVENT_NAME, $event);
return $this
->formBuilder()
->getForm('Drupal\\uc_cart\\Form\\CheckoutForm', $order);
}
public function review() {
if (!$this->session
->has('cart_order') || !$this->session
->has('uc_checkout_review_' . $this->session
->get('cart_order'))) {
return $this
->redirect('uc_cart.checkout');
}
$order = $this
->loadOrder();
if (!$order || $order
->getStateId() != 'in_checkout') {
$this->session
->remove('uc_checkout_complete_' . $this->session
->get('cart_order'));
return $this
->redirect('uc_cart.checkout');
}
elseif (!uc_order_product_revive($order->products)) {
$this
->messenger()
->addError($this
->t('Some of the products in this order are no longer available.'));
return $this
->redirect('uc_cart.cart');
}
$filter = [
'enabled' => FALSE,
];
if (!$order
->isShippable() && $this
->config('uc_cart.settings')
->get('panes.delivery.settings.delivery_not_shippable')) {
$filter['shippable'] = TRUE;
}
$panes = $this->checkoutPaneManager
->getPanes($filter);
foreach ($panes as $pane) {
$return = $pane
->review($order);
if (!is_null($return)) {
$data[$pane
->getTitle()] = $return;
}
}
$build = [
'#theme' => 'uc_cart_checkout_review',
'#panes' => $data,
'#form' => $this
->formBuilder()
->getForm('Drupal\\uc_cart\\Form\\CheckoutReviewForm', $order),
];
$build['#attached']['library'][] = 'uc_cart/uc_cart.styles';
$build['#attached']['library'][] = 'uc_cart/uc_cart.review.scripts';
$this
->moduleHandler()
->invokeAll('uc_cart_checkout_review_order', [
$order,
]);
$event = new CheckoutReviewOrderEvent($order);
\Drupal::service('event_dispatcher')
->dispatch($event::EVENT_NAME, $event);
return $build;
}
public function complete() {
if (!$this->session
->has('cart_order') || !$this->session
->has('uc_checkout_complete_' . $this->session
->get('cart_order'))) {
return $this
->redirect('uc_cart.cart');
}
$order = $this
->loadOrder();
if (empty($order)) {
$this
->messenger()
->addError($this
->t("We're sorry. An error occurred while processing your order that prevents us from completing it at this time. Please contact us and we will resolve the issue as soon as possible."));
$this
->getLogger('uc_cart')
->error('An empty order made it to checkout! Cart order ID: @cart_order', [
'@cart_order' => $this->session
->get('cart_order'),
]);
return $this
->redirect('uc_cart.cart');
}
$this->session
->remove('uc_checkout_complete_' . $this->session
->get('cart_order'));
$this->session
->remove('cart_order');
uc_order_comment_save($order
->id(), 0, $this
->t('Order created through website.'), 'admin');
return $this->cartManager
->completeSale($order);
}
protected function loadOrder() {
$id = $this->session
->get('cart_order');
$storage = $this
->entityTypeManager()
->getStorage('uc_order');
$storage
->resetCache([
$id,
]);
return $storage
->load($id);
}
}