l10n_server-2.x-dev/l10n_community/src/Controller/L10nCommunityWelcomePageController.php

l10n_community/src/Controller/L10nCommunityWelcomePageController.php
<?php

declare(strict_types=1);

namespace Drupal\l10n_community\Controller;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\l10n_community\L10nStatistics;
use Drupal\l10n_groups\L10nGroupManager;
use Drupal\language\Entity\ConfigurableLanguage;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Returns responses for Localization community UI routes.
 */
final class L10nCommunityWelcomePageController extends ControllerBase {

  /**
   * The controller constructor.
   *
   * @param \Drupal\l10n_community\L10nStatistics $statistics
   *   The l10n_community.statistics service.
   * @param \Drupal\Core\Config\ConfigManagerInterface $configManager
   *   The config.manager service.
   * @param \Drupal\l10n_groups\L10nGroupManager $l10nGroupsManager
   *   The l10n_groups.manager service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   The request stack.
   */
  public function __construct(
    private readonly L10nStatistics $statistics,
    private readonly ConfigManagerInterface $configManager,
    private readonly L10nGroupManager $l10nGroupsManager,
    private readonly RequestStack $requestStack,
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    return new L10nCommunityWelcomePageController(
      $container->get('l10n_community.statistics'),
      $container->get('config.manager'),
      $container->get('l10n_groups.manager'),
      $container->get('request_stack'),
    );
  }

