arch-8.x-1.x-dev/modules/price/arch_price.module
modules/price/arch_price.module
<?php
/**
* @file
* Enables the organization of content into categories.
*/
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Element;
use Drupal\Core\Template\Attribute;
/**
* Implements hook_theme().
*/
function arch_price_theme() {
return [
'price' => [
'render element' => 'elements',
],
'price_form_table' => [
'render element' => 'element',
],
];
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function arch_price_theme_suggestions_price(array $variables) {
$suggestions = [];
$suggestions[] = 'price__' . $variables['elements']['#mode'];
return $suggestions;
}
/**
* Prepares variables for price templates.
*
* Default template: price.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An associative array containing the price. Properties used:
* - #price: A \Drupal\arch_price\PriceInterface object.
* - #view_mode: The current view mode for this price, e.g.
* 'full' or 'teaser'.
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_price(array &$variables) {
$mode = $variables['elements']['#mode'];
/** @var \Drupal\currency\Entity\CurrencyInterface $currency */
$currency = $variables['elements']['#currency'];
$currency_code = $variables['elements']['#values']['currency'];
$variables['#cache']['tags'][] = 'currency:' . $currency_code;
if (
$mode == 'vat'
&& empty($variables['elements']['#values'][$mode])
) {
$price_value = $variables['elements']['#values']['vat_value'];
}
else {
$price_value = $variables['elements']['#values'][$mode];
}
$wrapper_element = 'div';
if (
!empty($variables['elements']['#settings']['wrapper_element'])
&& is_string($variables['elements']['#settings']['wrapper_element'])
) {
$wrapper_element = $variables['elements']['#settings']['wrapper_element'];
}
$variables['wrapper_element'] = $wrapper_element;
$variables['attributes'] = [
'class' => [
'price',
'price--' . $mode,
'price--' . $currency_code,
'price--' . $mode . '--' . $currency_code,
],
'data-price-type' => $mode,
'data-price-currency' => $currency_code,
'data-price-value' => $price_value,
];
$variables['title_attributes'] = [
'class' => [
'price-label',
],
];
$variables['mode'] = $mode;
$variables['currency_sign'] = $currency->getSign();
$variables['label'] = $variables['elements']['#label'];
$variables['label_display'] = (bool) $variables['elements']['#label_display'];
$variables['original_price'] = (isset($variables['elements']['#original_price']) ? (bool) $variables['elements']['#original_price'] : FALSE);
$variables['modified_price'] = (isset($variables['elements']['#modified_price']) ? (bool) $variables['elements']['#modified_price'] : FALSE);
$variables['has_modified_price'] = (isset($variables['elements']['#has_modified_price']) ? (bool) $variables['elements']['#has_modified_price'] : FALSE);
$variables['show_original'] = (isset($variables['elements']['#settings']['show_original']) ? (bool) $variables['elements']['#settings']['show_original'] : FALSE);
$template = $variables['elements']['#formatted'];
$template = str_replace($variables['currency_sign'], '<span{{ attributes }}>{{ currency_sign }}</span>', $template);
$template = str_replace($variables['currency_sign'], '<span{{ attributes }}>{{ currency_sign }}</span>', $template);
$variables['price'] = [
'#type' => 'inline_template',
'#template' => $template,
'#context' => [
'currency_sign' => $currency->getSign(),
'attributes' => new Attribute([
'class' => [
'currency-sign',
'currency-sign--' . $currency_code,
],
]),
],
];
if (!(bool) $variables['elements']['#vat_info_display']) {
return;
}
if ($mode == 'gross') {
$vat_info_text = t('Includes @vat% VAT', ['@vat' => $variables['elements']['#vat_rate'] * 100], ['context' => 'arch_price']);
}
elseif ($mode == 'net') {
$vat_info_text = t('VAT (@vat%) not included', ['@vat' => $variables['elements']['#vat_rate'] * 100], ['context' => 'arch_price']);
}
$variables['vat_info'] = [
'#type' => 'inline_template',
'#template' => '<span{{ attributes }}>{{ vat_info }}</span>',
'#context' => [
'vat_info' => $vat_info_text,
'attributes' => new Attribute([
'class' => [
'includes-vat',
],
]),
],
];
}
/**
* Get names for all price type.
*
* @return array
* A list of existing price type IDs.
*/
function arch_price_price_type_get_names() {
$names = &drupal_static(__FUNCTION__);
if (!isset($names)) {
$names = [];
$config_names = \Drupal::configFactory()->listAll('arch_price.price_type.');
foreach ($config_names as $config_name) {
$id = substr($config_name, strlen('arch_price.price_type.'));
$names[$id] = $id;
}
}
return $names;
}
/**
* Get names for all VAT category.
*
* @return array
* A list of existing VAT category IDs.
*/
function arch_price_vat_category_get_names() {
$names = &drupal_static(__FUNCTION__);
if (!isset($names)) {
$names = [];
$config_names = \Drupal::configFactory()->listAll('arch_price.vat_category.');
foreach ($config_names as $config_name) {
$id = substr($config_name, strlen('arch_price.vat_category.'));
$names[$id] = $id;
}
}
return $names;
}
/**
* Preprocess arch price form table.
*
* @param array $variables
* Variables array.
*/
function template_preprocess_price_form_table(array &$variables) {
$element = $variables['element'];
$variables['multiple'] = $element['#cardinality_multiple'];
$variables['label'] = [
'#theme' => 'form_element_label',
'#title' => $element['#title'],
'#title_display' => 'above',
];
if (empty($variables['multiple'])) {
$variables['elements'] = [];
foreach (Element::children($element) as $key) {
$variables['elements'][] = $element[$key];
}
return;
}
$table_id = Html::getUniqueId($element['#field_name'] . '_values');
$order_class = $element['#field_name'] . '-delta-order';
$header = [
[
'data' => NULL,
],
[
'data' => t('Price type', [], ['context' => 'arch_price']),
'class' => ['header-value', 'header-value--type', 'col-narrow'],
],
[
'data' => t('Currency', [], ['context' => 'arch_price']),
'class' => ['header-value', 'header-value--currency', 'col-narrow'],
],
[
'data' => t('Price', [], ['context' => 'arch_price']),
'class' => ['header-value', 'header-value--price', 'col-narrow'],
],
[
'data' => t('VAT', [], ['context' => 'arch_price']),
'class' => ['header-value', 'header-value--vat', 'col-narrow'],
],
[
'data' => t('Date limitation', [], ['context' => 'arch_price']),
'class' => ['header-value', 'header-value--dates'],
],
t('Order', [], ['context' => 'Sort order']),
];
$rows = [];
// Sort items according to '_weight' (needed when the form comes back after
// preview or failed validation).
$items = [];
$variables['button'] = [];
$fields = [
'base' => [
'#title' => t('Base', [], ['context' => 'arch_price']),
],
'price_type' => [
'#title_display' => 'invisible',
],
'currency' => [
'#title_display' => 'invisible',
],
'net' => [
'#size' => 2,
],
'gross' => [
'#size' => 2,
],
'vat_category' => [
'#title' => t('Category', [], ['context' => 'arch_price__vat']),
],
'vat_rate' => [
'#size' => 2,
'#title' => t('Rate', [], ['context' => 'arch_price__vat']),
],
'vat_value' => [
'#size' => 2,
'#title' => t('Value', [], ['context' => 'arch_price__vat']),
],
'date_limitation' => [
'#title' => t('Date limitation', [], ['context' => 'arch_price__date']),
],
];
foreach (Element::children($element) as $key) {
if ($key === 'add_more') {
$variables['button'] = &$element[$key];
}
else {
$items[] = &$element[$key];
}
}
usort($items, '_field_multiple_value_form_sort_helper');
// Add the items as table rows.
foreach ($items as $item) {
$item['_weight']['#attributes']['class'] = [$order_class];
// Remove weight form element from item render array so it can be rendered
// in a separate table column.
$delta_element = $item['_weight'];
unset($item['_weight']);
foreach ($fields as $field => $settings) {
if (isset($item[$field])) {
$item[$field] = array_merge($item[$field], $settings);
}
}
$cells = [
[
'data' => '',
'class' => ['field-multiple-drag'],
],
[
'data' => $item['price_type'],
'class' => ['value', 'value--type', 'col-narrow'],
],
[
'data' => $item['currency'],
'class' => ['value', 'value--currency', 'col-narrow'],
],
[
'data' => [
$item['base'],
$item['net'],
$item['gross'],
],
'class' => ['value', 'value--price', 'col-narrow'],
],
[
'data' => [
$item['vat_category'],
$item['vat_rate'],
$item['vat_value'],
],
'class' => ['value', 'value--vat', 'col-narrow'],
],
[
'data' => [
$item['date_limitation'],
$item['dates'],
],
'class' => ['value', 'value--dates'],
],
['data' => $delta_element, 'class' => ['delta-order']],
];
$rows[] = [
'data' => $cells,
'class' => ['draggable'],
];
}
$variables['table'] = [
'#type' => 'table',
'#header' => $header,
'#rows' => $rows,
'#attributes' => [
'id' => $table_id,
'class' => [
'field-multiple-table',
'price-edit-table',
],
],
'#tabledrag' => [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => $order_class,
],
],
'#attached' => [
'library' => [
'arch_price/price_table_form',
],
],
];
if (!empty($element['#description'])) {
$description_id = $element['#attributes']['aria-describedby'];
$description_attributes['id'] = $description_id;
$variables['description']['attributes'] = new Attribute($description_attributes);
$variables['description']['content'] = $element['#description'];
// Add the description's id to the table aria attributes.
$variables['table']['#attributes']['aria-describedby'] = $element['#attributes']['aria-describedby'];
}
}
/**
* Implements hook_library_info_alter().
*/
function arch_price_library_info_alter(&$libraries, $extension) {
if ($extension == 'arch_price' && isset($libraries['price_widget'])) {
/** @var \Drupal\arch_price\Manager\PriceTypeManagerInterface $price_type_manager */
$price_type_manager = \Drupal::service('price_type.manager');
$price_types = $price_type_manager->getTypeListForWidget();
$libraries['price_widget']['drupalSettings']['arch_price']['price_types'] = $price_types;
/** @var \Drupal\arch_price\Manager\VatCategoryManagerInterface $vat_category_manager */
$vat_category_manager = \Drupal::service('vat_category.manager');
$vat_categories = $vat_category_manager->getVatCategoryListForWidget();
$libraries['price_widget']['drupalSettings']['arch_price']['vat_categories'] = $vat_categories;
}
}
