translators-8.x-1.x-dev/modules/translators_content/src/Plugin/views/filter/TranslationLanguageLimitedToTranslationSkills.php
modules/translators_content/src/Plugin/views/filter/TranslationLanguageLimitedToTranslationSkills.php
<?php
namespace Drupal\translators_content\Plugin\views\filter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\translators\Services\TranslatorSkills;
use Drupal\views\Plugin\views\filter\LanguageFilter;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class TranslationLanguageLimitedToTranslationSkills.
*
* @package Drupal\translators_content\Plugin\views\filter
*/
class TranslationLanguageLimitedToTranslationSkills extends LanguageFilter implements ContainerFactoryPluginInterface {
/**
* User skills service.
*
* @var \Drupal\translators\Services\TranslatorSkills
*/
protected $translatorSkills;
/**
* Current user account.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* Constructs a new TranslationLanguageLimitedToTranslationSkills instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* Language manager.
* @param \Drupal\translators\Services\TranslatorSkills $translatorSkills
* User skills service.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* Current user.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
LanguageManagerInterface $language_manager,
TranslatorSkills $translatorSkills,
AccountProxyInterface $current_user
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $language_manager);
$this->translatorSkills = $translatorSkills;
$this->currentUser = $current_user;
}
/**
* {@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('translators.skills'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function defineOptions() {
$options = parent::defineOptions();
$options['expose']['identifier'] = $this->getPluginId();
$options['limit'] = ['default' => FALSE];
$options['column'] = ['default' => ['source' => 'source', 'target' => '']];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['value']['#options'] = $this->getValueOptions();
$end = $form['clear_markup_end'];
unset($form['clear_markup_end']);
$form['limit'] = [
'#type' => 'checkbox',
'#title' => $this->t('Limit languages to 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 skills'),
'#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']) && $this->options['limit']) {
$language_options = $this->buildLimitedLanguageOptions();
$identifier = $this->options['expose']['identifier'];
$user_input = $form_state->getUserInput();
$langcodes = isset($user_input[$identifier]) ? $user_input[$identifier] : $this->value;
$valid_langcodes = $this->getValidLangcodes($langcodes, $language_options);
$this->setExposedValue($identifier, $valid_langcodes, $form_state);
}
if ($this->options['limit']) {
$form['value']['#options'] = $this->buildLimitedLanguageOptions();
}
else {
$form['value']['#options'] = $this->getValueOptions();
}
}
/**
* 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);
}
/**
* {@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->options['limit']
&& empty($this->translatorSkills->getAllLangcodes())) {
$field['#options'] = ['All' => $this->t('- Any -')];
$field['#value'] = $field['#default_value'] = 'All';
$this->translatorSkills->showMissingTranslationSkillsWarning();
}
}
/**
* {@inheritdoc}
*/
public function buildExposeForm(&$form, FormStateInterface $form_state) {
parent::buildExposeForm($form, $form_state);
if ($this->options['limit']) {
// 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;
}
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
$cache_tags = parent::getCacheTags();
// Additional cachetags to allow filters to rebuild
// after the user's skills gets changed.
if (!$this->currentUser->isAnonymous()) {
$cache_tags[] = "user:{$this->currentUser->id()}";
}
return $cache_tags;
}
/**
* Provide options for langcode dropdown.
*
* @return array
* Available options based on configurable languages.
*/
protected function buildLimitedLanguageOptions() {
$options = [];
$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);
}
}
}
if ($this->options['expose']['required']) {
return $options;
}
return array_merge(['All' => $this->t('- Any -')], $options);
}
/**
* Process column options.
*
* @param array $languages
* Languages array.
* @param string $column
* Column name.
* @param array $options
* 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();
}
}
/**
* Get a valid langcode from language options.
*
* @param string|array $langcodes
* Array of selected language identifier.
* @param array $language_options
* Available language options.
*
* @return string|array
* An array of valid langcodes.
*/
protected function getValidLangcodes($langcodes, array $language_options) {
if (is_array($langcodes)) {
foreach ($langcodes as $i => $langcode) {
if (!isset($language_options[$langcode])) {
unset($langcodes[$i]);
}
}
if (empty($langcodes) && $this->options['expose']['required']) {
return [array_keys($language_options)[0]];
}
return $langcodes;
}
else {
if (!isset($language_options[$langcodes])
&& $this->options['expose']['required']) {
return array_keys($language_options)[0];
}
}
return $langcodes;
}
}
