arch-8.x-1.x-dev/modules/price/src/Price/PriceFormatter.php

modules/price/src/Price/PriceFormatter.php
<?php

namespace Drupal\arch_price\Price;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\currency\Entity\CurrencyInterface;
use Drupal\currency\Plugin\Currency\AmountFormatter\AmountFormatterInterface;
use Drupal\currency\Plugin\Currency\AmountFormatter\AmountFormatterManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Price formatter service.
 *
 * @package Drupal\arch_price\Price
 */
class PriceFormatter implements PriceFormatterInterface, ContainerInjectionInterface {

  use StringTranslationTrait;

  /**
   * Renderer service.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Amount formatter.
   *
   * @var \Drupal\currency\Plugin\Currency\AmountFormatter\AmountFormatterInterface
   */
  protected $amountFormatter;

  /**
   * Currency entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $currencyStorage;

  /**
   * PriceFormatter constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager.
   * @param \Drupal\currency\Plugin\Currency\AmountFormatter\AmountFormatterManagerInterface $amount_formatter_manager
   *   Amount formatter manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   Module handler.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   Renderer.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    AmountFormatterManagerInterface $amount_formatter_manager,
    ModuleHandlerInterface $module_handler,
    RendererInterface $renderer,
  ) {
    $this->currencyStorage = $entity_type_manager->getStorage('currency');
    $this->amountFormatter = $amount_formatter_manager->createInstance('arch_price_currency_intl');
    $this->moduleHandler = $module_handler;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('plugin.manager.currency.amount_formatter'),
      $container->get('module_handler'),
      $container->get('renderer')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function setAmountFormatter(AmountFormatterInterface $amount_formatter) {
    $this->amountFormatter = $amount_formatter;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function buildFormatted(PriceInterface $price, $mode, array $settings = []) {
    if ($mode == self::FORMAT_FULL) {
      return $this->buildFull($price);
    }

    $price_values = $price->getValues();
    $currency = $price->getCurrency();

    $this->moduleHandler->alter('arch_price_display_settings', $settings, $price_values, $currency);

    $settings += ['wrapper_element' => 'div'];

    $values = [
      self::FORMAT_NET => $price_values['net'],
      self::FORMAT_GROSS => $price_values['gross'],
      self::FORMAT_VAT_VALUE => $price->getVatValue(),
    ];

    $label = NULL;
    if ($mode === self::FORMAT_NET) {
      $label = $this->t('Net', [], ['context' => 'arch_price']);
    }
    elseif ($mode === self::FORMAT_GROSS) {
      $label = $this->t('Gross', [], ['context' => 'arch_price']);
    }
    elseif ($mode === self::FORMAT_VAT_VALUE) {
      $label = $this->t('VAT', [], ['context' => 'arch_price']);
      $settings['vat_info'] = FALSE;
    }

    if (
      !empty($settings['display_currency'])
      && $settings['display_currency'] != $currency->id()
    ) {
      /** @var \Drupal\currency\Entity\CurrencyInterface $display_currency */
      $display_currency = $this->currencyStorage->load($settings['display_currency']);
      if (
        !empty($display_currency)
        && $exchanged_values = $price->getExchangedPriceValues($display_currency)
      ) {
        $price_values = $exchanged_values;
        $currency = $display_currency;
        $values = [
          self::FORMAT_NET => $price_values['net'],
          self::FORMAT_GROSS => $price_values['gross'],
          self::FORMAT_VAT_VALUE => $price_values['vat_value'],
        ];
      }
    }

    $build = [
      '#theme' => 'price',
      '#mode' => $mode,
      '#values' => $price_values,
      '#currency' => $currency,
      '#settings' => $settings,
      '#label' => $label,
      '#label_display' => $settings['label'] ?? TRUE,
      '#vat_rate' => $price->getVatRate(),
      '#vat_info_display' => $settings['vat_info'] ?? TRUE,
      '#formatted' => $this->amountFormatter->formatAmount(
        $currency,
        static::formatAmount($values[$mode], $currency)
      ),
    ];

    return $build;
  }

  /**
   * Apply rounding step currency settings for displayed value.
   *
   * @param float $amount
   *   Displayed amount value.
   * @param \Drupal\currency\Entity\CurrencyInterface $currency
   *   Currency entity.
   *
   * @return string|null
   *   Formatted amount.
   */
  protected static function formatAmount($amount, CurrencyInterface $currency) {
    $amount = bcdiv($amount, $currency->getRoundingStep(), 6);
    $amount = bcmul(round($amount), $currency->getRoundingStep(), 6);

    $decimal_mark_position = strpos($amount, '.');
    // The amount has no decimals yet, so add a decimal mark.
    if ($decimal_mark_position === FALSE) {
      $amount .= '.';
    }
    // Remove any existing trailing zeroes.
    $amount = rtrim($amount, '0');
    // Add the required number of trailing zeroes.
    $amount_decimals = strlen(substr($amount, $decimal_mark_position + 1));
    if ($amount_decimals < $currency->getDecimals()) {
      $amount .= str_repeat('0', $currency->getDecimals() - $amount_decimals);
    }

    return $amount;
  }

  /**
   * {@inheritdoc}
   */
  public function format(PriceInterface $price, $mode, array $settings = []) {
    $build = $this->buildFormatted($price, $mode, $settings);
    return $this->renderer->render($build);
  }

  /**
   * {@inheritdoc}
   */
  public function buildNet(PriceInterface $price, array $settings = []) {
    return $this->buildFormatted($price, self::FORMAT_NET, $settings);
  }

  /**
   * {@inheritdoc}
   */
  public function formatNet(PriceInterface $price, array $settings = []) {
    return $this->format($price, self::FORMAT_NET, $settings);
  }

  /**
   * {@inheritdoc}
   */
  public function buildGross(PriceInterface $price, array $settings = []) {
    return $this->buildFormatted($price, self::FORMAT_GROSS, $settings);
  }

  /**
   * {@inheritdoc}
   */
  public function formatGross(PriceInterface $price, array $settings = []) {
    return $this->format($price, self::FORMAT_GROSS, $settings);
  }

  /**
   * {@inheritdoc}
   */
  public function buildFull(PriceInterface $price, array $settings = []) {
    return [
      // @todo Consider adding VAT value.
      self::FORMAT_NET => $this->buildFormatted($price, self::FORMAT_NET, $settings),
      self::FORMAT_GROSS => $this->buildFormatted($price, self::FORMAT_GROSS, $settings),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function formatFull(PriceInterface $price, array $settings = []) {
    $build = $this->buildFull($price, $settings);
    return $this->renderer->render($build);
  }

  /**
   * {@inheritdoc}
   */
  public function buildVat(PriceInterface $price, array $settings = []) {
    return $this->buildFormatted($price, self::FORMAT_VAT_VALUE, $settings);
  }

  /**
   * {@inheritdoc}
   */
  public function formatVat(PriceInterface $price, array $settings = []) {
    return $this->format($price, self::FORMAT_VAT_VALUE, $settings);
  }

}

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

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