2364
2362
return $issue_id;
2369
* Method used to get a specific parameter in the issue listing cookie.
2372
* @param string $name The name of the parameter
2373
* @return mixed The value of the specified parameter
2375
function getParam($name)
2377
$profile = Search_Profile::getProfile(Auth::getUserID(), Auth::getCurrentProject(), 'issue');
2379
if (isset($_GET[$name])) {
2380
return $_GET[$name];
2381
} elseif (isset($_POST[$name])) {
2382
return $_POST[$name];
2383
} elseif (isset($profile[$name])) {
2384
return $profile[$name];
2392
* Method used to save the current search parameters in a cookie.
2395
* @return array The search parameters
2397
function saveSearchParams()
2399
$sort_by = self::getParam('sort_by');
2400
$sort_order = self::getParam('sort_order');
2401
$rows = self::getParam('rows');
2402
$hide_closed = self::getParam('hide_closed');
2403
if ($hide_closed === '') {
2406
$search_type = self::getParam('search_type');
2407
if (empty($search_type)) {
2408
$search_type = 'all_text';
2410
$custom_field = self::getParam('custom_field');
2411
if (is_string($custom_field)) {
2412
$custom_field = unserialize(urldecode($custom_field));
2415
'rows' => Misc::escapeInteger($rows ? $rows : APP_DEFAULT_PAGER_SIZE),
2416
'pagerRow' => Misc::escapeInteger(self::getParam('pagerRow')),
2417
'hide_closed' => $hide_closed,
2418
"sort_by" => Misc::stripHTML($sort_by ? $sort_by : "pri_rank"),
2419
"sort_order" => Misc::stripHTML($sort_order ? $sort_order : "ASC"),
2420
"customer_id" => Misc::escapeInteger(self::getParam('customer_id')),
2421
// quick filter form
2422
'keywords' => self::getParam('keywords'),
2423
'search_type' => Misc::stripHTML($search_type),
2424
'users' => Misc::escapeInteger(self::getParam('users')),
2425
'status' => Misc::escapeInteger(self::getParam('status')),
2426
'priority' => Misc::escapeInteger(self::getParam('priority')),
2427
'category' => Misc::escapeInteger(self::getParam('category')),
2428
'customer_email' => Misc::stripHTML(self::getParam('customer_email')),
2429
// advanced search form
2430
'show_authorized_issues' => Misc::escapeInteger(self::getParam('show_authorized_issues')),
2431
'show_notification_list_issues' => Misc::escapeInteger(self::getParam('show_notification_list_issues')),
2432
'reporter' => Misc::escapeInteger(self::getParam('reporter')),
2434
'release' => Misc::escapeInteger(self::getParam('release')),
2436
'custom_field' => Misc::stripHTML($custom_field)
2438
// now do some magic to properly format the date fields
2439
$date_fields = array(
2442
'last_response_date',
2443
'first_response_date',
2446
foreach ($date_fields as $field_name) {
2447
$field = Misc::stripHTML(self::getParam($field_name));
2448
if (empty($field)) {
2451
if (@$field['filter_type'] == 'in_past') {
2452
@$cookie[$field_name] = array(
2453
'filter_type' => 'in_past',
2454
'time_period' => $field['time_period']
2457
$end_field_name = $field_name . '_end';
2458
$end_field = Misc::stripHTML(self::getParam($end_field_name));
2459
@$cookie[$field_name] = array(
2460
'past_hour' => $field['past_hour'],
2461
'Year' => $field['Year'],
2462
'Month' => $field['Month'],
2463
'Day' => $field['Day'],
2464
'start' => $field['Year'] . '-' . $field['Month'] . '-' . $field['Day'],
2465
'filter_type' => $field['filter_type'],
2466
'end' => $end_field['Year'] . '-' . $end_field['Month'] . '-' . $end_field['Day']
2468
@$cookie[$end_field_name] = array(
2469
'Year' => $end_field['Year'],
2470
'Month' => $end_field['Month'],
2471
'Day' => $end_field['Day']
2475
Search_Profile::save(Auth::getUserID(), Auth::getCurrentProject(), 'issue', $cookie);
2481
* Method used to get the current sorting options used in the grid layout
2482
* of the issue listing page.
2485
* @param array $options The current search parameters
2486
* @return array The sorting options
2488
function getSortingInfo($options)
2491
$custom_fields = Custom_Field::getFieldsToBeListed(Auth::getCurrentProject());
2493
// default order for last action date, priority should be descending
2494
// for textual fields, like summary, ascending is reasonable
2496
"pri_rank" => "desc",
2498
"iss_customer_id" => "desc",
2499
"prc_title" => "asc",
2500
"sta_rank" => "asc",
2501
"iss_created_date" => "desc",
2502
"iss_summary" => "asc",
2503
"last_action_date" => "desc",
2504
"usr_full_name" => "asc",
2505
"iss_expected_resolution_date" => "desc",
2506
"pre_title" => "asc",
2507
"assigned" => "asc",
2510
foreach ($custom_fields as $fld_id => $fld_name) {
2511
$fields['custom_field_' . $fld_id] = "desc";
2514
$sortfields = array_combine(array_keys($fields), array_keys($fields));
2515
$sortfields["pre_title"] = "pre_scheduled_date";
2516
$sortfields["assigned"] = "isu_usr_id";
2522
foreach ($sortfields as $field => $sortfield) {
2523
$sort_order = $fields[$field];
2524
if ($options["sort_by"] == $sortfield) {
2525
$items["images"][$field] = "images/" . strtolower($options["sort_order"]) . ".gif";
2526
if (strtolower($options["sort_order"]) == "asc") {
2527
$sort_order = "desc";
2529
$sort_order = "asc";
2532
$items["links"][$field] = $_SERVER["PHP_SELF"] . "?sort_by=" . $sortfield . "&sort_order=" . $sort_order;
2539
2366
* Returns the list of action date fields appropriate for the
2540
2367
* current user ID.
2543
2369
* @return array The list of action date fields
2545
function getLastActionFields()
2371
public static function getLastActionFields()
2547
2373
$last_action_fields = array(
2548
2374
"iss_last_public_action_date"
2562
* Method used to get the list of issues to be displayed in the grid layout.
2565
* @param integer $prj_id The current project ID
2566
* @param array $options The search parameters
2567
* @param integer $current_row The current page number
2568
* @param integer $max The maximum number of rows per page. 'ALL' for unlimited.
2569
* @return array The list of issues to be displayed
2571
function getListing($prj_id, $options, $current_row = 0, $max = 5)
2573
if (strtoupper($max) == "ALL") {
2576
$start = $current_row * $max;
2577
// get the current user's role
2578
$usr_id = Auth::getUserID();
2579
$role_id = User::getRoleByUser($usr_id, $prj_id);
2581
// get any custom fields that should be displayed
2582
$custom_fields = Custom_Field::getFieldsToBeListed($prj_id);
2590
iss_customer_contract_id,
2593
iss_last_response_date,
2595
iss_last_customer_action_date,
2601
sta_color status_color,
2606
iss_last_public_action_date,
2607
iss_last_public_action_type,
2608
iss_last_internal_action_date,
2609
iss_last_internal_action_type,
2610
" . self::getLastActionFields() . ",
2611
IF(iss_last_internal_action_date > iss_last_public_action_date, 'internal', 'public') AS action_type,
2614
iss_percent_complete,
2616
iss_expected_resolution_date
2619
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,
2620
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "user";
2621
// join custom fields if we are searching by custom fields
2622
if ((is_array($options['custom_field'])) && (count($options['custom_field']) > 0)) {
2623
foreach ($options['custom_field'] as $fld_id => $search_value) {
2624
if (empty($search_value)) {
2627
$field = Custom_Field::getDetails($fld_id);
2628
if (($field['fld_type'] == 'date') && ((empty($search_value['Year'])) || (empty($search_value['Month'])) || (empty($search_value['Day'])))) {
2631
if (($field['fld_type'] == 'integer') && empty($search_value['value'])) {
2634
if ($field['fld_type'] == 'multiple') {
2635
$search_value = Misc::escapeInteger($search_value);
2636
foreach ($search_value as $cfo_id) {
2637
$stmt .= ",\n" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_custom_field as cf" . $fld_id . '_' . $cfo_id . "\n";
2640
$stmt .= ",\n" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_custom_field as cf" . $fld_id . "\n";
2645
// check for the custom fields we want to sort by
2646
if (strstr($options['sort_by'], 'custom_field') !== false) {
2647
$fld_id = str_replace("custom_field_", '', $options['sort_by']);
2648
$stmt .= "\n LEFT JOIN \n" .
2649
APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_custom_field as cf_sort
2651
(cf_sort.icf_iss_id = iss_id AND cf_sort.icf_fld_id = $fld_id) \n";
2653
if (!empty($options["users"]) || $options["sort_by"] === "isu_usr_id") {
2656
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
2660
if ((!empty($options["show_authorized_issues"])) || (($role_id == User::getRoleID("Reporter")) && (Project::getSegregateReporters($prj_id)))) {
2663
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user_replier
2667
if (!empty($options["show_notification_list_issues"])) {
2670
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "subscription
2676
" . APP_DEFAULT_DB . ".`" . APP_TABLE_PREFIX . "group`
2680
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_category
2684
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_release
2688
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "status
2692
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_priority
2696
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_quarantine
2698
iss_id=iqu_iss_id AND
2699
(iqu_expiration > '" . Date_Helper::getCurrentDateGMT() . "' OR iqu_expiration IS NULL)
2701
iss_prj_id= " . Misc::escapeInteger($prj_id);
2702
$stmt .= self::buildWhereClause($options);
2704
if (strstr($options["sort_by"], 'custom_field') !== false) {
2705
$fld_details = Custom_Field::getDetails($fld_id);
2706
$sort_by = 'cf_sort.' . Custom_Field::getDBValueFieldNameByType($fld_details['fld_type']);
2708
$sort_by = Misc::escapeString($options["sort_by"]);
2715
" . $sort_by . " " . Misc::escapeString($options["sort_order"]) . ",
2717
$total_rows = Pager::getTotalRows($stmt);
2720
" . Misc::escapeInteger($start) . ", " . Misc::escapeInteger($max);
2721
$res = DB_Helper::getInstance()->getAll($stmt, DB_FETCHMODE_ASSOC);
2722
if (PEAR::isError($res)) {
2723
Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
2729
if (count($res) > 0) {
2730
self::getAssignedUsersByIssues($res);
2731
Time_Tracking::getTimeSpentByIssues($res);
2732
// need to get the customer titles for all of these issues...
2733
if (Customer::hasCustomerIntegration($prj_id)) {
2734
Customer::getCustomerTitlesByIssues($prj_id, $res);
2735
Customer::getSupportLevelsByIssues($prj_id, $res);
2737
self::formatLastActionDates($res);
2738
self::getLastStatusChangeDates($prj_id, $res);
2739
} elseif ($current_row > 0) {
2740
// if there are no results, and the page is not the first page reset page to one and reload results
2741
Auth::redirect("list.php?pagerRow=0&rows=$max");
2743
$groups = Group::getAssocList($prj_id);
2744
$categories = Category::getAssocList($prj_id);
2745
$column_headings = self::getColumnHeadings($prj_id);
2746
if (count($custom_fields) > 0) {
2747
$column_headings = array_merge($column_headings,$custom_fields);
2749
$csv[] = @implode("\t", $column_headings);
2750
for ($i = 0; $i < count($res); $i++) {
2751
$res[$i]["time_spent"] = Misc::getFormattedTime($res[$i]["time_spent"]);
2752
$res[$i]["iss_created_date"] = Date_Helper::getFormattedDate($res[$i]["iss_created_date"]);
2753
$res[$i]["iss_expected_resolution_date"] = Date_Helper::getSimpleDate($res[$i]["iss_expected_resolution_date"], false);
2755
$res[$i]['pri_title'],
2757
$res[$i]['usr_full_name'],
2759
// hide the group column from the output if no
2760
// groups are available in the database
2761
if (count($groups) > 0) {
2762
$fields[] = $res[$i]['group'];
2764
$fields[] = $res[$i]['assigned_users'];
2765
$fields[] = $res[$i]['time_spent'];
2766
// hide the category column from the output if no
2767
// categories are available in the database
2768
if (count($categories) > 0) {
2769
$fields[] = $res[$i]['prc_title'];
2771
if (Customer::hasCustomerIntegration($prj_id)) {
2772
$fields[] = @$res[$i]['customer_title'];
2773
// check if current user is acustomer and has a per incident contract.
2774
// if so, check if issue is redeemed.
2775
if (User::getRoleByUser($usr_id, $prj_id) == User::getRoleID('Customer')) {
2776
if ((Customer::hasPerIncidentContract($prj_id, self::getCustomerID($res[$i]['iss_id'])) &&
2777
(Customer::isRedeemedIncident($prj_id, $res[$i]['iss_id'])))) {
2778
$res[$i]['redeemed'] = true;
2782
$fields[] = $res[$i]['sta_title'];
2783
$fields[] = $res[$i]["status_change_date"];
2784
$fields[] = $res[$i]["last_action_date"];
2785
$fields[] = $res[$i]['iss_dev_time'];
2786
$fields[] = $res[$i]['iss_summary'];
2787
$fields[] = $res[$i]['iss_expected_resolution_date'];
2789
if (count($custom_fields) > 0) {
2790
$res[$i]['custom_field'] = array();
2791
$custom_field_values = Custom_Field::getListByIssue($prj_id, $res[$i]['iss_id']);
2792
foreach ($custom_field_values as $this_field) {
2793
if (!empty($custom_fields[$this_field['fld_id']])) {
2794
$res[$i]['custom_field'][$this_field['fld_id']] = $this_field['value'];
2795
$fields[] = $this_field['value'];
2800
$csv[] = @implode("\t", $fields);
2802
$total_pages = ceil($total_rows / $max);
2803
$last_page = $total_pages - 1;
2807
"current_page" => $current_row,
2808
"start_offset" => $start,
2809
"end_offset" => $start + count($res),
2810
"total_rows" => $total_rows,
2811
"total_pages" => $total_pages,
2812
"previous_page" => ($current_row == 0) ? "-1" : ($current_row - 1),
2813
"next_page" => ($current_row == $last_page) ? "-1" : ($current_row + 1),
2814
"last_page" => $last_page,
2815
"custom_fields" => $custom_fields
2817
"csv" => @implode("\n", $csv)
2824
2388
* Processes a result set to format the "Last Action Date" column.
2827
2390
* @param array $result The result set
2829
function formatLastActionDates(&$result)
2392
public static function formatLastActionDates(&$result)
2831
2394
for ($i = 0; $i < count($result); $i++) {
2832
2395
if (($result[$i]['action_type'] == "internal") &&
2890
* Method used to get the list of issues to be displayed in the grid layout.
2893
* @param array $options The search parameters
2894
* @return string The where clause
2896
function buildWhereClause($options)
2898
$usr_id = Auth::getUserID();
2899
$prj_id = Auth::getCurrentProject();
2900
$role_id = User::getRoleByUser($usr_id, $prj_id);
2902
$stmt = ' AND iss_usr_id = usr_id';
2903
if ($role_id == User::getRoleID('Customer')) {
2904
$stmt .= " AND iss_customer_id=" . User::getCustomerID($usr_id);
2905
} elseif (($role_id == User::getRoleID("Reporter")) && (Project::getSegregateReporters($prj_id))) {
2907
iss_usr_id = $usr_id OR
2908
iur_usr_id = $usr_id
2912
if (!empty($options["users"])) {
2913
$stmt .= " AND (\n";
2914
if (stristr($options["users"], "grp") !== false) {
2915
$chunks = explode(":", $options["users"]);
2916
$stmt .= 'iss_grp_id = ' . Misc::escapeInteger($chunks[1]);
2918
if ($options['users'] == '-1') {
2919
$stmt .= 'isu_usr_id IS NULL';
2920
} elseif ($options['users'] == '-2') {
2921
$stmt .= 'isu_usr_id IS NULL OR isu_usr_id=' . $usr_id;
2922
} elseif ($options['users'] == '-3') {
2923
$stmt .= 'isu_usr_id = ' . $usr_id . ' OR iss_grp_id = ' . User::getGroupID($usr_id);
2924
} elseif ($options['users'] == '-4') {
2925
$stmt .= 'isu_usr_id IS NULL OR isu_usr_id = ' . $usr_id . ' OR iss_grp_id = ' . User::getGroupID($usr_id);
2927
$stmt .= 'isu_usr_id =' . Misc::escapeInteger($options["users"]);
2932
if (!empty($options["reporter"])) {
2933
$stmt .= " AND iss_usr_id = " . Misc::escapeInteger($options["reporter"]);
2935
if (!empty($options["show_authorized_issues"])) {
2936
$stmt .= " AND (iur_usr_id=$usr_id)";
2938
if (!empty($options["show_notification_list_issues"])) {
2939
$stmt .= " AND (sub_usr_id=$usr_id)";
2941
if (!empty($options["keywords"])) {
2942
$stmt .= " AND (\n";
2943
if (($options['search_type'] == 'all_text') && (APP_ENABLE_FULLTEXT)) {
2944
$stmt .= "iss_id IN(" . join(', ', self::getFullTextIssues($options)) . ")";
2945
} elseif (($options['search_type'] == 'customer') && (Customer::hasCustomerIntegration($prj_id))) {
2946
// check if the user is trying to search by customer email
2947
$customer_ids = Customer::getCustomerIDsLikeEmail($prj_id, $options['keywords']);
2948
if (count($customer_ids) > 0) {
2949
$stmt .= " iss_customer_id IN (" . implode(', ', $customer_ids) . ")";
2951
// no results, kill query
2952
$stmt .= " iss_customer_id = -1";
2955
$stmt .= "(" . Misc::prepareBooleanSearch('iss_summary', $options["keywords"]);
2956
$stmt .= " OR " . Misc::prepareBooleanSearch('iss_description', $options["keywords"]) . ")";
2960
if (!empty($options['customer_id'])) {
2961
$stmt .= " AND iss_customer_id=" . Misc::escapeInteger($options["customer_id"]);
2963
if (!empty($options["priority"])) {
2964
$stmt .= " AND iss_pri_id=" . Misc::escapeInteger($options["priority"]);
2966
if (!empty($options["status"])) {
2967
$stmt .= " AND iss_sta_id=" . Misc::escapeInteger($options["status"]);
2969
if (!empty($options["category"])) {
2970
if (!is_array($options['category'])) {
2971
$options['category'] = array($options['category']);
2973
$stmt .= " AND iss_prc_id IN(" . join(', ', Misc::escapeInteger($options["category"])) . ")";
2975
if (!empty($options["hide_closed"])) {
2976
$stmt .= " AND sta_is_closed=0";
2978
if (!empty($options['release'])) {
2979
$stmt .= " AND iss_pre_id = " . Misc::escapeInteger($options['release']);
2981
// now for the date fields
2982
$date_fields = array(
2985
'last_response_date',
2986
'first_response_date',
2989
foreach ($date_fields as $field_name) {
2990
if (!empty($options[$field_name])) {
2991
switch ($options[$field_name]['filter_type']) {
2993
$stmt .= " AND iss_$field_name >= '" . Misc::escapeString($options[$field_name]['start']) . "'";
2996
$stmt .= " AND iss_$field_name <= '" . Misc::escapeString($options[$field_name]['start']) . "'";
2999
$stmt .= " AND iss_$field_name BETWEEN '" . Misc::escapeString($options[$field_name]['start']) . "' AND '" . Misc::escapeString($options[$field_name]['end']) . "'";
3002
$stmt .= " AND iss_$field_name IS NULL";
3005
if (strlen($options[$field_name]['time_period']) == 0) {
3006
$options[$field_name]['time_period'] = 0;
3008
$stmt .= " AND (UNIX_TIMESTAMP('" . Date_Helper::getCurrentDateGMT() . "') - UNIX_TIMESTAMP(iss_$field_name)) <= (" .
3009
Misc::escapeInteger($options[$field_name]['time_period']) . "*3600)";
3015
if ((is_array($options['custom_field'])) && (count($options['custom_field']) > 0)) {
3016
foreach ($options['custom_field'] as $fld_id => $search_value) {
3017
if (empty($search_value)) {
3020
$field = Custom_Field::getDetails($fld_id);
3021
$fld_db_name = Custom_Field::getDBValueFieldNameByType($field['fld_type']);
3022
if (($field['fld_type'] == 'date') &&
3023
((empty($search_value['Year'])) || (empty($search_value['Month'])) || (empty($search_value['Day'])))) {
3026
if (($field['fld_type'] == 'integer') && empty($search_value['value'])) {
3030
if ($field['fld_type'] == 'multiple') {
3031
$search_value = Misc::escapeInteger($search_value);
3032
foreach ($search_value as $cfo_id) {
3033
$stmt .= " AND\n cf" . $fld_id . '_' . $cfo_id . ".icf_iss_id = iss_id";
3034
$stmt .= " AND\n cf" . $fld_id . '_' . $cfo_id . ".icf_fld_id = $fld_id";
3035
$stmt .= " AND\n cf" . $fld_id . '_' . $cfo_id . "." . $fld_db_name . " = $cfo_id";
3037
} elseif ($field['fld_type'] == 'date') {
3038
if ((empty($search_value['Year'])) || (empty($search_value['Month'])) || (empty($search_value['Day']))) {
3041
$search_value = $search_value['Year'] . "-" . $search_value['Month'] . "-" . $search_value['Day'];
3042
$stmt .= " AND\n (iss_id = cf" . $fld_id . ".icf_iss_id AND
3043
cf" . $fld_id . "." . $fld_db_name . " = '" . Misc::escapeString($search_value) . "')";
3044
} else if ($field['fld_type'] == 'integer') {
3045
$value = $search_value['value'];
3046
switch ($search_value['filter_type']) {
3063
$stmt .= " AND\n (iss_id = cf" . $fld_id . ".icf_iss_id";
3064
$stmt .= " AND\n cf" . $fld_id . ".icf_fld_id = $fld_id";
3065
$stmt .= " AND cf" . $fld_id . "." . $fld_db_name . $cmp . Misc::escapeString($value) . ')';
3067
$stmt .= " AND\n (iss_id = cf" . $fld_id . ".icf_iss_id";
3068
$stmt .= " AND\n cf" . $fld_id . ".icf_fld_id = $fld_id";
3069
if ($field['fld_type'] == 'combo') {
3070
$stmt .= " AND cf" . $fld_id . "." . $fld_db_name . " IN(" . join(', ', Misc::escapeInteger($search_value)) . ")";
3072
$stmt .= " AND cf" . $fld_id . "." . $fld_db_name . " LIKE '%" . Misc::escapeString($search_value) . "%'";
3078
// clear cached full-text values if we are not searching fulltext anymore
3079
if ((APP_ENABLE_FULLTEXT) && (@$options['search_type'] != 'all_text')) {
3080
Session::set('fulltext_string', '');
3081
Session::set('fulltext_issues', '');
3088
2452
* Method used to get the previous and next issues that are available
3089
2453
* according to the current search parameters.
4118
* Returns an array of issues based on full text search results.
4120
* @param array $options An array of search options
4121
* @return array An array of issue IDS
4123
function getFullTextIssues($options)
4125
// check if a list of issues for this full text search is already cached
4126
$fulltext_string = Session::get('fulltext_string');
4127
if ((!empty($fulltext_string)) && ($fulltext_string == $options['keywords'])) {
4128
return Session::get('fulltext_issues');
4131
// no pre-existing list, generate them
4135
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue
4137
MATCH(iss_summary, iss_description) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)
4140
DISTINCT(not_iss_id)
4142
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "note
4144
MATCH(not_note) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)
4147
DISTINCT(ttr_iss_id)
4149
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking
4151
MATCH(ttr_summary) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)
4154
DISTINCT(phs_iss_id)
4156
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "phone_support
4158
MATCH(phs_description) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)
4161
DISTINCT(sup_iss_id)
4163
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email,
4164
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email_body
4166
sup_id = seb_sup_id AND
4167
MATCH(seb_body) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)
4169
$res = DB_Helper::getInstance()->getCol($stmt);
4170
if (PEAR::isError($res)) {
4171
Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
4175
DISTINCT(icf_iss_id)
4177
" . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_custom_field
4179
MATCH (icf_value) AGAINST ('" . Misc::escapeString($options['keywords']) . "' IN BOOLEAN MODE)";
4180
$custom_res = DB_Helper::getInstance()->getCol($stmt);
4181
if (PEAR::isError($custom_res)) {
4182
Error_Handler::logError(array($custom_res->getMessage(), $custom_res->getDebugInfo()), __FILE__, __LINE__);
4185
$issues = array_merge($res, $custom_res);
4186
// we kill the query results on purpose to flag that no
4187
// issues could be found with fulltext search
4188
if (count($issues) < 1) {
4189
$issues = array(-1);
4191
Session::set('fulltext_string', $options['keywords']);
4192
Session::set('fulltext_issues', $issues);
4199
3481
* Method to determine if user can access a particular issue