class CheckoutController in Ubercart 8.4
Controller routines for the checkout.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\uc_cart\Controller\CheckoutController implements ContainerInjectionInterface
Expanded class hierarchy of CheckoutController
File
- uc_cart/
src/ Controller/ CheckoutController.php, line 21
Namespace
Drupal\uc_cart\ControllerView source
class CheckoutController extends ControllerBase implements ContainerInjectionInterface {
/**
* The checkout pane manager.
*
* @var \Drupal\uc_cart\Plugin\CheckoutPaneManager
*/
protected $checkoutPaneManager;
/**
* The cart manager.
*
* @var \Drupal\uc_cart\CartManagerInterface
*/
protected $cartManager;
/**
* The session.
*
* @var \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
protected $session;
/**
* The datetime.time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $dateTime;
/**
* Constructs a CheckoutController.
*
* @param \Drupal\uc_cart\Plugin\CheckoutPaneManager $checkout_pane_manager
* The checkout pane plugin manager.
* @param \Drupal\uc_cart\CartManagerInterface $cart_manager
* The cart manager.
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
* The session.
* @param \Drupal\Component\Datetime\TimeInterface $date_time
* The datetime.time service.
*/
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;
}
/**
* {@inheritdoc}
*/
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'));
}
/**
* Builds the cart checkout page from available checkout pane plugins.
*/
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');
}
// Send anonymous users to login page when anonymous checkout is disabled.
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(),
]);
}
// Load an order from the session, if available.
if ($this->session
->has('cart_order')) {
$order = $this
->loadOrder();
if ($order) {
// To prevent identity theft, don't use an existing order if it has
// changed status or owner, or if there has been no activity for 10
// minutes.
$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) {
// Mark expired orders as abandoned.
$order
->setStatusId('abandoned')
->save();
}
unset($order);
}
}
else {
// Ghost session.
$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');
}
}
// Determine if the form is being submitted or built for the first time.
if (isset($_POST['form_id']) && $_POST['form_id'] == 'uc_cart_checkout_form') {
// If this is a form submission, make sure the cart order is still valid.
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 {
// Prepare the cart order.
$rebuild = FALSE;
if (!isset($order)) {
// Create a new order if necessary.
$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')) {
// Or, if the cart has changed, then remove old products and line items.
$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) {
// Copy the cart contents to the cart order.
$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');
}
// Invoke the customer starts checkout hook.
$this
->moduleHandler()
->invokeAll('uc_cart_checkout_start', [
$order,
]);
// Trigger the checkout start event.
/* rules_invoke_event('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);
}
/**
* Allows a customer to review their order before finally submitting it.
*/
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 the cart isn't shippable, bypass panes with shippable == TRUE.
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';
// Invoke the customer reviews order checkout hook.
$this
->moduleHandler()
->invokeAll('uc_cart_checkout_review_order', [
$order,
]);
// Trigger the checkout review order event.
/* rules_invoke_event('uc_cart_checkout_review_order', $order); */
$event = new CheckoutReviewOrderEvent($order);
\Drupal::service('event_dispatcher')
->dispatch($event::EVENT_NAME, $event);
return $build;
}
/**
* Completes the sale and finishes checkout.
*/
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)) {
// If order was lost, display customer message and log the occurrence.
$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');
// Add a comment to let sales team know this came in through the site.
uc_order_comment_save($order
->id(), 0, $this
->t('Order created through website.'), 'admin');
return $this->cartManager
->completeSale($order);
}
/**
* Loads the order that is being processed for checkout from the session.
*
* @return \Drupal\uc_order\OrderInterface
* The order object.
*/
protected function loadOrder() {
$id = $this->session
->get('cart_order');
// Reset uc_order entity cache then load order.
$storage = $this
->entityTypeManager()
->getStorage('uc_order');
$storage
->resetCache([
$id,
]);
return $storage
->load($id);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CheckoutController:: |
protected | property | The cart manager. | |
CheckoutController:: |
protected | property | The checkout pane manager. | |
CheckoutController:: |
protected | property | The datetime.time service. | |
CheckoutController:: |
protected | property | The session. | |
CheckoutController:: |
public | function | Builds the cart checkout page from available checkout pane plugins. | |
CheckoutController:: |
public | function | Completes the sale and finishes checkout. | |
CheckoutController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
CheckoutController:: |
protected | function | Loads the order that is being processed for checkout from the session. | |
CheckoutController:: |
public | function | Allows a customer to review their order before finally submitting it. | |
CheckoutController:: |
public | function | Constructs a CheckoutController. | |
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |