arch-8.x-1.x-dev/modules/order/arch_order.module

modules/order/arch_order.module
<?php
/**
 * @file
 * Arch Order module.
 */

use Drupal\arch_order\Entity\OrderInterface;
use Drupal\arch_order\Services\OrderAddressServiceInterface;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Template\Attribute;

require_once __DIR__ . '/includes/deprecated.inc';

/**
 * Implements hook_theme().
 */
function arch_order_theme() {
  return [
    'order' => [
      'render element' => 'elements',
    ],
    'order_line_items__advanced' => [
      'render element' => 'elements',
    ],
  ];
}

/**
 * Implements hook_entity_extra_field_info().
 */
function arch_order_entity_extra_field_info() {
  $extra = [];

  $extra['order']['order']['display']['shipping_price'] = [
    'label' => t('Shipping price', [], ['context' => 'arch_order']),
    'weight' => 100,
    'visible' => TRUE,
  ];
  $extra['order']['order']['display']['shipping_extra'] = [
    'label' => t('Shipping extra', [], ['context' => 'arch_order']),
    'weight' => 101,
    'visible' => TRUE,
  ];

  $extra['order']['order']['display']['payment_fee'] = [
    'label' => t('Payment fee', [], ['context' => 'arch_order']),
    'weight' => 110,
    'visible' => TRUE,
  ];

  $extra['order']['order']['display']['exchange_rate'] = [
    'label' => t('Exchange rate', [], ['context' => 'arch_order']),
    'weight' => 120,
    'visible' => TRUE,
  ];

  return $extra;
}

/**
 * Implements hook_ENTITY_TYPE_view_alter().
 */
