translation_views-8.x-1.x-dev/src/Plugin/views/filter/TranslationTargetLanguageFilter.php

src/Plugin/views/filter/TranslationTargetLanguageFilter.php
<?php

namespace Drupal\translation_views\Plugin\views\filter;

use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Drupal\translation_views\TranslationViewsTargetLanguage as TargetLanguage;
use Drupal\views\Plugin\views\PluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides filtering by translation target language.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("translation_views_target_language")
 */
class TranslationTargetLanguageFilter extends FilterPluginBase implements ContainerFactoryPluginInterface {
  use TargetLanguage;

  /**
   * Flag about module 'translators_content' existence.
   *
   * @var bool
   */
  protected $translatorsContent = FALSE;
  /**
   * Translators skills service.
   *
   * @var \Drupal\translators\Services\TranslatorsSkills|null
   */
  protected $translatorSkills = NULL;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration, $plugin_id, $plugin_definition,
      $container->get('language_manager'),
      $container->get('module_handler')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, LanguageManagerInterface $language_manager, ModuleHandlerInterface $handler) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->languageManager = $language_manager;
    $this->translatorsContent = $handler->moduleExists('translators_content');
    if ($this->translatorsContent && \Drupal::hasService('translators.skills')) {
      $this->translatorSkills = \Drupal::service('translators.skills');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildExposeForm(&$form, FormStateInterface $form_state) {
    parent::buildExposeForm($form, $form_state);

    $form['expose']['multiple'] = [
      '#type' => 'hidden',
      '#value' => FALSE,
    ];
    $form['expose']['required'] = [
      '#type' => 'hidden',
      '#value' => TRUE,
    ];

    if ($this->translatorsContent) {
      // We need to force this option to allow users to use only the languages,
      // specified as the user's translation skills.
      $form['expose']['reduce']['#default_value'] = TRUE;
      $form['expose']['reduce']['#disabled'] = TRUE;
    }

    $form['expose']['identifier'] = [
      '#type' => 'hidden',
      '#value' => static::$targetExposedKey,
    ];
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();

    $options['expose']['contains']['label'] = [
      'default' => $this->t('Target language'),
    ];

    $options['expose']['contains']['identifier'] = [
      'default' => static::$targetExposedKey,
    ];

    $options['value']['default'] = '';
    $options['remove']['default'] = TRUE;
    $options['exposed']['default'] = TRUE;

    if ($this->translatorsContent) {
      $options['limit'] = ['default' => FALSE];
      $options['column'] = ['default' => ['source' => '', 'target' => 'target']];
    }

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildExposedForm(&$form, FormStateInterface $form_state) {
    parent::buildExposedForm($form, $form_state);
    $field =& $form[$this->field];
    // Avoide validation error when list of allowed languages changes.
    if (isset($field['#value']) && !isset($field['#options'][$field['#value']])) {
      $field['#value'] = $field['#default_value'] = '';
    }
    // Show empty registered skills message inside this window.
    if ($this->translatorsContent
      && $this->options['limit']
      && empty($this->translatorSkills->getAllLangcodes())) {
      $field['#options'] = ['All' => $this->t('- Any -')];
      $field['#value'] = $field['#default_value'] = 'All';
      $this->translatorSkills->showMissingTranslationSkillsWarning();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);
    $form['remove'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Remove rows where language equals target language.'),
      '#default_value' => $this->options['remove'],
      '#weight' => -50,
    ];
    // Build values list independently in order to see all the options.
    $form['value']['#options'] = $this->listLanguages(
      LanguageInterface::STATE_CONFIGURABLE
      | LanguageInterface::STATE_SITE_DEFAULT
      | PluginBase::INCLUDE_NEGOTIATED
    );
    if ($this->translatorsContent) {
      $end = $form['clear_markup_end'];
      unset($form['clear_markup_end']);
      $form['limit'] = [
        '#type'          => 'checkbox',
        '#title'         => $this->t('Limit target languages by translation skills'),
        '#required'      => FALSE,
        '#default_value' => $this->options['limit'],
      ];
      $form['column'] = [
        '#type'          => 'checkboxes',
        '#options'       => [
          'source' => $this->t('Source languages'),
          'target'   => $this->t('Target languages'),
        ],
        '#title'         => $this->t('Translation skill'),
        '#required'      => TRUE,
        '#default_value' => $this->options['column'],
        '#states' => [
          'visible' => [
            'input[name="options[limit]"]' => ['checked' => TRUE],
          ],
        ],
      ];
      $form['clear_markup_end'] = $end;
      $form['value']['#prefix'] = '<div class="views-group-box views-right-60">';
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function valueForm(&$form, FormStateInterface $form_state) {
    parent::valueForm($form, $form_state);

    if (!empty($this->options['exposed'])) {
      $language_options = $this->buildLanguageOptions();
      $identifier = $this->options['expose']['identifier'];
      $user_input = $form_state->getUserInput();
      $target_langcode = isset($user_input[$identifier]) ? $user_input[$identifier] : $this->value;
      $valid_langcode = $this->getValidLangcode($target_langcode, $language_options);
      $this->setExposedValue($identifier, $valid_langcode, $form_state);
    }

    $this->always_required = TRUE;

    $form['value'] = [
      '#type' => 'select',
      '#title' => $this->t('Default target language'),
      '#options' => $this->buildLanguageOptions(),
      '#multiple' => FALSE,
      '#required' => TRUE,
      '#default_value' => $this->value,
    ];

    $form['expose']['identifier'] = [
      '#type' => 'hidden',
      '#value' => static::$targetExposedKey,
    ];
  }

  /**
   * Provide options for langcode dropdown.
   *
   * @return array
   *   Available options based on configurable languages.
   */
  protected function buildLanguageOptions() {
    $options = [];
    if ($this->translatorsContent && $this->options['limit']) {
      $translators_languages = $this->translatorSkills->getTranslationSkills();
      // Handle column options.
      foreach ($this->options['column'] as $name => $column) {
        if (!empty($column)) {
          foreach ($translators_languages as $langs) {
            $this->processColumnOption($langs, $name, $options);
          }
        }
      }
    }
    else {
      $options = $this->listLanguages(LanguageInterface::STATE_CONFIGURABLE);
    }
    return $options;
  }

  /**
   * Get a valid langcode from language options.
   *
   * @param string $target_langcode
   *   Target language identifier.
   * @param array $language_options
   *   Available language options.
   *
   * @return string|null
   *   A valid langcode, or NULL if no valid langcodes exist.
   */
  protected function getValidLangcode($target_langcode, array $language_options) {
    if ($target_langcode === '***LANGUAGE_site_default***') {
      $target_langcode = $this->languageManager->getDefaultLanguage()->getId();
    }
    elseif ($target_langcode === '***LANGUAGE_language_interface***') {
      $target_langcode = $this->languageManager->getCurrentLanguage()->getId();
    }
    if (!isset($language_options[$target_langcode]) && !empty($language_options)) {
      return array_keys($language_options)[0];
    }
    elseif (empty($language_options)) {
      return NULL;
    }
    return $target_langcode;
  }

  /**
   * Process column options.
   *
   * @param array $languages
   *   Languages array.
   * @param string $column
   *   Column name.
   * @param array $options
   *   Available language options.
   */
  protected function processColumnOption(array $languages, $column, array &$options) {
    $key = "language_$column";
    if (isset($languages[$key])) {
      $key = $languages[$key];
      $options[$key] = $this->languageManager
        ->getLanguage($key)
        ->getName();
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function listLanguages($flags = LanguageInterface::STATE_ALL, array $current_values = NULL) {
    return array_map(function ($language) {
      return (string) $language;
    }, parent::listLanguages($flags, $current_values));
  }

  /**
   * {@inheritdoc}
   */
  public function query() {
    if ($this->options['remove']) {
      $this->query->addWhere(
        $this->options['group'],
        $this->view->storage->get('base_table') . '.langcode',
        '***TRANSLATION_VIEWS_TARGET_LANG***',
        '<>'
      );
    }

    if (isset($this->options['limit']) && $this->options['limit']) {
      $table_alias = $this->ensureMyTable();

      $this->query->addWhereExpression(
        $this->options['group'],
        "FIND_IN_SET(:langcode_limit, $table_alias.langs) >= '0' AND :langcode_limit != ''",
        [
          ':langcode_limit' => '***TRANSLATION_VIEWS_TARGET_LIMIT_LANG***',
        ]
      );
    }
  }

  /**
   * Special setter for exposed value in views.
   */
  protected function setExposedValue($identifier, $value, FormStateInterface $form_state) {
    $user_input = $form_state->getUserInput();
    $user_input[$identifier] = $value;

    $form_state->setUserInput($user_input);
    $this->view->setExposedInput($user_input);
  }

}

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

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