View source
<?php
namespace Drupal\commerce_cart_blocks\Plugin\Block;
use Drupal\commerce_cart\CartProviderInterface;
use Drupal\commerce_price\Price;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class CartBlockBase extends BlockBase implements ContainerFactoryPluginInterface {
protected $cartProvider;
protected $entityTypeManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, CartProviderInterface $cart_provider, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->cartProvider = $cart_provider;
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('commerce_cart.cart_provider'), $container
->get('entity_type.manager'));
}
public function defaultConfiguration() {
return [
'hide_if_empty' => FALSE,
'display_links' => [
'cart' => 'cart',
],
'cart_link_text' => 'Cart',
'checkout_link_text' => 'Checkout',
'count_text_singular' => '@count item',
'count_text_plural' => '@count items',
'count_text_empty' => '',
];
}
public function blockForm($form, FormStateInterface $form_state) {
$form['hide_if_empty'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Hide if empty'),
'#description' => $this
->t('When checked, then the block will be hidden if the cart is empty.'),
'#default_value' => $this->configuration['hide_if_empty'],
];
$form['display_links'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Display links'),
'#description' => $this
->t('Choose which links to display within the block content.'),
'#options' => [
'cart' => $this
->t('Cart'),
'checkout' => $this
->t('Checkout'),
],
'#default_value' => $this->configuration['display_links'],
];
$form['cart_link_text'] = [
'#type' => 'textfield',
'#title' => $this
->t('Cart link text'),
'#description' => $this
->t('Enter the text for the Cart link, if shown.'),
'#default_value' => $this->configuration['cart_link_text'],
];
$form['checkout_link_text'] = [
'#type' => 'textfield',
'#title' => $this
->t('Checkout link text'),
'#description' => $this
->t('Enter the text for the Checkout link, if shown.'),
'#default_value' => $this->configuration['checkout_link_text'],
];
$form['count_text_plural'] = [
'#type' => 'textfield',
'#title' => $this
->t('Count text (plural)'),
'#description' => $this
->t('The text to use when describing the number of cart items, including the @count placeholder.'),
'#default_value' => $this->configuration['count_text_plural'],
];
$form['count_text_singular'] = [
'#type' => 'textfield',
'#title' => $this
->t('Count text (singular)'),
'#description' => $this
->t('The text to use when describing a single cart item, including the @count placeholder.'),
'#default_value' => $this->configuration['count_text_singular'],
];
$form['count_text_empty'] = [
'#type' => 'textfield',
'#title' => $this
->t('Count text (empty)'),
'#description' => $this
->t('The text to use when describing an empty cart item, including the @count placeholder.'),
'#default_value' => $this->configuration['count_text_empty'],
];
return $form;
}
public function blockSubmit($form, FormStateInterface $form_state) {
$this
->setConfigurationValue('hide_if_empty', $form_state
->getValue('hide_if_empty'));
$this
->setConfigurationValue('display_links', $form_state
->getValue('display_links'));
$this
->setConfigurationValue('cart_link_text', $form_state
->getValue('cart_link_text'));
$this
->setConfigurationValue('checkout_link_text', $form_state
->getValue('checkout_link_text'));
$this
->setConfigurationValue('count_text_plural', $form_state
->getValue('count_text_plural'));
$this
->setConfigurationValue('count_text_singular', $form_state
->getValue('count_text_singular'));
$this
->setConfigurationValue('count_text_empty', $form_state
->getValue('count_text_empty'));
}
protected function buildCache() {
$cacheableMetadata = $this
->getCacheabilityMetadata();
return [
'contexts' => $cacheableMetadata
->getCacheContexts(),
'tags' => $cacheableMetadata
->getCacheTags(),
'max-age' => $cacheableMetadata
->getCacheMaxAge(),
];
}
protected function isInCart() {
return \Drupal::routeMatch()
->getRouteName() === 'commerce_cart.page';
}
protected function buildLinks() {
$links = [];
$displayLinks = $this->configuration['display_links'];
if ($displayLinks['checkout']) {
$carts = $this
->getCarts();
if (!empty($carts)) {
$cart = array_shift($carts);
$links[] = [
'#type' => 'link',
'#title' => $this->configuration['checkout_link_text'],
'#url' => Url::fromRoute('commerce_checkout.form', [
'commerce_order' => $cart
->id(),
]),
];
}
}
if ($displayLinks['cart']) {
$links[] = [
'#type' => 'link',
'#title' => $this->configuration['cart_link_text'],
'#url' => Url::fromRoute('commerce_cart.page'),
];
}
return $links;
}
protected function getCountText() {
if (!$this
->getCartCount()) {
return $this->configuration['count_text_empty'];
}
return $this
->formatPlural($this
->getCartCount(), $this->configuration['count_text_singular'], $this->configuration['count_text_plural']);
}
protected function getTotal() {
$carts = $this
->getCarts();
$firstCart = array_shift($carts);
if (!empty($firstCart)) {
$price = $firstCart
->getTotalPrice();
foreach ($carts as $cart_id => $cart) {
$price
->add($cart
->getTotalPrice());
}
}
else {
$price = $this
->createPrice(0);
}
return $price;
}
protected function createPrice($amount) {
$storage = $this->entityTypeManager
->getStorage('commerce_store');
$defaultStore = $storage
->loadDefault();
$currencyCode = $defaultStore ? $defaultStore
->getDefaultCurrencyCode() : 'USD';
return new Price($amount, $currencyCode);
}
protected function getTotalText() {
$element = [];
$element['price'] = [
'#type' => 'inline_template',
'#template' => '{{ price|commerce_price_format }}',
'#context' => [
'price' => $this
->getTotal(),
],
];
return \Drupal::service('renderer')
->renderPlain($element);
}
protected function getLibraries() {
return [];
}
protected function getCacheabilityMetadata() {
$carts = $this
->getCarts();
$cacheableMetadata = new CacheableMetadata();
$cacheableMetadata
->addCacheContexts([
'user',
'session',
]);
foreach ($carts as $cart) {
$cacheableMetadata
->addCacheableDependency($cart);
}
return $cacheableMetadata;
}
protected function getCartCount() {
$carts = $this
->getCarts();
$count = 0;
foreach ($carts as $cart_id => $cart) {
foreach ($cart
->getItems() as $order_item) {
$count += (int) $order_item
->getQuantity();
}
}
return $count;
}
protected function getCarts() {
$carts = $this->cartProvider
->getCarts();
return array_filter($carts, function ($cart) {
return $cart
->hasItems() && $cart->cart->value;
});
}
protected function shouldHide() {
return $this->configuration['hide_if_empty'] && !$this
->getCartCount();
}
protected function getCartViews() {
$carts = $this
->getCarts();
$availableViews = $this
->getAvailableViews($carts);
$cartViews = [];
foreach ($carts as $cartId => $cart) {
$cartViews[] = [
'#prefix' => '<div class="cart cart-block">',
'#suffix' => '</div>',
'#type' => 'view',
'#name' => $availableViews[$cartId],
'#arguments' => [
$cartId,
],
'#embed' => TRUE,
];
}
return $cartViews;
}
private function getOrderTypeIds(array $carts) {
return array_map(function ($cart) {
return $cart
->bundle();
}, $carts);
}
private function getAvailableViews(array $carts) {
try {
$orderTypeIds = $this
->getOrderTypeIds($carts);
$orderTypeStorage = $this->entityTypeManager
->getStorage('commerce_order_type');
$orderTypes = $orderTypeStorage
->loadMultiple(array_unique($orderTypeIds));
$availableViews = [];
foreach ($orderTypeIds as $cartId => $order_type_id) {
$order_type = $orderTypes[$order_type_id];
$availableViews[$cartId] = $order_type
->getThirdPartySetting('commerce_cart', 'cart_block_view', 'commerce_cart_block');
}
return $availableViews;
} catch (InvalidPluginDefinitionException $e) {
return [];
}
}
public function getCacheMaxAge() {
return 0;
}
}