web/drupal/includes/tablesort.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: tablesort.inc,v 1.47.2.1 2009/07/01 20:51:55 goba Exp $
       
     3 
       
     4 /**
       
     5  * @file
       
     6  * Functions to aid in the creation of sortable tables.
       
     7  *
       
     8  * All tables created with a call to theme('table') have the option of having
       
     9  * column headers that the user can click on to sort the table by that column.
       
    10  */
       
    11 
       
    12 /**
       
    13  * Initialize the table sort context.
       
    14  */
       
    15 function tablesort_init($header) {
       
    16   $ts = tablesort_get_order($header);
       
    17   $ts['sort'] = tablesort_get_sort($header);
       
    18   $ts['query_string'] = tablesort_get_querystring();
       
    19   return $ts;
       
    20 }
       
    21 
       
    22 /**
       
    23  * Create an SQL sort clause.
       
    24  *
       
    25  * This function produces the ORDER BY clause to insert in your SQL queries,
       
    26  * assuring that the returned database table rows match the sort order chosen
       
    27  * by the user.
       
    28  *
       
    29  * @param $header
       
    30  *   An array of column headers in the format described in theme_table().
       
    31  * @param $before
       
    32  *   An SQL string to insert after ORDER BY and before the table sorting code.
       
    33  *   Useful for sorting by important attributes like "sticky" first.
       
    34  * @return
       
    35  *   An SQL string to append to the end of a query.
       
    36  *
       
    37  * @ingroup database
       
    38  */
       
    39 function tablesort_sql($header, $before = '') {
       
    40   $ts = tablesort_init($header);
       
    41   if ($ts['sql']) {
       
    42     // Based on code from db_escape_table(), but this can also contain a dot.
       
    43     $field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']);
       
    44 
       
    45     // Sort order can only be ASC or DESC.
       
    46     $sort = drupal_strtoupper($ts['sort']);
       
    47     $sort = in_array($sort, array('ASC', 'DESC')) ? $sort : '';
       
    48 
       
    49     return " ORDER BY $before $field $sort";
       
    50   }
       
    51 }
       
    52 
       
    53 /**
       
    54  * Format a column header.
       
    55  *
       
    56  * If the cell in question is the column header for the current sort criterion,
       
    57  * it gets special formatting. All possible sort criteria become links.
       
    58  *
       
    59  * @param $cell
       
    60  *   The cell to format.
       
    61  * @param $header
       
    62  *   An array of column headers in the format described in theme_table().
       
    63  * @param $ts
       
    64  *   The current table sort context as returned from tablesort_init().
       
    65  * @return
       
    66  *   A properly formatted cell, ready for _theme_table_cell().
       
    67  */
       
    68 function tablesort_header($cell, $header, $ts) {
       
    69   // Special formatting for the currently sorted column header.
       
    70   if (is_array($cell) && isset($cell['field'])) {
       
    71     $title = t('sort by @s', array('@s' => $cell['data']));
       
    72     if ($cell['data'] == $ts['name']) {
       
    73       $ts['sort'] = (($ts['sort'] == 'asc') ? 'desc' : 'asc');
       
    74       if (isset($cell['class'])) {
       
    75         $cell['class'] .= ' active';
       
    76       }
       
    77       else {
       
    78         $cell['class'] = 'active';
       
    79       }
       
    80       $image = theme('tablesort_indicator', $ts['sort']);
       
    81     }
       
    82     else {
       
    83       // If the user clicks a different header, we want to sort ascending initially.
       
    84       $ts['sort'] = 'asc';
       
    85       $image = '';
       
    86     }
       
    87 
       
    88     if (!empty($ts['query_string'])) {
       
    89       $ts['query_string'] = '&'. $ts['query_string'];
       
    90     }
       
    91     $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('attributes' => array('title' => $title), 'query' => 'sort='. $ts['sort'] .'&order='. urlencode($cell['data']) . $ts['query_string'], 'html' => TRUE));
       
    92 
       
    93     unset($cell['field'], $cell['sort']);
       
    94   }
       
    95   return $cell;
       
    96 }
       
    97 
       
    98 /**
       
    99  * Format a table cell.
       
   100  *
       
   101  * Adds a class attribute to all cells in the currently active column.
       
   102  *
       
   103  * @param $cell
       
   104  *   The cell to format.
       
   105  * @param $header
       
   106  *   An array of column headers in the format described in theme_table().
       
   107  * @param $ts
       
   108  *   The current table sort context as returned from tablesort_init().
       
   109  * @param $i
       
   110  *   The index of the cell's table column.
       
   111  * @return
       
   112  *   A properly formatted cell, ready for _theme_table_cell().
       
   113  */
       
   114 function tablesort_cell($cell, $header, $ts, $i) {
       
   115   if (isset($header[$i]['data']) && $header[$i]['data'] == $ts['name'] && !empty($header[$i]['field'])) {
       
   116     if (is_array($cell)) {
       
   117       if (isset($cell['class'])) {
       
   118         $cell['class'] .= ' active';
       
   119       }
       
   120       else {
       
   121         $cell['class'] = 'active';
       
   122       }
       
   123     }
       
   124     else {
       
   125       $cell = array('data' => $cell, 'class' => 'active');
       
   126     }
       
   127   }
       
   128   return $cell;
       
   129 }
       
   130 
       
   131 /**
       
   132  * Compose a query string to append to table sorting requests.
       
   133  *
       
   134  * @return
       
   135  *   A query string that consists of all components of the current page request
       
   136  *   except for those pertaining to table sorting.
       
   137  */
       
   138 function tablesort_get_querystring() {
       
   139   return drupal_query_string_encode($_REQUEST, array_merge(array('q', 'sort', 'order', 'pass'), array_keys($_COOKIE)));
       
   140 }
       
   141 
       
   142 /**
       
   143  * Determine the current sort criterion.
       
   144  *
       
   145  * @param $headers
       
   146  *   An array of column headers in the format described in theme_table().
       
   147  * @return
       
   148  *   An associative array describing the criterion, containing the keys:
       
   149  *   - "name": The localized title of the table column.
       
   150  *   - "sql": The name of the database field to sort on.
       
   151  */
       
   152 function tablesort_get_order($headers) {
       
   153   $order = isset($_GET['order']) ? $_GET['order'] : '';
       
   154   foreach ($headers as $header) {
       
   155     if (isset($header['data']) && $order == $header['data']) {
       
   156       return array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
       
   157     }
       
   158 
       
   159     if (isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) {
       
   160       $default = array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : '');
       
   161     }
       
   162   }
       
   163 
       
   164   if (isset($default)) {
       
   165     return $default;
       
   166   }
       
   167   else {
       
   168     // The first column specified is initial 'order by' field unless otherwise specified
       
   169     if (is_array($headers[0])) {
       
   170       $headers[0] += array('data' => NULL, 'field' => NULL);
       
   171       return array('name' => $headers[0]['data'], 'sql' => $headers[0]['field']);
       
   172     }
       
   173     else {
       
   174       return array('name' => $headers[0]);
       
   175     }
       
   176   }
       
   177 }
       
   178 
       
   179 /**
       
   180  * Determine the current sort direction.
       
   181  *
       
   182  * @param $headers
       
   183  *   An array of column headers in the format described in theme_table().
       
   184  * @return
       
   185  *   The current sort direction ("asc" or "desc").
       
   186  */
       
   187 function tablesort_get_sort($headers) {
       
   188   if (isset($_GET['sort'])) {
       
   189     return ($_GET['sort'] == 'desc') ? 'desc' : 'asc';
       
   190   }
       
   191   // User has not specified a sort. Use default if specified; otherwise use "asc".
       
   192   else {
       
   193     foreach ($headers as $header) {
       
   194       if (is_array($header) && array_key_exists('sort', $header)) {
       
   195         return $header['sort'];
       
   196       }
       
   197     }
       
   198   }
       
   199   return 'asc';
       
   200 }