r938: - Basics of the sorting system are now working
authorRobert Sesek <rsesek@bluestatic.org>
Mon, 24 Jul 2006 21:33:54 +0000 (21:33 +0000)
committerRobert Sesek <rsesek@bluestatic.org>
Mon, 24 Jul 2006 21:33:54 +0000 (21:33 +0000)
- Renamed bug.(productid, componentid, versionid) to be without the "id" bits

docs/schema_changes.sql
includes/api_bug.php
includes/class_sort.php [new file with mode: 0644]
index.php
templates/global.css
templates/trackerhome.tpl

index ac6e27f0743377dddacc2ae308672835341327ae..8b9ee8cdeefa568d99612de1279ad57545631477 100644 (file)
@@ -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';
index 91657132126f01fe3bd9d349721473c5ba120639..6d3227de574a4e780af81b19fd9da1ae6ee4c3e2 100644 (file)
@@ -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 (file)
index 0000000..3bf68a0
--- /dev/null
@@ -0,0 +1,296 @@
+<?php
+/*=====================================================================*\
+|| ###################################################################
+|| # Bugdar [#]version[#]
+|| # Copyright ©2002-[#]year[#] Iris Studios, Inc.
+|| #
+|| # This program is free software; you can redistribute it and/or modify
+|| # it under the terms of the GNU General Public License as published by
+|| # the Free Software Foundation; version [#]gpl[#] of the License.
+|| #
+|| # This program is distributed in the hope that it will be useful, but
+|| # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+|| # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+|| # more details.
+|| #
+|| # You should have received a copy of the GNU General Public License along
+|| # with this program; if not, write to the Free Software Foundation, Inc.,
+|| # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+|| ###################################################################
+\*=====================================================================*/
+
+/**
+* Bug Listing Sorter
+*
+* This class is used to sort bugs based on user-sent options and variables.
+*
+* @author              Iris Studios, Inc.
+* @copyright   Copyright ©2002 - [#]year[#], Iris Studios, Inc.
+* @version             $Revision$
+* @package             Bugdar
+* 
+*/
+class ListSorter
+{
+       /**
+       * Bugsys registry
+       * @var  object
+       * @access       private
+       */
+       var $registry;
+       
+       /**
+       * Page name
+       * @var  string
+       * @access       public
+       */
+       var $page = '';
+       
+       /**
+       * Current sort key
+       * @var  string
+       * @access       private
+       */
+       var $sortkey = '';
+       
+       /**
+       * Current sort direction
+       * @var  string
+       * @access       private
+       */
+       var $direction = '';
+       
+       // ###################################################################
+       /**
+       * Constructor: set the page name
+       *
+       * @access       public
+       *
+       * @param        string  File name without the .php extension
+       */
+       function ListSorter($page)
+       {
+               global $bugsys;
+               $this->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 <img> tag for the sort arrow
+       *
+       * @access       public
+       *
+       * @return       string  HTML <img> tag
+       */
+       function fetch_sort_image()
+       {
+               return '<img src="templates/images/arrow_' . $this->fetch_sort_direction() . '.gif" alt="" style="vertical-align: top; border: none" />';
+       }
+       
+       // ###################################################################
+       /**
+       * Returns the href value for an <a> 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 .= '&amp;';
+               }
+               
+               return $this->page . '.php?' . $params . 'by=' . $key . '&amp;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
index e28b0526520f7bc22b8ba775f78e370998a65688..0954748e17b76a1bcb29d1675d05269df6e4596e 100644 (file)
--- 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 . '&amp;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'];
index 6de6efaaea69fd3aab774bfd92c05c4386efb044..fcd9d7bf2d11945fe7c79c73d3f30c9a7bc6ee15 100644 (file)
@@ -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;
index b1d637054af34cd257aacd390efe80343c1fdb24..0802aa64b137bd6045274348c8e29b92b425e857 100644 (file)
@@ -11,12 +11,12 @@ $header
 
 <table border="$stylevar[border]" cellspacing="$stylevar[spacing]" cellpadding="$stylevar[padding]px" width="$stylevar[normal_width]">
 <tr class="listinghead">
-       <td>{@"ID"}</td>
-       <td>{@"Summary/Reporter"}</td>
-       <td>{@"Product/Version"}</td>
-       <td>{@"Status/Resolution"}</td>
-       <td>{@"Priority/Severity"}</td>
-       <td>{@"Last Post"}</td>
+       <td><a href="{$order['id']['href']}">{@"ID"}</a> {$order['id']['image']}</td>
+       <td><a href="{$order['summary']['href']}">{@"Summary"}</a> {$order['summary']['image']}/ <a href="{$order['reporter']['href']}">{@"Reporter"}</a> {$order['reporter']['image']}</td>
+       <td><a href="{$order['product']['href']}">{@"Product/Version"}</a> {$order['product']['image']}</td>
+       <td><a href="{$order['status']['href']}">{@"Status"}</a> {$order['status']['image']}/ <a href="{$order['resolution']['href']}">{@"Resolution"}</a> {$order['resolution']['image']}</td>
+       <td><a href="{$order['priority']['href']}">{@"Priority"}</a> {$order['priority']['image']}</a>/ <a href="{$order['severity']['href']}">{@"Severity"}</a> {$order['severity']['image']}</td>
+       <td><a href="{$order['lastpost']['href']}">{@"Last Post"}</a> {$order['lastpost']['image']}</td>
 </tr>
 $bugs
 </table>