diff --git a/admin/install.php b/admin/install.php index be2ef6a..a74c593 100644 --- a/admin/install.php +++ b/admin/install.php @@ -28,6 +28,7 @@ $g_skip_open_db = true; # don't open the database in database_api.php define( 'PLUGINS_DISABLED', true ); @require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'core.php' ); + @require_once( 'install_functions.php' ); $g_error_send_page_header = false; # bypass page headers in error handler define( 'BAD', 0 ); diff --git a/admin/install_functions.php b/admin/install_functions.php new file mode 100644 index 0000000..0612550 --- /dev/null +++ b/admin/install_functions.php @@ -0,0 +1,59 @@ + and referenced as just . + */ + + /** + * Migrate the legacy category data to the new category_id-based schema. + */ + function install_category_migrate() { + $t_bug_table = config_get( 'mantis_bug_table' ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_project_category_table = config_get( 'mantis_project_category_table' ); + + $query = "SELECT project_id, category FROM $t_project_category_table ORDER BY project_id, category"; + $cresult = db_query( $query ); + + $query = "SELECT id, project_id, category FROM $t_bug_table ORDER BY project_id, category"; + $bresult = db_query( $query ); + + $t_data = Array(); + while ( $row = db_fetch_array( $cresult ) ) { + $t_pid = $row['project_id']; + $t_name = $row['category']; + $t_data[$t_pid][$t_name] = Array(); + } + while ( $row = db_fetch_array( $bresult ) ) { + $t_bid = $row['id']; + $t_pid = $row['project_id']; + $t_name = $row['category']; + + $t_data[$t_pid][$t_name][] = $t_bid; + } + + foreach ( $t_data as $t_pid => $t_categories ) { + foreach ( $t_categories as $t_name => $t_bugs ) { + $query = "INSERT INTO $t_category_table ( name, project_id ) VALUES ( '$t_name', '$t_pid' )"; + db_query( $query ); + $t_category_id = db_insert_id( $t_category_table ); + + $query = "UPDATE $t_bug_table SET category_id='$t_category_id' + WHERE project_id='$t_pid' AND category='$t_name'"; + db_query( $query ); + } + } + + return 2; + } + diff --git a/admin/schema.php b/admin/schema.php index 440504e..63bb06e 100644 --- a/admin/schema.php +++ b/admin/schema.php @@ -370,4 +370,21 @@ $upgrade[] = Array('CreateTableSQL', Array( config_get( 'mantis_plugin_table' ), ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) ); $upgrade[] = Array('AlterColumnSQL', Array( config_get_global( 'mantis_user_pref_table' ), "redirect_delay I NOTNULL DEFAULT 0" ) ); + +$upgrade[] = Array( 'CreateTableSQL', Array( config_get( 'mantis_category_table' ), " + id I UNSIGNED NOTNULL PRIMARY AUTOINCREMENT, + project_id I UNSIGNED NOTNULL DEFAULT '0', + user_id I UNSIGNED NOTNULL DEFAULT '0', + name C(100) NOTNULL PRIMARY DEFAULT \" '' \", + status I UNSIGNED NOTNULL DEFAULT '0' + ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) ); +$upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_category', config_get( 'mantis_category_table' ), 'project_id, status' ) ); +$upgrade[] = Array( 'InsertData', Array( config_get( 'mantis_category_table' ), " + ( project_id, user_id, name, status ) VALUES + ( '0', '0', 'Unknown', '0' ) " ) ); +$upgrade[] = Array( 'AddColumnSQL', Array( config_get( 'mantis_bug_table' ), "category_id I UNSIGNED NOTNULL DEFAULT '0'" ) ); +$upgrade[] = Array( 'UpdateFunction', "category_migrate" ); +$upgrade[] = Array( 'DropColumnSQL', Array( config_get( 'mantis_bug_table' ), "category" ) ); +$upgrade[] = Array( 'DropTableSQL', Array( config_get( 'mantis_project_category_table' ) ) ); + ?> diff --git a/bug_report.php b/bug_report.php index 58588dc..a41fb29 100644 --- a/bug_report.php +++ b/bug_report.php @@ -44,7 +44,7 @@ $t_bug_data->handler_id = gpc_get_int( 'handler_id', 0 ); $t_bug_data->view_state = gpc_get_int( 'view_state', config_get( 'default_bug_view_status' ) ); - $t_bug_data->category = gpc_get_string( 'category', config_get( 'default_bug_category' ) ); + $t_bug_data->category_id = gpc_get_string( 'category_id', config_get( 'default_bug_category' ) ); $t_bug_data->reproducibility = gpc_get_int( 'reproducibility', config_get( 'default_bug_reproducibility' ) ); $t_bug_data->severity = gpc_get_int( 'severity', config_get( 'default_bug_severity' ) ); $t_bug_data->priority = gpc_get_int( 'priority', config_get( 'default_bug_priority' ) ); @@ -171,7 +171,7 @@ ?>

