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; } }