Index: includes/common.inc
===================================================================
--- includes/common.inc (revision 1657)
+++ includes/common.inc (working copy)
@@ -4497,7 +4497,6 @@
require_once DRUPAL_ROOT . '/includes/theme.inc';
require_once DRUPAL_ROOT . '/includes/pager.inc';
require_once DRUPAL_ROOT . '/includes/menu.inc';
- require_once DRUPAL_ROOT . '/includes/tablesort.inc';
require_once DRUPAL_ROOT . '/includes/file.inc';
require_once DRUPAL_ROOT . '/includes/unicode.inc';
require_once DRUPAL_ROOT . '/includes/image.inc';
Index: includes/theme.inc
===================================================================
--- includes/theme.inc (revision 1657)
+++ includes/theme.inc (working copy)
@@ -1755,22 +1755,29 @@
}
}
- // Format the table header:
+ // Format the table header.
if (count($header)) {
- $ts = tablesort_init($header);
+ // Determine whether we need to load tablesort.
+ foreach ($header as $column) {
+ if (is_array($column) && isset($column['field'])) {
+ require_once DRUPAL_ROOT . '/includes/tablesort.inc';
+ $ts = tablesort_init($header);
+ break;
+ }
+ }
+
// HTML requires that the thead tag has tr tags in it followed by tbody
// tags. Using ternary operator to check and see if we have any rows.
$output .= (count($rows) ? ' ' : '
');
foreach ($header as $cell) {
- $cell = tablesort_header($cell, $header, $ts);
+ if (isset($ts)) {
+ $cell = tablesort_header($cell, $header, $ts);
+ }
$output .= _theme_table_cell($cell, TRUE);
}
// Using ternary operator to close the tags based on whether or not there are rows
$output .= (count($rows) ? "
\n" : "\n");
}
- else {
- $ts = array();
- }
// Add the 'empty' row message if available.
if (!count($rows) && $empty) {
@@ -1808,7 +1815,9 @@
$output .= '
';
$i = 0;
foreach ($cells as $cell) {
- $cell = tablesort_cell($cell, $header, $ts, $i++);
+ if (isset($ts)) {
+ $cell = tablesort_cell($cell, $header, $ts, $i++);
+ }
$output .= _theme_table_cell($cell);
}
$output .= "
\n";
Index: includes/tablesort.inc
===================================================================
--- includes/tablesort.inc (revision 1657)
+++ includes/tablesort.inc (working copy)
@@ -16,7 +16,7 @@
class TableSort extends SelectQueryExtender {
/**
- * The array of fields that can be sorted by.
+ * An array of table header columns that can be sorted by, as described in theme_table().
*
* @var array
*/
@@ -34,23 +34,22 @@
/**
* Order the query based on a header array.
*
- * @see theme_table()
* @param $header
- * Table header array.
+ * An array of table header columns as described in theme_table().
+ *
* @return SelectQueryInterface
* The called object.
+ *
+ * @see theme_table()
*/
- public function orderByHeader(Array $header) {
+ public function orderByHeader(array $header) {
$this->header = $header;
$ts = $this->init();
- if (!empty($ts['sql'])) {
- // Based on code from db_escape_table(), but this can also contain a dot.
- $field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']);
-
+ if (!empty($ts['field'])) {
// Sort order can only be ASC or DESC.
$sort = drupal_strtoupper($ts['sort']);
$sort = in_array($sort, array('ASC', 'DESC')) ? $sort : '';
- $this->orderBy($field, $sort);
+ $this->orderBy($ts['field'], $sort);
}
return $this;
}
@@ -69,23 +68,12 @@
* Determine the current sort direction.
*
* @param $headers
- * An array of column headers in the format described in theme_table().
+ * An array of table header columns as described in theme_table().
* @return
* The current sort direction ("asc" or "desc").
*/
protected function getSort() {
- if (isset($_GET['sort'])) {
- return ($_GET['sort'] == 'desc') ? 'desc' : 'asc';
- }
- // User has not specified a sort. Use default if specified; otherwise use "asc".
- else {
- foreach ($this->header as $header) {
- if (is_array($header) && array_key_exists('sort', $header)) {
- return $header['sort'];
- }
- }
- }
- return 'asc';
+ return tablesort_get_sort($this->header);
}
/**
@@ -104,38 +92,13 @@
/**
* Determine the current sort criterion.
*
- * @param $headers
- * An array of column headers in the format described in theme_table().
* @return
* An associative array describing the criterion, containing the keys:
- * - "name": The localized title of the table column.
- * - "sql": The name of the database field to sort on.
+ * - name: The localized title of the table column.
+ * - field: The name of the database field to sort on.
*/
protected function order() {
- $order = isset($_GET['order']) ? $_GET['order'] : '';
- foreach ($this->header as $header) {
- if (isset($header['data']) && $order == $header['data']) {
- return array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
- }
-
- if (isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) {
- $default = array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
- }
- }
-
- if (isset($default)) {
- return $default;
- }
- else {
- // The first column specified is initial 'order by' field unless otherwise specified
- if (is_array($this->header[0])) {
- $this->header[0] += array('data' => NULL, 'field' => NULL);
- return array('name' => $this->header[0]['data'], 'sql' => $this->header[0]['field']);
- }
- else {
- return array('name' => $this->header[0]);
- }
- }
+ return tablesort_get_order($this->header);
}
}
@@ -158,7 +121,7 @@
* @param $cell
* The cell to format.
* @param $header
- * An array of column headers in the format described in theme_table().
+ * An array of table header columns as described in theme_table().
* @param $ts
* The current table sort context as returned from tablesort_init().
* @return
@@ -168,7 +131,7 @@
// Special formatting for the currently sorted column header.
if (is_array($cell) && isset($cell['field'])) {
$title = t('sort by @s', array('@s' => $cell['data']));
- if ($cell['data'] == $ts['name']) {
+ if ($cell['field'] == $ts['field']) {
$ts['sort'] = (($ts['sort'] == 'asc') ? 'desc' : 'asc');
$cell['class'][] = 'active';
$image = theme('tablesort_indicator', array('style' => $ts['sort']));
@@ -178,7 +141,12 @@
$ts['sort'] = 'asc';
$image = '';
}
- $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('attributes' => array('title' => $title), 'query' => array_merge($ts['query'], array('sort' => $ts['sort'], 'order' => $cell['data'])), 'html' => TRUE));
+ $options = array(
+ 'attributes' => array('title' => $title),
+ 'query' => array_merge($ts['query'], array('sort' => $ts['sort'], 'order' => $cell['field'])),
+ 'html' => TRUE,
+ );
+ $cell['data'] = l($cell['data'] . $image, $_GET['q'], $options);
unset($cell['field'], $cell['sort']);
}
@@ -193,7 +161,7 @@
* @param $cell
* The cell to format.
* @param $header
- * An array of column headers in the format described in theme_table().
+ * An array of table header columns as described in theme_table().
* @param $ts
* The current table sort context as returned from tablesort_init().
* @param $i
@@ -202,7 +170,7 @@
* A properly formatted cell, ready for _theme_table_cell().
*/
function tablesort_cell($cell, $header, $ts, $i) {
- if (isset($header[$i]['data']) && $header[$i]['data'] == $ts['name'] && !empty($header[$i]['field'])) {
+ if (isset($header[$i]['field']) && $header[$i]['field'] == $ts['field']) {
if (is_array($cell)) {
$cell['class'][] = 'active';
}
@@ -227,58 +195,65 @@
/**
* Determine the current sort criterion.
*
- * @param $headers
- * An array of column headers in the format described in theme_table().
+ * @param $header
+ * An array of table header columns as described in theme_table().
* @return
* An associative array describing the criterion, containing the keys:
- * - "name": The localized title of the table column.
- * - "sql": The name of the database field to sort on.
+ * - name: The localized title of the table column.
+ * - field: The name of the database field to sort on.
*/
-function tablesort_get_order($headers) {
+function tablesort_get_order($header) {
$order = isset($_GET['order']) ? $_GET['order'] : '';
- foreach ($headers as $header) {
- if (isset($header['data']) && $order == $header['data']) {
- return array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
+ foreach ($header as $column) {
+ if (!is_array($column) || !isset($column['field'])) {
+ continue;
}
-
- if (isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) {
- $default = array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
+ // Use the header column matching the URL parameter.
+ if ($order == $column['field']) {
+ return array('name' => $column['data'], 'field' => $column['field']);
}
+ // In case no header column will match the URL parameter, and this column
+ // defines 'sort', it is supposed to be the default sorting column.
+ if (isset($column['sort']) && ($column['sort'] == 'asc' || $column['sort'] == 'desc')) {
+ $default_column = array('name' => $column['data'], 'field' => $column['field']);
+ }
+ // In case there is no default sorting header column, store the first that
+ // defines a field.
+ elseif (!isset($first_column)) {
+ $first_column = array('name' => $column['data'], 'field' => $column['field']);
+ }
}
- if (isset($default)) {
- return $default;
+ // If there was a default sorting column, return that.
+ if (isset($default_column)) {
+ return $default_column;
}
- else {
- // The first column specified is the initial 'order by' field unless otherwise specified.
- $first = current($headers);
- if (is_array($first)) {
- $first += array('data' => NULL, 'field' => NULL);
- return array('name' => $first['data'], 'sql' => $first['field']);
- }
- else {
- return array('name' => $first, 'sql' => '');
- }
+ // Otherwise, use the first header column that defines a field.
+ if (isset($first_column)) {
+ return $first_column;
}
+ // If we end up here, then a table header did not define any valid tablesort
+ // data.
+ throw new Exception(t('Invalid TableSort data; header needs to define at least one sorting field.'));
}
/**
* Determine the current sort direction.
*
- * @param $headers
- * An array of column headers in the format described in theme_table().
+ * @param $header
+ * An array of table header columns as described in theme_table().
* @return
* The current sort direction ("asc" or "desc").
*/
-function tablesort_get_sort($headers) {
+function tablesort_get_sort($header) {
if (isset($_GET['sort'])) {
return ($_GET['sort'] == 'desc') ? 'desc' : 'asc';
}
// User has not specified a sort. Use default if specified; otherwise use "asc".
else {
- foreach ($headers as $header) {
- if (is_array($header) && array_key_exists('sort', $header)) {
- return $header['sort'];
+ foreach ($header as $column) {
+ if (is_array($column) && isset($column['sort'])) {
+ return $column['sort'];
}
}
}
Index: modules/forum/forum.module
===================================================================
--- modules/forum/forum.module (revision 1657)
+++ modules/forum/forum.module (working copy)
@@ -57,7 +57,7 @@
return array(
'forums' => array(
'template' => 'forums',
- 'variables' => array('forums' => NULL, 'topics' => NULL, 'parents' => NULL, 'tid' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
+ 'variables' => array('forums' => NULL, 'topics' => array(), 'parents' => NULL, 'tid' => NULL, 'header' => array(), 'forum_per_page' => NULL),
),
'forum_list' => array(
'template' => 'forum-list',
@@ -65,7 +65,7 @@
),
'forum_topic_list' => array(
'template' => 'forum-topic-list',
- 'variables' => array('tid' => NULL, 'topics' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
+ 'variables' => array('tid' => NULL, 'topics' => array(), 'header' => array(), 'forum_per_page' => NULL),
),
'forum_icon' => array(
'template' => 'forum-icon',
@@ -807,30 +807,16 @@
->fetchField();
}
-function forum_get_topics($tid, $sortby, $forum_per_page) {
- global $user, $forum_topic_list_header;
+function forum_get_topics($tid, $header, $forum_per_page) {
+ global $user;
- $forum_topic_list_header = array(
- NULL,
- array('data' => t('Topic'), 'field' => 'f.title'),
- array('data' => t('Replies'), 'field' => 'f.comment_count'),
- array('data' => t('Last reply'), 'field' => 'f.last_comment_timestamp'),
- );
-
- $order = _forum_get_topic_order($sortby);
- for ($i = 0; $i < count($forum_topic_list_header); $i++) {
- if ($forum_topic_list_header[$i]['field'] == $order['field']) {
- $forum_topic_list_header[$i]['sort'] = $order['sort'];
- }
- }
-
$query = db_select('forum_index', 'f')->extend('PagerDefault')->extend('TableSort');
$query->fields('f');
$query
->condition('f.tid', $tid)
->addTag('node_access')
->orderBy('f.sticky', 'DESC')
- ->orderByHeader($forum_topic_list_header)
+ ->orderByHeader($header)
->orderBy('f.last_comment_timestamp', 'DESC')
->limit($forum_per_page);
@@ -892,7 +878,7 @@
* - $topics
* - $parents
* - $tid
- * - $sortby
+ * - $header
* - $forum_per_page
*
* @see forums.tpl.php
@@ -1011,20 +997,21 @@
* $variables contains the following data:
* - $tid
* - $topics
- * - $sortby
+ * - $header
* - $forum_per_page
*
* @see forum-topic-list.tpl.php
* @see theme_forum_topic_list()
*/
function template_preprocess_forum_topic_list(&$variables) {
- global $forum_topic_list_header;
+ // Render the table header; this is required, because the forum topic list
+ // table does not use theme_table().
+ require_once DRUPAL_ROOT . '/includes/tablesort.inc';
+ $ts = tablesort_init($variables['header']);
- // Create the tablesorting header.
- $ts = tablesort_init($forum_topic_list_header);
$header = '';
- foreach ($forum_topic_list_header as $cell) {
- $cell = tablesort_header($cell, $forum_topic_list_header, $ts);
+ foreach ($variables['header'] as $cell) {
+ $cell = tablesort_header($cell, $variables['header'], $ts);
$header .= _theme_table_cell($cell, TRUE);
}
$variables['header'] = $header;
@@ -1062,10 +1049,6 @@
}
}
- else {
- // Make this safe for the template
- $variables['topics'] = array();
- }
// Give meaning to $tid for themers. $tid actually stands for term id.
$variables['topic_id'] = $variables['tid'];
unset($variables['tid']);
@@ -1133,16 +1116,16 @@
switch ($sortby) {
case 1:
return array('field' => 'ncs.last_comment_timestamp', 'sort' => 'desc');
- break;
+
case 2:
return array('field' => 'ncs.last_comment_timestamp', 'sort' => 'asc');
- break;
+
case 3:
return array('field' => 'ncs.comment_count', 'sort' => 'desc');
- break;
+
case 4:
return array('field' => 'ncs.comment_count', 'sort' => 'asc');
- break;
+
}
}
Index: modules/forum/forum.pages.inc
===================================================================
--- modules/forum/forum.pages.inc (revision 1657)
+++ modules/forum/forum.pages.inc (working copy)
@@ -10,15 +10,27 @@
* Menu callback; prints a forum listing.
*/
function forum_page($tid = 0) {
- $topics = '';
$forum_per_page = variable_get('forum_per_page', 25);
- $sortby = variable_get('forum_order', 1);
+ $header = array(
+ NULL,
+ array('data' => t('Topic'), 'field' => 'n.title'),
+ array('data' => t('Replies'), 'field' => 'ncs.comment_count'),
+ array('data' => t('Last reply'), 'field' => 'ncs.last_comment_timestamp'),
+ );
+ $order = _forum_get_topic_order(variable_get('forum_order', 1));
+ for ($i = 0; $i < count($header); $i++) {
+ if ($header[$i]['field'] == $order['field']) {
+ $header[$i]['sort'] = $order['sort'];
+ }
+ }
+
$forums = forum_get_forums($tid);
$parents = taxonomy_get_parents_all($tid);
+ $topics = array();
if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
- $topics = forum_get_topics($tid, $sortby, $forum_per_page);
+ $topics = forum_get_topics($tid, $header, $forum_per_page);
}
- return theme('forums', array('forums' => $forums, 'topics' => $topics, 'parents' => $parents, 'tid' => $tid, 'sortby' => $sortby, 'forums_per_page' => $forum_per_page));
+ return theme('forums', $forums, $topics, $parents, $tid, $header, $forum_per_page);
}
Index: modules/simpletest/tests/database_test.test
===================================================================
--- modules/simpletest/tests/database_test.test (revision 1657)
+++ modules/simpletest/tests/database_test.test (working copy)
@@ -2065,10 +2065,10 @@
*/
function testTableSortQuery() {
$sorts = array(
- array('field' => t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'),
- array('field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'),
- array('field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'),
- array('field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'),
+ array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'),
+ array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'),
+ array('data' => t('Task'), 'field' => 'task', 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'),
+ array('data' => t('Task'), 'field' => 'task', 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'),
// more elements here
);
@@ -2091,10 +2091,10 @@
*/
function testTableSortQueryFirst() {
$sorts = array(
- array('field' => t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'),
- array('field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'),
- array('field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'),
- array('field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'),
+ array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'),
+ array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'),
+ array('data' => t('Task'), 'field' => 'task', 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'),
+ array('data' => t('Task'), 'field' => 'task', 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'),
// more elements here
);