- + diff --git a/bug_report_advanced_page.php b/bug_report_advanced_page.php index ed694e3..85117a7 100644 --- a/bug_report_advanced_page.php +++ b/bug_report_advanced_page.php @@ -82,7 +82,7 @@ $f_profile_id = 0; $f_handler_id = $t_bug->handler_id; - $f_category = $t_bug->category; + $f_category_id = $t_bug->category_id; $f_reproducibility = $t_bug->reproducibility; $f_severity = $t_bug->severity; $f_priority = $t_bug->priority; @@ -105,7 +105,7 @@ $f_profile_id = gpc_get_int( 'profile_id', 0 ); $f_handler_id = gpc_get_int( 'handler_id', 0 ); - $f_category = gpc_get_string( 'category', config_get( 'default_bug_category' ) ); + $f_category_id = gpc_get_string( 'category_id', config_get( 'default_bug_category' ) ); $f_reproducibility = gpc_get_int( 'reproducibility', config_get( 'default_bug_reproducibility' ) ); $f_severity = gpc_get_int( 'severity', config_get( 'default_bug_severity' ) ); $f_priority = gpc_get_int( 'priority', config_get( 'default_bug_priority' ) ); @@ -161,13 +161,13 @@ project_id, 'name' ) . "] "; } ?> - name="category_id"> ', string_attribute( lang_get( 'select_option' ) ), ''; } - print_category_option_list( $f_category ); + print_category_option_list( $f_category_id ); ?> @@ -555,7 +555,7 @@ diff --git a/bug_report_page.php b/bug_report_page.php index 4446331..65bb875 100644 --- a/bug_report_page.php +++ b/bug_report_page.php @@ -73,7 +73,7 @@ access_ensure_project_level( config_get( 'report_bug_threshold' ) ); $f_product_version = $t_bug->version; - $f_category = $t_bug->category; + $f_category_id = $t_bug->category_id; $f_reproducibility = $t_bug->reproducibility; $f_severity = $t_bug->severity; $f_priority = $t_bug->priority; @@ -87,7 +87,7 @@ access_ensure_project_level( config_get( 'report_bug_threshold' ) ); $f_product_version = gpc_get_string( 'product_version', '' ); - $f_category = gpc_get_string( 'category', config_get( 'default_bug_category' ) ); + $f_category_id = gpc_get_string( 'category_id', config_get( 'default_bug_category' ) ); $f_reproducibility = gpc_get_int( 'reproducibility', config_get( 'default_bug_reproducibility' ) ); $f_severity = gpc_get_int( 'severity', config_get( 'default_bug_severity' ) ); $f_priority = gpc_get_int( 'priority', config_get( 'default_bug_priority' ) ); @@ -143,13 +143,13 @@ project_id, 'name' ) . "] "; } ?> - name="category_id"> ', string_attribute( lang_get( 'select_option' ) ), ''; } - print_category_option_list( $f_category ); + print_category_option_list( $f_category_id ); ?> @@ -385,7 +385,7 @@ diff --git a/bug_update.php b/bug_update.php index dd0a2e6..5b16e80 100644 --- a/bug_update.php +++ b/bug_update.php @@ -67,7 +67,7 @@ $t_bug_data->status = gpc_get_int( 'status', $t_bug_data->status ); $t_bug_data->resolution = gpc_get_int( 'resolution', $t_bug_data->resolution ); $t_bug_data->projection = gpc_get_int( 'projection', $t_bug_data->projection ); - $t_bug_data->category = gpc_get_string( 'category', $t_bug_data->category ); + $t_bug_data->category_id = gpc_get_int( 'category_id', $t_bug_data->category_id ); $t_bug_data->eta = gpc_get_int( 'eta', $t_bug_data->eta ); $t_bug_data->os = gpc_get_string( 'os', $t_bug_data->os ); $t_bug_data->os_build = gpc_get_string( 'os_build', $t_bug_data->os_build ); diff --git a/bug_update_advanced_page.php b/bug_update_advanced_page.php index cf429d3..03ed16d 100644 --- a/bug_update_advanced_page.php +++ b/bug_update_advanced_page.php @@ -118,8 +118,8 @@ project_id, 'name' ) . "] "; } ?> - name="category_id"> + category_id, $t_bug->project_id ) ?> diff --git a/bug_update_page.php b/bug_update_page.php index 1af51da..151b1bc 100644 --- a/bug_update_page.php +++ b/bug_update_page.php @@ -121,8 +121,8 @@ project_id, 'name' ) . "] "; } ?> - name="category_id"> + category_id, $t_bug->project_id ) ?> diff --git a/bug_view_advanced_page.php b/bug_view_advanced_page.php index d16f69e..b0581e7 100644 --- a/bug_view_advanced_page.php +++ b/bug_view_advanced_page.php @@ -168,8 +168,7 @@ project_id, 'name' ) ); - echo "[$t_project_name] $t_bug->category"; + echo string_display( category_full_name( $t_bug->category_id ) ); ?> diff --git a/bug_view_page.php b/bug_view_page.php index 5ff445a..ad82077 100644 --- a/bug_view_page.php +++ b/bug_view_page.php @@ -171,8 +171,7 @@ project_id, 'name' ) ); - echo "[$t_project_name] $t_bug->category"; + echo string_display( category_full_name( $t_bug->category_id ) ); ?> diff --git a/config_defaults_inc.php b/config_defaults_inc.php index 185a83e..8d79641 100644 --- a/config_defaults_inc.php +++ b/config_defaults_inc.php @@ -1345,9 +1345,10 @@ $g_mantis_bug_text_table = '%db_table_prefix%_bug_text%db_table_suffix%'; $g_mantis_bugnote_table = '%db_table_prefix%_bugnote%db_table_suffix%'; $g_mantis_bugnote_text_table = '%db_table_prefix%_bugnote_text%db_table_suffix%'; + $g_mantis_category_table = '%db_table_prefix%_category%db_table_suffix%'; $g_mantis_news_table = '%db_table_prefix%_news%db_table_suffix%'; $g_mantis_plugin_table = '%db_table_prefix%_plugin%db_table_suffix%'; - $g_mantis_project_category_table = '%db_table_prefix%_project_category%db_table_suffix%'; + $g_mantis_project_category_table = '%db_table_prefix%_project_category%db_table_suffix%'; # Legacy table $g_mantis_project_file_table = '%db_table_prefix%_project_file%db_table_suffix%'; $g_mantis_project_table = '%db_table_prefix%_project%db_table_suffix%'; $g_mantis_project_user_list_table = '%db_table_prefix%_project_user_list%db_table_suffix%'; diff --git a/core/bug_api.php b/core/bug_api.php index f6fce02..6fd0542 100644 --- a/core/bug_api.php +++ b/core/bug_api.php @@ -52,7 +52,7 @@ var $status = NEW_; var $resolution = OPEN; var $projection = 10; - var $category = ''; + var $category_id = 0; var $date_submitted = ''; var $last_updated = ''; var $eta = 10; @@ -353,7 +353,7 @@ $c_priority = db_prepare_int( $p_bug_data->priority ); $c_severity = db_prepare_int( $p_bug_data->severity ); $c_reproducibility = db_prepare_int( $p_bug_data->reproducibility ); - $c_category = db_prepare_string( $p_bug_data->category ); + $c_category_id = db_prepare_int( $p_bug_data->category_id ); $c_os = db_prepare_string( $p_bug_data->os ); $c_os_build = db_prepare_string( $p_bug_data->os_build ); $c_platform = db_prepare_string( $p_bug_data->platform ); @@ -378,11 +378,6 @@ trigger_error( ERROR_EMPTY_FIELD, ERROR ); } - if ( is_blank( $c_category ) ) { - error_parameters( lang_get( 'category' ) ); - trigger_error( ERROR_EMPTY_FIELD, ERROR ); - } - # Only set target_version if user has access to do so if ( access_has_project_level( config_get( 'roadmap_update_threshold' ) ) ) { $c_target_version = db_prepare_string( $p_bug_data->target_version ); @@ -392,7 +387,7 @@ $t_bug_table = config_get_global( 'mantis_bug_table' ); $t_bug_text_table = config_get_global( 'mantis_bug_text_table' ); - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); + $t_category_table = config_get_global( 'mantis_category_table' ); # Insert text information $query = "INSERT INTO $t_bug_text_table @@ -415,9 +410,9 @@ # if a default user is associated with the category and we know at this point # that that the bug was not assigned to somebody, then assign it automatically. $query = "SELECT user_id - FROM $t_project_category_table - WHERE project_id=" .db_param(0) . " AND category=" . db_param(1); - $result = db_query_bound( $query, Array( $c_project_id, $c_category ) ); + FROM $t_category_table + WHERE project_id='$c_project_id' AND id='$c_category_id'"; + $result = db_query( $query ); if ( db_num_rows( $result ) > 0 ) { $c_handler_id = $p_handler_id = db_result( $result ); @@ -438,7 +433,7 @@ duplicate_id, priority, severity, reproducibility, status, resolution, - projection, category, + projection, category_id, date_submitted, last_updated, eta, bug_text_id, os, os_build, @@ -453,7 +448,7 @@ '0', '$c_priority', '$c_severity', '$c_reproducibility', '$t_status', '$t_resolution', - 10, '$c_category', + 10, '$c_category_id', " . db_now() . "," . db_now() . ", 10, '$t_text_id', '$c_os', '$c_os_build', @@ -817,7 +812,7 @@ status='$c_bug_data->status', resolution='$c_bug_data->resolution', projection='$c_bug_data->projection', - category='$c_bug_data->category', + category_id='$c_bug_data->category_id', eta='$c_bug_data->eta', os='$c_bug_data->os', os_build='$c_bug_data->os_build', @@ -854,7 +849,7 @@ history_log_event_direct( $p_bug_id, 'status', $t_old_data->status, $p_bug_data->status ); history_log_event_direct( $p_bug_id, 'resolution', $t_old_data->resolution, $p_bug_data->resolution ); history_log_event_direct( $p_bug_id, 'projection', $t_old_data->projection, $p_bug_data->projection ); - history_log_event_direct( $p_bug_id, 'category', $t_old_data->category, $p_bug_data->category ); + history_log_event_direct( $p_bug_id, 'category_id', $t_old_data->category_id, $p_bug_data->category_id ); history_log_event_direct( $p_bug_id, 'eta', $t_old_data->eta, $p_bug_data->eta ); history_log_event_direct( $p_bug_id, 'os', $t_old_data->os, $p_bug_data->os ); history_log_event_direct( $p_bug_id, 'os_build', $t_old_data->os_build, $p_bug_data->os_build ); @@ -1429,7 +1424,7 @@ $t_bug_data->status = db_prepare_int( $p_bug_data->status ); $t_bug_data->resolution = db_prepare_int( $p_bug_data->resolution ); $t_bug_data->projection = db_prepare_int( $p_bug_data->projection ); - $t_bug_data->category = db_prepare_string( $p_bug_data->category ); + $t_bug_data->category_id = db_prepare_string( $p_bug_data->category_id ); $t_bug_data->date_submitted = db_prepare_string( $p_bug_data->date_submitted ); $t_bug_data->last_updated = db_prepare_string( $p_bug_data->last_updated ); $t_bug_data->eta = db_prepare_int( $p_bug_data->eta ); @@ -1456,7 +1451,7 @@ # Return a copy of the bug structure with all the instvars prepared for editing # in an HTML form function bug_prepare_edit( $p_bug_data ) { - $p_bug_data->category = string_attribute( $p_bug_data->category ); + $p_bug_data->category_id = string_attribute( $p_bug_data->category_id ); $p_bug_data->date_submitted = string_attribute( $p_bug_data->date_submitted ); $p_bug_data->last_updated = string_attribute( $p_bug_data->last_updated ); $p_bug_data->os = string_attribute( $p_bug_data->os ); @@ -1480,7 +1475,7 @@ # Return a copy of the bug structure with all the instvars prepared for editing # in an HTML form function bug_prepare_display( $p_bug_data ) { - $p_bug_data->category = string_display_line( $p_bug_data->category ); + $p_bug_data->category_id = string_display_line( $p_bug_data->category_id ); $p_bug_data->date_submitted = string_display_line( $p_bug_data->date_submitted ); $p_bug_data->last_updated = string_display_line( $p_bug_data->last_updated ); $p_bug_data->os = string_display_line( $p_bug_data->os ); diff --git a/core/category_api.php b/core/category_api.php index 97c5b8d..64c047a 100644 --- a/core/category_api.php +++ b/core/category_api.php @@ -23,6 +23,9 @@ ### Category API ### + # Category data cache (to prevent excessive db queries) + $g_category_cache = array(); + #=================================== # Boolean queries and ensures #=================================== @@ -30,31 +33,32 @@ # -------------------- # Check whether the category exists in the project # Return true if the category exists, false otherwise - function category_exists( $p_project_id, $p_category ) { - $c_project_id = db_prepare_int( $p_project_id ); - $c_category = db_prepare_string( $p_category ); + function category_exists( $p_category_id ) { + global $g_category_cache; + if ( isset( $g_category_cache[$p_category_id] ) ) { + return true; + } - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); + $c_category_id = db_prepare_int( $p_category_id ); - $query = "SELECT COUNT(*) - FROM $t_project_category_table - WHERE project_id=" . db_param(0) . " AND - category=" . db_param(1); - $result = db_query_bound( $query, Array( $c_project_id, $c_category ) ); - $category_count = db_result( $result ); + $t_category_table = config_get( 'mantis_category_table' ); - if ( 0 < $category_count ) { - return true; + $query = "SELECT COUNT(*) FROM $t_category_table + WHERE id=" . db_param(0); + $count = db_result( db_query_bound( $query, array( $c_category_id ) ) ); + + if ( 0 < $count ) { + return true; } else { - return false; + return false; } } # -------------------- # Check whether the category exists in the project # Trigger an error if it does not - function category_ensure_exists( $p_project_id, $p_category ) { - if ( !category_exists( $p_project_id, $p_category ) ) { + function category_ensure_exists( $p_category_id ) { + if ( !category_exists( $p_category_id ) ) { trigger_error( ERROR_CATEGORY_NOT_FOUND, ERROR ); } } @@ -62,15 +66,28 @@ # -------------------- # Check whether the category is unique within a project # Returns true if the category is unique, false otherwise - function category_is_unique( $p_project_id, $p_category ) { - return !category_exists( $p_project_id, $p_category ); + function category_is_unique( $p_project_id, $p_name ) { + $c_project_id = db_prepare_int( $p_project_id ); + $c_name = db_prepare_string( $p_name ); + + $t_category_table = config_get( 'mantis_category_table' ); + + $query = "SELECT COUNT(*) FROM $t_category_table + WHERE project_id=" . db_param(0) . " AND " . db_helper_like( 'name', db_param(1) ); + $count = db_result( db_query_bound( $query, array( $c_project_id, $c_name ) ) ); + + if ( 0 < $count ) { + return false; + } else { + return true; + } } # -------------------- # Check whether the category is unique within a project # Trigger an error if it is not - function category_ensure_unique( $p_project_id, $p_category ) { - if ( !category_is_unique( $p_project_id, $p_category ) ) { + function category_ensure_unique( $p_project_id, $p_name ) { + if ( !category_is_unique( $p_project_id, $p_name ) ) { trigger_error( ERROR_CATEGORY_DUPLICATE, ERROR ); } } @@ -82,51 +99,41 @@ # -------------------- # Add a new category to the project - function category_add( $p_project_id, $p_category ) { + function category_add( $p_project_id, $p_name ) { $c_project_id = db_prepare_int( $p_project_id ); - $c_category = db_prepare_string( $p_category ); + $c_name = db_prepare_string( $p_name ); - category_ensure_unique( $p_project_id, $p_category ); + category_ensure_unique( $p_project_id, $p_name ); - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); + $t_category_table = config_get( 'mantis_category_table' ); - $query = "INSERT INTO $t_project_category_table - ( project_id, category ) + $query = "INSERT INTO $t_category_table + ( project_id, name ) VALUES - ( " . db_param(0) . ',' . db_param(1) . ')'; - db_query_bound( $query, Array( $c_project_id, $c_category ) ); + ( " . db_param(0) . ', ' . db_param(1) . ' )'; + db_query_bound( $query, array( $c_project_id, $c_name ) ); # db_query errors on failure so: - return true; + return db_insert_id( $t_category_table ); } # -------------------- # Update the name and user associated with the category - function category_update( $p_project_id, $p_category, $p_new_category, $p_assigned_to ) { - $c_project_id = db_prepare_int( $p_project_id ); - $c_category = db_prepare_string( $p_category ); - $c_new_category = db_prepare_string( $p_new_category ); + function category_update( $p_category_id, $p_name, $p_assigned_to ) { + $c_category_id = db_prepare_int( $p_category_id ); + $c_name = db_prepare_string( $p_name ); $c_assigned_to = db_prepare_int( $p_assigned_to ); - category_ensure_exists( $p_project_id, $p_category ); + category_ensure_exists( $p_category_id ); - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); - $t_bug_table = config_get_global( 'mantis_bug_table' ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_bug_table = config_get( 'mantis_bug_table' ); - $query = "UPDATE $t_project_category_table - SET category=" . db_param(0) . ", - user_id=" . db_param(1) . " - WHERE category=" . db_param(2) . " AND - project_id=" . db_param(3); - db_query_bound( $query, Array( $c_new_category, $c_assigned_to, $c_category, $c_project_id ) ); - - if ( $p_category != $p_new_category ) { - $query = "UPDATE $t_bug_table - SET category=" . db_param(0) . " - WHERE category=" . db_param(1) . " AND - project_id=" . db_param(2); - db_query_bound( $query, Array( $c_new_category, $c_category, $c_project_id ) ); - } + $query = "UPDATE $t_category_table + SET name=" . db_param(0) . ', + user_id=' . db_param(1) . ' + WHERE id=' . db_param(2); + db_query_bound( $query, array( $c_name, $c_assigned_to, $c_category_id ) ); # db_query errors on failure so: return true; @@ -134,29 +141,26 @@ # -------------------- # Remove a category from the project - function category_remove( $p_project_id, $p_category, $p_new_category='' ) { - $c_project_id = db_prepare_int( $p_project_id ); - $c_category = db_prepare_string( $p_category ); - $c_new_category = db_prepare_string( $p_new_category ); + function category_remove( $p_category_id, $p_new_category=0 ) { + $c_category_id = db_prepare_int( $p_category_id ); + $c_new_category = db_prepare_int( $p_new_category ); - category_ensure_exists( $p_project_id, $p_category ); - if ( !is_blank( $p_new_category ) ) { - category_ensure_exists( $p_project_id, $p_new_category ); + category_ensure_exists( $p_category_id ); + if ( 0 != $p_new_category ) { + category_ensure_exists( $p_new_category ); } - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); - $t_bug_table = config_get_global( 'mantis_bug_table' ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_bug_table = config_get( 'mantis_bug_table' ); - $query = "DELETE FROM $t_project_category_table - WHERE project_id=" . db_param(0) . " AND - category=" . db_param(1); - db_query_bound( $query, Array( $c_project_id, $c_category ) ); + $query = "DELETE FROM $t_category_table + WHERE id=" . db_param(0); + db_query_bound( $query, array( $c_category_id ) ); $query = "UPDATE $t_bug_table - SET category=" . db_param(0) . " - WHERE category=" . db_param(1) . " AND - project_id=" . db_param(2); - db_query_bound( $query, Array( $c_new_category, $c_category, $c_project_id ) ); + SET category_id=" . db_param(0) . " + WHERE category_id=" . db_param(1); + db_query_bound( $query, array( $c_new_category, $c_category_id ) ); # db_query errors on failure so: return true; @@ -164,22 +168,26 @@ # -------------------- # Remove all categories associated with a project - function category_remove_all( $p_project_id ) { + function category_remove_all( $p_project_id, $p_new_category=0 ) { $c_project_id = db_prepare_int( $p_project_id ); + $c_new_category = db_prepare_int( $p_new_category ); project_ensure_exists( $p_project_id ); + if ( 0 != $p_new_category ) { + category_ensure_exists( $p_new_category ); + } - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); - $t_bug_table = config_get_global( 'mantis_bug_table' ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_bug_table = config_get( 'mantis_bug_table' ); - $query = "DELETE FROM $t_project_category_table - WHERE project_id=" . db_param(0); - db_query_bound( $query, Array( $c_project_id ) ); + $query = "DELETE FROM $t_category_table + WHERE project_id='$c_project_id'"; + db_query_bound( $query, array( $c_project_id ) ); $query = "UPDATE $t_bug_table - SET category='' - WHERE project_id=" . db_param(0); - db_query_bound( $query, Array( $c_project_id ) ); + SET category='$c_new_category' + WHERE project_id='$c_project_id'"; + db_query_bound( $query, array( $c_new_category, $c_project_id ) ); # db_query errors on failure so: return true; @@ -192,45 +200,74 @@ # -------------------- # Return the definition row for the category - function category_get_row( $p_project_id, $p_category ) { - $c_project_id = db_prepare_int( $p_project_id ); - $c_category = db_prepare_string( $p_category ); + function category_get_row( $p_category_id ) { + global $g_category_cache; + if ( isset( $g_category_cache[$p_category_id] ) ) { + return $g_category_cache[$p_category_id]; + } - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); + $c_category_id = db_prepare_int( $p_category_id ); - $query = "SELECT category, user_id - FROM $t_project_category_table - WHERE project_id=" . db_param(0) . " AND - category=" . db_param(1); - $result = db_query_bound( $query, Array( $c_project_id, $c_category ) ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_project_table = config_get( 'mantis_project_table' ); + + $query = "SELECT c.*, p.name AS project_name FROM $t_category_table AS c + JOIN $t_project_table AS p + ON c.project_id=p.id + WHERE c.id=" . db_param(0); + $result = db_query_bound( $query, array( $c_category_id ) ); $count = db_num_rows( $result ); if ( 0 == $count ) { trigger_error( ERROR_CATEGORY_NOT_FOUND, ERROR ); } - return db_fetch_array( $result ); + $row = db_fetch_array( $result ); + $g_category_cache[$p_category_id] = $row; + return $row; } # -------------------- # Return all categories for the specified project id function category_get_all_rows( $p_project_id ) { + global $g_category_cache; + $c_project_id = db_prepare_int( $p_project_id ); - $t_project_category_table = config_get_global( 'mantis_project_category_table' ); + $t_category_table = config_get( 'mantis_category_table' ); + $t_project_table = config_get( 'mantis_project_table' ); - $query = "SELECT category, user_id - FROM $t_project_category_table - WHERE project_id=" . db_param(0) . " - ORDER BY category"; - $result = db_query_bound( $query, Array( $c_project_id ) ); + $t_project_where = helper_project_specific_where( $c_project_id ); + + $query = "SELECT c.*, p.name AS project_name FROM $t_category_table AS c + JOIN $t_project_table AS p + ON c.project_id=p.id + WHERE $t_project_where + ORDER BY c.name "; + $result = db_query_bound( $query, array() ); $count = db_num_rows( $result ); $rows = array(); for ( $i = 0 ; $i < $count ; $i++ ) { $row = db_fetch_array( $result ); $rows[] = $row; + $g_category_cache[$row['id']] = $row; } return $rows; } -?> + + # Helpers + + function category_full_name( $p_category_id, $p_show_project=true ) { + if ( $p_category_id == 0 ) { + return lang_get( 'no_category' ); + } + + $t_row = category_get_row( $p_category_id ); + + if ( $p_show_project ) { + return "[$t_row[project_name]] $t_row[name]"; + } else { + return $t_row['name']; + } + } diff --git a/core/columns_api.php b/core/columns_api.php index 65bc271..8f08254 100644 --- a/core/columns_api.php +++ b/core/columns_api.php @@ -534,7 +534,7 @@ echo ']
'; } - echo string_display( $p_row['category'] ); + echo string_display( category_full_name( $p_row['category_id'], false ) ); echo ''; } diff --git a/core/filter_api.php b/core/filter_api.php index a7b3cd6..a60033d 100644 --- a/core/filter_api.php +++ b/core/filter_api.php @@ -413,6 +413,7 @@ $t_bug_table = config_get_global( 'mantis_bug_table' ); $t_bug_text_table = config_get_global( 'mantis_bug_text_table' ); $t_bugnote_table = config_get_global( 'mantis_bugnote_table' ); + $t_category_table = config_get_global( 'mantis_category_table' ); $t_custom_field_string_table = config_get_global( 'mantis_custom_field_string_table' ); $t_bugnote_text_table = config_get_global( 'mantis_bugnote_text_table' ); $t_project_table = config_get_global( 'mantis_project_table' ); @@ -696,9 +697,7 @@ $t_clauses = array(); foreach( $t_filter['show_category'] as $t_filter_member ) { - $t_filter_member = stripslashes( $t_filter_member ); if ( META_FILTER_NONE == $t_filter_member ) { - array_push( $t_clauses, "''" ); } else { $c_show_category = db_prepare_string( $t_filter_member ); array_push( $t_clauses, "'$c_show_category'" ); @@ -706,9 +705,9 @@ } if ( 1 < count( $t_clauses ) ) { - array_push( $t_where_clauses, "( $t_bug_table.category in (". implode( ', ', $t_clauses ) .") )" ); + array_push( $t_where_clauses, "( $t_bug_table.category_id in ( SELECT id FROM $t_category_table WHERE name in (". implode( ', ', $t_clauses ) .") ) )" ); } else { - array_push( $t_where_clauses, "( $t_bug_table.category=$t_clauses[0] )" ); + array_push( $t_where_clauses, "( $t_bug_table.category_id in ( SELECT id FROM $t_category_table WHERE name=$t_clauses[0] ) )" ); } } @@ -1765,13 +1764,11 @@ } else { $t_first_flag = true; foreach( $t_filter['show_category'] as $t_current ) { - $t_current = stripslashes( $t_current ); ?> - + strtotime( '-'.$t_filter['highlight_changed'].' hours' ) ) { echo ' - ' . $t_last_updated . ''; diff --git a/core/print_api.php b/core/print_api.php index 65c4795..34ecb7c 100644 --- a/core/print_api.php +++ b/core/print_api.php @@ -424,7 +424,7 @@ # -------------------- # print a news item given a row in the news table. - function print_news_entry_from_row( $p_news_row ) { + function print_news_entry_from_row( $p_news_row ) { extract( $p_news_row, EXTR_PREFIX_ALL, 'v' ); print_news_entry( $v_headline, $v_body, $v_poster_id, $v_view_state, $v_announcement, $v_date_posted ); } @@ -673,12 +673,14 @@ PRINT ">$v_name"; } # end for } + # -------------------- # Since categories can be orphaned we need to grab all unique instances of category # We check in the project category table and in the bug table # We put them all in one array and make sure the entries are unique - function print_category_option_list( $p_category='', $p_project_id = null ) { - $t_mantis_project_category_table = config_get_global( 'mantis_project_category_table' ); + function print_category_option_list( $p_category_id = 0, $p_project_id = null ) { + $t_category_table = config_get( 'mantis_category_table' ); + $t_project_table = config_get( 'mantis_project_table' ); if ( null === $p_project_id ) { $c_project_id = helper_get_current_project(); @@ -690,81 +692,61 @@ # grab all categories in the project category table $cat_arr = array(); - $query = "SELECT DISTINCT category - FROM $t_mantis_project_category_table + $query = "SELECT id,name FROM $t_category_table WHERE $t_project_where - ORDER BY category"; + ORDER BY name"; $result = db_query( $query ); - $category_count = db_num_rows( $result ); - for ($i=0;$i<$category_count;$i++) { - $row = db_fetch_array( $result ); - $cat_arr[] = string_attribute( $row['category'] ); - } - # Add the default option if not in the list retrieved from DB - # This is useful for default categories and when updating an - # issue with a deleted category. - if ( !is_blank( $p_category ) && !in_array( $p_category, $cat_arr ) ) { - $cat_arr[] = $p_category; + while ( $row = db_fetch_array( $result ) ) { + $cat_arr[$row['id']] = $row['name']; } + asort($cat_arr); - sort( $cat_arr ); - $cat_arr = array_unique( $cat_arr ); - - foreach( $cat_arr as $t_category ) { - PRINT ""; + foreach( $cat_arr as $t_category_id => $t_name ) { + PRINT ""; } } # -------------------- # Since categories can be orphaned we need to grab all unique instances of category # We check in the project category table and in the bug table # We put them all in one array and make sure the entries are unique - function print_category_complete_option_list( $p_category='', $p_project_id = null ) { - $t_mantis_project_category_table = config_get_global( 'mantis_project_category_table' ); - $t_mantis_bug_table = config_get_global( 'mantis_bug_table' ); + function print_category_complete_option_list( $p_category_id = 0, $p_project_id = null ) { + return print_category_option_list( $p_category_id, $p_project_id ); + } + + # --------- + # Now that categories are identified by numerical ID, we need an old-style name + # based option list to keep existing filter functionality. + function print_category_filter_option_list( $p_category_name = '', $p_project_id = null ) { + $t_category_table = config_get( 'mantis_category_table' ); + $t_project_table = config_get( 'mantis_project_table' ); if ( null === $p_project_id ) { - $t_project_id = helper_get_current_project(); + $c_project_id = helper_get_current_project(); } else { - $t_project_id = $p_project_id; + $c_project_id = db_prepare_int( $p_project_id ); } - $t_project_where = helper_project_specific_where( $t_project_id ); + $t_project_where = helper_project_specific_where( $c_project_id ); # grab all categories in the project category table $cat_arr = array(); - $query = "SELECT DISTINCT category - FROM $t_mantis_project_category_table + $query = "SELECT DISTINCT name FROM $t_category_table WHERE $t_project_where - ORDER BY category"; + ORDER BY name"; $result = db_query( $query ); - $category_count = db_num_rows( $result ); - for ($i=0;$i<$category_count;$i++) { - $row = db_fetch_array( $result ); - $cat_arr[] = string_attribute( $row['category'] ); - } - # grab all categories in the bug table - $query = "SELECT DISTINCT category - FROM $t_mantis_bug_table - WHERE $t_project_where - ORDER BY category"; - $result = db_query( $query ); - $category_count = db_num_rows( $result ); - - for ($i=0;$i<$category_count;$i++) { - $row = db_fetch_array( $result ); - $cat_arr[] = string_attribute( $row['category'] ); + while ( $row = db_fetch_array( $result ) ) { + $cat_arr[] = $row['name']; } - sort( $cat_arr ); - $cat_arr = array_unique( $cat_arr ); + sort($cat_arr); - foreach( $cat_arr as $t_category ) { - PRINT ""; + foreach( $cat_arr as $t_name ) { + PRINT ""; } } @@ -1257,26 +1239,26 @@ } # -------------------- function print_project_category_string( $p_project_id ) { - $t_mantis_project_category_table = config_get_global( 'mantis_project_category_table' ); + $t_mantis_category_table = config_get( 'mantis_category_table' ); $c_project_id = db_prepare_int( $p_project_id ); - $query = "SELECT category - FROM $t_mantis_project_category_table - WHERE project_id=" . db_param(0) . " - ORDER BY category"; - $result = db_query_bound( $query, Array( $c_project_id ) ); + $query = "SELECT name + FROM $t_mantis_category_table + WHERE project_id='$c_project_id' + ORDER BY name"; + $result = db_query( $query ); $category_count = db_num_rows( $result ); $t_string = ''; for ($i=0;$i<$category_count;$i++) { $row = db_fetch_array( $result ); - $t_category = $row['category']; + $t_name = $row['name']; if ( $i+1 < $category_count ) { - $t_string .= $t_category.', '; + $t_string .= $t_name.', '; } else { - $t_string .= $t_category; + $t_string .= $t_name; } } @@ -1500,7 +1482,7 @@ } print_page_link( $p_page, $t_last, $p_end, $p_current, $p_temp_filter_id ); - print( " ]" ); + print( " ]" ); } # -------------------- # print a mailto: href link diff --git a/core/summary_api.php b/core/summary_api.php index e0a8e4f..3d514da 100644 --- a/core/summary_api.php +++ b/core/summary_api.php @@ -536,6 +536,7 @@ # print a bug count per category function summary_print_by_category() { $t_mantis_bug_table = config_get_global( 'mantis_bug_table' ); + $t_mantis_category_table = config_get( 'mantis_category_table' ); $t_mantis_project_table = config_get_global( 'mantis_project_table' ); $t_summary_category_include_project = config_get( 'summary_category_include_project' ); @@ -548,15 +549,17 @@ } $t_project_query = ( ON == $t_summary_category_include_project ) ? 'project_id, ' : ''; - $query = "SELECT COUNT(id) as bugcount, $t_project_query category, status + $query = "SELECT COUNT(id) as bugcount, $t_project_query c.name AS category_name, c.id AS categor_id status FROM $t_mantis_bug_table - WHERE category>'' AND $specific_where - GROUP BY $t_project_query category, status - ORDER BY $t_project_query category, status"; + JOIN $t_mantis_category_table AS c ON category_id=c.id + WHERE $specific_where + GROUP BY $t_project_query category_name, status + ORDER BY $t_project_query category_name, status"; $result = db_query( $query ); - $last_category = -1; + $last_category_name = -1; + $last_category_id = -1; $last_project = -1; $t_bugs_open = 0; $t_bugs_resolved = 0; @@ -569,13 +572,13 @@ while ( $row = db_fetch_array( $result ) ) { extract( $row, EXTR_PREFIX_ALL, 'v' ); - if ( ( $v_category != $last_category ) && ( $last_category != -1 ) ) { - $label = $last_category; + if ( ( $v_category_id != $last_category_id ) && ( $last_category_id != -1 ) ) { + $label = $last_category_name; if ( ( ON == $t_summary_category_include_project ) && ( ALL_PROJECTS == $t_project_id ) ) { $label = sprintf( '[%s] %s', project_get_name( $last_project ), $label ); } - $t_bug_link = '' . $t_bugs_open . ''; } @@ -606,19 +609,20 @@ $t_bugs_open += $row['bugcount']; } - $last_category = $v_category; + $last_category_id = $v_category_id; + $last_category_name = $v_category_name; if ( ( ON == $t_summary_category_include_project ) && ( ALL_PROJECTS == $t_project_id ) ) { $last_project = $v_project_id; } } if ( 0 < $t_bugs_total ) { - $label = $last_category; + $label = $last_category_name; if ( ( ON == $t_summary_category_include_project ) && ( ALL_PROJECTS == $t_project_id ) ) { $label = sprintf( '[%s] %s', project_get_name( $last_project ), $label ); } - $t_bug_link = '' . $t_bugs_open . ''; diff --git a/graphs/graph_by_category.php b/graphs/graph_by_category.php index a969d25..8e5f098 100644 --- a/graphs/graph_by_category.php +++ b/graphs/graph_by_category.php @@ -36,12 +36,13 @@ $data_category_arr = array(); $data_count_arr = array(); - $query = "SELECT category, COUNT(category) as count + $query = "SELECT c.name AS name, COUNT(name) as count FROM mantis_bug_table - WHERE project_id=" . db_param(0) . " - GROUP BY category - ORDER BY category"; - $result = db_query_bound( $query, Array( $t_project_id ) ); + JOIN mantis_category_table AS c + WHERE project_id='$t_project_id' + GROUP BY name + ORDER BY name"; + $result = db_query( $query ); $category_count = db_num_rows( $result ); $total = 0; $longest_size = 0; @@ -50,11 +51,11 @@ extract( $row ); $total += $count; - $data_category_arr[] = $category; + $data_category_arr[] = $name; $data_count_arr[] = $count; - if ( strlen( $category ) > $longest_size ) { - $longest_size = strlen( $category ); + if ( strlen( $name ) > $longest_size ) { + $longest_size = strlen( $name ); } } $longest_size++; diff --git a/lang/strings_english.txt b/lang/strings_english.txt index 4d1527d..afc07b0 100644 --- a/lang/strings_english.txt +++ b/lang/strings_english.txt @@ -592,6 +592,7 @@ $s_update_simple_link = 'Update Simple'; $s_updating_bug_advanced_title = 'Updating Issue Information'; $s_id = 'ID'; $s_category = 'Category'; +$s_no_category = 'N/A'; $s_severity = 'Severity'; $s_reproducibility = 'Reproducibility'; $s_date_submitted = 'Date Submitted'; diff --git a/manage_proj_cat_add.php b/manage_proj_cat_add.php index 27717f9..9675b08 100644 --- a/manage_proj_cat_add.php +++ b/manage_proj_cat_add.php @@ -30,25 +30,25 @@ auth_reauthenticate(); $f_project_id = gpc_get_int( 'project_id' ); - $f_category = gpc_get_string( 'category' ); + $f_name = gpc_get_string( 'name' ); access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id ); - if ( is_blank( $f_category ) ) { + if ( is_blank( $f_name ) ) { trigger_error( ERROR_EMPTY_FIELD, ERROR ); } - $t_categories = explode( '|', $f_category ); - $t_category_count = count( $t_categories ); + $t_names = explode( '|', $f_name ); + $t_category_count = count( $t_names ); - foreach ( $t_categories as $t_category ) { - if ( is_blank( $t_category ) ) { + foreach ( $t_names as $t_name ) { + if ( is_blank( $t_name ) ) { continue; } - $t_category = trim( $t_category ); - if ( category_is_unique( $f_project_id, $t_category ) ) { - category_add( $f_project_id, $t_category ); + $t_name = trim( $t_name ); + if ( category_is_unique( $f_project_id, $t_name ) ) { + category_add( $f_project_id, $t_name ); } else if ( 1 == $t_category_count ) { # We only error out on duplicates when a single value was # given. If multiple values were given, we just add the diff --git a/manage_proj_cat_copy.php b/manage_proj_cat_copy.php index d7b7c12..f205c71 100644 --- a/manage_proj_cat_copy.php +++ b/manage_proj_cat_copy.php @@ -50,10 +50,10 @@ $rows = category_get_all_rows( $t_src_project_id ); foreach ( $rows as $row ) { - $t_category = $row['category']; + $t_name = $row['name']; - if ( category_is_unique( $t_dst_project_id, $t_category ) ) { - category_add( $t_dst_project_id, $t_category ); + if ( category_is_unique( $t_dst_project_id, $t_name ) ) { + category_add( $t_dst_project_id, $t_name ); } } diff --git a/manage_proj_cat_delete.php b/manage_proj_cat_delete.php index 6dc7966..934e7bf 100644 --- a/manage_proj_cat_delete.php +++ b/manage_proj_cat_delete.php @@ -29,19 +29,22 @@ auth_reauthenticate(); - $f_project_id = gpc_get_int( 'project_id' ); - $f_category = gpc_get_string( 'category' ); + $f_category_id = gpc_get_string( 'id' ); access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id ); + $t_row = category_get_row( $f_category_id ); + $t_name = category_full_name( $f_category_id ); + $t_project_id = $t_row['project_id']; + # Confirm with the user helper_ensure_confirmed( lang_get( 'category_delete_sure_msg' ) . - '
' . lang_get( 'category' ) . ': ' . $f_category, + '
' . lang_get( 'category' ) . ': ' . $t_name, lang_get( 'delete_category_button' ) ); - category_remove( $f_project_id, $f_category ); + category_remove( $f_category_id ); - $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id; + $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $t_project_id; html_page_top1(); html_meta_redirect( $t_redirect_url ); diff --git a/manage_proj_cat_edit_page.php b/manage_proj_cat_edit_page.php index ca00e1b..ed69979 100644 --- a/manage_proj_cat_edit_page.php +++ b/manage_proj_cat_edit_page.php @@ -29,13 +29,14 @@ auth_reauthenticate(); - $f_project_id = gpc_get_int( 'project_id' ); - $f_category = gpc_get_string( 'category' ); + $f_category_id = gpc_get_string( 'id' ); access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id ); - $t_row = category_get_row( $f_project_id, $f_category ); + $t_row = category_get_row( $f_category_id ); $t_assigned_to = $t_row['user_id']; + $t_project_id = $t_row['project_id']; + $t_name = $t_row['name']; html_page_top1(); html_page_top2(); @@ -54,12 +55,11 @@ > - - + - + > @@ -69,7 +69,7 @@ @@ -89,8 +89,7 @@
- - +
diff --git a/manage_proj_cat_update.php b/manage_proj_cat_update.php index 05afd1e..98610e8 100644 --- a/manage_proj_cat_update.php +++ b/manage_proj_cat_update.php @@ -29,29 +29,28 @@ auth_reauthenticate(); - $f_project_id = gpc_get_int( 'project_id' ); - $f_category = gpc_get_string( 'category' ); - $f_new_category = gpc_get_string( 'new_category' ); + $f_category_id = gpc_get_int( 'category_id' ); + $f_name = trim( gpc_get_string( 'name' ) ); $f_assigned_to = gpc_get_int( 'assigned_to', 0 ); access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id ); - if ( is_blank( $f_new_category ) ) { + if ( is_blank( $f_name ) ) { trigger_error( ERROR_EMPTY_FIELD, ERROR ); } - $f_category = trim( $f_category ); - $f_new_category = trim( $f_new_category ); + $t_row = category_get_row( $f_category_id ); + $t_old_name = $t_row['name']; + $t_project_id = $t_row['project_id']; # check for duplicate - if ( strtolower( $f_category ) == strtolower( $f_new_category ) || - category_is_unique( $f_project_id, $f_new_category ) ) { - category_update( $f_project_id, $f_category, $f_new_category, $f_assigned_to ); - } else { - trigger_error( ERROR_CATEGORY_DUPLICATE, ERROR ); + if ( strtolower( $f_name ) != strtolower( $t_old_name ) ) { + category_ensure_unique( $t_project_id, $f_name ); } + + category_update( $f_category_id, $f_name, $f_assigned_to ); - $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id; + $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $t_project_id; html_page_top1(); diff --git a/manage_proj_edit_page.php b/manage_proj_edit_page.php index 41c4304..13c83a2 100644 --- a/manage_proj_edit_page.php +++ b/manage_proj_edit_page.php @@ -302,7 +302,8 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?> } foreach ( $t_categories as $t_category ) { - $t_name = $t_category['category']; + $t_id = $t_category['id']; + $t_name = $t_category['name']; if ( NO_USER != $t_category['user_id'] && user_exists( $t_category['user_id'] )) { $t_user_name = user_get_name( $t_category['user_id'] ); @@ -320,11 +321,11 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?> @@ -337,7 +338,7 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
- +
diff --git a/my_view_page.php b/my_view_page.php index febd47b..d286294 100644 --- a/my_view_page.php +++ b/my_view_page.php @@ -34,6 +34,9 @@ $t_current_user_id = auth_get_current_user_id(); + # Improve performance by caching category data in one pass + category_get_all_rows( helper_get_current_project() ); + compress_enable(); html_page_top1( lang_get( 'my_view_link' ) ); diff --git a/view_all_inc.php b/view_all_inc.php index 16e4992..8131b17 100644 --- a/view_all_inc.php +++ b/view_all_inc.php @@ -43,6 +43,9 @@ $t_icon_path = config_get( 'icon_path' ); $t_update_bug_threshold = config_get( 'update_bug_threshold' ); + # Improve performance by caching category data in one pass + category_get_all_rows( helper_get_current_project() ); + $t_columns = helper_get_columns_to_view( COLUMNS_TARGET_VIEW_PAGE ); $col_count = sizeof( $t_columns );