function arch_order_order_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
  $order_data = [];
  if (
    !$entity->get('data')->isEmpty()
    && $entity->get('data')->count() > 0
  ) {
    $order_data = $entity->get('data')->first()->getValue();
  }

  $shipping_price = NULL;
  $shipping_extra = NULL;
  $payment_fee = NULL;
  foreach ($entity->get('line_items') as $line_item) {
    /** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemFieldItem $line_item */

    if ($line_item->isShipping()) {
      $shipping_price = $line_item;
    }
    elseif ($line_item->isShippingExtra()) {
      $shipping_extra = $line_item;
    }
    elseif ($line_item->isPaymentFee()) {
      $payment_fee = $line_item;
    }
  }

  /** @var \Drupal\arch_price\Price\PriceFactoryInterface $price_factory */
  $price_factory = \Drupal::service('price_factory');
  /** @var \Drupal\arch_price\Price\PriceFormatterInterface $price_formatter */
  $price_formatter = \Drupal::service('price_formatter');
  $formatter_defaults = [
    'vat_info' => FALSE,
    'label' => FALSE,
    'wrapper_element' => 'span',
  ];

  if (
    $display->getComponent('shipping_price')
    && !empty($shipping_price)
    && (float) $shipping_price->get('calculated_gross')->getValue() > 0
  ) {
    $price = $price_factory->getInstance([
      'base' => 'gross',
      'net' => $shipping_price->get('calculated_net')->getValue(),
      'gross' => $shipping_price->get('calculated_gross')->getValue(),
      'vat_rate' => $shipping_price->get('calculated_vat_rate')->getValue(),
      'vat_category' => $shipping_price->get('calculated_vat_cat_name')->getValue(),
      'vat_amount' => $shipping_price->get('calculated_vat_amount')->getValue(),
      'currency' => $entity->get('currency')->getString(),
    ]);

    $display_shipping_price = $display->getComponent('shipping_price');
    $build['shipping_price'] = [
      '#weight' => $display_shipping_price['weight'],
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'field',
          'field--name-shipping-price',
          'field--type-string',
          'field--label-inline',
        ],
      ],
      'label' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => t('Shipping price', [], ['context' => 'arch_order']),
        '#attributes' => [
          'class' => [
            'field--label',
          ],
        ],
      ],
      'value' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => $price_formatter->formatGross($price, $formatter_defaults),
        '#attributes' => [
          'class' => [
            'field--item',
          ],
        ],
      ],
    ];
  }

  if (
    $display->getComponent('shipping_extra')
    && !empty($shipping_extra)
    && (float) $shipping_extra->get('calculated_gross')->getValue() > 0
  ) {
    $price = $price_factory->getInstance([
      'base' => 'gross',
      'net' => $shipping_extra->get('calculated_net')->getValue(),
      'gross' => $shipping_extra->get('calculated_gross')->getValue(),
      'vat_rate' => $shipping_extra->get('calculated_vat_rate')->getValue(),
      'vat_category' => $shipping_extra->get('calculated_vat_cat_name')->getValue(),
      'vat_amount' => $shipping_extra->get('calculated_vat_amount')->getValue(),
      'currency' => $entity->get('currency')->getString(),
    ]);

    $display_shipping_extra = $display->getComponent('shipping_extra');
    $build['shipping_extra'] = [
      '#weight' => $display_shipping_extra['weight'],
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'field',
          'field--name-shipping-extra-price',
          'field--type-string',
          'field--label-inline',
        ],
      ],
      'label' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => t('Shipping extra', [], ['context' => 'arch_order']),
        '#attributes' => [
          'class' => [
            'field--label',
          ],
        ],
      ],
      'value' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => $price_formatter->formatGross($price, $formatter_defaults),
        '#attributes' => [
          'class' => [
            'field--item',
          ],
        ],
      ],
    ];
  }

  if (
    $display->getComponent('payment_fee')
    && !empty($payment_fee)
    && (float) $payment_fee->get('calculated_gross')->getValue() > 0
  ) {
    $price = $price_factory->getInstance([
      'base' => 'gross',
      'net' => $payment_fee->get('calculated_net')->getValue(),
      'gross' => $payment_fee->get('calculated_gross')->getValue(),
      'vat_rate' => $payment_fee->get('calculated_vat_rate')->getValue(),
      'vat_category' => $payment_fee->get('calculated_vat_cat_name')->getValue(),
      'vat_amount' => $payment_fee->get('calculated_vat_amount')->getValue(),
      'currency' => $entity->get('currency')->getString(),
    ]);

    $build['payment_fee'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'field',
          'field--name-payment-fee',
          'field--type-string',
          'field--label-inline',
        ],
      ],
      'label' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => t('Payment fee', [], ['context' => 'arch_order']),
        '#attributes' => [
          'class' => [
            'field--label',
          ],
        ],
      ],
      'value' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => $price_formatter->formatGross($price, $formatter_defaults),
        '#attributes' => [
          'class' => [
            'field--item',
          ],
        ],
      ],
    ];
  }

  if (
    $display->getComponent('exchange_rate')
    && isset($order_data['exchange_rate'])
    && !empty($order_data['exchange_rate'])
  ) {
    $exchange_currency = NULL;
    if (isset($order_data['exchange_currency'])) {
      $exchange_currency = '<span class="exchange-currency"><b>' . t('Source currency', [], ['context' => 'arch_order'])->render() . '</b>: ' . $order_data['exchange_currency'] . '</span>';
    }

    $build['exchange_rate'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'field',
          'field--name-exchange-rate',
          'field--type-string',
          'field--label-inline',
        ],
      ],
      'label' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => t('Exchange rate', [], ['context' => 'arch_order']),
        '#attributes' => [
          'class' => [
            'field--label',
          ],
        ],
      ],
      'value' => [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#value' => $order_data['exchange_rate'] . ($exchange_currency ?: ''),
        '#attributes' => [
          'class' => [
            'field--item',
          ],
        ],
      ],
    ];
  }
}

/**
 * Add english translation for the order mails.
 */
