Loading l10n_community/config/install/l10n_community.settings.yml +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 l10n_community/config/schema/l10n_community.schema.yml +6 −0 Original line number Diff line number Diff line Loading @@ -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' l10n_community/l10n_community.routing.yml +7 −0 Original line number Diff line number Diff line Loading @@ -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' l10n_community/src/Controller/L10nCommunityExploreProjectsController.php 0 → 100644 +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; } } l10n_community/src/Form/JumpForm.php 0 → 100644 +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
l10n_community/config/install/l10n_community.settings.yml +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
l10n_community/config/schema/l10n_community.schema.yml +6 −0 Original line number Diff line number Diff line Loading @@ -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'
l10n_community/l10n_community.routing.yml +7 −0 Original line number Diff line number Diff line Loading @@ -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'
l10n_community/src/Controller/L10nCommunityExploreProjectsController.php 0 → 100644 +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; } }
l10n_community/src/Form/JumpForm.php 0 → 100644 +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); } } } }