Loading l10n_community/l10n_community.routing.yml +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ l10n_community.project.explore: path: '/translate/projects' defaults: _title: 'Explore projects' _controller: '\Drupal\l10n_community\Controller\L10nCommunityExploreProjectsController::build' _controller: '\Drupal\l10n_community\Controller\L10nCommunityProjectsController::explore' requirements: _permission: 'access localization community' Loading l10n_community/src/Controller/L10nCommunityExploreProjectsController.phpdeleted 100644 → 0 +0 −257 Original line number Diff line number Diff line <?php namespace Drupal\l10n_community\Controller; use Drupal\Core\Cache\Cache; 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', ], ], '#cache' => [ 'max-age' => Cache::PERMANENT, ], ]; return $build; } } l10n_community/src/Controller/L10nCommunityProjectsController.php +230 −0 Original line number Diff line number Diff line Loading @@ -3,8 +3,11 @@ declare(strict_types=1); namespace Drupal\l10n_community\Controller; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigManagerInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Database\Connection; use Drupal\Core\Url; use Drupal\l10n_server\Entity\L10nServerProjectInterface; use Drupal\l10n_server\Entity\L10nServerReleaseInterface; use Symfony\Component\DependencyInjection\ContainerInterface; Loading @@ -14,6 +17,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class L10nCommunityProjectsController extends ControllerBase { /** * The database connection. * * @var \Drupal\Core\Database\Connection */ protected $connection; /** * The config manager. * Loading @@ -24,12 +34,16 @@ class L10nCommunityProjectsController extends ControllerBase { /** * The controller constructor. * * @param \Drupal\Core\Database\Connection $connection * The database connection. * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager * The config manager. */ public function __construct( Connection $connection, ConfigManagerInterface $config_manager ) { $this->connection = $connection; $this->configManager = $config_manager; } Loading @@ -40,10 +54,110 @@ class L10nCommunityProjectsController extends ControllerBase { ContainerInterface $container ) { return new static( $container->get('database'), $container->get('config.manager') ); } /** * Builds the response. */ public function explore() { /** @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', ], ], '#cache' => [ 'max-age' => Cache::PERMANENT, ], ]; return $build; } /** * Builds the response. * Loading Loading @@ -105,4 +219,120 @@ class L10nCommunityProjectsController extends ControllerBase { return $build; } /** * 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; } } Loading
l10n_community/l10n_community.routing.yml +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ l10n_community.project.explore: path: '/translate/projects' defaults: _title: 'Explore projects' _controller: '\Drupal\l10n_community\Controller\L10nCommunityExploreProjectsController::build' _controller: '\Drupal\l10n_community\Controller\L10nCommunityProjectsController::explore' requirements: _permission: 'access localization community' Loading
l10n_community/src/Controller/L10nCommunityExploreProjectsController.phpdeleted 100644 → 0 +0 −257 Original line number Diff line number Diff line <?php namespace Drupal\l10n_community\Controller; use Drupal\Core\Cache\Cache; 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', ], ], '#cache' => [ 'max-age' => Cache::PERMANENT, ], ]; return $build; } }
l10n_community/src/Controller/L10nCommunityProjectsController.php +230 −0 Original line number Diff line number Diff line Loading @@ -3,8 +3,11 @@ declare(strict_types=1); namespace Drupal\l10n_community\Controller; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigManagerInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Database\Connection; use Drupal\Core\Url; use Drupal\l10n_server\Entity\L10nServerProjectInterface; use Drupal\l10n_server\Entity\L10nServerReleaseInterface; use Symfony\Component\DependencyInjection\ContainerInterface; Loading @@ -14,6 +17,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class L10nCommunityProjectsController extends ControllerBase { /** * The database connection. * * @var \Drupal\Core\Database\Connection */ protected $connection; /** * The config manager. * Loading @@ -24,12 +34,16 @@ class L10nCommunityProjectsController extends ControllerBase { /** * The controller constructor. * * @param \Drupal\Core\Database\Connection $connection * The database connection. * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager * The config manager. */ public function __construct( Connection $connection, ConfigManagerInterface $config_manager ) { $this->connection = $connection; $this->configManager = $config_manager; } Loading @@ -40,10 +54,110 @@ class L10nCommunityProjectsController extends ControllerBase { ContainerInterface $container ) { return new static( $container->get('database'), $container->get('config.manager') ); } /** * Builds the response. */ public function explore() { /** @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', ], ], '#cache' => [ 'max-age' => Cache::PERMANENT, ], ]; return $build; } /** * Builds the response. * Loading Loading @@ -105,4 +219,120 @@ class L10nCommunityProjectsController extends ControllerBase { return $build; } /** * 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; } }