function _arch_order_install_english_order_mails() {
  /** @var \Drupal\arch_order\OrderMail\OrderMailManagerInterface $mail_manager */
  $mail_manager = \Drupal::service('arch_order_mail');

  $langcode = 'en';
  $mail_list = [
    'order_confirmation_to_user' => [
      'subject' => 'Thanks for your order!',
      'body' => 'Thank you for your purchase!',
    ],
    'order_confirmation_to_shop' => [
      'subject' => 'New order',
      'body' => 'New order received!',
    ],
    'order_modification' => [
      'subject' => 'Order modified',
      'body' => 'The order has changed!',
    ],
    'order_status_change' => [
      'subject' => 'Order status changed',
      'body' => 'Order status has been updated!',
    ],
  ];

  foreach ($mail_list as $plugin_id => $item) {
    /** @var \Drupal\arch_order\OrderMail\OrderMailBase $plugin */
    $plugin = $mail_manager->get($plugin_id);
    if (!$plugin) {
      continue;
    }

    $plugin->setTranslation(
      $langcode,
      $item['subject'],
      [
        'format' => 'basic_html',
        'value' => $item['body'],
      ]
    );
  }
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function arch_order_theme_suggestions_order(array $variables) {
  $suggestions = [];
  /** @var \Drupal\arch_order\Entity\OrderInterface $order */
  $order = $variables['elements']['#order'];
  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');

  $suggestions[] = 'order__' . $sanitized_view_mode;
  $suggestions[] = 'order__' . $order->id();
  $suggestions[] = 'order__' . $order->id() . '__' . $sanitized_view_mode;

  return $suggestions;
}

/**
 * Implements hook_menu_links_discovered_alter().
 */
function arch_order_menu_links_discovered_alter(&$links) {
  if (\Drupal::moduleHandler()->moduleExists('field_ui')) {
    $links['entity.order.field_ui_fields_'] = [
      'title' => t('Manage fields'),
      'route_name' => 'entity.order.field_ui_fields',
      'menu_name' => 'admin',
      'parent' => 'entity.order.admin_form',
    ];
    $links['entity.entity_form_display.order.default_'] = [
      'title' => t('Manage form display'),
      'route_name' => 'entity.entity_form_display.order.default',
      'menu_name' => 'admin',
      'parent' => 'entity.order.admin_form',
    ];
    $links['entity.entity_view_display.order.default_'] = [
      'title' => t('Manage display'),
      'route_name' => 'entity.entity_view_display.order.default',
      'menu_name' => 'admin',
      'parent' => 'entity.order.admin_form',
    ];
  }
}

/**
 * Fetches an array of permission IDs granted to the given user ID.
 *
 * The implementation here provides only the universal "all" grant. A produc
 * access module should implement hook_order_grants() to provide a grant list
 * for the user.
 *
 * After the default grants have been loaded, we allow modules to alter the
 * grants array by reference. This hook allows for complex business logic to be
 * applied when integrating multiple order access modules.
 *
 * @param string $op
 *   The operation that the user is trying to perform.
 * @param \Drupal\Core\Session\AccountInterface $account
 *   The account object for the user performing the operation.
 *
 * @return array
 *   An associative array in which the keys are realms, and the values are
 *   arrays of grants for those realms.
 */
function arch_order_access_grants($op, AccountInterface $account) {
  // Fetch order access grants from other modules.
  $grants = \Drupal::moduleHandler()->invokeAll('order_grants', [$account, $op]);
  // Allow modules to alter the assigned grants.
  \Drupal::moduleHandler()->alter('order_grants', $grants, $account, $op);

  return array_merge(['all' => [0]], $grants);
}

/**
 * Implements hook_entity_operation().
 */
function arch_order_entity_operation(EntityInterface $entity) {
  if ($entity->getEntityTypeId() === 'order') {
    $operations = [];
    $has_view_access = $entity->access('view');

    if ($has_view_access) {
      $operations['view'] = [
        'title' => t('View'),
        'weight' => 20,
        'url' => $entity->toUrl(),
      ];
    }

    $has_revision_view_access = $entity->access('view all order revisions');

    if ($has_revision_view_access && $entity->hasLinkTemplate('version-history')) {
      $operations['revisions'] = [
        'title' => t('Revisions'),
        'weight' => 50,
        'url' => $entity->toUrl('version-history'),
      ];
    }

    return $operations;
  }
}

/**
 * Implements hook_entity_operation_alter().
 */
function arch_order_entity_operation_alter(array &$operations, EntityInterface $entity) {
  if ($entity->getEntityTypeId() === 'order') {
    $current_language = \Drupal::languageManager()->getCurrentLanguage();

    foreach ($operations as $key => $operation) {
      $operations[$key]['url']->setOption('language', $current_language);
    }
  }
}

/**
 * Implements hook_element_info_alter().
 *
 * @see \Drupal\arch_order\Element\OrderStatusesSelect
 */
function arch_order_element_info_alter(array &$info) {
  // Alter the order_statuses_select element so that it will be rendered like a
  // select field.
  if (isset($info['order_statuses_select'])) {
    if (!isset($info['order_statuses_select']['#process'])) {
      $info['order_statuses_select']['#process'] = [];
    }
    if (!isset($info['order_statuses_select']['#theme_wrappers'])) {
      $info['order_statuses_select']['#theme_wrappers'] = [];
    }
    $info['order_statuses_select']['#process'] = array_merge(
      $info['order_statuses_select']['#process'],
      [
        'arch_order_process_order_statuses_select',
        ['Drupal\Core\Render\Element\Select', 'processSelect'],
        ['Drupal\Core\Render\Element\RenderElement', 'processAjaxForm'],
      ]
    );
    $info['order_statuses_select']['#theme'] = 'select';
    $info['order_statuses_select']['#theme_wrappers'] = array_merge($info['order_statuses_select']['#theme_wrappers'], ['form_element']);
    $info['order_statuses_select']['#multiple'] = FALSE;
  }
}

/**
 * Processes a order statuses select list form element.
 *
 * @param array $element
 *   The form element to process.
 *
 * @return array
 *   The processed form element.
 */
function arch_order_process_order_statuses_select(array $element) {
  if (!isset($element['#options'])) {
    /** @var \Drupal\arch_order\Entity\OrderStatusInterface[] $order_statuses */
    $order_statuses = \Drupal::service('order.statuses')->getOrderStatuses();
    foreach ($order_statuses as $id => $order_status) {
      $element['#options'][$id] = $order_status->getLabel();
    }
  }

  return $element;
}

/**
 * Implements hook_local_tasks_alter().
 */
function arch_order_local_tasks_alter(&$local_tasks) {
  if (isset($local_tasks['entity.revisions_overview:order'])) {
    unset($local_tasks['entity.revisions_overview:order']);
  }
}

/**
 * Implements hook_entity_load().
 */
function arch_order_entity_load(array $entities, $entity_type_id) {
  if ($entity_type_id !== 'order') {
    return;
  }

  /** @var \Drupal\arch_order\Services\OrderAddressServiceInterface $order_address_service */
  $order_address_service = \Drupal::service('order.address');

  /** @var \Drupal\arch_payment\PaymentMethodManagerInterface $payment_method_manager */
  $payment_method_manager = \Drupal::service('plugin.manager.payment_method');

  /** @var \Drupal\arch_order\Entity\OrderInterface $entity */
  foreach ($entities as $entity) {
    $entity->setOrderAddressService($order_address_service);
    $addresses = $order_address_service->getAddresses($entity->id());
    if (!empty($addresses)) {
      foreach ($addresses as $address) {
        if ($address->address_type == OrderAddressServiceInterface::TYPE_BILLING) {
          $entity->setBillingAddress($address);
        }
        elseif ($address->address_type == OrderAddressServiceInterface::TYPE_SHIPPING) {
          $entity->setShippingAddress($address);
        }
      }
    }

    $payment_method = $entity->get('payment_method');
    if (!empty($payment_method)) {
      $payment_method_plugin_id = $payment_method->getString();
      try {
        $payment_method = $payment_method_manager->createInstance($payment_method_plugin_id);
        $entity->setPaymentMethod($payment_method);
      }
      catch (PluginException $e) {
        // @todo Handle error.
      }
    }
  }
}

/**
 * Implements hook_checkout_completed().
 */
function arch_order_checkout_completed(OrderInterface $order) {
  if ($order->getEntityTypeId() !== 'order') {
    return;
  }

  /** @var \Drupal\arch_order\OrderMail\OrderMailManagerInterface $order_mail_manager */
  $order_mail_manager = \Drupal::service('arch_order_mail');

  $order_mail_manager->send('order_confirmation_to_user', $order);
  $order_mail_manager->send('order_confirmation_to_shop', $order);
}

/**
 * Implements hook_entity_update().
 */
function arch_order_entity_update(EntityInterface $entity) {
  if (\Drupal::isConfigSyncing()) {
    // Do not change data while config import in progress.
    return;
  }

  if ($entity->getEntityTypeId() !== 'order' || !isset($entity->original)) {
    return;
  }

  /** @var \Drupal\arch_order\OrderMail\OrderMailManagerInterface $order_mail_manager */
  $order_mail_manager = \Drupal::service('arch_order_mail');

  $old_status = $entity->original->get('status')->getValue()[0]['value'];
  $new_status = $entity->get('status')->getValue()[0]['value'];

  if ($old_status !== $new_status) {
    $order_mail_manager->send('order_status_change', $entity);
  }
  else {
    $order_mail_manager->send('order_modification', $entity);
  }
}

/**
 * Checks if the current page is the full page view of the passed-in order.
 *
 * @param Drupal\arch_order\Entity\OrderInterface $order
 *   A order entity.
 *
 * @return int|false
 *   The ID of the order if this is a full page view, otherwise FALSE.
 */
function arch_order_is_page(OrderInterface $order) {
  $route_match = \Drupal::routeMatch();
  if ($route_match->getRouteName() == 'entity.order.canonical') {
    $page = $route_match->getParameter('order');
  }
  return (!empty($page) ? $page->id() == $order->id() : FALSE);
}

/**
 * Prepares variables for order templates.
 *
 * Default template: order.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An array of elements to display in view mode.
 *   - order: The order object.
 *   - view_mode: View mode; e.g., 'full', 'teaser', etc.
 */
function template_preprocess_order(array &$variables) {
  $variables['view_mode'] = $variables['elements']['#view_mode'];
  // Provide a distinct $teaser boolean.
  $variables['teaser'] = $variables['view_mode'] == 'teaser';
  $variables['order'] = $variables['elements']['#order'];
  /** @var \Drupal\arch_order\Entity\OrderInterface $order */
  $order = $variables['order'];
  $variables['date'] = \Drupal::service('renderer')->render($variables['elements']['created']);
  unset($variables['elements']['created']);
  $variables['author_name'] = \Drupal::service('renderer')->render($variables['elements']['uid']);
  unset($variables['elements']['uid']);

  $variables['url'] = $order->toUrl('canonical');
  $variables['label'] = $order->get($order->getEntityType()->getKey('label'))->getString();
  // The 'page' variable is set to TRUE if:
  // - The view mode is 'full' and we are on the 'order.view' route.
  $variables['page'] = (
    $variables['view_mode'] == 'full'
    && arch_order_is_page($order)
  );

  // Helpful $content variable for templates.
  $variables += ['content' => []];
  foreach (Element::children($variables['elements']) as $key) {
    $variables['content'][$key] = $variables['elements'][$key];
  }

  // Used by RDF to add attributes around the author and date submitted.
  $variables['author_attributes'] = new Attribute();

  // Add article ARIA role.
  $variables['attributes']['role'] = 'article';
}

/**
 * Prepares variables for order templates.
 *
 * Default template: order-line-items--advanced.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An array of elements to display in view mode.
 *   - order: The order object.
 *   - products: Product entities object.
 */
function template_preprocess_order_line_items__advanced(array &$variables) {
  // Add table ARIA role.
  $variables['attributes']['role'] = 'table';
  $variables['attributes']['class'][] = 'order--line-items';
  $variables['attributes']['class'][] = 'advanced';

  $variables['order'] = $variables['elements']['#order'];
  $variables['products'] = $variables['elements']['#products'];
  $variables['rows'] = $variables['elements']['#rows'];
  $variables['url'] = $variables['elements']['#url'];
}

/**
 * Implements hook_mail().
 */
function arch_order_mail($key, &$message, $params) {
  switch ($key) {
    case 'arch_order_mail_manager':
      if (isset($params['from'])) {
        $message['from'] = $params['from'];
      }
      else {
        $message['from'] = \Drupal::config('system.site')->get('mail');
      }
      $message['subject'] = $params['subject'];
      $html = check_markup($params['message'], 'basic_html');
      $message['body'][] = new FormattableMarkup($html, []);

      // Set HTML Header.
      $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
      $message['params']['format'] = 'text/html';
      $message['params']['plain'] = NULL;

      break;

  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc