Unverified Commit 4ad8ecff authored by Stefan Auditor's avatar Stefan Auditor Committed by Stefan Auditor
Browse files

Issue #3282696 by sanduhrs: Port of l10n_community: Pushing latest works

parent acb8bda9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
highlighted_project: 'Drupal core'
stats_enabled: true
stats_explore_projects_enabled: true
package_count: true
project_per_page: 10
+6 −0
Original line number Diff line number Diff line
@@ -8,6 +8,12 @@ l10n_community.settings:
    stats_enabled:
      type: boolean
      label: 'Stats enabled'
    stats_explore_projects_enabled:
      type: boolean
      label: 'Stats explore projects enabled'
    package_count:
      type: boolean
      label: 'Package count enabled'
    project_per_page:
      type: integer
      label: 'Project pager'
+7 −0
Original line number Diff line number Diff line
@@ -13,3 +13,10 @@ l10n_community.explore_languages:
    _controller: '\Drupal\l10n_community\Controller\L10nCommunityExploreLanguagesController::build'
  requirements:
    _permission: 'access localization community'
l10n_community.explore_projects:
  path: '/translate/projects'
  defaults:
    _title: 'Explore projects'
    _controller: '\Drupal\l10n_community\Controller\L10nCommunityExploreProjectsController::build'
  requirements:
    _permission: 'access localization community'
