arch-8.x-1.x-dev/modules/cart/arch_cart.module
modules/cart/arch_cart.module
<?php /** * @file * Cart module file. */ use Drupal\arch_product\Entity\ProductType; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Template\Attribute; use Drupal\Core\Url; /** * Implements hook_theme(). */ function arch_cart_theme($existing, $type, $theme, $path) { return [ 'add_to_api_cart' => [ 'variables' => [ 'product' => NULL, 'text' => NULL, 'not_available_text' => NULL, 'attributes' => [], 'icon_attributes' => [], 'throbber_attributes' => [], ], ], 'api_cart_template' => [ 'variables' => [ 'title' => NULL, 'grand_total_label' => NULL, 'cart_link' => NULL, 'checkout_link' => NULL, 'settings' => NULL, ], ], 'mini_cart' => [ 'variables' => [ 'attributes' => NULL, 'count' => NULL, 'url' => NULL, 'text' => NULL, 'link_attributes' => NULL, 'templates' => NULL, 'settings' => NULL, ], ], 'cart_page_totals' => [ 'variables' => [ 'price_format_settings' => [], 'cart' => NULL, 'total_price' => NULL, 'grand_total_price' => NULL, 'subtotal_price' => NULL, 'subtotal_vat_price' => NULL, 'grandtotal_price' => NULL, 'grandtotal_vat_price' => NULL, 'hide_subtotal' => NULL, 'hide_subtotal_vat' => NULL, 'hide_grandtotal' => NULL, 'hide_grandtotal_vat' => TRUE, 'subtotal_label' => NULL, 'subtotal_vat_label' => NULL, 'grandtotal_label' => NULL, 'grandtotal_vat_label' => NULL, 'attributes' => [], 'subtotal_attributes' => [], 'subtotal_vat_attributes' => [], 'grandtotal_attributes' => [], 'grandtotal_vat_attributes' => [], 'subtotal_label_attributes' => [], 'subtotal_vat_label_attributes' => [], 'grandtotal_label_attributes' => [], 'grandtotal_vat_label_attributes' => [], ], ], ]; } /** * Implements hook_preprocess_HOOK(). */ function template_preprocess_add_to_api_cart(&$variables) { /** @var \Drupal\arch_product\Entity\ProductInterface $product */ $product = &$variables['product']; $is_available = $product->availableForSell($variables['user']); $has_price = TRUE; if ( !$product->hasPrice() || $product->getActivePrice()->getNetPrice() <= 0 ) { $has_price = FALSE; } $variables['attributes']['class'][] = 'button'; $variables['attributes']['class'][] = 'form-submit'; $variables['attributes']['class'][] = 'add-to-api-cart--button'; $variables['attributes']['data-quantity'] = 1; $variables['attributes']['data-product-id'] = $product->id(); if ($has_price && $is_available) { $variables['attributes']['data-enabled'] = TRUE; } else { $variables['attributes']['disabled'] = TRUE; $variables['attributes']['data-disabled'] = TRUE; } $variables['has_price'] = $has_price; $variables['available_for_sell'] = $is_available; if (!$has_price) { $variables['has_price'] = FALSE; $variables['attributes']['class'][] = 'add-to-api-cart--button--no-price'; } if (!$is_available) { $variables['available_for_sell'] = FALSE; $variables['attributes']['class'][] = 'add-to-api-cart--button--not-available-for-sell'; } if (empty($variables['text'])) { $variables['text'] = t('Add to cart', [], ['context' => 'arch_cart']); } if (empty($variables['not_available_text'])) { $variables['not_available_text'] = t('Not available', [], ['context' => 'arch_cart']); } if (empty($variables['icon_attributes'])) { $variables['icon_attributes']['class'][] = 'ajax-progress'; $variables['icon_attributes']['class'][] = 'ajax-progress-throbber'; } if (empty($variables['throbber_attributes'])) { $variables['throbber_attributes']['class'][] = 'throbber'; } $variables['attributes'] = new Attribute($variables['attributes']); $variables['icon_attributes'] = new Attribute($variables['icon_attributes']); $variables['throbber_attributes'] = new Attribute($variables['throbber_attributes']); $variables['#attached']['library'][] = 'arch_cart/add-to-api-cart'; $variables['#attached']['drupalSettings']['arch_api_cart']['api'] = _arch_cart_api_cart_endpoints(); $variables['#cache']['tags'][] = 'product'; $variables['#cache']['tags'][] = 'product:' . $product->id(); } /** * Implements hook_preprocess_HOOK(). */ function template_preprocess_api_cart_template(&$variables) { if (empty($variables['title'])) { $variables['title'] = t('Cart', [], ['context' => 'arch_cart']); } if (empty($variables['grand_total_label'])) { $variables['grand_total_label'] = t('Grand total', [], ['context' => 'arch_cart']); } if (empty($variables['remove_title'])) { $variables['remove_title'] = t('Remove', [], ['context' => 'arch_cart']); } if (empty($variables['cart_link'])) { $variables['cart_link'] = [ '#type' => 'link', '#url' => Url::fromRoute('arch_cart.content'), '#title' => t('Cart', [], ['context' => 'arch_cart']), '#attributes' => [ 'class' => [ 'btn', 'btn-default', ], ], ]; } if (empty($variables['checkout_link'])) { $variables['checkout_link'] = [ '#type' => 'link', '#url' => Url::fromRoute('arch_checkout.checkout'), '#title' => t('Checkout', [], ['context' => 'arch_cart']), '#attributes' => [ 'class' => [ 'btn', 'btn-default', ], ], ]; } $variables['#attached']['drupalSettings']['arch_api_cart']['templates'] = [ 'cart' => '#arch-cart--api-cart', 'message' => '#arch-cart--message', 'item' => '#arch-cart--api-cart--item', 'itemQuantity' => '#arch-cart--api-cart--item--quantity', 'itemRemove' => '#arch-cart--api-cart--item--remove', 'count' => '#arch-cart--api-cart--count', ]; } /** * Implements hook_preprocess_HOOK(). */ function template_preprocess_mini_cart(&$variables) { if (!isset($variables['text'])) { $variables['text'] = t('Cart', [], ['context' => 'arch_cart']); } $variables['link_attributes'] = new Attribute($variables['link_attributes']); $variables['#attached']['library'][] = 'arch_cart/api-cart'; $variables['#attached']['drupalSettings']['arch_api_cart']['api'] = _arch_cart_api_cart_endpoints(); $variables['#attached']['drupalSettings']['arch_api_cart']['settings'] = [ 'theme' => !empty($variables['settings']['theme']) ? $variables['settings']['theme'] : NULL, 'allow_modify_quantity' => !empty($variables['settings']['allow_modify_quantity']), 'allow_remove' => !empty($variables['settings']['allow_remove']), 'show_cart_item_count' => !empty($variables['settings']['show_cart_item_count']), 'click_event' => !empty($variables['settings']['click_event']) ? $variables['settings']['click_event'] : 'open', ]; $variables['templates']['#settings'] = (array) $variables['settings']; } /** * Implements hook_preprocess_HOOK(). */ function template_preprocess_cart_page_totals(&$variables) { $labels = [ 'subtotal_label' => t('Subtotal', [], ['context' => 'arch_cart']), 'subtotal_vat_label' => t('VAT', [], ['context' => 'arch_price']), 'grandtotal_label' => t('Grand total', [], ['context' => 'arch_cart']), 'grandtotal_vat_label' => t('Grand total VAT', [], ['context' => 'arch_cart']), ]; foreach ($labels as $variable => $label) { if (empty($variables[$variable])) { $variables[$variable] = $label; } } /** @var \Drupal\arch_price\Price\PriceFormatterInterface $price_formatter */ $price_formatter = \Drupal::service('price_formatter'); /** @var \Drupal\arch_price\Price\PriceInterface $total_cart_price */ $total_cart_price = $variables['total_price']; /** @var \Drupal\arch_price\Price\PriceInterface $grand_total_price */ $grand_total_price = $variables['grand_total_price']; $price_format_settings = $variables['price_format_settings']; $variables['subtotal_price'] = $price_formatter->buildNet($total_cart_price, $price_format_settings); $variables['subtotal_vat_price'] = $price_formatter->buildVat($total_cart_price, $price_format_settings); $variables['grandtotal_price'] = $price_formatter->buildGross($grand_total_price, $price_format_settings); $variables['grandtotal_vat_price'] = $price_formatter->buildVat($grand_total_price, $price_format_settings); $attributes = [ 'attributes' => [ 'class' => [ 'totals', ], ], 'subtotal_attributes' => [ 'class' => [ 'total-item', 'total-item--subtotal', 'clearfix', ], ], 'subtotal_vat_attributes' => [ 'class' => [ 'total-item', 'total-item--subtotal-vat', 'clearfix', ], ], 'grandtotal_attributes' => [ 'class' => [ 'total-item', 'total-item--grandtotal', 'clearfix', ], ], 'grandtotal_vat_attributes' => [ 'class' => [ 'total-item', 'total-item--grandtotal-vat', 'clearfix', ], ], 'subtotal_label_attributes' => [ 'class' => [ 'total-item-label', 'total-item-label--subtotal', 'clearfix', ], ], 'subtotal_vat_label_attributes' => [ 'class' => [ 'total-item-label', 'total-item-label--subtotal-vat', 'clearfix', ], ], 'grandtotal_label_attributes' => [ 'class' => [ 'total-item-label', 'total-item-label--grandtotal', 'clearfix', ], ], 'grandtotal_vat_label_attributes' => [ 'class' => [ 'total-item-label', 'total-item-label--grandtotal-vat', 'clearfix', ], ], ]; foreach ($attributes as $variable => $defaults) { $attribute = NestedArray::mergeDeep($defaults, $variables[$variable]); $variables[$variable] = new Attribute($attribute); } } /** * Get list of API endpoints. * * @return array * Endpoints. */ function _arch_cart_api_cart_endpoints() { $endpoints = []; $cart = Url::fromRoute('arch_cart.api.cart'); $endpoints['cart'] = $cart->toString(); $cart_add = Url::fromRoute('arch_cart.api.cart_add'); $endpoints['add'] = $cart_add->toString(); $quantity = Url::fromRoute('arch_cart.api.cart_quantity'); $endpoints['quantity'] = $quantity->toString(); $remove = Url::fromRoute('arch_cart.api.cart_remove'); $endpoints['remove'] = $remove->toString(); return $endpoints; } /** * Implements hook_entity_extra_field_info(). */ function arch_cart_entity_extra_field_info() { $extra = []; /** @var \Drupal\arch_product\Entity\ProductTypeInterface $bundle */ foreach (ProductType::loadMultiple() as $bundle) { $extra['product'][$bundle->id()]['display']['add_to_api_cart'] = [ 'label' => t('Cart API: Add to cart', [], ['context' => 'arch_cart']), 'visible' => FALSE, ]; } return $extra; } /** * Implements hook_entity_view(). */ function arch_cart_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { if ($entity->getEntityTypeId() !== 'product') { return; } /** @var \Drupal\arch_product\Entity\ProductInterface $entity */ if ($display->getComponent('add_to_api_cart')) { $build['add_to_api_cart'] = [ '#theme' => 'add_to_api_cart', '#product' => $entity, ]; } }