From b385503d2b1e52f699d1c39f1bc33f84fc4a2559 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Tue, 13 Feb 2007 02:33:06 +0000 Subject: [PATCH] r1399: - Searches no longer store the actual DB query but rather the parameters for the query - Modified process_custom_fields() to no longer worry about custom data input - Added a flag in process_custom_fields() for $searchMode - The mass-update feature now works, except for logging --- docs/changes.txt | 2 + docs/todo.txt | 1 - includes/functions.php | 21 ++- search.php | 299 +++++++++++++++++++++-------------------- 4 files changed, 173 insertions(+), 150 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index f470b51..4af03b0 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -14,6 +14,8 @@ - Move custom field data into the bug table to reduce the use of JOINs - Remove a query on userctrl.php's save options called by build_assignedto() because the API already does this for us - Setting system cleanup that improves speed by reducing queries and not using eval() +- Can now mass update of bug fields from the search screen +- Search system no longer stores the actual query of the search, but rather the paramters 1.1.5 =============================== diff --git a/docs/todo.txt b/docs/todo.txt index 700c7f2..3079a9e 100755 --- a/docs/todo.txt +++ b/docs/todo.txt @@ -5,7 +5,6 @@ SVN: $Id$ ############################################################################### BUGDAR 1.2 -- Mass updates and deletes - Importing from other bug systems (bug://report/41) - Workflow interface diff --git a/includes/functions.php b/includes/functions.php index a713d2c..0604580 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -337,11 +337,11 @@ function construct_custom_fields($bug = array(), $ignore21mask = false, $nodefau * @param object A BugAPI object * @param object MessageReporter object * @param bool If there are errors, add them to an errorbox format? If not, then display-on-encounter -* @param array If you don't want to get the data from $bugsys->in[], then an optional input source +* @param bool Search mode: don't change certain fields when they're 0 or empty * * @return mixed NULL if an ID is passed, string if bugid is NULL */ -function process_custom_fields(&$bugapi, &$msg, $errorbox = false, $inputdata = array()) +function process_custom_fields(&$bugapi, &$msg, $errorbox = false, $searchMode = false) { global $bugsys; @@ -363,11 +363,15 @@ function process_custom_fields(&$bugapi, &$msg, $errorbox = false, $inputdata = $fieldname = "custom$field[fieldid]"; if ($field['type'] == 'input_checkbox') { + if ($searchMode AND intval($inputdata["$fieldname"]) == 0) + { + continue; + } $bugapi->set($fieldname, intval(isset($inputdata["$fieldname"]))); continue; } - if ($field['required'] AND empty($inputdata["$fieldname"])) + if ($field['required'] AND empty($inputdata["$fieldname"]) AND !$searchMode) { $errorlist[] = sprintf(_('The "%1$s" field is a required field.'), $field['name']); continue; @@ -383,16 +387,23 @@ function process_custom_fields(&$bugapi, &$msg, $errorbox = false, $inputdata = } if (isset($inputdata["$fieldname"])) - { + { if ($field['type'] == 'input_text') { + if (empty($inputdata["$fieldname"]) AND $searchMode) + { + continue; + } $bugapi->set($fieldname, $inputdata["$fieldname"]); } else { if ($inputdata["$fieldname"] == -1) { - $bugapi->set($fieldname, ''); + if (!$searchMode) + { + $bugapi->set($fieldname, ''); + } continue; } diff --git a/search.php b/search.php index 8c5a070..d32ce57 100644 --- a/search.php +++ b/search.php @@ -37,6 +37,7 @@ $focus['search'] = 'focus'; require_once('./global.php'); require_once('./includes/functions_product.php'); require_once('./includes/class_sort.php'); +require_once('./includes/class_logging.php'); require_once('./includes/api_bug.php'); require_once('./includes/class_api_error.php'); @@ -47,9 +48,9 @@ if (!can_perform('cansearch')) $message->error_permission(); } -define('MODE_ANY', ($bugsys->in['mode'] == 1)); -define('MODE_ALL', ($bugsys->in['mode'] == 2)); -define('MODE_RAW', ($bugsys->in['mode'] == 3)); +define('MODE_ANY', 1); +define('MODE_ALL', 2); +define('MODE_RAW', 3); $var = $db->query_first("SHOW VARIABLES LIKE 'ft_min_word_len'"); define('SEARCH_WORD_MIN', $var['Value']); @@ -67,6 +68,108 @@ if (empty($_REQUEST['do'])) // ################################################################### +if ($_REQUEST['do'] == 'search') +{ + if ($bugsys->in['new']) + { + $newsearch = true; + } + else if ($bugsys->in['searchid']) + { + $cachedsearch = $db->query_first("SELECT * FROM " . TABLE_PREFIX . "search WHERE searchid = " . $bugsys->input_clean('searchid', TYPE_UINT) . " AND userid = " . $bugsys->userinfo['userid']); + } + else if ($bugsys->userinfo['userid']) + { + $cachedsearch = $db->query_first("SELECT * FROM " . TABLE_PREFIX . "search WHERE name IS NULL AND userid = " . $bugsys->userinfo['userid']); + } + else + { + $newsearch = true; + } + + if ($cachedsearch) + { + $show['cached'] = true; + if ($cachedsearch['dateline'] < TIMNOW - 900 OR $bugsys->in['rerun']) + { + $_REQUEST['do'] = 'process'; + $bugsys->in = array_merge(unserialize($cachedsearch['query']), $bugsys->in); + } + else + { + $search = $cachedsearch; + $_POST['do'] = 'results'; + } + } + else + { + $newsearch = true; + } + + if ($newsearch) + { + if (!is_array($bugsys->datastore['product'])) + { + $message->error(_('No products are setup, therefore there can be no bugs and thus search cannot function.')); + } + + if (!is_array($bugsys->datastore['version'])) + { + $message->error(_('No versions have been added underneath your product(s), there can be no bugs and thus search cannot function.')); + } + + $productSelect = ConstructProductSelect(); + + // ------------------------------------------------------------------- + // custom fields + $fields = construct_custom_fields(null, true, false, true); + $i = 0; + foreach ($fields AS $field) + { + if ($i % 2 == 0) + { + $customfields['left'] .= $field; + } + else + { + $customfields['right'] .= $field; + } + $i++; + } + + // ------------------------------------------------------------------- + // built-in fields + $select['severity'] = construct_datastore_select('severity', 'severity', 'severityid'); + $select['priority'] = construct_datastore_select('priority', 'priority', 'priorityid'); + $select['status'] = construct_datastore_select('status', 'status', 'statusid'); + $select['resolution'] = construct_datastore_select('resolution', 'resolution', 'resolutionid'); + + $searches = ''; + if ($bugsys->userinfo['userid']) + { + $searchesFetch = $db->query("SELECT * FROM " . TABLE_PREFIX . "search WHERE name IS NOT NULL AND userid = " . $bugsys->userinfo['userid']); + while ($search = $db->fetch_array($searchesFetch)) + { + $value = $search['searchid']; + $label = $search['name']; + eval('$searches .= "' . $template->fetch('selectoption') . '";'); + } + } + + $select['dev'] = ''; + foreach ($bugsys->datastore['assignto'] AS $dev) + { + $value = $dev['userid']; + $label = construct_user_display($dev, false); + eval('$select[dev] .= "' . $template->fetch('selectoption') . '";'); + } + + eval('$template->flush("' . $template->fetch('search') . '");'); + } +} + +// ################################################################### + if ($_REQUEST['do'] == 'process') { // ------------------------------------------------------------------- @@ -84,7 +187,7 @@ if ($_REQUEST['do'] == 'process') continue; } - if (MODE_ALL) + if ($bugsys->in['mode'] == MODE_ALL) { $querybuild['text'] .= " +$word"; } @@ -105,7 +208,7 @@ if ($_REQUEST['do'] == 'process') $temp = trim($querybuild['text']); - if (MODE_ALL OR MODE_RAW) + if ($bugsys->in['mode'] == MODE_ALL OR $bugsys->in['mode'] == MODE_RAW) { $bool_flag = ' IN BOOLEAN MODE'; } @@ -259,21 +362,26 @@ if ($_REQUEST['do'] == 'process') // ------------------------------------------------------------------- // do the search - $query = " + + $search = $db->query(" SELECT bug.*, comment.commentid FROM " . TABLE_PREFIX . "bug AS bug LEFT JOIN " . TABLE_PREFIX . "comment AS comment ON (bug.bugid = comment.bugid) WHERE bug.bugid <> 0 - AND bug.product IN (#<'ONBITS:VIEW'>#) - AND (!bug.hidden OR (bug.hidden AND bug.product IN (#<'ONBITS:HIDDEN'>#))" . (can_perform('canviewownhidden') ? " OR (bug.hidden AND bug.userid = " . $bugsys->userinfo['userid'] . " AND bug.product IN (#<'ONBITS:OWNHIDDEN'>#))" : "") . ") + AND bug.product IN (" . fetch_on_bits('canviewbugs') . ") + AND + ( + !bug.hidden + OR + (bug.hidden AND bug.product IN (" . fetch_on_bits('canviewhidden') . "))" . (can_perform('canviewownhidden') ? " + OR + (bug.hidden AND bug.userid = " . $bugsys->userinfo['userid'] . " AND bug.product IN (" . fetch_on_bits('canviewonhidden') . "))" : "") . " + ) " . implode("\n\t\t", $querybuild) . " GROUP BY bug.bugid - $sortclause"; - - $runquery = str_replace(array("#<'ONBITS:VIEW'>#", "#<'ONBITS:HIDDEN'>#", "#<'ONBITS:OWNHIDDEN'>#"), array(fetch_on_bits('canviewbugs'), fetch_on_bits('canviewhidden'), fetch_on_bits('canviewonhidden')), $query); - - $search = $db->query($runquery); + $sortclause + "); $numrows = $db->num_rows($search); @@ -288,124 +396,40 @@ if ($_REQUEST['do'] == 'process') $results[] = $result; } - if ($bugsys->userinfo['userid']) + if ($bugsys->userinfo['userid'] AND $cachedsearch['name'] == null AND !$bugsys->in['rerun']) { $db->query("DELETE FROM " . TABLE_PREFIX . "search WHERE userid = " . $bugsys->userinfo['userid'] . " AND name IS NULL"); } - $db->query(" - INSERT INTO " . TABLE_PREFIX . "search - (userid, dateline, query, ids, orderby, hilight, resultcount) - VALUES - (" . $bugsys->userinfo['userid'] . ", - " . TIMENOW . ", '" . $bugsys->escape($query) . "', - '" . implode(',', $ids) . "', '" . $bugsys->escape($sortclause) . "', - '" . $bugsys->escape($hilight) . "', - " . sizeof($results) . " - )" - ); - - $searchid = $db->insert_id(); - - $justprocess = true; - $search = array('ids' => implode(',', $ids), 'orderby' => $sortclause); - - $_POST['do'] = 'results'; -} - -// ################################################################### - -if ($_REQUEST['do'] == 'search') -{ - if ($bugsys->in['searchid'] AND !$bugsys->in['new']) + // store the search params + $params = $bugsys->in; + foreach ($_COOKIE AS $key => $value) { - if ($cachedsearch = $db->query_first("SELECT * FROM " . TABLE_PREFIX . "search WHERE searchid = " . $bugsys->input_clean('searchid', TYPE_UINT) . " AND userid = " . $bugsys->userinfo['userid'])) - { - $_POST['do'] = 'results'; - $searchid = $cachedsearch['searchid']; - } - else - { - $newsearch = true; - } + unset($params["$key"]); } - else if ($bugsys->userinfo['userid'] AND !$bugsys->in['new']) + + if ($cachedsearch) { - if ($cachedsearch = $db->query_first("SELECT * FROM " . TABLE_PREFIX . "search WHERE name IS NULL AND userid = " . $bugsys->userinfo['userid'])) - { - $_POST['do'] = 'results'; - $searchid = $cachedsearch['searchid']; - } - else - { - $newsearch = true; - } + $db->query("UPDATE " . TABLE_PREFIX . "search SET ids = '" . implode(',', $ids) . "', resultcount = " . sizeof($results) . " WHERE searchid = " . $cachedsearch['searchid']); + $search = $cachedsearch; } else { - $newsearch = true; + $db->query(" + INSERT INTO " . TABLE_PREFIX . "search + (userid, dateline, query, ids, orderby, hilight, resultcount) + VALUES + (" . $bugsys->userinfo['userid'] . ", + " . TIMENOW . ", '" . $bugsys->escape(serialize($params)) . "', + '" . implode(',', $ids) . "', '" . $bugsys->escape($sortclause) . "', + '" . $bugsys->escape($hilight) . "', + " . sizeof($results) . " + )" + ); + $search = array('searchid' => $db->insert_id(), 'ids' => implode(',', $ids), 'orderby' => $sortclause, 'hilight' => $hilight, 'resultcount' => sizeof($results)); } - if ($newsearch) - { - if (!is_array($bugsys->datastore['product'])) - { - $message->error(_('No products are setup, therefore there can be no bugs and thus search cannot function.')); - } - - if (!is_array($bugsys->datastore['version'])) - { - $message->error(_('No versions have been added underneath your product(s), there can be no bugs and thus search cannot function.')); - } - - $productSelect = ConstructProductSelect(); - - // ------------------------------------------------------------------- - // custom fields - $fields = construct_custom_fields(null, true, false, true); - $i = 0; - foreach ($fields AS $field) - { - if ($i % 2 == 0) - { - $customfields['left'] .= $field; - } - else - { - $customfields['right'] .= $field; - } - $i++; - } - - // ------------------------------------------------------------------- - // built-in fields - $select['severity'] = construct_datastore_select('severity', 'severity', 'severityid'); - $select['priority'] = construct_datastore_select('priority', 'priority', 'priorityid'); - $select['status'] = construct_datastore_select('status', 'status', 'statusid'); - $select['resolution'] = construct_datastore_select('resolution', 'resolution', 'resolutionid'); - - $searches = ''; - if ($bugsys->userinfo['userid']) - { - $searchesFetch = $db->query("SELECT * FROM " . TABLE_PREFIX . "search WHERE name IS NOT NULL AND userid = " . $bugsys->userinfo['userid']); - while ($search = $db->fetch_array($searchesFetch)) - { - $value = $search['searchid']; - $label = $search['name']; - eval('$searches .= "' . $template->fetch('selectoption') . '";'); - } - } - - $select['dev'] = ''; - foreach ($bugsys->datastore['assignto'] AS $dev) - { - $value = $dev['userid']; - $label = construct_user_display($dev, false); - eval('$select[dev] .= "' . $template->fetch('selectoption') . '";'); - } - - eval('$template->flush("' . $template->fetch('search') . '");'); - } + $_POST['do'] = 'results'; } // ################################################################### @@ -492,6 +516,9 @@ if ($_POST['do'] == 'doupdate') } $api = new BugApi($bugsys); + $api->set('bugid', $bug['bugid']); + $api->set_condition(); + $log = new Logging(); $log->set_bugid($bug['bugid']); $log->add_data(true, $bug, $log->getCommonFields()); @@ -514,7 +541,7 @@ if ($_POST['do'] == 'doupdate') } if ($bugsys->in['assignedto'] AND can_perform('canassign', $bug['product'])) { - $api->set('severity', $bugsys->in['severity']); + $api->set('assignedto', $bugsys->in['assignedto']); } if ($bugsys->in['product']) { @@ -524,15 +551,15 @@ if ($_POST['do'] == 'doupdate') $api->set('version', $product[2]); } - $log->add_data(false, $api->values, $log->getCommonFields()); - - process_custom_fields($api, $message); + process_custom_fields($api, $message, false, true); + $log->add_data(false, $api->values, $log->getCommonFields()); + $api->update(); $log->update_history(); } - $message->redirect(_('The specified bugs have been updated and you will now return to your search results.'), 'search.php?do=results&searchid=' . $bugsys->in['searchid']); + $message->redirect(_('The specified bugs have been updated and you will now return to your search results.'), 'search.php?searchid=' . $bugsys->in['searchid']); } // ################################################################### @@ -645,31 +672,15 @@ if ($_REQUEST['do'] == 'save') // ################################################################### if ($_POST['do'] == 'results') -{ - $show['cached'] = false; - if ($searchid AND !$justprocess) - { - $search = $cachedsearch; - if ($search['dateline'] < TIMENOW - 900 OR $bugsys->in['rerun']) - { - $research = $db->query(str_replace(array("#<'ONBITS:VIEW'>#", "#<'ONBITS:HIDDEN'>#", "#<'ONBITS:OWNHIDDEN'>#"), array(fetch_on_bits('canviewbugs'), fetch_on_bits('canviewhidden'), fetch_on_bits('canviewownhidden')), $search['query'])); - while ($bug = $db->fetch_array($research)) - { - $ids[] = $bug['bugid']; - $results[] = $bug; - } - $search['ids'] = implode(',', $ids); - $db->query("UPDATE " . TABLE_PREFIX . "search SET ids = '" . implode(',', $ids) . "', dateline = " . TIMENOW . ", resultcount = " . sizeof($results) . " WHERE searchid = " . $search['searchid']); - } - $show['cached'] = true; - $hilight = $search['hilight']; - } - +{ if (!$search['ids']) { $message->error(_('No bugs matched your search criteria. Please try again with different search requirements.')); } + $searchid = $search['searchid']; + $hilight = $search['hilight']; + LoadPaginationFramework(); $pagination->setTotal($search['resultcount']); $pagination->splitPages(); -- 2.22.5