diff options
-rw-r--r-- | includes/tablesort.inc | 81 | ||||
-rw-r--r-- | includes/theme.inc | 46 | ||||
-rw-r--r-- | modules/simpletest/simpletest.info | 1 | ||||
-rw-r--r-- | modules/simpletest/tests/tablesort.test | 167 |
4 files changed, 221 insertions, 74 deletions
diff --git a/includes/tablesort.inc b/includes/tablesort.inc index 55a3f4cec..121a1b909 100644 --- a/includes/tablesort.inc +++ b/includes/tablesort.inc @@ -73,18 +73,7 @@ class TableSort extends SelectQueryExtender { * 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) && isset($header['sort'])) { - return $header['sort']; - } - } - } - return 'asc'; + return tablesort_get_sort($this->header); } /** @@ -111,32 +100,7 @@ class TableSort extends SelectQueryExtender { * - "sql": 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 - $headers = array_values($this->header); - $header = $headers[0]; - if (is_array($header)) { - $header += array('data' => NULL, 'field' => NULL); - return array('name' => $header['data'], 'sql' => $header['field']); - } - else { - return array('name' => $header); - } - } + return tablesort_get_order($this->header); } } @@ -238,29 +202,27 @@ function tablesort_get_query_parameters() { function tablesort_get_order($headers) { $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'] : ''); - } + if (is_array($header)) { + if (isset($header['data']) && $order == $header['data']) { + $default = $header; + break; + } - if (isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) { - $default = array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : ''); + if (empty($default) && isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) { + $default = $header; + } } } - if (isset($default)) { - return $default; - } - 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' => ''); + if (!isset($default)) { + $default = reset($headers); + if (!is_array($default)) { + $default = array('data' => $default); } } + + $default += array('data' => NULL, 'field' => NULL); + return array('name' => $default['data'], 'sql' => $default['field']); } /** @@ -273,12 +235,15 @@ function tablesort_get_order($headers) { */ function tablesort_get_sort($headers) { if (isset($_GET['sort'])) { - return ($_GET['sort'] == 'desc') ? 'desc' : 'asc'; + return (strtolower($_GET['sort']) == 'desc') ? 'desc' : 'asc'; } - // User has not specified a sort. Use default if specified; otherwise use "asc". + // The user has not specified a sort. Use the default for the currently sorted + // header if specified; otherwise use "asc". else { + // Find out which header is currently being sorted. + $ts = tablesort_get_order($headers); foreach ($headers as $header) { - if (isset($header['sort'])) { + if (is_array($header) && isset($header['data']) && $header['data'] == $ts['name'] && isset($header['sort'])) { return $header['sort']; } } diff --git a/includes/theme.inc b/includes/theme.inc index 806e5ee9f..81165b36a 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -362,7 +362,6 @@ function drupal_theme_rebuild() { */ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { $result = array(); - $function = $name . '_theme'; // Processor functions work in two distinct phases with the process // functions always being executed after the preprocess functions. @@ -371,24 +370,43 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { 'process functions' => 'process', ); + $hook_defaults = array( + 'variables' => TRUE, + 'render element' => TRUE, + 'pattern' => TRUE, + 'base hook' => TRUE, + ); + + // Invoke the hook_theme() implementation, process what is returned, and + // merge it into $cache. + $function = $name . '_theme'; if (function_exists($function)) { $result = $function($cache, $type, $theme, $path); foreach ($result as $hook => $info) { + // When a theme or engine overrides a module's theme function + // $result[$hook] will only contain key/value pairs for information being + // overridden. Pull the rest of the information from what was defined by + // an earlier hook. + + // Fill in the type and path of the module, theme, or engine that + // implements this theme function. $result[$hook]['type'] = $type; $result[$hook]['theme path'] = $path; - // if function and file are left out, default to standard naming + + // If function and file are omitted, default to standard naming // conventions. if (!isset($info['template']) && !isset($info['function'])) { $result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name . '_') . $hook; } - // If a path is set in the info, use what was set. Otherwise use the - // default path. This is mostly so system.module can declare theme - // functions on behalf of core .include files. - // All files are included to be safe. Conditionally included - // files can prevent them from getting registered. + if (isset($cache[$hook]['includes'])) { $result[$hook]['includes'] = $cache[$hook]['includes']; } + + // If the theme implementation defines a file, then also use the path + // that it defined. Otherwise use the default path. This allows + // system.module to declare theme functions on behalf of core .include + // files. if (isset($info['file'])) { $include_file = isset($info['path']) ? $info['path'] : $path; $include_file .= '/' . $info['file']; @@ -396,14 +414,10 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { $result[$hook]['includes'][] = $include_file; } - // If these keys are left unspecified within overridden entries returned - // by hook_theme(), carry them forward from the prior entry. This is so - // that themes don't need to specify this information, since the module - // that registered the theme hook already has. - foreach (array('variables', 'render element', 'pattern', 'base hook') as $key) { - if (!isset($info[$key]) && isset($cache[$hook][$key])) { - $result[$hook][$key] = $cache[$hook][$key]; - } + // If the default keys are not set, use the default values registered + // by the module. + if (isset($cache[$hook])) { + $result[$hook] += array_intersect_key($cache[$hook], $hook_defaults); } // The following apply only to theming hooks implemented as templates. @@ -468,7 +482,7 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { } // Merge the newly created theme hooks into the existing cache. - $cache = array_merge($cache, $result); + $cache = $result + $cache; } // Let themes have variable processors even if they didn't register a template. diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info index 0e3c630f7..15d2bfd0e 100644 --- a/modules/simpletest/simpletest.info +++ b/modules/simpletest/simpletest.info @@ -32,6 +32,7 @@ files[] = tests/path.test files[] = tests/registry.test files[] = tests/schema.test files[] = tests/session.test +files[] = tests/tablesort.test files[] = tests/theme.test files[] = tests/unicode.test files[] = tests/update.test diff --git a/modules/simpletest/tests/tablesort.test b/modules/simpletest/tests/tablesort.test new file mode 100644 index 000000000..3462ce33e --- /dev/null +++ b/modules/simpletest/tests/tablesort.test @@ -0,0 +1,167 @@ +<?php +// $Id$ + +/** + * @file + * Various tablesort tests. + */ + +/** + * Test unicode handling features implemented in unicode.inc. + */ +class TableSortTest extends DrupalUnitTestCase { + + /** + * Storage for initial value of $_GET. + * + * @var array + */ + protected $GET = array(); + + public static function getInfo() { + return array( + 'name' => 'Tablesort', + 'description' => 'Tests table sorting.', + 'group' => 'System', + ); + } + + function setUp() { + // Save the original $_GET to be restored later. + $this->GET = $_GET; + + parent::setUp(); + } + + function tearDown() { + // Revert $_GET. + $_GET = $this->GET; + + parent::tearDown(); + } + + /** + * Test tablesort_init(). + */ + function testTableSortInit() { + + // Test simple table headers. + + $headers = array('foo', 'bar', 'baz'); + // Reset $_GET to prevent parameters from Simpletest and Batch API ending + // up in $ts['query']. + $_GET = array('q' => 'jahwohl'); + $expected_ts = array( + 'name' => 'foo', + 'sql' => '', + 'sort' => 'asc', + 'query' => array(), + ); + $ts = tablesort_init($headers); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Simple table headers sorted correctly.')); + + // Test with simple table headers plus $_GET parameters that should _not_ + // override the default. + + $_GET = array( + 'q' => 'jahwohl', + // This should not override the table order because only complex + // headers are overridable. + 'order' => 'bar', + ); + $ts = tablesort_init($headers); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Simple table headers plus non-overriding $_GET parameters sorted correctly.')); + + // Test with simple table headers plus $_GET parameters that _should_ + // override the default. + + $_GET = array( + 'q' => 'jahwohl', + 'sort' => 'DESC', + // Add an unrelated parameter to ensure that tablesort will include + // it in the links that it creates. + 'alpha' => 'beta', + ); + $expected_ts['sort'] = 'desc'; + $expected_ts['query'] = array('alpha' => 'beta'); + $ts = tablesort_init($headers); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Simple table headers plus $_GET parameters sorted correctly.')); + + // Test complex table headers. + + $headers = array( + 'foo', + array( + 'data' => '1', + 'field' => 'one', + 'sort' => 'asc', + 'colspan' => 1, + ), + array( + 'data' => '2', + 'field' => 'two', + 'sort' => 'desc', + ), + ); + // Reset $_GET from previous assertion. + $_GET = array( + 'q' => 'jahwohl', + 'order' => '2', + ); + $ts = tablesort_init($headers); + $expected_ts = array( + 'name' => '2', + 'sql' => 'two', + 'sort' => 'desc', + 'query' => array(), + ); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Complex table headers sorted correctly.')); + + // Test complex table headers plus $_GET parameters that should _not_ + // override the default. + + $_GET = array( + 'q' => 'jahwohl', + // This should not override the table order because this header does not + // exist. + 'order' => 'bar', + ); + $ts = tablesort_init($headers); + $expected_ts = array( + 'name' => '1', + 'sql' => 'one', + 'sort' => 'asc', + 'query' => array(), + ); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Complex table headers plus non-overriding $_GET parameters sorted correctly.')); + unset($_GET['sort'], $_GET['order'], $_GET['alpha']); + + // Test complex table headers plus $_GET parameters that _should_ + // override the default. + + $_GET = array( + 'q' => 'jahwohl', + 'order' => '1', + 'sort' => 'ASC', + // Add an unrelated parameter to ensure that tablesort will include + // it in the links that it creates. + 'alpha' => 'beta', + ); + $expected_ts = array( + 'name' => '1', + 'sql' => 'one', + 'sort' => 'asc', + 'query' => array('alpha' => 'beta'), + ); + $ts = tablesort_init($headers); + $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE))))); + $this->assertEqual($ts, $expected_ts, t('Complex table headers plus $_GET parameters sorted correctly.')); + unset($_GET['sort'], $_GET['order'], $_GET['alpha']); + + } +} |