Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
TwigExtension.php 5.08 KiB
<?php

declare(strict_types = 1);

namespace Drupal\oe_whitelabel_helper\TwigExtension;

use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\oe_whitelabel_helper\EuropeanUnionLanguages;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

/**
 * Collection of extra Twig extensions as filters and functions.
 */
class TwigExtension extends AbstractExtension {

  /**
   * The plugin.manager.block service.
   *
   * @var \Drupal\Core\Cache\CacheableDependencyInterface
   */
  protected $pluginManagerBlock;

  /**
   * Constructs the TwigExtension object.
   */
  public function __construct(CacheableDependencyInterface $plugin_manager_block) {
    $this->pluginManagerBlock = $plugin_manager_block;
  }

  /**
   * {@inheritdoc}
   */
  public function getFilters(): array {
    return [
      new TwigFilter('bcl_timeago', [$this, 'bclTimeAgo']),
      new TwigFilter('to_internal_language_id', [$this, 'toInternalLanguageId']),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFunctions(): array {
    return [
      new TwigFunction('bcl_footer_links', [$this, 'bclFooterLinks'], ['needs_context' => TRUE]),
      new TwigFunction('bcl_block', [$this, 'bclBlock']),
    ];
  }

  /**
   * Filters a timestamp in "time ago" format.
   *
   * @param string $timestamp
   *   Datetime to be parsed.
   *
   * @return \Drupal\Core\StringTranslation\PluralTranslatableMarkup
   *   The translated time ago string.
   */
  public function bclTimeAgo(string $timestamp): PluralTranslatableMarkup {
    $time = \Drupal::time()->getCurrentTime() - $timestamp;
    $time_ago = new PluralTranslatableMarkup(0, 'N/A', 'N/A');
    $units = [
      31536000 => [
        'singular' => '@number year ago',
        'plural' => '@number years ago',
      ],
      2592000 => [
        'singular' => '@number month ago',
        'plural' => '@number months ago',
      ],
      604800 => [
        'singular' => '@number week ago',
        'plural' => '@number weeks ago',
      ],
      86400 => [
        'singular' => '@number day ago',
        'plural' => '@number days ago',
      ],
      3600 => [
        'singular' => '@number hour ago',
        'plural' => '@number hours ago',
      ],
      60 => [
        'singular' => '@number minute ago',
        'plural' => '@number minutes ago',
      ],
      1 => [
        'singular' => '@number second ago',
        'plural' => '@number seconds ago',
      ],
    ];

    foreach ($units as $unit => $format) {
      if ($time < $unit) {
        continue;
      }

      $number_of_units = floor($time / $unit);
      $time_ago = \Drupal::translation()
        ->formatPlural($number_of_units, $format['singular'], $format['plural'], ['@number' => $number_of_units]);
      break;
    }

    return $time_ago;
  }

  /**
   * Processes footer links to make them compatible with BCL formatting.
   *
   * @param array $context
   *   The twig context.
   * @param array $links
   *   Set of links to be processed.
   *
   * @return array
   *   Set of processed links.
   */
  public function bclFooterLinks(array $context, array $links): array {
    $altered_links = [];

    foreach ($links as $link) {
      $altered_link = [
        'label' => $link['label'],
        'path' => $link['href'],
        'icon_position' => 'after',
        'standalone' => TRUE,
        'attributes' => [
          'class' => [
            'd-block',
            'mb-1',
          ],
        ],
      ];

      if (!empty($link['external']) && $link['external'] === TRUE) {
        $altered_link['icon'] = [
          'path' => $context['bcl_icon_path'],
          'name' => 'box-arrow-up-right',
          'size' => 'xs',
        ];
      }

      if (!empty($link['social_network'])) {
        $altered_link['icon_position'] = 'before';
        $altered_link['icon'] = [
          'path' => $context['bcl_icon_path'],
          'name' => $link['social_network'],
          'size' => 'xs',
        ];
      }

      $altered_links[] = $altered_link;
    }

    return $altered_links;
  }

  /**
   * Builds the render array for a block.
   *
   * @param string $id
   *   The block plugin ID.
   * @param array $configuration
   *   The block configuration.
   *
   * @return array
   *   The block render array.
   */
  public function bclBlock(string $id, array $configuration = []): array {
    $configuration += ['label_display' => 'hidden'];

    /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */
    $block_plugin = $this->pluginManagerBlock->createInstance($id, $configuration);

    return $block_plugin->build();
  }

  /**
   * Get an internal language ID given its code.
   *
   * @param string $language_code
   *   The language code as defined by the W3C language tags document.
   *
   * @return string
   *   The internal language ID, or the given language code if none found.
   */
  public function toInternalLanguageId($language_code): string {
    if (EuropeanUnionLanguages::hasLanguage($language_code)) {
      return EuropeanUnionLanguages::getInternalLanguageCode($language_code);
    }

    return $language_code;
  }

}