+253 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\l10n_community\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Connection;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

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

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * The controller constructor.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   */
  public function __construct(Connection $connection) {
    $this->connection = $connection;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('database')
    );
  }

  /**
   * Provides a list of projects from the database, ordered by uri.
   *
   * @param $options
   *   Associative array of options
   *    - 'uri': Project URI, if requesting information about one project only.
   *      If not specified, information about all projects is returned.
   *    - 'pager': Number of projects to return a pager query result with. If
   *      NULL, no pager is used.
   *    - 'all': If not specified, unpublished projects are excluded (default).
   *      If TRUE, even unpublished projects are returned (for admin pages).
   * @return
   *   An associative array keyed with project uris.
   */
  private function getProjects(array $options = []) {
    static $projects = [];

    $select= \Drupal::database()
      ->select('l10n_server_project', 'p')
      ->fields('p', []);

    // Consider returning all projects or just published ones.
    if (empty($options['all'])) {
      $select->condition('status', 1);
    }

    if (isset($options['pager'])) {
      if (isset($options['initial'])) {
        $initials = $this->getProjectInitials();
        if (isset($initials[$options['initial']])) {
          $args = $initials[$options['initial']]['values'];
          for ($i=0; $i < count($args); $i++) { $arguments[':p_' . $i] = $args[$i]; }
          $placeholders = implode(',', array_keys($arguments));
          $select->where("SUBSTRING(title, 1, 1) IN ($placeholders)", $arguments);
        }
      }

      // If a pager view was asked for, collect data independently.
      $select->orderBy('title');
      $result = $select
        ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
        ->limit($options['pager'])
        ->execute();
      $pager_results = $result
        ->fetchAllAssoc('uri');

      // Save project information for later, if someone asks for it by uri.
      $projects = array_merge($projects, $pager_results);

      return $pager_results;
    }
    else {
      if (isset($options['uri'])) {
        // A specific project was asked for.
        if (isset($projects[$options['uri']])) {
          // Can be served from the local cache.
          return $projects[$options['uri']];
        }
        // Not found in cache, so query and cache before returning.
        $result = \Drupal::database()
          ->query("SELECT * FROM {l10n_server_project} WHERE uri = :uri", [
            ':uri' => $options['uri'],
          ]);
        if ($project = $result->fetchObject()) {
          $projects[$options['uri']] = $project;
          return $project;
        }
      }
      else {
        // A list of *all* projects was asked for.
        $results = $select->orderBy('uri')->execute();
        foreach ($results as $project) {
          $projects[$project->uri] = $project;
        }
        return $projects;
      }
    }
  }

  /**
   * Build a list of initials of active projects for listings.
   */
  private function getProjectInitials() {
    // Grab the unique initials of all active projects
    $result = \Drupal::database()
      ->query('SELECT DISTINCT(SUBSTR(title, 1, 1)) AS initial FROM {l10n_server_project} WHERE status = :status ORDER BY initial ASC', [
        ':status' => 1,
      ]);

    // Create an array of elements, all non-letters are grouped in '#'.
    $initials = [];
    foreach ($result as $row) {
      $initial = $row->initial;
      if (preg_match('/[A-Za-z]/', $initial)) {
        $initials[strtolower($initial)] = [
          'title' => strtoupper($initial),
          'values' => [
            strtoupper($initial),
          ],
        ];
      }
      elseif (!isset($initials[0])) {
        $initials[0] = [
          'title' => '#',
          'values' => [
            $initial,
          ],
        ];
      }
      else {
        $initials[0]['values'][] = $initial;
      }
    }
    return $initials;
  }

  /**
   * Builds the response.
   */
  public function build() {
    /** @var \Drupal\l10n_community\L10nStatistics $statistic */
    $statistic = \Drupal::service('l10n_community.statistics');
    $config = \Drupal::config('l10n_community.settings');

    if (!$config->get('stats_enabled')
        || !$config->get('stats_explore_projects_enabled')) {
      return t('Statistics for projects have been disabled.');
    }

    $pager_setting = $config->get('project_per_page');

    $options = ['pager' => $pager_setting];
    if (isset($_GET['initial'])) {
      $options['initial'] = strtolower($_GET['initial']);
    }

    if (!$projects = $this->getProjects($options)) {
      $build['content'] = [
        '#type' => 'item',
        '#markup' => $this->t('No projects found.'),
      ];
      return $build;
    }

    $languages = \Drupal::languageManager()->getLanguages();
    $language_count = count($languages);
    $string_counts = $statistic->getProjectsStringCount();

    // If we have more projects compared to what we show at the moment, display
    // an autocomplete jumpbox to jump to a project.
//    if (count($string_counts) > $pager_setting) {
//      $form = drupal_get_form('l10n_community_explore_projects_jump_form');
//      $output .= drupal_render($form);
//    }

//    $pager = theme('pager', array('tags' => NULL, 'element' => 0));

//    $output .= _l10n_community_alphabetic_pager();
//    $output .= $pager;

    $rows = [];
    foreach ($projects as $project) {
      $rows[] = [
        [
          'data' => t('<a href="@url">@project</a>', [
            '@project' => $project->title,
            '@url' => Url::fromUri('internal:/translate/projects/' . $project->pid)->toString(),
          ]),
        ],
        [
          'data' => [
            '#theme' => 'l10n_community_progress_columns',
            '#sum' => 100,
            '#translated' => rand(0, 100),
            '#has_suggestion' => 9,
          ],
        ],
      ];
//      $rows[] = array_merge(
//        [
//            'data' => t('<a href="@url">@project</a>', [
//              '@project' => $project->title,
//              '@url' => Url::fromUri('internal:/translate/projects/' . $project->pid)->toString(),
//            ]),
//            'class' => ['rowhead'],
//        ],
//        // Multiply summary count by languages handled, so we get an
//        // accurate picture of completeness.
//        ['data' => $progress],
//      );
    }
//    $output .= theme('table', array('header' => theme('l10n_community_progress_headers', array('mainhead' => t('Project'))), 'rows' => $table, 'attributes' => array('class' => array('l10n-community-overview'))));
//    $output .= $pager;
//    return $output . '<div class="clear-block"></div>';

    $build['content'] = [
      '#type' => 'table',
      '#header' => [
        t('Project'),
        t('Progress'),
      ],
      '#rows' => $rows,
      '#attributes' => [
        'class' => [
          'l10n-community-overview',
        ],
      ],
    ];

    return $build;
  }

}
+55 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\l10n_community\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

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

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'l10n_community_jump';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['project'] = [
      '#type' => 'entity_autocomplete',
      '#target_type' => 'l10n_server_project',
      "#prefix" => '<strong>' . $this->t('Pick a project to jump to') . '</strong>',
    ];
    $form['actions'] = [
      '#type' => 'actions',
    ];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Go'),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($pid = $form_state->getValue('project')) {
      $project = \Drupal::entityTypeManager()
        ->getStorage('l10n_server_project')
        ->load($pid);
      if ($project) {
        $url = Url::fromUri('internal:/translate/projects/' . $pid);
        $form_state->setRedirectUrl($url);
      }
    }
  }

}
Loading