Relationship Graph
View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0008435 | mantisbt | feature | public | 2007-10-02 14:22 | 2011-10-04 03:59 |
| Reporter | jreese | Assigned To | jreese | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | closed | Resolution | fixed | ||
| Target Version | 1.2.0a1 | Fixed in Version | 1.2.0a1 | ||
| Summary | 0008435: Implement Global and Inheriting Categories Structure | ||||
| Description | Implement a set of features for the Mantis bugtracker that will enable a simple and logical method of reducing and reusing project categories by:
The overall requirements outline for this planned feature has been posted on the wiki: | ||||
| Tags | No tags attached. | ||||
| Attached Files | mantis-categories-2007-11-10.patch (59,115 bytes)
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 @@
+<?php
+ # Mantis - a php based bugtracking system
+ # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
+ # Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net
+ # This program is distributed under the terms and conditions of the GPL
+ # See the README and LICENSE files for details
+
+ # --------------------------------------------------------
+ # $Id: $
+ # --------------------------------------------------------
+
+ /**
+ * Update functions for the installation schema's 'UpdateFunction' option.
+ * All functions must be name install_<function_name> and referenced as just <function_name>.
+ */
+
+ /**
+ * 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 @@
?>
<p>
<form method="post" action="<?php echo string_get_bug_report_url() ?>">
- <input type="hidden" name="category" value="<?php echo $t_bug_data->category ?>" />
+ <input type="hidden" name="category_id" value="<?php echo $t_bug_data->category_id ?>" />
<input type="hidden" name="severity" value="<?php echo $t_bug_data->severity ?>" />
<input type="hidden" name="reproducibility" value="<?php echo $t_bug_data->reproducibility ?>" />
<input type="hidden" name="profile_id" value="<?php echo $t_bug_data->profile_id ?>" />
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
<?php
- if ( is_blank( $f_category ) ) {
+ if ( is_blank( $f_category_id ) ) {
echo '<option value="" selected="selected">', string_attribute( lang_get( 'select_option' ) ), '</option>';
}
- print_category_option_list( $f_category );
+ print_category_option_list( $f_category_id );
?>
</select>
</td>
@@ -555,7 +555,7 @@
<?php if ( ON == config_get( 'use_javascript' ) ) { ?>
<script type="text/javascript" language="JavaScript">
<!--
- window.document.report_bug_form.category.focus();
+ window.document.report_bug_form.category_id.focus();
-->
</script>
<?php } ?>
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
<?php
- if ( is_blank( $f_category ) ) {
+ if ( is_blank( $f_category_id ) ) {
echo '<option value="" selected="selected">', string_attribute( lang_get( 'select_option' ) ), '</option>';
}
- print_category_option_list( $f_category );
+ print_category_option_list( $f_category_id );
?>
</select>
</td>
@@ -385,7 +385,7 @@
<?php if ( ON == config_get( 'use_javascript' ) ) { ?>
<script type="text/javascript" language="JavaScript">
<!--
- window.document.report_bug_form.category.focus();
+ window.document.report_bug_form.category_id.focus();
-->
</script>
<?php } ?>
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
- <?php print_category_option_list( $t_bug->category, $t_bug->project_id ) ?>
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
+ <?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
</td>
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
- <?php print_category_option_list( $t_bug->category, $t_bug->project_id ) ?>
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
+ <?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
</td>
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 @@
<!-- Category -->
<td>
<?php
- $t_project_name = string_display( project_get_field( $t_bug->project_id, 'name' ) );
- echo "[$t_project_name] $t_bug->category";
+ echo string_display( category_full_name( $t_bug->category_id ) );
?>
</td>
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 @@
<!-- Category -->
<td>
<?php
- $t_project_name = string_display( project_get_field( $t_bug->project_id, 'name' ) );
- echo "[$t_project_name] $t_bug->category";
+ echo string_display( category_full_name( $t_bug->category_id ) );
?>
</td>
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 ']</small><br />';
}
- echo string_display( $p_row['category'] );
+ echo string_display( category_full_name( $p_row['category_id'], false ) );
echo '</td>';
}
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 );
?>
- <input type="hidden" name="show_category[]" value="<?php echo string_display( $t_current );?>" />
+ <input type="hidden" name="show_category[]" value="<?php echo $t_current;?>" />
<?php
$t_this_string = '';
- if ( ( ( $t_current == META_FILTER_ANY ) && ( is_numeric( $t_current ) ) )
- || ( is_blank( $t_current ) ) ) {
+ if ( is_blank( $t_current ) || $t_current === "0" || $t_current === META_FILTER_ANY ) {
$t_any_found = true;
} else {
$t_this_string = string_display( $t_current );
@@ -3334,8 +3331,7 @@
<!-- Category -->
<select <?php PRINT $t_select_modifier;?> name="show_category[]">
<option value="<?php echo META_FILTER_ANY ?>" <?php check_selected( $t_filter['show_category'], META_FILTER_ANY ); ?>>[<?php echo lang_get( 'any' ) ?>]</option>
- <?php # This shows orphaned categories as well as selectable categories ?>
- <?php print_category_complete_option_list( $t_filter['show_category'] ) ?>
+ <?php print_category_filter_option_list( $t_filter['show_category'] ) ?>
</select>
<?php
}
diff --git a/core/graph_api.php b/core/graph_api.php
index 2393a11..df60a9a 100644
--- a/core/graph_api.php
+++ b/core/graph_api.php
@@ -591,30 +591,28 @@
global $category_name, $category_bug_count;
$t_project_id = helper_get_current_project();
- $t_cat_table = config_get_global( 'mantis_project_category_table' );
- $t_bug_table = config_get_global( 'mantis_bug_table' );
+ $t_cat_table = config_get( 'mantis_category_table' );
+ $t_bug_table = config_get( 'mantis_bug_table' );
$t_user_id = auth_get_current_user_id();
$specific_where = helper_project_specific_where( $t_project_id, $t_user_id );
- $query = "SELECT DISTINCT category
+ $query = "SELECT id, name
FROM $t_cat_table
WHERE $specific_where
- ORDER BY category";
+ ORDER BY name";
$result = db_query( $query );
$category_count = db_num_rows( $result );
- if ( 0 == $category_count ) {
- return array();
- }
+ $t_metrics = array();
for ($i=0;$i<$category_count;$i++) {
$row = db_fetch_array( $result );
- $t_cat_name = $row['category'];
- $c_category_name = addslashes($t_cat_name);
+ $t_cat_name = $row['name'];
+ $t_cat_id = $row['id'];
$query = "SELECT COUNT(*)
FROM $t_bug_table
- WHERE category='$c_category_name' AND $specific_where";
+ WHERE category_id='$t_cat_id' AND $specific_where";
$result2 = db_query( $query );
- $t_metrics[$t_cat_name] = db_result( $result2, 0, 0 );
+ $t_metrics[$t_cat_name] = $t_metrics[$t_cat_name] + db_result( $result2, 0, 0 );
} # end for
return $t_metrics;
}
diff --git a/core/history_api.php b/core/history_api.php
index 2a6b003..0f51a76 100644
--- a/core/history_api.php
+++ b/core/history_api.php
@@ -216,6 +216,11 @@
case 'category':
$t_field_localized = lang_get( 'category' );
break;
+ case 'category_id':
+ $t_field_localized = lang_get( 'category' );
+ $p_old_value = category_full_name( $p_old_value, false );
+ $p_new_value = category_full_name( $p_new_value, false );
+ break;
case 'status':
$p_old_value = get_enum_element( 'status', $p_old_value );
$p_new_value = get_enum_element( 'status', $p_new_value );
diff --git a/core/my_view_inc.php b/core/my_view_inc.php
index dbc86b3..e46e7ab 100644
--- a/core/my_view_inc.php
+++ b/core/my_view_inc.php
@@ -279,11 +279,10 @@
# type project name if viewing 'all projects' or bug is in subproject
if ( ON == config_get( 'show_bug_project_links' ) &&
helper_get_current_project() != $v_project_id ) {
- echo '[';
- print( $project_name );
- echo '] ';
+ echo string_display( category_full_name( $v_category_id ) );
+ } else {
+ echo string_display( category_full_name( $v_category_id, false ) );
}
- echo string_display( $v_category );
if ( $v_last_updated > strtotime( '-'.$t_filter['highlight_changed'].' hours' ) ) {
echo ' - <b>' . $t_last_updated . '</b>';
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</option>";
} # 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 "<option value=\"$t_category\"";
- check_selected( $t_category, $p_category );
- PRINT ">$t_category</option>";
+ foreach( $cat_arr as $t_category_id => $t_name ) {
+ PRINT "<option value=\"$t_category_id\"";
+ check_selected( $p_category_id, $t_category_id );
+ PRINT ">$t_name</option>";
}
}
# --------------------
# 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 "<option value=\"$t_category\"";
- check_selected( $p_category, $t_category );
- PRINT ">$t_category</option>";
+ foreach( $cat_arr as $t_name ) {
+ PRINT "<option value=\"$t_name\"";
+ check_selected( $p_category_name, $t_name );
+ PRINT ">$t_name</option>";
}
}
@@ -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 = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category );
+ $t_bug_link = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category_id );
if ( 0 < $t_bugs_open ) {
$t_bugs_open = $t_bug_link . '&hide_status=' . RESOLVED . '">' . $t_bugs_open . '</a>';
}
@@ -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 = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category );
+ $t_bug_link = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category_id );
if ( !is_blank( $t_bug_link ) ) {
if ( 0 < $t_bugs_open ) {
$t_bugs_open = $t_bug_link . '&hide_status=' . RESOLVED . '">' . $t_bugs_open . '</a>';
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' ) .
- '<br/>' . lang_get( 'category' ) . ': ' . $f_category,
+ '<br/>' . 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 @@
</tr>
<tr <?php echo helper_alternate_class() ?>>
<td class="category">
- <input type="hidden" name="project_id" value="<?php echo string_attribute( $f_project_id ) ?>" />
- <input type="hidden" name="category" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="hidden" name="category_id" value="<?php echo string_attribute( $f_category_id ) ?>" />
<?php echo lang_get( 'category' ) ?>
</td>
<td>
- <input type="text" name="new_category" size="32" maxlength="64" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="text" name="name" size="32" maxlength="64" value="<?php echo string_attribute( $t_name ) ?>" />
</td>
</tr>
<tr <?php echo helper_alternate_class() ?>>
@@ -69,7 +69,7 @@
<td>
<select name="assigned_to">
<option value="0"></option>
- <?php print_assign_to_option_list( $t_assigned_to, $f_project_id ) ?>
+ <?php print_assign_to_option_list( $t_assigned_to, $t_project_id ) ?>
</select>
</td>
</tr>
@@ -89,8 +89,7 @@
<div class="border-center">
<form method="post" action="manage_proj_cat_delete.php">
- <input type="hidden" name="project_id" value="<?php echo string_attribute( $f_project_id ) ?>" />
- <input type="hidden" name="category" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="hidden" name="category_id" value="<?php echo string_attribute( $f_category_id ) ?>" />
<input type="submit" class="button" value="<?php echo lang_get( 'delete_category_button' ) ?>" />
</form>
</div>
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' ) ) ) { ?>
</td>
<td class="center">
<?php
- $t_name = urlencode( $t_name );
+ $t_id = urlencode( $t_id );
- print_button( 'manage_proj_cat_edit_page.php?project_id=' . $f_project_id . '&category=' . $t_name, lang_get( 'edit_link' ) );
+ print_button( 'manage_proj_cat_edit_page.php?id=' . $t_id, lang_get( 'edit_link' ) );
echo ' ';
- print_button( 'manage_proj_cat_delete.php?project_id=' . $f_project_id . '&category=' . $t_name, lang_get( 'delete_link' ) );
+ print_button( 'manage_proj_cat_delete.php?id=' . $t_id, lang_get( 'delete_link' ) );
?>
</td>
</tr>
@@ -337,7 +338,7 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
<td class="left" colspan="3">
<form method="post" action="manage_proj_cat_add.php">
<input type="hidden" name="project_id" value="<?php echo $f_project_id ?>" />
- <input type="text" name="category" size="32" maxlength="64" />
+ <input type="text" name="name" size="32" maxlength="64" />
<input type="submit" class="button" value="<?php echo lang_get( 'add_category_button' ) ?>" />
</form>
</td>
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 );
mantis-categories-2007-11-12.patch (60,540 bytes)
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..ddda15f
--- /dev/null
+++ b/admin/install_functions.php
@@ -0,0 +1,64 @@
+<?php
+ # Mantis - a php based bugtracking system
+ # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
+ # Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net
+ # This program is distributed under the terms and conditions of the GPL
+ # See the README and LICENSE files for details
+
+ # --------------------------------------------------------
+ # $Id: $
+ # --------------------------------------------------------
+
+ /**
+ * Update functions for the installation schema's 'UpdateFunction' option.
+ * All functions must be name install_<function_name> and referenced as just <function_name>.
+ */
+
+ /**
+ * 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";
+ $t_category_result = db_query( $query );
+
+ $query = "SELECT project_id, category FROM $t_bug_table ORDER BY project_id, category";
+ $t_bug_result = db_query( $query );
+
+ $t_data = Array();
+
+ # Find categories specified by project
+ while ( $row = db_fetch_array( $t_category_result ) ) {
+ $t_project_id = $row['project_id'];
+ $t_name = $row['category'];
+ $t_data[$t_project_id][$t_name] = true;
+ }
+
+ # Find orphaned categories from bugs
+ while ( $row = db_fetch_array( $t_bug_result ) ) {
+ $t_project_id = $row['project_id'];
+ $t_name = $row['category'];
+
+ $t_data[$t_project_id][$t_name] = true;
+ }
+
+ # In every project, go through all the categories found, and create them and update the bug
+ foreach ( $t_data as $t_project_id => $t_categories ) {
+ foreach ( $t_categories as $t_name => $t_true ) {
+ $query = "INSERT INTO $t_category_table ( name, project_id ) VALUES ( " . db_param(0) . ', ' . db_param(1) . ' )';
+ db_query_bound( $query, array( $t_name, $t_project_id ) );
+ $t_category_id = db_insert_id( $t_category_table );
+
+ $query = "UPDATE $t_bug_table SET category_id=" . db_param(0) . '
+ WHERE project_id=' . db_param(1) . ' AND category=' . db_param(2);
+ db_query_bound( $query, array( $t_category_id, $t_project_id, $t_name ) );
+ }
+ }
+
+ # return 2 because that's what ADOdb/DataDict does when things happen properly
+ return 2;
+ }
+
diff --git a/admin/schema.php b/admin/schema.php
index 440504e..a186339 100644
--- a/admin/schema.php
+++ b/admin/schema.php
@@ -370,4 +370,22 @@ $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(128) NOTNULL DEFAULT \" '' \",
+ status I UNSIGNED NOTNULL DEFAULT '0'
+ ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) );
+$upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_project_name', config_get( 'mantis_category_table' ), 'project_id, name', array( 'UNIQUE' ) ) );
+$upgrade[] = Array( 'InsertData', Array( config_get( 'mantis_category_table' ), "
+ ( project_id, user_id, name, status ) VALUES
+ ( '0', '0', 'None', '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' ) ) );
+$upgrade[] = Array( 'AddColumnSQL', Array( config_get( 'mantis_project_table' ), "category_id I UNSIGNED NOTNULL DEFAULT '0'" ) );
+
?>
diff --git a/bug_report.php b/bug_report.php
index 58588dc..81f7a0f 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_int( 'category_id', 0 );
$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 @@
?>
<p>
<form method="post" action="<?php echo string_get_bug_report_url() ?>">
- <input type="hidden" name="category" value="<?php echo $t_bug_data->category ?>" />
+ <input type="hidden" name="category_id" value="<?php echo $t_bug_data->category_id ?>" />
<input type="hidden" name="severity" value="<?php echo $t_bug_data->severity ?>" />
<input type="hidden" name="reproducibility" value="<?php echo $t_bug_data->reproducibility ?>" />
<input type="hidden" name="profile_id" value="<?php echo $t_bug_data->profile_id ?>" />
diff --git a/bug_report_advanced_page.php b/bug_report_advanced_page.php
index ed694e3..f6d4c8a 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_int( 'category_id', 0 );
$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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
<?php
- if ( is_blank( $f_category ) ) {
+ if ( 0 === $f_category_id ) {
echo '<option value="" selected="selected">', string_attribute( lang_get( 'select_option' ) ), '</option>';
}
- print_category_option_list( $f_category );
+ print_category_option_list( $f_category_id );
?>
</select>
</td>
@@ -555,7 +555,7 @@
<?php if ( ON == config_get( 'use_javascript' ) ) { ?>
<script type="text/javascript" language="JavaScript">
<!--
- window.document.report_bug_form.category.focus();
+ window.document.report_bug_form.category_id.focus();
-->
</script>
<?php } ?>
diff --git a/bug_report_page.php b/bug_report_page.php
index 4446331..7cc53aa 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_int( 'category_id', 0 );
$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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
<?php
- if ( is_blank( $f_category ) ) {
+ if ( 0 === $f_category_id ) {
echo '<option value="" selected="selected">', string_attribute( lang_get( 'select_option' ) ), '</option>';
}
- print_category_option_list( $f_category );
+ print_category_option_list( $f_category_id );
?>
</select>
</td>
@@ -385,7 +385,7 @@
<?php if ( ON == config_get( 'use_javascript' ) ) { ?>
<script type="text/javascript" language="JavaScript">
<!--
- window.document.report_bug_form.category.focus();
+ window.document.report_bug_form.category_id.focus();
-->
</script>
<?php } ?>
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
- <?php print_category_option_list( $t_bug->category, $t_bug->project_id ) ?>
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
+ <?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
</td>
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 @@
<?php if ( $t_changed_project ) {
echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
} ?>
- <select <?php echo helper_get_tab_index() ?> name="category">
- <?php print_category_option_list( $t_bug->category, $t_bug->project_id ) ?>
+ <select <?php echo helper_get_tab_index() ?> name="category_id">
+ <?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
</td>
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 @@
<!-- Category -->
<td>
<?php
- $t_project_name = string_display( project_get_field( $t_bug->project_id, 'name' ) );
- echo "[$t_project_name] $t_bug->category";
+ echo string_display( category_full_name( $t_bug->category_id ) );
?>
</td>
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 @@
<!-- Category -->
<td>
<?php
- $t_project_name = string_display( project_get_field( $t_bug->project_id, 'name' ) );
- echo "[$t_project_name] $t_bug->category";
+ echo string_display( category_full_name( $t_bug->category_id ) );
?>
</td>
diff --git a/config_defaults_inc.php b/config_defaults_inc.php
index d1da3ab..069dd3e 100644
--- a/config_defaults_inc.php
+++ b/config_defaults_inc.php
@@ -684,9 +684,6 @@
# Default bug reproducibility when reporting a new bug
$g_default_bug_reproducibility = REPRODUCIBILITY_HAVENOTTRIED;
- # Default bug category when reporting a new bug
- $g_default_bug_category = '';
-
# --- viewing defaults ------------
# site defaults for viewing preferences
$g_default_limit_view = 50;
@@ -1370,9 +1367,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 082b1d2..5f1a004 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;
@@ -381,7 +381,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 );
@@ -406,11 +406,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 );
@@ -420,7 +415,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
@@ -443,9 +438,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=" . db_param(0) . ' AND id=' . db_param(1);
+ $result = db_query_bound( $query, array( $c_project_id, $c_category_id ) );
if ( db_num_rows( $result ) > 0 ) {
$c_handler_id = $p_handler_id = db_result( $result );
@@ -466,7 +461,7 @@
duplicate_id, priority,
severity, reproducibility,
status, resolution,
- projection, category,
+ projection, category_id,
date_submitted, last_updated,
eta, bug_text_id,
os, os_build,
@@ -481,7 +476,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',
@@ -782,8 +777,8 @@
$query = "SELECT id
FROM $t_bug_table
- WHERE project_id='$c_project_id'";
- $result = db_query( $query );
+ WHERE project_id=" . db_param(0);
+ $result = db_query_bound( $query, array( $c_project_id ) );
$bug_count = db_num_rows( $result );
@@ -845,7 +840,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',
@@ -882,7 +877,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 );
@@ -1457,7 +1452,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_int( $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 );
@@ -1484,7 +1479,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 );
@@ -1508,7 +1503,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..ec0c2c0 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', $c_name );
+ $count = db_result( db_query_bound( $query, array( $c_project_id ) ) );
+
+ 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_id = 0 ) {
+ $c_category_id = db_prepare_int( $p_category_id );
+ $c_new_category_id = db_prepare_int( $p_new_category_id );
- 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_id ) {
+ category_ensure_exists( $p_new_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 = "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_id, $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_id = 0 ) {
$c_project_id = db_prepare_int( $p_project_id );
+ $c_new_category_id = db_prepare_int( $p_new_category_id );
project_ensure_exists( $p_project_id );
+ if ( 0 != $p_new_category_id ) {
+ category_ensure_exists( $p_new_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 = "DELETE FROM $t_project_category_table
+ $query = "DELETE FROM $t_category_table
WHERE project_id=" . db_param(0);
- db_query_bound( $query, Array( $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=" . db_param(0) . '
+ WHERE project_id=' . db_param(1);
+ db_query_bound( $query, array( $c_new_category_id, $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];
+ }
+
+ $c_category_id = db_prepare_int( $p_category_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) . " AND
- category=" . db_param(1);
- $result = db_query_bound( $query, Array( $c_project_id, $c_category ) );
+ $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' );
+
+ $t_project_where = helper_project_specific_where( $c_project_id );
- $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 ) );
+ $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 );
$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 ']</small><br />';
}
- echo string_display( $p_row['category'] );
+ echo string_display( category_full_name( $p_row['category_id'], false ) );
echo '</td>';
}
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 );
?>
- <input type="hidden" name="show_category[]" value="<?php echo string_display( $t_current );?>" />
+ <input type="hidden" name="show_category[]" value="<?php echo $t_current;?>" />
<?php
$t_this_string = '';
- if ( ( ( $t_current == META_FILTER_ANY ) && ( is_numeric( $t_current ) ) )
- || ( is_blank( $t_current ) ) ) {
+ if ( is_blank( $t_current ) || $t_current === "0" || $t_current === META_FILTER_ANY ) {
$t_any_found = true;
} else {
$t_this_string = string_display( $t_current );
@@ -3334,8 +3331,7 @@
<!-- Category -->
<select <?php PRINT $t_select_modifier;?> name="show_category[]">
<option value="<?php echo META_FILTER_ANY ?>" <?php check_selected( $t_filter['show_category'], META_FILTER_ANY ); ?>>[<?php echo lang_get( 'any' ) ?>]</option>
- <?php # This shows orphaned categories as well as selectable categories ?>
- <?php print_category_complete_option_list( $t_filter['show_category'] ) ?>
+ <?php print_category_filter_option_list( $t_filter['show_category'] ) ?>
</select>
<?php
}
diff --git a/core/graph_api.php b/core/graph_api.php
index 2393a11..df60a9a 100644
--- a/core/graph_api.php
+++ b/core/graph_api.php
@@ -591,30 +591,28 @@
global $category_name, $category_bug_count;
$t_project_id = helper_get_current_project();
- $t_cat_table = config_get_global( 'mantis_project_category_table' );
- $t_bug_table = config_get_global( 'mantis_bug_table' );
+ $t_cat_table = config_get( 'mantis_category_table' );
+ $t_bug_table = config_get( 'mantis_bug_table' );
$t_user_id = auth_get_current_user_id();
$specific_where = helper_project_specific_where( $t_project_id, $t_user_id );
- $query = "SELECT DISTINCT category
+ $query = "SELECT id, name
FROM $t_cat_table
WHERE $specific_where
- ORDER BY category";
+ ORDER BY name";
$result = db_query( $query );
$category_count = db_num_rows( $result );
- if ( 0 == $category_count ) {
- return array();
- }
+ $t_metrics = array();
for ($i=0;$i<$category_count;$i++) {
$row = db_fetch_array( $result );
- $t_cat_name = $row['category'];
- $c_category_name = addslashes($t_cat_name);
+ $t_cat_name = $row['name'];
+ $t_cat_id = $row['id'];
$query = "SELECT COUNT(*)
FROM $t_bug_table
- WHERE category='$c_category_name' AND $specific_where";
+ WHERE category_id='$t_cat_id' AND $specific_where";
$result2 = db_query( $query );
- $t_metrics[$t_cat_name] = db_result( $result2, 0, 0 );
+ $t_metrics[$t_cat_name] = $t_metrics[$t_cat_name] + db_result( $result2, 0, 0 );
} # end for
return $t_metrics;
}
diff --git a/core/history_api.php b/core/history_api.php
index 2a6b003..0f51a76 100644
--- a/core/history_api.php
+++ b/core/history_api.php
@@ -216,6 +216,11 @@
case 'category':
$t_field_localized = lang_get( 'category' );
break;
+ case 'category_id':
+ $t_field_localized = lang_get( 'category' );
+ $p_old_value = category_full_name( $p_old_value, false );
+ $p_new_value = category_full_name( $p_new_value, false );
+ break;
case 'status':
$p_old_value = get_enum_element( 'status', $p_old_value );
$p_new_value = get_enum_element( 'status', $p_new_value );
diff --git a/core/my_view_inc.php b/core/my_view_inc.php
index dbc86b3..e46e7ab 100644
--- a/core/my_view_inc.php
+++ b/core/my_view_inc.php
@@ -279,11 +279,10 @@
# type project name if viewing 'all projects' or bug is in subproject
if ( ON == config_get( 'show_bug_project_links' ) &&
helper_get_current_project() != $v_project_id ) {
- echo '[';
- print( $project_name );
- echo '] ';
+ echo string_display( category_full_name( $v_category_id ) );
+ } else {
+ echo string_display( category_full_name( $v_category_id, false ) );
}
- echo string_display( $v_category );
if ( $v_last_updated > strtotime( '-'.$t_filter['highlight_changed'].' hours' ) ) {
echo ' - <b>' . $t_last_updated . '</b>';
diff --git a/core/obsolete.php b/core/obsolete.php
index 30725c2..899ec87 100644
--- a/core/obsolete.php
+++ b/core/obsolete.php
@@ -120,4 +120,6 @@
# changes in 1.1.0rc2
config_obsolete( 'wait_time', 'default_redirect_delay' );
+ config_obsolete( 'default_bug_category' );
+
?>
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</option>";
} # 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 "<option value=\"$t_category\"";
- check_selected( $t_category, $p_category );
- PRINT ">$t_category</option>";
+ foreach( $cat_arr as $t_category_id => $t_name ) {
+ PRINT "<option value=\"$t_category_id\"";
+ check_selected( $p_category_id, $t_category_id );
+ PRINT ">$t_name</option>";
}
}
# --------------------
# 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 "<option value=\"$t_category\"";
- check_selected( $p_category, $t_category );
- PRINT ">$t_category</option>";
+ foreach( $cat_arr as $t_name ) {
+ PRINT "<option value=\"$t_name\"";
+ check_selected( $p_category_name, $t_name );
+ PRINT ">$t_name</option>";
}
}
@@ -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 6241eec..2964af1 100644
--- a/core/summary_api.php
+++ b/core/summary_api.php
@@ -547,6 +547,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' );
@@ -559,15 +560,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 category_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_id, category_name, status
+ ORDER BY $t_project_query category_id, 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;
@@ -580,13 +583,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 = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category );
+ $t_bug_link = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category_id );
if ( 0 < $t_bugs_open ) {
$t_bugs_open = $t_bug_link . '&hide_status=' . RESOLVED . '">' . $t_bugs_open . '</a>';
}
@@ -617,19 +620,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 = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category );
+ $t_bug_link = '<a class="subtle" href="' . config_get( 'bug_count_hyperlink_prefix' ) . '&show_category=' . urlencode( $last_category_id );
if ( !is_blank( $t_bug_link ) ) {
if ( 0 < $t_bugs_open ) {
$t_bugs_open = $t_bug_link . '&hide_status=' . RESOLVED . '">' . $t_bugs_open . '</a>';
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' ) .
- '<br/>' . lang_get( 'category' ) . ': ' . $f_category,
+ '<br/>' . 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..781d938 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 @@
</tr>
<tr <?php echo helper_alternate_class() ?>>
<td class="category">
- <input type="hidden" name="project_id" value="<?php echo string_attribute( $f_project_id ) ?>" />
- <input type="hidden" name="category" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="hidden" name="category_id" value="<?php echo string_attribute( $f_category_id ) ?>" />
<?php echo lang_get( 'category' ) ?>
</td>
<td>
- <input type="text" name="new_category" size="32" maxlength="64" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="text" name="name" size="32" maxlength="128" value="<?php echo string_attribute( $t_name ) ?>" />
</td>
</tr>
<tr <?php echo helper_alternate_class() ?>>
@@ -69,7 +69,7 @@
<td>
<select name="assigned_to">
<option value="0"></option>
- <?php print_assign_to_option_list( $t_assigned_to, $f_project_id ) ?>
+ <?php print_assign_to_option_list( $t_assigned_to, $t_project_id ) ?>
</select>
</td>
</tr>
@@ -89,8 +89,7 @@
<div class="border-center">
<form method="post" action="manage_proj_cat_delete.php">
- <input type="hidden" name="project_id" value="<?php echo string_attribute( $f_project_id ) ?>" />
- <input type="hidden" name="category" value="<?php echo string_attribute( $f_category ) ?>" />
+ <input type="hidden" name="category_id" value="<?php echo string_attribute( $f_category_id ) ?>" />
<input type="submit" class="button" value="<?php echo lang_get( 'delete_category_button' ) ?>" />
</form>
</div>
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..a2270e6 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' ) ) ) { ?>
</td>
<td class="center">
<?php
- $t_name = urlencode( $t_name );
+ $t_id = urlencode( $t_id );
- print_button( 'manage_proj_cat_edit_page.php?project_id=' . $f_project_id . '&category=' . $t_name, lang_get( 'edit_link' ) );
+ print_button( 'manage_proj_cat_edit_page.php?id=' . $t_id, lang_get( 'edit_link' ) );
echo ' ';
- print_button( 'manage_proj_cat_delete.php?project_id=' . $f_project_id . '&category=' . $t_name, lang_get( 'delete_link' ) );
+ print_button( 'manage_proj_cat_delete.php?id=' . $t_id, lang_get( 'delete_link' ) );
?>
</td>
</tr>
@@ -337,7 +338,7 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
<td class="left" colspan="3">
<form method="post" action="manage_proj_cat_add.php">
<input type="hidden" name="project_id" value="<?php echo $f_project_id ?>" />
- <input type="text" name="category" size="32" maxlength="64" />
+ <input type="text" name="name" size="32" maxlength="128" />
<input type="submit" class="button" value="<?php echo lang_get( 'add_category_button' ) ?>" />
</form>
</td>
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 );
mantis-categories.2008-02-04.patch (30,956 bytes)
diff --git a/admin/schema.php b/admin/schema.php
index 6aefc72..c8423ba 100644
--- a/admin/schema.php
+++ b/admin/schema.php
@@ -382,7 +382,7 @@ $upgrade[] = Array( 'CreateTableSQL', Array( db_get_table( 'mantis_category_tabl
$upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_category_project_name', db_get_table( 'mantis_category_table' ), 'project_id, name', array( 'UNIQUE' ) ) );
$upgrade[] = Array( 'InsertData', Array( db_get_table( 'mantis_category_table' ), "
( project_id, user_id, name, status ) VALUES
- ( '0', '0', 'None', '0' ) " ) );
+ ( '0', '0', 'General', '0' ) " ) );
$upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_bug_table' ), "category_id I UNSIGNED NOTNULL DEFAULT '1'" ) );
$upgrade[] = Array( 'UpdateFunction', "category_migrate" );
$upgrade[] = Array( 'DropColumnSQL', Array( db_get_table( 'mantis_bug_table' ), "category" ) );
diff --git a/bug_update_advanced_page.php b/bug_update_advanced_page.php
index 03ed16d..8f7768f 100644
--- a/bug_update_advanced_page.php
+++ b/bug_update_advanced_page.php
@@ -115,9 +115,6 @@
<!-- Category -->
<td>
- <?php if ( $t_changed_project ) {
- echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
- } ?>
<select <?php echo helper_get_tab_index() ?> name="category_id">
<?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
diff --git a/bug_update_page.php b/bug_update_page.php
index 151b1bc..abf3501 100644
--- a/bug_update_page.php
+++ b/bug_update_page.php
@@ -118,9 +118,6 @@
<!-- Category -->
<td>
- <?php if ( $t_changed_project ) {
- echo "[" . project_get_field( $t_bug->project_id, 'name' ) . "] ";
- } ?>
<select <?php echo helper_get_tab_index() ?> name="category_id">
<?php print_category_option_list( $t_bug->category_id, $t_bug->project_id ) ?>
</select>
diff --git a/core/category_api.php b/core/category_api.php
index cabde42..a768fae 100644
--- a/core/category_api.php
+++ b/core/category_api.php
@@ -149,7 +149,7 @@
# --------------------
# Remove a category from the project
- function category_remove( $p_category_id, $p_new_category_id = 1 ) {
+ function category_remove( $p_category_id, $p_new_category_id = 0 ) {
$t_category_row = category_get_row( $p_category_id );
$c_category_id = db_prepare_int( $p_category_id );
@@ -172,7 +172,6 @@
$t_result = db_query_bound( $query, array( $c_category_id ) );
while ( $t_bug_row = db_fetch_array( $t_result ) ) {
- var_dump( $t_bug_row );
history_log_event_direct( $t_bug_row['id'], 'category', $t_category_row['name'], category_full_name( $p_new_category_id, false ) );
}
@@ -188,7 +187,7 @@
# --------------------
# Remove all categories associated with a project
- function category_remove_all( $p_project_id, $p_new_category_id = 1 ) {
+ function category_remove_all( $p_project_id, $p_new_category_id = 0 ) {
$c_project_id = db_prepare_int( $p_project_id );
$c_new_category_id = db_prepare_int( $p_new_category_id );
@@ -258,19 +257,55 @@
}
# --------------------
- # Return all categories for the specified project id
- function category_get_all_rows( $p_project_id ) {
+ # Sort categories based on what project they're in.
+ # Call beforehand with a single parameter to set a 'preferred' project.
+ function category_sort_rows_by_project( $p_category1, $p_category2=null ) {
+ static $p_project_id=null;
+ if ( is_null( $p_category2 ) ) { # Set a target project
+ $p_project_id = $p_category1;
+ return;
+ }
+
+ if ( !is_null( $p_project_id ) ) {
+ if ( $p_category1['project_id'] == $p_project_id &&
+ $p_category2['project_id'] != $p_project_id ) {
+ return -1;
+ }
+ if ( $p_category1['project_id'] != $p_project_id &&
+ $p_category2['project_id'] == $p_project_id ) {
+ return 1;
+ }
+ }
+
+ $t_proj_cmp = strcasecmp( $p_category1['project_name'], $p_category2['project_name'] );
+ if ( $t_proj_cmp != 0 ) {
+ return $t_proj_cmp;
+ }
+
+ return strcasecmp( $p_category1['name'], $p_category2['name'] );
+ }
+ # --------------------
+ # Return all categories for the specified project id.
+ # Obeys project hierarchies and such.
+ function category_get_all_rows( $p_project_id, $p_inherit=true, $p_sort_by_project=false ) {
global $g_category_cache;
+ project_hierarchy_cache();
+
$c_project_id = db_prepare_int( $p_project_id );
$t_category_table = db_get_table( 'mantis_category_table' );
$t_project_table = db_get_table( 'mantis_project_table' );
- $t_project_where = helper_project_specific_where( $c_project_id );
+ if ( $p_inherit ) {
+ $t_project_ids = project_hierarchy_inheritance( $p_project_id );
+ $t_project_where = ' project_id IN ( ' . implode( ', ', $t_project_ids ) . ' ) ';
+ } else {
+ $t_project_where = ' project_id=' . $p_project_id . ' ';
+ }
$query = "SELECT c.*, p.name AS project_name FROM $t_category_table AS c
- JOIN $t_project_table AS p
+ LEFT JOIN $t_project_table AS p
ON c.project_id=p.id
WHERE $t_project_where
ORDER BY c.name ";
@@ -284,6 +319,12 @@
$g_category_cache[$row['id']] = $row;
}
+ if ( $p_sort_by_project ) {
+ category_sort_rows_by_project( $p_project_id );
+ usort( $rows, 'category_sort_rows_by_project' );
+ category_sort_rows_by_project( null );
+ }
+
return $rows;
}
@@ -311,7 +352,7 @@
$t_row = category_get_row( $p_category_id );
$t_project_id = $t_row['project_id'];
- if ( $p_show_project && ALL_PROJECTS != $t_project_id ) {
+ if ( $p_show_project ) {
return '[' . project_get_name( $t_project_id ) . '] ' . $t_row['name'];
}
diff --git a/core/print_api.php b/core/print_api.php
index 536a644..894e9c4 100644
--- a/core/print_api.php
+++ b/core/print_api.php
@@ -696,29 +696,17 @@
$t_project_table = db_get_table( 'mantis_project_table' );
if ( null === $p_project_id ) {
- $c_project_id = helper_get_current_project();
+ $t_project_id = helper_get_current_project();
} else {
- $c_project_id = db_prepare_int( $p_project_id );
+ $t_project_id = $p_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 id,name FROM $t_category_table
- WHERE $t_project_where
- ORDER BY name";
- $result = db_query( $query );
-
- while ( $row = db_fetch_array( $result ) ) {
- $cat_arr[$row['id']] = $row['name'];
- }
- asort($cat_arr);
+ $cat_arr = category_get_all_rows( $t_project_id, true, !is_null( $p_project_id ) );
- foreach( $cat_arr as $t_category_id => $t_name ) {
- PRINT "<option value=\"$t_category_id\"";
- check_selected( $p_category_id, $t_category_id );
- PRINT ">$t_name</option>";
+ foreach( $cat_arr as $t_category_row ) {
+ $t_category_id = $t_category_row['id'];
+ echo "<option value=\"$t_category_id\"", check_selected( $p_category_id, $t_category_id ), '>';
+ echo category_full_name( $t_category_id, $t_category_row['project_id'] != $p_project_id ), '</option>';
}
}
# --------------------
@@ -742,7 +730,16 @@
$c_project_id = db_prepare_int( $p_project_id );
}
- $t_project_where = helper_project_specific_where( $c_project_id );
+ project_hierarchy_cache();
+ $t_project_ids = project_hierarchy_inheritance( $c_project_id );
+
+ $t_subproject_ids = array();
+ foreach ( $t_project_ids as $t_project_id ) {
+ $t_subproject_ids = array_merge( $t_subproject_ids, current_user_get_all_accessible_subprojects( $t_project_id ) );
+ }
+
+ $t_project_ids = array_merge( $t_project_ids, $t_subproject_ids );
+ $t_project_where = ' project_id IN ( ' . implode( ', ', $t_project_ids ) . ' ) ';
# grab all categories in the project category table
$cat_arr = array();
diff --git a/core/project_api.php b/core/project_api.php
index 66476a8..194ee44 100644
--- a/core/project_api.php
+++ b/core/project_api.php
@@ -211,7 +211,7 @@
# --------------------
# Create a new project
- function project_create( $p_name, $p_description, $p_status, $p_view_state = VS_PUBLIC, $p_file_path = '', $p_enabled = true ) {
+ function project_create( $p_name, $p_description, $p_status, $p_view_state = VS_PUBLIC, $p_file_path = '', $p_enabled = true, $p_inherit_global = true ) {
# Make sure file path has trailing slash
$p_file_path = terminate_directory_path( $p_file_path );
@@ -221,6 +221,7 @@
$c_view_state = db_prepare_int( $p_view_state );
$c_file_path = db_prepare_string( $p_file_path );
$c_enabled = db_prepare_bool( $p_enabled );
+ $c_inherit_global = db_prepare_bool( $p_inherit_global );
if ( is_blank( $p_name ) ) {
trigger_error( ERROR_PROJECT_NAME_INVALID, ERROR );
@@ -235,9 +236,9 @@
$t_project_table = db_get_table( 'mantis_project_table' );
$query = "INSERT INTO $t_project_table
- ( name, status, enabled, view_state, file_path, description )
+ ( name, status, enabled, view_state, file_path, description, inherit_global )
VALUES
- ( '$c_name', '$c_status', '$c_enabled', '$c_view_state', '$c_file_path', '$c_description' )";
+ ( '$c_name', '$c_status', '$c_enabled', '$c_view_state', '$c_file_path', '$c_description', '$c_inherit_global' )";
db_query( $query );
@@ -302,7 +303,7 @@
# --------------------
# Update a project
- function project_update( $p_project_id, $p_name, $p_description, $p_status, $p_view_state, $p_file_path, $p_enabled ) {
+ function project_update( $p_project_id, $p_name, $p_description, $p_status, $p_view_state, $p_file_path, $p_enabled, $p_inherit_global ) {
# Make sure file path has trailing slash
$p_file_path = terminate_directory_path( $p_file_path );
@@ -313,6 +314,7 @@
$c_view_state = db_prepare_int( $p_view_state );
$c_file_path = db_prepare_string( $p_file_path );
$c_enabled = db_prepare_bool( $p_enabled );
+ $c_inherit_global = db_prepare_bool( $p_inherit_global );
if ( is_blank( $p_name ) ) {
trigger_error( ERROR_PROJECT_NAME_INVALID, ERROR );
@@ -336,7 +338,8 @@
enabled='$c_enabled',
view_state='$c_view_state',
file_path='$c_file_path',
- description='$c_description'
+ description='$c_description',
+ inherit_global='$c_inherit_global'
WHERE id='$c_project_id'";
db_query( $query );
diff --git a/core/project_hierarchy_api.php b/core/project_hierarchy_api.php
index accb345..1be60ac 100644
--- a/core/project_hierarchy_api.php
+++ b/core/project_hierarchy_api.php
@@ -26,7 +26,7 @@
$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
# --------------------
- function project_hierarchy_add( $p_child_id, $p_parent_id ) {
+ function project_hierarchy_add( $p_child_id, $p_parent_id, $p_inherit_parent = true ) {
if ( in_array( $p_parent_id, project_hierarchy_get_all_subprojects( $p_child_id ) ) ) {
trigger_error( ERROR_PROJECT_RECURSIVE_HIERARCHY, ERROR );
}
@@ -35,13 +35,28 @@
$c_child_id = db_prepare_int( $p_child_id );
$c_parent_id = db_prepare_int( $p_parent_id );
+ $c_inherit_parent = db_prepare_bool( $p_inherit_parent );
$query = "INSERT INTO $t_project_hierarchy_table
- ( child_id, parent_id )
+ ( child_id, parent_id, inherit_parent )
VALUES
- ( " . db_param(0) . ", " . db_param(1) . " )";
+ ( " . db_param(0) . ', ' . db_param(1) . ', ' . db_param(2) . ' )';
- db_query_bound($query, Array( $c_child_id, $c_parent_id ) );
+ db_query_bound($query, Array( $c_child_id, $c_parent_id, $c_inherit_parent ) );
+ }
+
+ function project_hierarchy_update( $p_child_id, $p_parent_id, $p_inherit_parent = true ) {
+ $t_project_hierarchy_table = db_get_table( 'mantis_project_hierarchy_table' );
+
+ $c_child_id = db_prepare_int( $p_child_id );
+ $c_parent_id = db_prepare_int( $p_parent_id );
+ $c_inherit_parent = db_prepare_bool( $p_inherit_parent );
+
+ $query = "UPDATE $t_project_hierarchy_table
+ SET inherit_parent=" . db_param(0) . '
+ WHERE child_id=' . db_param(1) . '
+ AND parent_id=' . db_param(2);
+ db_query_bound( $query, Array( $c_inherit_parent, $c_child_id, $c_parent_id ) );
}
# --------------------
@@ -87,16 +102,21 @@
}
$g_cache_project_hierarchy = null;
+ $g_cache_project_inheritance = null;
# --------------------
function project_hierarchy_cache( $p_show_disabled = false ) {
- global $g_cache_project_hierarchy;
+ global $g_cache_project_hierarchy, $g_cache_project_inheritance;
+
+ if ( !is_null( $g_cache_project_hierarchy ) ) {
+ return;
+ }
$t_project_table = db_get_table( 'mantis_project_table' );
$t_project_hierarchy_table = db_get_table( 'mantis_project_hierarchy_table' );
$t_enabled_clause = $p_show_disabled ? '1=1' : 'p.enabled = ' . db_param(0);
- $query = "SELECT DISTINCT p.id, ph.parent_id, p.name
+ $query = "SELECT DISTINCT p.id, ph.parent_id, p.name, p.inherit_global, ph.inherit_parent
FROM $t_project_table p
LEFT JOIN $t_project_hierarchy_table ph
ON ph.child_id = p.id
@@ -107,6 +127,7 @@
$row_count = db_num_rows( $result );
$g_cache_project_hierarchy = array();
+ $g_cache_project_inheritance = array();
for ( $i=0 ; $i < $row_count ; $i++ ){
$row = db_fetch_array( $result );
@@ -120,9 +141,57 @@
} else {
$g_cache_project_hierarchy[ $row['parent_id'] ] = array( $row['id'] );
}
+
+ if ( !isset( $g_cache_project_inheritance[ $row['id'] ] ) ) {
+ $g_cache_project_inheritance[ $row['id'] ] = array();
+ }
+
+ if ( $row['inherit_global'] && !isset( $g_cache_project_inheritance[ $row['id'] ][ ALL_PROJECTS ] ) ) {
+ $g_cache_project_inheritance[ $row['id'] ][] = ALL_PROJECTS;
+ }
+ if ( $row['inherit_parent'] && !isset( $g_cache_project_inheritance[ $row['id'] ][ $row['parent_id'] ] ) ) {
+ $g_cache_project_inheritance[ $row['id'] ][] = (int)$row['parent_id'];
+ }
}
}
+ # --------------------
+ # Returns true if the child project inherits categories from the parent.
+ function project_hierarchy_inherit_parent( $p_child_id, $p_parent_id ) {
+ global $g_cache_project_inheritance;
+
+ return in_array( $p_parent_id, $g_cache_project_inheritance[ $p_child_id ] );
+ }
+
+ # --------------------
+ # Generate an array of project's the given project inherits from,
+ # including the original project in the result.
+ function project_hierarchy_inheritance( $p_project_id ) {
+ global $g_cache_project_inheritance;
+
+ $t_project_ids = array( (int)$p_project_id );
+ $t_lookup_ids = array( (int)$p_project_id );
+
+ while( count( $t_lookup_ids ) > 0 ) {
+ $t_project_id = array_shift( $t_lookup_ids );
+
+ if ( !isset( $g_cache_project_inheritance[ $t_project_id ] ) ) {
+ continue;
+ }
+
+ foreach( $g_cache_project_inheritance[ $t_project_id ] as $t_parent_id ) {
+ if ( !in_array( $t_parent_id, $t_project_ids ) ) {
+ $t_project_ids[] = $t_parent_id;
+
+ if ( !in_array( $t_lookup_ids, $t_project_ids ) ) {
+ $t_lookup_ids[] = $t_parent_id;
+ }
+ }
+ }
+ }
+
+ return $t_project_ids;
+ }
# --------------------
function project_hierarchy_get_subprojects( $p_project_id, $p_show_disabled = false ) {
diff --git a/lang/strings_english.txt b/lang/strings_english.txt
index 5c1a2dc..f791f53 100644
--- a/lang/strings_english.txt
+++ b/lang/strings_english.txt
@@ -99,7 +99,13 @@ $s_empty_password_sure_msg = 'The user has an empty password. Are you sure that
$s_empty_password_button = 'Use Empty Password';
$s_reauthenticate_title = 'Authenticate';
$s_reauthenticate_message = 'You are visting a secure page, and your secure session has expired. Please authenticate yourself to continue.';
+
$s_no_category = 'No Category';
+$s_global_categories = 'Global Categories';
+$s_inherit = 'Inherit Categories';
+$s_inherit_global = 'Inherit Global Categories';
+$s_inherit_parent = 'Inherit Parent Categories';
+$s_update_subproject_inheritance = 'Update Subproject Inheritance';
$s_duplicate_of = "duplicate of";
$s_has_duplicate = "has duplicate";
diff --git a/manage_proj_cat_add.php b/manage_proj_cat_add.php
index 9675b08..92764b8 100644
--- a/manage_proj_cat_add.php
+++ b/manage_proj_cat_add.php
@@ -59,7 +59,11 @@
}
}
- $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id;
+ if ( $f_project_id == ALL_PROJECTS ) {
+ $t_redirect_url = 'manage_proj_page.php';
+ } else {
+ $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id;
+ }
print_header_redirect( $t_redirect_url );
?>
diff --git a/manage_proj_cat_copy.php b/manage_proj_cat_copy.php
index f205c71..43e6b9f 100644
--- a/manage_proj_cat_copy.php
+++ b/manage_proj_cat_copy.php
@@ -57,5 +57,11 @@
}
}
- print_header_redirect( 'manage_proj_edit_page.php?project_id=' . $f_project_id );
+ if ( $f_project_id == ALL_PROJECTS ) {
+ $t_redirect_url = 'manage_proj_page.php';
+ } else {
+ $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id;
+ }
+
+ print_header_redirect( $t_redirect_url );
?>
diff --git a/manage_proj_cat_delete.php b/manage_proj_cat_delete.php
index 934e7bf..971b8cd 100644
--- a/manage_proj_cat_delete.php
+++ b/manage_proj_cat_delete.php
@@ -30,6 +30,7 @@
auth_reauthenticate();
$f_category_id = gpc_get_string( 'id' );
+ $f_project_id = gpc_get_int( 'project_id' );
access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id );
@@ -44,7 +45,11 @@
category_remove( $f_category_id );
- $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $t_project_id;
+ if ( $f_project_id == ALL_PROJECTS ) {
+ $t_redirect_url = 'manage_proj_page.php';
+ } else {
+ $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_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 781d938..2491518 100644
--- a/manage_proj_cat_edit_page.php
+++ b/manage_proj_cat_edit_page.php
@@ -30,6 +30,7 @@
auth_reauthenticate();
$f_category_id = gpc_get_string( 'id' );
+ $f_project_id = gpc_get_string( 'project_id' );
access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id );
diff --git a/manage_proj_cat_update.php b/manage_proj_cat_update.php
index 98610e8..7c736f4 100644
--- a/manage_proj_cat_update.php
+++ b/manage_proj_cat_update.php
@@ -30,6 +30,7 @@
auth_reauthenticate();
$f_category_id = gpc_get_int( 'category_id' );
+ $f_project_id = gpc_get_int( 'project_id' );
$f_name = trim( gpc_get_string( 'name' ) );
$f_assigned_to = gpc_get_int( 'assigned_to', 0 );
@@ -50,7 +51,11 @@
category_update( $f_category_id, $f_name, $f_assigned_to );
- $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $t_project_id;
+ if ( $f_project_id == ALL_PROJECTS ) {
+ $t_redirect_url = 'manage_proj_page.php';
+ } else {
+ $t_redirect_url = 'manage_proj_edit_page.php?project_id=' . $f_project_id;
+ }
html_page_top1();
diff --git a/manage_proj_create.php b/manage_proj_create.php
index 3dcd7a4..9d7d87b 100644
--- a/manage_proj_create.php
+++ b/manage_proj_create.php
@@ -36,8 +36,10 @@
$f_view_state = gpc_get_int( 'view_state' );
$f_status = gpc_get_int( 'status' );
$f_file_path = gpc_get_string( 'file_path', '' );
+ $f_inherit_global = gpc_get_bool( 'inherit_global', 1 );
+ $f_inherit_parent = gpc_get_bool( 'inherit_parent', 1 );
- $t_project_id = project_create( strip_tags( $f_name ), $f_description, $f_status, $f_view_state, $f_file_path );
+ $t_project_id = project_create( strip_tags( $f_name ), $f_description, $f_status, $f_view_state, $f_file_path, true, $f_inherit_global );
if ( ( $f_view_state == VS_PRIVATE ) && ( false === current_user_is_administrator() ) ) {
$t_access_level = access_get_global_level();
@@ -48,7 +50,7 @@
$f_parent_id = gpc_get_int( 'parent_id', 0 );
if ( 0 != $f_parent_id ) {
- project_hierarchy_add( $t_project_id, $f_parent_id );
+ project_hierarchy_add( $t_project_id, $f_parent_id, $f_inherit_parent );
}
$t_redirect_url = 'manage_proj_page.php';
diff --git a/manage_proj_create_page.php b/manage_proj_create_page.php
index bf6f7c2..6714c0c 100644
--- a/manage_proj_create_page.php
+++ b/manage_proj_create_page.php
@@ -84,6 +84,24 @@
</select>
</td>
</tr>
+<tr class="row-2">
+ <td class="category">
+ <?php echo lang_get( 'inherit_global' ) ?>
+ </td>
+ <td>
+ <input type="checkbox" name="inherit_global" checked="checked" />
+ </td>
+</tr>
+<?php if ( !is_null( $f_parent_id ) ) { ?>
+<tr class="row-1">
+ <td class="category">
+ <?php echo lang_get( 'inherit_parent' ) ?>
+ </td>
+ <td>
+ <input type="checkbox" name="inherit_parent" checked="checked" />
+ </td>
+</tr>
+<?php } ?>
<?php
if ( config_get( 'allow_file_upload' ) ) {
?>
diff --git a/manage_proj_edit_page.php b/manage_proj_edit_page.php
index 5292cdd..c819219 100644
--- a/manage_proj_edit_page.php
+++ b/manage_proj_edit_page.php
@@ -95,6 +95,16 @@
</td>
</tr>
+<!-- Category Inheritance -->
+<tr <?php echo helper_alternate_class() ?>>
+ <td class="category">
+ <?php echo lang_get( 'inherit_global' ) ?>
+ </td>
+ <td>
+ <input type="checkbox" name="inherit_global" <?php check_checked( $row['inherit_global'], ON ); ?> />
+ </td>
+</tr>
+
<!-- View Status (public/private) -->
<tr <?php echo helper_alternate_class() ?>>
<td class="category">
@@ -179,7 +189,10 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
</tr>
<!-- Subprojects -->
+<form name="update_children_form" action="manage_proj_update_children.php" method="post">
+<input type="hidden" name="project_id" value="<?php echo $f_project_id ?>" />
<?php
+ project_hierarchy_cache();
$t_subproject_ids = current_user_get_accessible_subprojects( $f_project_id, /* show_disabled */ true );
if ( Array() != $t_subproject_ids ) {
@@ -195,9 +208,12 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
<?php echo lang_get( 'enabled' ) ?>
</td>
<td width="10%">
+ <?php echo lang_get( 'inherit' ) ?>
+ </td>
+ <td width="10%">
<?php echo lang_get( 'view_status' ) ?>
</td>
- <td width="30%">
+ <td width="20%">
<?php echo lang_get( 'description' ) ?>
</td>
<td width="20%">
@@ -208,18 +224,22 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
<?php
foreach ( $t_subproject_ids as $t_subproject_id ) {
$t_subproject = project_get_row( $t_subproject_id );
+ $t_inherit_parent = project_hierarchy_inherit_parent( $t_subproject_id, $f_project_id );
?>
<tr <?php echo helper_alternate_class() ?>>
<td>
<a href="manage_proj_edit_page.php?project_id=<?php echo $t_subproject['id'] ?>"><?php echo string_display( $t_subproject['name'] ) ?></a>
</td>
- <td>
+ <td class="center">
<?php echo get_enum_element( 'project_status', $t_subproject['status'] ) ?>
</td>
- <td>
+ <td class="center">
<?php echo trans_bool( $t_subproject['enabled'] ) ?>
</td>
- <td>
+ <td class="center">
+ <input type="checkbox" name="inherit_child_<?php echo $t_subproject_id ?>" <?php echo ( $t_inherit_parent ? 'checked="checked"' : '' ) ?> />
+ </td>
+ <td class="center">
<?php echo get_enum_element( 'project_view_state', $t_subproject['view_state'] ) ?>
</td>
<td>
@@ -227,9 +247,8 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
</td>
<td class="center">
<?php
- print_button( 'manage_proj_edit_page.php?project_id=' . $t_subproject['id'], lang_get( 'edit_link' ) );
- echo ' ';
- print_button( 'manage_proj_subproj_delete.php?project_id=' . $f_project_id . '&subproject_id=' . $t_subproject['id'], lang_get( 'unlink_link' ) );
+ print_bracket_link( 'manage_proj_edit_page.php?project_id=' . $t_subproject['id'], lang_get( 'edit_link' ) );
+ print_bracket_link( 'manage_proj_subproj_delete.php?project_id=' . $f_project_id . '&subproject_id=' . $t_subproject['id'], lang_get( 'unlink_link' ) );
?>
</td>
</tr>
@@ -238,9 +257,16 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
} # End of hiding subproject listing if there are no subprojects
?>
+<tr>
+ <td colspan="6">
+ <input type="submit" value="<?php echo lang_get( 'update_subproject_inheritance' ) ?>" />
+ </form>
+ </td>
+</tr>
+
<!-- Add subproject -->
<tr>
- <td class="left" colspan="2">
+ <td colspan="7">
<form method="post" action="manage_proj_subproj_add.php">
<input type="hidden" name="project_id" value="<?php echo $f_project_id ?>" />
<select name="subproject_id">
@@ -307,8 +333,14 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
foreach ( $t_categories as $t_category ) {
$t_id = $t_category['id'];
- $t_name = $t_category['name'];
+ if ( $t_category['project_id'] != $f_project_id ) {
+ $t_inherited = true;
+ } else {
+ $t_inherited = false;
+ }
+
+ $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'] );
} else {
@@ -318,19 +350,20 @@ if ( access_has_global_level ( config_get( 'delete_project_threshold' ) ) ) { ?>
<!-- Repeated Info Row -->
<tr <?php echo helper_alternate_class() ?>>
<td>
- <?php echo string_display( $t_name ) ?>
+ <?php echo string_display( category_full_name( $t_category['id'] , $t_inherited ) ) ?>
</td>
<td>
<?php echo $t_user_name ?>
</td>
<td class="center">
- <?php
+ <?php if ( !$t_inherited ) {
$t_id = urlencode( $t_id );
+ $t_project_id = urlencode( $f_project_id );
- print_button( 'manage_proj_cat_edit_page.php?id=' . $t_id, lang_get( 'edit_link' ) );
+ print_button( 'manage_proj_cat_edit_page.php?id=' . $t_id . '&project_id=' . $t_project_id, lang_get( 'edit_link' ) );
echo ' ';
- print_button( 'manage_proj_cat_delete.php?id=' . $t_id, lang_get( 'delete_link' ) );
- ?>
+ print_button( 'manage_proj_cat_delete.php?id=' . $t_id . '&project_id=' . $t_project_id, lang_get( 'delete_link' ) );
+ } ?>
</td>
</tr>
<?php
diff --git a/manage_proj_page.php b/manage_proj_page.php
index c0b1b25..fe004b8 100644
--- a/manage_proj_page.php
+++ b/manage_proj_page.php
@@ -140,5 +140,83 @@
}
?>
</table>
+<br/>
+
+<!-- GLOBAL CATEGORIES -->
+<a name="categories" />
+<div align="center">
+<table class="width75" cellspacing="1">
+
+<!-- Title -->
+<tr>
+ <td class="form-title" colspan="3">
+ <?php echo lang_get( 'global_categories' ) ?>
+ </td>
+</tr>
+<?php
+ $t_categories = category_get_all_rows( ALL_PROJECTS, false );
+
+ if ( count( $t_categories ) > 0 ) {
+?>
+ <tr class="row-category">
+ <td>
+ <?php echo lang_get( 'category' ) ?>
+ </td>
+ <td>
+ <?php echo lang_get( 'assign_to' ) ?>
+ </td>
+ <td class="center">
+ <?php echo lang_get( 'actions' ) ?>
+ </td>
+ </tr>
+<?php
+ }
+
+ foreach ( $t_categories as $t_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'] );
+ } else {
+ $t_user_name = '';
+ }
+?>
+<!-- Repeated Info Row -->
+ <tr <?php echo helper_alternate_class() ?>>
+ <td>
+ <?php echo string_display( category_full_name( $t_category['id'], false ) ) ?>
+ </td>
+ <td>
+ <?php echo $t_user_name ?>
+ </td>
+ <td class="center">
+ <?php
+ $t_id = urlencode( $t_id );
+ $t_project_id = urlencode( ALL_PROJECTS );
+
+ print_button( 'manage_proj_cat_edit_page.php?id=' . $t_id . '&project_id=' . $t_project_id, lang_get( 'edit_link' ) );
+ echo ' ';
+ print_button( 'manage_proj_cat_delete.php?id=' . $t_id . '&project_id=' . $t_project_id, lang_get( 'delete_link' ) );
+ ?>
+ </td>
+ </tr>
+<?php
+ } # end for loop
+?>
+
+<!-- Add Category Form -->
+<tr>
+ <td class="left" colspan="3">
+ <form method="post" action="manage_proj_cat_add.php">
+ <input type="hidden" name="project_id" value="<?php echo ALL_PROJECTS ?>" />
+ <input type="text" name="name" size="32" maxlength="128" />
+ <input type="submit" class="button" value="<?php echo lang_get( 'add_category_button' ) ?>" />
+ </form>
+ </td>
+</tr>
+
+</table>
+</div>
<?php html_page_bottom1( __FILE__ ) ?>
diff --git a/manage_proj_update.php b/manage_proj_update.php
index 2ddbdd2..3cbd2e6 100644
--- a/manage_proj_update.php
+++ b/manage_proj_update.php
@@ -32,10 +32,11 @@
$f_view_state = gpc_get_int( 'view_state' );
$f_file_path = gpc_get_string( 'file_path', '' );
$f_enabled = gpc_get_bool( 'enabled' );
+ $f_inherit_global = gpc_get_bool( 'inherit_global', 1 );
access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id );
- project_update( $f_project_id, $f_name, $f_description, $f_status, $f_view_state, $f_file_path, $f_enabled );
+ project_update( $f_project_id, $f_name, $f_description, $f_status, $f_view_state, $f_file_path, $f_enabled, $f_inherit_global );
print_header_redirect( 'manage_proj_page.php' );
?>
diff --git a/manage_proj_update_children.php b/manage_proj_update_children.php
new file mode 100644
index 0000000..3a7cbe6
--- /dev/null
+++ b/manage_proj_update_children.php
@@ -0,0 +1,39 @@
+<?php
+# Mantis - a php based bugtracking system
+
+# Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
+# Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net
+
+# Mantis 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, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Mantis 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 Mantis. If not, see <http://www.gnu.org/licenses/>.
+
+ require_once( 'core.php' );
+
+ $t_core_path = config_get( 'core_path' );
+
+ require_once( $t_core_path.'project_hierarchy_api.php' );
+
+ auth_reauthenticate();
+
+ $f_project_id = gpc_get_int( 'project_id' );
+
+ access_ensure_project_level( config_get( 'manage_project_threshold' ), $f_project_id );
+
+ $t_subproject_ids = current_user_get_accessible_subprojects( $f_project_id, true );
+ foreach ( $t_subproject_ids as $t_subproject_id ) {
+ $f_inherit_child = gpc_get_bool( 'inherit_child_' . $t_subproject_id, false );
+ var_dump( $t_subproject_id, $f_project_id, $f_inherit_child );
+ project_hierarchy_update( $t_subproject_id, $f_project_id, $f_inherit_child );
+ }
+
+ print_successful_redirect( 'manage_proj_edit_page.php?project_id=' . $f_project_id );
| ||||
| parent of | 0008771 | closed | jreese | Port 0008738: Allow bugs to have no category |
| has duplicate | 0006048 | closed | jreese | mantis_bug_table: 'category' field should have ID of a category |
| has duplicate | 0007841 | closed | jreese | Categories for subproject |
| has duplicate | 0006039 | closed | giallu | global categories |
| related to | 0000946 | closed | jreese | Implementation of sub-categories |
| related to | 0003370 | closed | jreese | No category filter in "View Bugs" view, when in "All Projects" mode |
| related to | 0008582 | assigned | dregad | Default Category for Project / Global default Category |
|
I've attached a patch containing the first step in this process. The patch includes:
This patch will require you to upgrade your database to work properly. Make sure you backup data before upgrading so that you can revert when you are done testing. |
|
|
Partial Review: install_category_migrate()
schema.php
Configuration
bug_report_page.php
bug_api.php
category_api.php
strings_english.txt stopped @ filter_api.php |
|
|
Latest patch attached with changes suggested by Victor: category_migrate()
schema.php
config
bug_report_page.php
bug_api.php
category_api.php
other
|
|
|
New version of today's patch uploaded with numerous fixes suggested by Paul and others. Same name, more fixes. |
|
|
Patch mantis-categories.2008-02-04.patch attached. I've finalized my work and completed implementation of global and inheriting categories. This is a feature-complete patch, but I would like the eyes of everyone to make sure I'm not making any dumb mistakes. Cheers |
|
|
Fixed in trunk 1.2.x r5032. |
|
|
MantisBT: master 829889da 2007-11-19 20:09 Details Diff |
First phase of bug 0008435: Implement Global and Inheriting Categories Structure. Implemented category ID behaviors to replicate all existing functionality. git-svn-id: http://mantisbt.svn.sourceforge.net/svnroot/mantisbt/trunk@4770 <a class="text" href="/?p=mantisbt.git;a=object;h=f5dc347c">f5dc347c</a>-c33d-0410-90a0-b07cc1902cb9 |
Affected Issues 0008435 |
|
| mod - bug_update_advanced_page.php | Diff File | ||
| mod - bug_update_page.php | Diff File | ||
| mod - core/print_api.php | Diff File | ||
| mod - core/filter_api.php | Diff File | ||
| mod - bug_update.php | Diff File | ||
| mod - core/category_api.php | Diff File | ||
| mod - manage_proj_cat_edit_page.php | Diff File | ||
| mod - bug_report_page.php | Diff File | ||
| mod - view_all_inc.php | Diff File | ||
| mod - bug_report.php | Diff File | ||
| mod - config_defaults_inc.php | Diff File | ||
| mod - core/obsolete.php | Diff File | ||
| mod - graphs/graph_by_category.php | Diff File | ||
| mod - core/columns_api.php | Diff File | ||
| add - admin/install_functions.php | Diff File | ||
| mod - admin/schema.php | Diff File | ||
| mod - manage_proj_cat_delete.php | Diff File | ||
| mod - manage_proj_cat_add.php | Diff File | ||
| mod - manage_proj_cat_update.php | Diff File | ||
| mod - core/summary_api.php | Diff File | ||
| mod - manage_proj_edit_page.php | Diff File | ||
| mod - admin/install.php | Diff File | ||
| mod - core/bug_api.php | Diff File | ||
| mod - core/graph_api.php | Diff File | ||
| mod - bug_view_page.php | Diff File | ||
| mod - bug_view_advanced_page.php | Diff File | ||
| mod - my_view_page.php | Diff File | ||
| mod - core/my_view_inc.php | Diff File | ||
| mod - manage_proj_cat_copy.php | Diff File | ||
| mod - bug_report_advanced_page.php | Diff File | ||
related to
child of
duplicate of