From e5f15144e414a71c51b77dedef464abd1ab3c31b Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Mon, 24 Jul 2006 21:33:54 +0000 Subject: [PATCH] r938: - Basics of the sorting system are now working - Renamed bug.(productid, componentid, versionid) to be without the "id" bits --- docs/schema_changes.sql | 6 + includes/api_bug.php | 24 ++-- includes/class_sort.php | 296 ++++++++++++++++++++++++++++++++++++++ index.php | 24 ++-- templates/global.css | 16 +++ templates/trackerhome.tpl | 12 +- 6 files changed, 348 insertions(+), 30 deletions(-) create mode 100644 includes/class_sort.php diff --git a/docs/schema_changes.sql b/docs/schema_changes.sql index ac6e27f..8b9ee8c 100644 --- a/docs/schema_changes.sql +++ b/docs/schema_changes.sql @@ -18,3 +18,9 @@ DROP TABLE dependency; ALTER TABLE user ADD usedst BOOL NOT NULL; ALTER TABLE user ADD hidestatuses mediumtext NOT NULL; + +ALTER TABLE bug CHANGE productid product INT(10) UNSIGNED NOT NULL DEFAULT '0'; + +ALTER TABLE bug CHANGE componentid component INT(10) UNSIGNED NOT NULL DEFAULT '0'; + +ALTER TABLE bug CHANGE versionid version INT(10) UNSIGNED NOT NULL DEFAULT '0'; diff --git a/includes/api_bug.php b/includes/api_bug.php index 9165713..6d3227d 100644 --- a/includes/api_bug.php +++ b/includes/api_bug.php @@ -45,9 +45,9 @@ class BugAPI extends API 'userid' => array(TYPE_UINT, REQ_NO), 'username' => array(TYPE_STR, REQ_NO), 'dateline' => array(TYPE_UINT, REQ_SET), - 'productid' => array(TYPE_UINT, REQ_YES, ':self'), - 'componentid' => array(TYPE_UINT, REQ_NO, ':self'), - 'versionid' => array(TYPE_UINT, REQ_YES, ':self'), + 'product' => array(TYPE_UINT, REQ_YES, ':self'), + 'component' => array(TYPE_UINT, REQ_NO, ':self'), + 'version' => array(TYPE_UINT, REQ_YES, ':self'), 'summary' => array(TYPE_STR, REQ_YES, 'verify_noempty'), 'priority' => array(TYPE_UINT, REQ_NO, ':self'), 'severity' => array(TYPE_UINT, REQ_NO, ':self'), @@ -119,15 +119,15 @@ class BugAPI extends API // ################################################################### /** - * Verify: productid + * Verify: product * * @access private */ - function verify_productid() + function verify_product() { - $this->verify_nozero('productid'); + $this->verify_nozero('product'); - if (!$this->registry->datastore['product'][ $this->values['productid'] ]) + if (!$this->registry->datastore['product'][ $this->values['product'] ]) { return false; } @@ -140,9 +140,9 @@ class BugAPI extends API * * @access private */ - function verify_componentid() + function verify_component() { - if ($this->values['componentid'] != 0) + if ($this->values['component'] != 0) { $product = $this->registry->datastore['product'][ $this->values['product'] ]; $version = $this->registry->datastore['version'][ $this->values['version'] ]; @@ -164,11 +164,11 @@ class BugAPI extends API * * @access private */ - function verify_versionid() + function verify_version() { - $this->verify_nozero('versionid'); + $this->verify_nozero('version'); - if (!$this->registry->datastore['version'][ $this->values['versionid'] ]) + if (!$this->registry->datastore['version'][ $this->values['version'] ]) { return false; } diff --git a/includes/class_sort.php b/includes/class_sort.php new file mode 100644 index 0000000..3bf68a0 --- /dev/null +++ b/includes/class_sort.php @@ -0,0 +1,296 @@ +registry = $bugsys; + $this->page = $page; + $this->process_incoming(); + } + + // ################################################################### + /** + * Processes the incoming variables and then sets all the sort order + * information appropriately + * + * @access private + */ + function process_incoming() + { + $this->sortkey = $this->registry->in['by']; + if (!$this->fetch_by_text($this->registry->in['by'])) + { + $this->sortkey = 'lastpost'; + } + + $this->direction = $this->registry->in['as']; + if (!in_array($this->direction, array('asc', 'desc'))) + { + $this->direction = 'desc'; + } + } + + // ################################################################### + /** + * Fetch a SQL query to gather bugs with the sort filters applied + * + * @access public + * + * @param string Additional WHERE clauses in an array + * @param string A LIMIT clause + * + * @return string Compiled SQL query + */ + function fetch_sql_query($where = null, $limit = null) + { + // this WHERE clause is used for all the queries + $basewhere = "bug.product IN (" . fetch_on_bits('canviewbugs') . ") + AND (!bug.hidden OR (bug.hidden AND bug.product IN (" . fetch_on_bits('canviewhidden') . ")))" . (($this->registry->options['hidestatuses'] OR isset($this->registry->userinfo['hidestatuses'])) ? " + AND bug.status NOT IN (" . (isset($this->registry->userinfo['hidestatuses']) ? $this->registry->userinfo['hidestatuses'] : $this->registry->options['hidestatuses']) . ")" : ""); + + // remap the sort keys to be actual SQL fields + $querykeys = array( + 'id' => 'bugid', + 'summary' => 'summary', + 'reporter' => 'userid', + 'lastpost' => (can_perform('canviewhidden') ? "lastposttime" : "hiddenlastposttime") + ); + + switch ($this->sortkey) + { + case 'id': + case 'summary': + case 'reporter': + case 'lastpost': + $query = " + SELECT * FROM " . TABLE_PREFIX . "bug AS bug + WHERE $basewhere" . + (is_array($where) ? " + AND " . implode("\nAND ", $where) : "") . " + ORDER BY " . $querykeys[ $this->sortkey ] . ($this->sortkey != 'lastpost' ? ", " . $querykeys['lastpost'] : "") . " " . strtoupper($this->direction) . ($limit ? " + LIMIT $limit" : ""); + break; + case 'product': + case 'status': + case 'resolution': + case 'priority': + case 'severity': + $query = " + SELECT * FROM " . TABLE_PREFIX . "{$this->sortkey} AS {$this->sortkey} + RIGHT JOIN " . TABLE_PREFIX . "bug AS bug + ON (bug.{$this->sortkey} = {$this->sortkey}.{$this->sortkey}id) + WHERE $basewhere" . + (is_array($where) ? " + AND " . implode("\nAND ", $where) : "") . " + ORDER BY {$this->sortkey}.displayorder " . strtoupper($this->direction) . ", bug.$querykeys[lastpost] " . strtoupper($this->direction) . ($limit ? " + LIMIT $limit" : ""); + break; + } + + return $query; + } + + // ################################################################### + /** + * Returns the display text for a given sort order key + * + * @access public static + * + * @param string Sort order key, or FALSE for the array + * + * @return mixed Display text if param is string, or array of all key=>text if param is NULL + */ + function fetch_by_text($key) + { + global $lang; + + $keys = array( + 'id' => $lang->string('Bug ID'), + 'summary' => $lang->string('Summary'), + 'reporter' => $lang->string('Reporter'), + 'product' => $lang->string('Product'), + 'status' => $lang->string('Status'), + 'resolution' => $lang->string('Resolution'), + 'priority' => $lang->string('Priority'), + 'severity' => $lang->string('Severity'), + 'lastpost' => $lang->string('Last Post Time') + ); + + if ($key === false) + { + return $keys; + } + else + { + return $keys["$key"]; + } + } + + // ################################################################### + /** + * Returns a multi-dimensional array with sort by keys indexing arrays + * with 'image' and 'href' keys that store the values from + * fetch_sort_image() and fetch_sort_link(), respectively + * + * @access public + * + * @param string Extra GET parameters to pass to fetch_sort_link() + * + * @return array Array as described above + */ + function fetch_display_array($params = null) + { + $return = $this->fetch_by_text(false); + + foreach ($return AS $key => $nil) + { + $return["$key"] = array('image' => ($this->sortkey == $key ? $this->fetch_sort_image() : ''), 'href' => $this->fetch_sort_link($key, $params)); + } + + return $return; + } + + // ################################################################### + /** + * Returns the entire tag for the sort arrow + * + * @access public + * + * @return string HTML tag + */ + function fetch_sort_image() + { + return ''; + } + + // ################################################################### + /** + * Returns the href value for an tag by generating all the necessary + * bits and concat'ing it onto an extra string of GETs (optional) + * + * @access public + * + * @param string Sorting key + * @param string Additional GET parameters + * + * @return string HREF + */ + function fetch_sort_link($key, $params = null) + { + if ($params) + { + $params .= '&'; + } + + return $this->page . '.php?' . $params . 'by=' . $key . '&as=' . ($this->sortkey == $key ? $this->fetch_opposite_sort_direction() . '" class="select' : $this->fetch_sort_direction()); + } + + // ################################################################### + /** + * Returns the OPPOSITE direction to sort when you click on a link + * + * @access public + * + * @return string Either asc or desc + */ + function fetch_opposite_sort_direction() + { + if ($this->direction == 'asc') + { + return 'desc'; + } + else + { + return 'asc'; + } + } + + // ################################################################### + /** + * Returns the current sorted direction for the image path + * + * @access public + * + * @return string Either asc or desc + */ + function fetch_sort_direction() + { + return $this->direction; + } +} + +/*=====================================================================*\ +|| ################################################################### +|| # $HeadURL$ +|| # $Id$ +|| ################################################################### +\*=====================================================================*/ +?> \ No newline at end of file diff --git a/index.php b/index.php index e28b052..0954748 100644 --- a/index.php +++ b/index.php @@ -32,41 +32,41 @@ $focus['index'] = 'focus'; require_once('./global.php'); require_once('./includes/class_pagination.php'); +require_once('./includes/class_sort.php'); if (!can_perform('canviewbugs')) { $message->error_permission(); } +$sort = new ListSorter('index'); + // ################################################################### $pagination = new Pagination('p', 'pp'); $count = $db->query_first(" SELECT COUNT(*) AS count FROM " . TABLE_PREFIX . "bug - WHERE (!hidden OR (hidden AND productid IN (" . fetch_on_bits('canviewhidden') . "))) - AND productid IN (" . fetch_on_bits('canviewbugs') . ")" . (($bugsys->options['hidestatuses'] OR isset($bugsys->userinfo['hidestatuses'])) ? " + WHERE (!hidden OR (hidden AND product IN (" . fetch_on_bits('canviewhidden') . "))) + AND product IN (" . fetch_on_bits('canviewbugs') . ")" . (($bugsys->options['hidestatuses'] OR isset($bugsys->userinfo['hidestatuses'])) ? " AND status NOT IN (" . (isset($bugsys->userinfo['hidestatuses']) ? $bugsys->userinfo['hidestatuses'] : $bugsys->options['hidestatuses']) . ")" : "") ); +echo $sort->fetch_sql_query(null, $pagination->fetch_limit($pagination->page - 1) . ", " . $pagination->perpage); + $pagination->total = $count['count']; $pagination->split_pages(); -$bugs_fetch = $db->query(" - SELECT * FROM " . TABLE_PREFIX . "bug - WHERE productid IN (" . fetch_on_bits('canviewbugs') . ") - AND (!hidden OR (hidden AND productid IN (" . fetch_on_bits('canviewhidden') . ")))" . (($bugsys->options['hidestatuses'] OR isset($bugsys->userinfo['hidestatuses'])) ? " - AND status NOT IN (" . (isset($bugsys->userinfo['hidestatuses']) ? $bugsys->userinfo['hidestatuses'] : $bugsys->options['hidestatuses']) . ")" : "") . " - ORDER BY " . (can_perform('canviewhidden') ? "lastposttime" : "hiddenlastposttime") . " DESC - LIMIT " . $pagination->fetch_limit($pagination->page - 1) . ", " . $pagination->perpage -); +$bugs_fetch = $db->query($sort->fetch_sql_query(null, $pagination->fetch_limit($pagination->page - 1) . ", " . $pagination->perpage)); + +$order = $sort->fetch_display_array('p=' . $pagination->page . '&pp=' . $pagination->perpage); while ($bug = $db->fetch_array($bugs_fetch)) { $funct->exec_swap_bg($stylevar['alt_colour'], ''); $bug['bgcolour'] = ($bugsys->userinfo['showcolours'] ? $bugsys->datastore['status']["$bug[status]"]['color'] : $funct->bgcolour); - $bug['product'] = $bugsys->datastore['product']["$bug[productid]"]['title']; - $bug['version'] = $bugsys->datastore['version']["$bug[versionid]"]['version']; + $bug['product'] = $bugsys->datastore['product']["$bug[product]"]['title']; + $bug['version'] = $bugsys->datastore['version']["$bug[version]"]['version']; $bug['status'] = $bugsys->datastore['status']["$bug[status]"]['status']; $bug['resolution'] = $bugsys->datastore['resolution']["$bug[resolution]"]['resolution']; $bug['priority'] = $bugsys->datastore['priority']["$bug[priority]"]['priority']; diff --git a/templates/global.css b/templates/global.css index 6de6efa..fcd9d7b 100644 --- a/templates/global.css +++ b/templates/global.css @@ -122,6 +122,22 @@ a font-weight: bold; } +.listinghead a +{ + color: rgb(255, 255, 255); +} + +.listinghead a:hover +{ + color: rgb(64, 102, 112); +} + +.listinghead .select +{ + color: rgb(187, 44, 0); + font-style: italic; +} + .form { display: inline; diff --git a/templates/trackerhome.tpl b/templates/trackerhome.tpl index b1d6370..0802aa6 100644 --- a/templates/trackerhome.tpl +++ b/templates/trackerhome.tpl @@ -11,12 +11,12 @@ $header - - - - - - + + + + + + $bugs
{@"ID"}{@"Summary/Reporter"}{@"Product/Version"}{@"Status/Resolution"}{@"Priority/Severity"}{@"Last Post"}{@"ID"} {$order['id']['image']}{@"Summary"} {$order['summary']['image']}/ {@"Reporter"} {$order['reporter']['image']}{@"Product/Version"} {$order['product']['image']}{@"Status"} {$order['status']['image']}/ {@"Resolution"} {$order['resolution']['image']}{@"Priority"} {$order['priority']['image']}/ {@"Severity"} {$order['severity']['image']}{@"Last Post"} {$order['lastpost']['image']}
-- 2.22.5