l10n_server-2.x-dev/l10n_community/src/Form/PickGoForm.php

l10n_community/src/Form/PickGoForm.php
<?php

declare(strict_types=1);

namespace Drupal\l10n_community\Form;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\group\GroupMembershipLoaderInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a Localization community UI form.
 */
final class PickGoForm extends FormBase {

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\group\GroupMembershipLoaderInterface $group_membership_loader
   *   The group membership loader.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(
    private readonly Connection $connection,
    private readonly AccountInterface $current_user,
    private readonly GroupMembershipLoaderInterface $group_membership_loader,
    private readonly ModuleHandlerInterface $module_handler,
    private readonly LanguageManagerInterface $language_manager,
    private readonly EntityTypeManagerInterface $entity_type_manager
  ) {

  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    return new PickGoForm(
      $container->get('database'),
      $container->get('current_user'),
      $container->get('group.membership_loader'),
      $container->get('module_handler'),
      $container->get('language_manager'),
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'l10n_community_pick_go';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $project_count = $this->entity_type_manager
      ->getStorage('l10n_server_project')
      ->getQuery()
      ->count()
      ->execute();

    $language_list = [];
    foreach ($this->language_manager->getLanguages() as $langcode => $language) {
      // Need to load this again to get access to the third party settings :/.
      $language = ConfigurableLanguage::load($langcode);
      if ($language->getThirdPartySetting('l10n_pconfig', 'formula')) {
        $language_list[$langcode] = $this->t("@language", [
          '@language' => $language->getName(),
        ]);
      }
    }

    if (!count($language_list) || !$project_count) {
      $plural_config_tip = '';
      if (!$this->module_handler->moduleExists('l10n_pconfig')) {
        $plural_config_tip = ' ' . $this->t('The <a href="@plural_config">Plural formula configurator</a> module is recommended for plural formula setup.', [
          '@plural_config' => 'https://drupal.org/project/l10n_pconfig',
        ]);
      }

      $form['dummy'] = [
        '#markup' => $this->t('No languages with plural formulas defined or no projects scanned yet. Check the <a href="@languages">configuration of languages</a>, <a href="@connectors">list of connectors</a> and <a href="@projects">projects</a>.', [
          '@languages' => Url::fromUri('internal:/admin/config/regional/language')->toString(),
          '@connectors' => Url::fromUri('internal:/admin/config/l10n-server/connectors')->toString(),
          '@projects' => Url::fromUri('internal:/admin/localization/projects')->toString(),
        ]) . $plural_config_tip,
      ];

      return $form;
    }

    $default_language = '';
    if ($this->module_handler->moduleExists('l10n_groups')) {
      // We are dealing with a groups based permission model.
      $form['groups'] = $this->pickGo();
      if (
        isset($form['groups']['#l10n_groups']) &&
        is_array($form['groups']['#l10n_groups'])
      ) {
        // Pick the first language as default. Most people are only member of
        // one language, so this should be a safe default.
        $default_language = current($form['groups']['#l10n_groups']);
      }
    }

    if (count($language_list) > 1) {
      // If more than one language.
      $form['langcode'] = [
        // For three or less languages, display radio buttons, select otherwise.
        '#type' => (count($language_list) <= 3) ? 'radios' : 'select',
        '#title' => $this->t('Pick a language'),
        '#options' => ['' => $this->t('All')] + $language_list,
        '#description' => $this->t('Alternatively you can <a href="@explore">explore languages</a>.', [
          '@explore' => Url::fromUri('internal:/translate/languages')->toString(),
        ]),
        '#default_value' => $default_language,
      ];
    }
    else {
      // Only one language, store as form value.
      $language_code = key($language_list);
      $language_name = $language_list[$language_code];
      $form['langcode'] = [
        '#type' => 'value',
        '#value' => $language_code,
      ];
    }

    if (count($language_list) > 1) {
      $projects_title = $this->current_user->hasPermission('browse translations')
        ? $this->t('And/or pick a project')
        : $this->t('Or pick a project');
    }
    else {
      $projects_title = $this->t('Pick a project for @language translation', [
        '@language' => $language_name,
      ]);
    }
    $form['project'] = [
      '#title' => $projects_title,
      '#description' => $this->t('Alternatively you can <a href="@explore">explore projects</a>.', [
        '@explore' => Url::fromUri('internal:/translate/projects')->toString(),
      ]),
      '#default_value' => $form_state->getValue('project'),
    ];
    if ($project_count <= 30) {
      // Radio box widget for as much as 5 projects, select widget for 5-30
      // projects.
      $form['project']['#type'] = ($project_count <= 5 ? 'radios' : 'select');
      $form['project']['#options'] = ['' => $this->t('All')];
      $projects = \Drupal::entityTypeManager()
        ->getStorage('l10n_server_project')
        ->loadMultiple();
      foreach ($projects as $project) {
        // Title used to conform to the autocomplete behavior.
        $form['project']['#options'][$project->id()] = $project->label();
      }
    }
    else {
      // Autocomplete field for more than 30 projects.
      $form['project'] += [
        '#type' => 'entity_autocomplete',
        '#target_type' => 'l10n_server_project',
      ];
    }

    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Go there'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    if (
      empty($form_state->getValue('project')) &&
      empty($form_state->getValue('langcode'))
    ) {
      // We require at least one to be selected to be effective.
      $form_state->setErrorByName('langcode', $this->t('At least select a language or a project.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $langcode = $form_state->getValue('langcode');
    $pid = $form_state->getValue('project');
    $redirect_url = NULL;

    $uri = $this->connection
      ->query(
        "SELECT uri FROM {l10n_server_project} WHERE pid = :pid",
        [':pid' => $form_state->getValue('project')]
      )->fetchField();

    if (
      !empty($pid) &&
      $uri
    ) {
      // Project surely selected, possibly with language too.
      if (!empty($langcode) && $this->current_user->hasPermission('browse translations')) {
        $redirect_url = Url::fromUri('internal:/translate/languages/' . $langcode . '/translate', ['query' => ['project' => $uri]]);
      }
      else {
        // Only project set or both language and project set,
        // no access to browse > go to project.
        $redirect_url = Url::fromUri('internal:/translate/projects/' . $uri);
      }
    }
    elseif (!empty($langcode)) {
      // Only language set.
      $redirect_url = Url::fromUri('internal:/translate/languages/' . $langcode);
    }

    if ($redirect_url) {
      $form_state->setRedirectUrl($redirect_url);
    }
  }

  /**
   * List groups a user is a member of to help jump there.
   *
   * @return array
   *
   * @throws \Drupal\Core\Entity\EntityMalformedException
   * @throws \Drupal\Core\TypedData\Exception\MissingDataException
   */
  private function pickGo(): array {
    $group_memberships = $this->group_membership_loader->loadByUser($this->current_user->getAccount());

    if (empty($group_memberships)) {
      return [];
    }

    $l10n_groups = [];
    foreach ($group_memberships as $group_membership) {
      $group = $group_membership->getGroup();

      if ($group->getGroupType()->id() === 'translation') {
        $l10n_groups[$group->get('field_translation_language')->first()->getValue()['target_id']] = $this->t('<a href="@url">@name</a>', [
          '@name' => $group->label(),
          '@url' => $group->toUrl()->toString(),
        ]);
      }
    }
    if (!empty($l10n_groups)) {
      return [
        '#markup' => '<span>' . $this->formatPlural(count($l10n_groups), $this->t('Your group'), $this->t('Your groups')) . '</span><p>' . implode(', ', $l10n_groups) . '</p>',
        '#l10n_groups' => array_keys($l10n_groups),
      ];
    }
  }

}

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

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