From a112464f77ac9189c46fc8ef1e8a13a49a79ea1c Mon Sep 17 00:00:00 2001
From: Morten Wulff <wulff@ratatosk.net>
Date: Wed, 23 Mar 2011 10:41:34 +0100
Subject: [PATCH] Issue #806944 by wulff: Added alphabetic pager to the project overview page.

---
 l10n_community/l10n_community.css |    8 ++++
 l10n_community/pages.inc          |   67 ++++++++++++++++++++++++++++++++++--
 l10n_server/l10n_server.module    |   22 ++++++++++--
 3 files changed, 90 insertions(+), 7 deletions(-)

diff --git a/l10n_community/l10n_community.css b/l10n_community/l10n_community.css
index 418fd4a..2349b35 100644
--- a/l10n_community/l10n_community.css
+++ b/l10n_community/l10n_community.css
@@ -134,3 +134,11 @@ em.l10n-community-marker {
 #block-l10n_community-contributors tr.even, #block-l10n_community-contributors tr.odd {
   background-color: transparent;
 }
+
+/* Alphabetic pager for browsing projects */
+.item-list ul.pager-alphabetic {
+  margin: -1em 0 1em;
+  padding: 0.5em;
+  font-size: 14px;
+  background-color: #f6f6f2;
+}
diff --git a/l10n_community/pages.inc b/l10n_community/pages.inc
index cb4c9f3..2de7e75 100644
--- a/l10n_community/pages.inc
+++ b/l10n_community/pages.inc
@@ -94,13 +94,20 @@ function l10n_server_sort_by_column_language($a, $b) {
  * a pager on this screen.
  */
 function l10n_community_explore_projects() {
+  $output = '';
+
   $pager_setting = variable_get('l10n_community_project_per_page', 10);
 
-  $output = '';
-  if (!$projects = l10n_server_get_projects(array('pager' => $pager_setting))) {
+  $options = array('pager' => $pager_setting);
+  if (isset($_GET['initial'])) {
+    $options['initial'] = $_GET['initial'];
+  }
+
+  if (!$projects = l10n_server_get_projects($options)) {
     drupal_set_message(t('No projects found.'), 'error');
     return '';
   }
+
   $languages = l10n_community_get_languages('name');
   $language_count = count($languages);
   $string_counts = l10n_community_get_string_count('projects');
@@ -111,7 +118,11 @@ function l10n_community_explore_projects() {
     $output .= drupal_get_form('l10n_community_explore_projects_jump_form');
   }
 
-  $output .= theme('pager', NULL, $pager_setting, 0);
+  $pager = theme('pager', NULL, $pager_setting, 0);
+
+  $output .= _l10n_community_alphabetic_pager();
+  $output .= $pager;
+
   $table = array();
   foreach ($projects as $project) {
     $table[] = array_merge(
@@ -129,7 +140,7 @@ function l10n_community_explore_projects() {
     $table,
     array('class' => 'l10n-community-overview')
   );
-  $output .= theme('pager', NULL, $pager_setting, 0);
+  $output .= $pager;
   return $output .'<div class="clear-block"></div>';
 }
 
@@ -669,3 +680,51 @@ function l10n_community_get_string_count($type, $id = NULL) {
       return $accounts;
   }
 }
+
+/**
+ * Create an alphabetic pager for browsing projects.
+ */
+function _l10n_community_alphabetic_pager() {
+  $output = '';
+
+  // Grab the unique initials of all active projects
+  $result = db_query('SELECT DISTINCT(SUBSTR(title, 1, 1)) AS initial FROM l10n_server_project WHERE status = 1 ORDER BY initial ASC');
+
+  // Create an array of pager elements, all non-letters are grouped in the '#'
+  // element. We don't do any sorting of this array since the result should
+  // already be sorted correctly.
+  $initials = array();
+  while ($row = db_fetch_object($result)) {
+    $initial = $row->initial;
+
+    if (preg_match('/[[:alpha:]]/', $initial)) {
+      $initials[strtolower($initial)] = strtoupper($initial);
+    }
+    else {
+      $initials[0] = '#';
+    }
+  }
+
+  // Build a list of pager items, marking the active element
+  $items = array();
+  foreach ($initials as $link => $title) {
+    if (isset($_GET['initial']) && $_GET['initial'] == (string) $link) {
+      $items[] = array(
+        'class' => 'pager-current',
+        'data' => $title,
+      );
+    }
+    else {
+      $items[] = array(
+        'class' => 'pager-item',
+        'data' => l($title, 'translate/projects', array('query' => array('initial' => $link))),
+      );
+    }
+  }
+
+  if (!empty($items)) {
+    $output .= theme('item_list', $items, NULL, 'ul', array('class' => 'pager pager-alphabetic'));
+  }
+
+  return $output;
+}
diff --git a/l10n_server/l10n_server.module b/l10n_server/l10n_server.module
index 66c6612..a92bbc7 100644
--- a/l10n_server/l10n_server.module
+++ b/l10n_server/l10n_server.module
@@ -487,11 +487,27 @@ function l10n_server_get_projects($options = array()) {
   static $projects = array();
 
   // Consider returning all projects or just published ones.
-  $published = (empty($options['all']) ? 'WHERE status = 1 ' : '');
+  $where = (empty($options['all']) ? 'WHERE status = 1 ' : '');
 
   if (isset($options['pager'])) {
+    $arguments = array();
+
+    if (isset($options['initial'])) {
+      if (!empty($where)) {
+        $where .= 'AND ';
+      }
+
+      if ($options['initial'] == '0') {
+        $where .= "SUBSTR(title, 1, 1) NOT RLIKE '[[:alpha:]]' ";
+      }
+      else {
+        $where .= "SUBSTR(title, 1, 1) = '%s' ";
+        $arguments[] = $options['initial'];
+      }
+    }
+
     // If a pager view was asked for, collect data independently.
-    $results = pager_query('SELECT * FROM {l10n_server_project} '. $published .'ORDER BY title', $options['pager'], 0, NULL);
+    $results = pager_query('SELECT * FROM {l10n_server_project} '. $where .'ORDER BY title', $options['pager'], 0, NULL, $arguments);
     $pager_results = array();
     while ($project = db_fetch_object($results)) {
       $pager_results[$project->uri] = $project;
@@ -516,7 +532,7 @@ function l10n_server_get_projects($options = array()) {
     }
     else {
       // A list of *all* projects was asked for.
-      $results = db_query('SELECT * FROM {l10n_server_project} '. $published .'ORDER BY uri');
+      $results = db_query('SELECT * FROM {l10n_server_project} '. $where .'ORDER BY uri');
       while ($project = db_fetch_object($results)) {
         $projects[$project->uri] = $project;
       }
-- 
1.7.0.3