  /**
   * Title callback.
   *
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|void
   *   Translatable markup object.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function title(): FormattableMarkup {
    $project_name = $this->configManager
      ->getConfigFactory()
      ->get('l10n_community.settings')
      ->get('highlighted_project');

    $projects = $entities = $this->entityTypeManager()
      ->getStorage('l10n_server_project')
      ->loadByProperties(
        ['title' => $project_name]
      );

    if ($project = reset($projects)) {
      return $this->t('Latest @project_name translation status', [
        '@project_name' => $project->label(),
      ]);
    }

    return $this->t('Latest translation status');
  }

  /**
   * Builds the response.
   */
  public function build(): array {
    $config = $this->configManager->getConfigFactory()->get('l10n_community.settings');

    if (!$config->get('stats_enabled')) {
      $build['content'] = [
        '#type' => 'item',
        '#markup' => $this->t('Statistics for projects have been disabled.'),
      ];

      return $build;
    }
    elseif ($project_name = $config->get('highlighted_project')) {
      $projects = $this->entityTypeManager()
        ->getStorage('l10n_server_project')
        ->loadByProperties(
          ['title' => $project_name]
        );

      if (!$project = reset($projects)) {
        $build['content'] = [
          '#type' => 'item',
          '#markup' => $this->t('Highlighted project not found.'),
        ];

        return $build;
      }

      $releases = $this->entityTypeManager()
        ->getStorage('l10n_server_release')
        ->loadByProperties(
          ['pid' => $project->id()]
        );
      $release = reset($releases);

      $groups = $this->l10nGroupsManager
        ->getGroups();

      // Check for l10n_packager, for faster queries but only on latest release.
      if (
        $this->moduleHandler()->moduleExists('l10n_packager')
        && $config->get('package_count')
      ) {
        [$num_source, $string_counts] = $this->statistics->getReleaseStringCount(project: $project);
      }
      else {
        $num_source = $this->statistics->getProjectStringCount($project);
        $string_counts = $this->statistics->getLanguagesStringCount($project);
      }

      $stats = $this->statistics->getProjectStringStatsByLanguage($project);
      $stats['users'] = $this->statistics->getLanguagesStatistics()['users'];

      $build['status'] = [
        '#markup' => $this->t('Status based on @source source strings found in @project. Links are to untranslated strings in the release for that group.', [
          '@source' => $num_source,
          '@project' => $project->label(),
        ]),
      ];

      $table_rows = [];
      foreach ($this->languageManager()->getLanguages() as $langcode => $language) {
        if (!array_key_exists($langcode, $groups)) {
          // Not interested in languages attached to no group.
          continue;
        }

        // Need to load this again to get access to the third party settings :/.
        $language = ConfigurableLanguage::load($langcode);
        if (!$language->getThirdPartySetting('l10n_pconfig', 'formula')) {
          $table_rows[] = [
            [
              'data' => $this->t('@language', [
                '@language' => $language->getName(),
              ]),
              'sortdata' => $this->t('@language', [
                '@language' => $language->getName(),
              ]),
              'class' => ['rowhead'],
            ],
            [
              'data' => $this->t('Uninitialized plural formula. Please set up the plural formula in <a href="@language-config">the language configuration</a> or alternatively <a href="@import-url">import a valid interface translation</a> for Drupal in this language.', [
                '@import-url' => Url::fromUri('internal:/admin/structure/translate/import')->toString(),
                '@language-config' => Url::fromUri('internal:/admin/config/regional/language/edit/' . $language->getId())->toString(),
              ]),
              'sortdata' => '',
              'class' => ['error'],
            ],
            [
              'data' => 0,
              'sortdata' => 0,
            ],
          ];
        }
        else {
          $progress = [
            'data' => [
              '#theme' => 'l10n_community_progress_columns',
              '#sum' => $stats[$langcode]['count'] ?? 0,
              '#translated' => $stats[$langcode]['translations'] ?? 0,
              '#has_suggestion' => $stats[$langcode]['suggestions'] ?? 0,
            ],
          ];
          $table_rows[] = [
            [
              'data' => new FormattableMarkup('<a href=":link">@name</a>', [
                ':link' => Url::fromRoute('l10n_community.language.translate.translate', [
                  'group' => $groups[$langcode]->id(),
                ],
                [
                  'query' => [
                    'project' => $project->getUri(),
                    'status' => 1,
                    'release' => ($release ? $release->id() : 'all'),
                  ],
                ])->toString(),
                '@name' => $language->getName(),
              ]),
              'sortdata' => $this->t('@language', [
                '@language' => $language->getName(),
              ])->__toString(),
              'class' => ['rowhead'],
            ],
            [
              'data' => $progress,
              'sortdata' => ($num_source == 0 ? 0 : round(($string_counts[$langcode]['translations'] ?? 0) / $num_source * 100, 2)),
            ],
            [
              'data' => (int) (array_key_exists($langcode, $stats['users'])) ? $stats['users'][$langcode]['count'] : 0,
              'sortdata' => (int) (array_key_exists($langcode, $stats['users'])) ? $stats['users'][$langcode]['count'] : 0,
            ],
          ];
        }
      }

      if (
        !empty($this->requestStack->getCurrentRequest()->get('sort'))
        && !empty($this->requestStack->getCurrentRequest()->get('order'))
      ) {
        usort($table_rows, static::class . '::sortByColumns');
      }

      $header = [
        [
          'data' => $this->t('Language'),
          'field' => 'language',
          'class' => ['rowhead'],
        ],
        [
          'data' => $this->t('@project progress', [
            '@project' => $project->label(),
          ]),
          'field' => 'progress',
          'sort' => 'desc',
        ],
        [
          'data' => $this->t('Contributors'),
          'field' => 'contributors',
        ],
      ];

      $build['content'] = [
        '#type' => 'table',
        '#header' => $header,
        '#rows' => $table_rows,
        '#attributes' => [
          'class' => [
            'l10n-community-overview l10n-community-highlighted',
          ],
        ],
      ];
      $build['#attached']['library'][] = 'l10n_community/tables';

      $project_count = $this->entityTypeManager()
        ->getStorage('l10n_server_project')
        ->getQuery()
        ->accessCheck(TRUE)
        ->condition('status', 1)
        ->count()
        ->execute();

      if ($project_count > 1) {
        $build['count'] = [
          '#type' => 'html_tag',
          '#tag' => 'p',
          '#value' => $this->formatPlural(
            $project_count,
            '@project is just one of the <a href="@projects">@count projects translated on this server</a>. Check them out.',
            '@project is just one of the <a href="@projects">@count projects translated on this server</a>. Check them out.',
            [
              '@project' => $project->label(),
              '@projects' => Url::fromUri('internal:/translate/projects')->toString(),
            ]
          ),
        ];
      }

      return $build;
    }

    $build['content'] = [
      '#type' => 'item',
      '#markup' => $this->t('No highlighted project set.'),
      '#cache' => [
        'max-age' => Cache::PERMANENT,
      ],
    ];

    return $build;
  }

  /**
   * Order listing table by columns.
   */
  public static function sortByColumns(array $a, array $b): int {
    $requestStack = \Drupal::service('request_stack');
    $sortkey = (
      $requestStack->getCurrentRequest()->get('order') === t('Language')->__toString()
        ? 0
        : ($requestStack->getCurrentRequest()->get('order') === t('Contributors')->__toString()
          ? 2
          : 1
        )
    );

    if ($a[$sortkey]['sortdata'] === $b[$sortkey]['sortdata']) {
      return 0;
    }

    return (($a[$sortkey]['sortdata'] < $b[$sortkey]['sortdata']) ? -1 : 1) * ($requestStack->getCurrentRequest()->get('sort') === 'asc' ? 1 : -1);
  }

}

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

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