diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/admin/schema.php mantis-tagging/admin/schema.php
--- mantis-cvs/admin/schema.php 2007-08-07 10:54:56.000000000 -0400
+++ mantis-tagging/admin/schema.php 2007-08-17 15:19:22.000000000 -0400
@@ -330,6 +330,21 @@
$upgrade[] = Array('CreateIndexSQL',Array('idx_diskfile',config_get('mantis_bug_file_table'),'diskfile'));
$upgrade[] = Array('AlterColumnSQL', Array( config_get( 'mantis_user_print_pref_table' ), "print_pref C(64) NOTNULL" ) );
$upgrade[] = Array('AlterColumnSQL', Array( config_get( 'mantis_bug_history_table' ), "field_name C(64) NOTNULL" ) );
+$upgrade[] = Array('CreateTableSQL', Array( config_get( 'mantis_tag_table' ), "
+ id I UNSIGNED NOTNULL PRIMARY AUTOINCREMENT,
+ user_id I UNSIGNED NOTNULL DEFAULT '0',
+ name C(100) NOTNULL DEFAULT \" '' \",
+ description XL NOTNULL,
+ date_created T NOTNULL DEFAULT '1970-01-01 00:00:01',
+ date_updated T NOTNULL DEFAULT '1970-01-01 00:00:01'
+ ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) );
+$upgrade[] = Array('CreateIndexSQL', Array( 'idx_tag_name', config_get( 'mantis_tag_table' ), 'name', Array( 'UNIQUE' ) ) );
+$upgrade[] = Array('CreateTableSQL', Array( config_get( 'mantis_bug_tag_table' ), "
+ bug_id I UNSIGNED NOTNULL PRIMARY DEFAULT '0',
+ tag_id I UNSIGNED NOTNULL PRIMARY DEFAULT '0',
+ user_id I UNSIGNED NOTNULL DEFAULT '0',
+ date_attached T NOTNULL DEFAULT '1970-01-01 00:00:01'
+ ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) );
# Release marker: 1.1.0a4
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/bug_view_advanced_page.php mantis-tagging/bug_view_advanced_page.php
--- mantis-cvs/bug_view_advanced_page.php 2007-08-07 10:47:14.000000000 -0400
+++ mantis-tagging/bug_view_advanced_page.php 2007-08-17 11:29:28.000000000 -0400
@@ -20,6 +20,7 @@
require_once( $t_core_path.'date_api.php' );
require_once( $t_core_path.'relationship_api.php' );
require_once( $t_core_path.'last_visited_api.php' );
+ require_once( $t_core_path.'tag_api.php' );
$f_bug_id = gpc_get_int( 'bug_id' );
$f_history = gpc_get_bool( 'history', config_get( 'history_default_visible' ) );
@@ -464,13 +465,35 @@
+
+
+
>
+ |
+
+
+ |
+
+
+
+
+>
+ |
+
+
+ |
+
+
+
|
-
+
+
+>
+ |
+
+
+ |
+
+
+
+
+>
+ |
+
+
+ |
+
+
+
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/config_defaults_inc.php mantis-tagging/config_defaults_inc.php
--- mantis-cvs/config_defaults_inc.php 2007-08-16 13:23:56.000000000 -0400
+++ mantis-tagging/config_defaults_inc.php 2007-08-16 13:48:44.000000000 -0400
@@ -1331,6 +1331,7 @@
$g_mantis_bug_monitor_table = '%db_table_prefix%_bug_monitor%db_table_suffix%';
$g_mantis_bug_relationship_table = '%db_table_prefix%_bug_relationship%db_table_suffix%';
$g_mantis_bug_table = '%db_table_prefix%_bug%db_table_suffix%';
+ $g_mantis_bug_tag_table = '%db_table_prefix%_bug_tag%db_table_suffix%';
$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%';
@@ -1340,6 +1341,7 @@
$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%';
$g_mantis_project_version_table = '%db_table_prefix%_project_version%db_table_suffix%';
+ $g_mantis_tag_table = '%db_table_prefix%_tag%db_table_suffix%';
$g_mantis_user_table = '%db_table_prefix%_user%db_table_suffix%';
$g_mantis_user_profile_table = '%db_table_prefix%_user_profile%db_table_suffix%';
$g_mantis_user_pref_table = '%db_table_prefix%_user_pref%db_table_suffix%';
@@ -1835,6 +1837,34 @@
$g_recently_visited_count = 5;
#####################
+ # Bug Tagging
+ #####################
+
+ # String that will separate tags as entered for input
+ $g_tag_separator = ',';
+
+ # Access level required to view tags attached to a bug
+ $g_tag_view_threshold = VIEWER;
+
+ # Access level required to attach tags to a bug
+ $g_tag_attach_threshold = REPORTER;
+
+ # Access level required to detach tags from a bug
+ $g_tag_detach_threshold = DEVELOPER;
+
+ # Access level required to detach tags attached by the same user
+ $g_tag_detach_own_threshold = REPORTER;
+
+ # Access level required to create new tags
+ $g_tag_create_threshold = REPORTER;
+
+ # Access level required to edit tag names and descriptions
+ $g_tag_edit_threshold = DEVELOPER;
+
+ # Access level required to edit descriptions by the creating user
+ $g_tag_edit_own_threshold = REPORTER;
+
+ #####################
# Time tracking
#####################
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/constant_inc.php mantis-tagging/core/constant_inc.php
--- mantis-cvs/core/constant_inc.php 2007-08-07 10:47:13.000000000 -0400
+++ mantis-tagging/core/constant_inc.php 2007-08-16 13:48:43.000000000 -0400
@@ -153,6 +153,9 @@
define( 'CHECKIN', 22 );
define( 'BUG_REPLACE_RELATIONSHIP', 23 );
define( 'BUG_PAID_SPONSORSHIP', 24 );
+ define( 'TAG_ATTACHED', 25 );
+ define( 'TAG_DETACHED', 26 );
+ define( 'TAG_RENAMED', 27 );
# bug relationship constants
define( 'BUG_DUPLICATE', 0 );
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/filter_api.php mantis-tagging/core/filter_api.php
--- mantis-cvs/core/filter_api.php 2007-08-07 10:47:13.000000000 -0400
+++ mantis-tagging/core/filter_api.php 2007-08-17 14:31:51.000000000 -0400
@@ -56,6 +56,7 @@
define( 'FILTER_PROPERTY_FILTER_BY_DATE', 'do_filter_by_date' );
define( 'FILTER_PROPERTY_RELATIONSHIP_TYPE', 'relationship_type' );
define( 'FILTER_PROPERTY_RELATIONSHIP_BUG', 'relationship_bug' );
+ define( 'FILTER_PROPERTY_TAG_STRING', 'tag_string' );
###########################################################################
# Filter Query Parameter Names
@@ -96,6 +97,7 @@
define( 'FILTER_SEARCH_FILTER_BY_DATE', 'filter_by_date' );
define( 'FILTER_SEARCH_RELATIONSHIP_TYPE', 'relationship_type' );
define( 'FILTER_SEARCH_RELATIONSHIP_BUG', 'relationship_bug' );
+ define( 'FILTER_SEARCH_TAG_STRING', 'tag_string' );
# Checks the supplied value to see if it is an ANY value.
# $p_field_value - The value to check.
@@ -306,6 +308,10 @@
$t_query[] = filter_encode_field_and_value( FILTER_SEARCH_OS_BUILD, $p_custom_filter[FILTER_PROPERTY_OS_BUILD] );
}
+ if ( !filter_str_field_is_any( $p_custom_filter[FILTER_PROPERTY_TAG_STRING] ) ) {
+ $t_query[] = filter_encode_field_and_value( FILTER_SEARCH_TAG_STRING, $p_custom_filter[FILTER_PROPERTY_TAG_STRING] );
+ }
+
if ( isset( $p_custom_filter['custom_fields'] ) ) {
foreach( $p_custom_filter['custom_fields'] as $t_custom_field_id => $t_custom_field_values ) {
if ( !filter_str_field_is_any( $t_custom_field_values ) ) {
@@ -1057,6 +1063,59 @@
array_push( $t_where_clauses, '('. implode( ' OR ', $t_clauses ) .')' );
}
+ # tags
+ $c_tag_string = trim( $t_filter['tag_string'] );
+ if ( !is_blank( $c_tag_string ) ) {
+ require_once( $t_core_path . 'tag_api.php' );
+ $t_tags = tag_parse_filters( $c_tag_string );
+
+ if ( !count( $t_tags ) ) { break; }
+
+ $t_tags_all = array();
+ $t_tags_any = array();
+ $t_tags_none = array();
+
+ foreach( $t_tags as $t_tag_row ) {
+ switch ( $t_tag_row['filter'] ) {
+ case 1:
+ $t_tags_all[] = $t_tag_row;
+ break;
+ case 0:
+ $t_tags_any[] = $t_tag_row;
+ break;
+ case -1:
+ $t_tags_none[] = $t_tag_row;
+ break;
+ }
+ }
+
+ $t_bug_tag_table = config_get( 'mantis_bug_tag_table' );
+
+ if ( count( $t_tags_all ) ) {
+ $t_clauses = array();
+ foreach ( $t_tags_all as $t_tag_row ) {
+ array_push( $t_clauses, "$t_bug_table.id IN ( SELECT bug_id FROM $t_bug_tag_table WHERE $t_bug_tag_table.tag_id = $t_tag_row[id] )" );
+ }
+ array_push( $t_where_clauses, '('. implode( ' AND ', $t_clauses ) .')' );
+ }
+
+ if ( count( $t_tags_any ) ) {
+ $t_clauses = array();
+ foreach ( $t_tags_any as $t_tag_row ) {
+ array_push( $t_clauses, "$t_bug_tag_table.tag_id = $t_tag_row[id]" );
+ }
+ array_push( $t_where_clauses, "$t_bug_table.id IN ( SELECT bug_id FROM $t_bug_tag_table WHERE ( ". implode( ' OR ', $t_clauses ) .') )' );
+ }
+
+ if ( count( $t_tags_none ) ) {
+ $t_clauses = array();
+ foreach ( $t_tags_none as $t_tag_row ) {
+ array_push( $t_clauses, "$t_bug_tag_table.tag_id = $t_tag_row[id]" );
+ }
+ array_push( $t_where_clauses, "$t_bug_table.id NOT IN ( SELECT bug_id FROM $t_bug_tag_table WHERE ( ". implode( ' OR ', $t_clauses ) .') )' );
+ }
+ }
+
# custom field filters
if( ON == config_get( 'filter_by_custom_fields' ) ) {
# custom field filtering
@@ -2291,6 +2350,7 @@
:
+ :
|
8 ) {
echo ' | ';
@@ -2312,7 +2372,12 @@
print_multivalue_field( FILTER_PROPERTY_OS_BUILD, $t_filter[FILTER_PROPERTY_OS_BUILD] );
?>
-
+ |
+
+
+
|
+
+
+
+ ' . $p_new_value;
+ break;
}
}
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/html_api.php mantis-tagging/core/html_api.php
--- mantis-cvs/core/html_api.php 2007-08-07 10:47:13.000000000 -0400
+++ mantis-tagging/core/html_api.php 2007-08-17 11:56:56.000000000 -0400
@@ -1218,4 +1218,24 @@
echo '';
}
+
+ function html_button_tag_update( $p_tag_id ) {
+ if ( access_has_global_level( config_get( 'tag_edit_threshold' ) )
+ || ( auth_get_current_user_id() == tag_get_field( $p_tag_id, 'user_id' )
+ && access_has_global_level( config_get( 'tag_edit_own_threshold' ) ) ) )
+ {
+ html_button( 'tag_update_page.php', lang_get( 'tag_update_button' ), array( 'tag_id' => $p_tag_id ) );
+ }
+ }
+
+ function html_button_tag_delete( $p_tag_id ) {
+ if ( access_has_global_level( config_get( 'tag_edit_threshold' ) ) ) {
+ html_button( 'tag_delete.php', lang_get( 'tag_delete_button' ), array( 'tag_id' => $p_tag_id ) );
+ }
+ }
+
+ function html_buttons_tag_view_page( $p_tag_id ) {
+ html_button_tag_update( $p_tag_id );
+ html_button_tag_delete( $p_tag_id );
+ }
?>
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/print_api.php mantis-tagging/core/print_api.php
--- mantis-cvs/core/print_api.php 2007-08-14 10:12:41.000000000 -0400
+++ mantis-tagging/core/print_api.php 2007-08-17 11:02:32.000000000 -0400
@@ -11,6 +11,7 @@
$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
+ require_once( $t_core_dir . 'ajax_api.php' );
require_once( $t_core_dir . 'current_user_api.php' );
require_once( $t_core_dir . 'string_api.php' );
require_once( $t_core_dir . 'prepare_api.php' );
@@ -255,6 +256,54 @@
PRINT "";
}
}
+
+ function print_tag_attach_form( $p_bug_id, $p_string="" ) {
+ ?>
+
+
+
+
+
+
+ ',lang_get( 'tag_existing' ),'';
+ while ( $row = db_fetch_array( $result ) ) {
+ echo '';
+ }
+ }
+
# --------------------
# Get current headlines and id prefix with v_
function print_news_item_option_list() {
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/tag_api.php mantis-tagging/core/tag_api.php
--- mantis-cvs/core/tag_api.php 1969-12-31 19:00:00.000000000 -0500
+++ mantis-tagging/core/tag_api.php 2007-08-17 17:01:13.000000000 -0400
@@ -0,0 +1,474 @@
+ 0;
+ }
+
+ function tag_ensure_exists( $p_tag_id ) {
+ if ( !tag_exists( $p_tag_id ) ) {
+ error_parameters( $p_tag_id );
+ trigger_error( ERROR_TAG_NOT_FOUND, ERROR );
+ }
+ }
+
+ function tag_is_unique( $p_name ) {
+ $c_name = trim( db_prepare_string( $p_name ) );
+ $t_tag_table = config_get( 'mantis_tag_table' );
+
+ $query = "SELECT id FROM $t_tag_table WHERE name like '$c_name'";
+ $result = db_query( $query ) ;
+
+ return db_num_rows( $result ) == 0;
+ }
+
+ function tag_ensure_unique( $p_name ) {
+ if ( !tag_is_unique( $p_name ) ) {
+ trigger_error( ERROR_TAG_DUPLICATE, ERROR );
+ }
+ }
+
+ # Name must start with letter/number and consist of letters, numbers, hyphen, underscore, period, or spaces
+ function tag_name_is_valid( $p_name, $p_prefix="", &$p_matches=null ) {
+ $t_pattern = "/^$p_prefix([a-zA-Z0-9][a-zA-Z0-9-_. ]*)$/";
+ return preg_match( $t_pattern, $p_name, $p_matches );
+ }
+
+ function tag_ensure_name_is_valid( $p_name ) {
+ if ( !tag_name_is_valid( $p_name ) ) {
+ trigger_error( ERROR_TAG_NAME_INVALID, ERROR );
+ }
+ }
+
+ function tag_cmp_name( $p_tag1, $p_tag2 ) {
+ return strcasecmp( $p_tag1['name'], $p_tag2['name'] );
+ }
+
+ function tag_parse_string( $p_string ) {
+ $t_tags = array();
+
+ $t_strings = explode( config_get( 'tag_separator' ), $p_string );
+ foreach( $t_strings as $t_name ) {
+ $t_name = trim( $t_name );
+ if ( "" == trim( $t_name ) ) { continue; }
+
+ $t_tag_row = tag_get_by_name( $t_name );
+ if ( $t_tag_row !== false ) {
+ $t_tags[] = $t_tag_row;
+ } else {
+ if ( tag_name_is_valid( $t_name ) ) {
+ $t_id = -1;
+ } else {
+ $t_id = -2;
+ }
+ $t_tags[] = array( 'id' => $t_id, 'name' => $t_name );
+ }
+ }
+ usort( $t_tags, "tag_cmp_name" );
+ return $t_tags;
+ }
+
+ function tag_parse_filters( $p_string ) {
+ $t_tags = array();
+ $t_prefix = "[+-]{0,1}";
+
+ $t_strings = explode( config_get( 'tag_separator' ), $p_string );
+ foreach( $t_strings as $t_name ) {
+ $t_name = trim( $t_name );
+ if ( "" == trim( $t_name ) || !tag_name_is_valid( $t_name, $t_prefix ) ) { continue; }
+
+ $t_matches = array();
+ if ( tag_name_is_valid( $t_name, $t_prefix, $t_matches ) ) {
+ $t_tag_row = tag_get_by_name( $t_matches[1] );
+ if ( $t_tag_row !== false ) {
+ $t_filter = substr( $t_name, 0, 1 );
+
+ if ( "+" == $t_filter ) {
+ $t_tag_row['filter'] = 1;
+ } elseif ( "-" == $t_filter ) {
+ $t_tag_row['filter'] = -1;
+ } else {
+ $t_tag_row['filter'] = 0;
+ }
+
+ $t_tags[] = $t_tag_row;
+ }
+ }
+ }
+ usort( $t_tags, "tag_cmp_name" );
+ return $t_tags;
+ }
+
+ # CRUD
+
+ function tag_get( $p_tag_id ) {
+ tag_ensure_exists( $p_tag_id );
+
+ $c_tag_id = db_prepare_int( $p_tag_id );
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+
+ $query = "SELECT * FROM $t_tag_table
+ WHERE id='$c_tag_id'";
+ $result = db_query( $query );
+
+ if ( 0 == db_num_rows( $result ) ) {
+ return false;
+ }
+ $row = db_fetch_array( $result );
+
+ return $row;
+ }
+
+ function tag_get_by_name( $p_name ) {
+ $c_name = db_prepare_string( $p_name );
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+
+ $query = "SELECT * FROM $t_tag_table
+ WHERE name LIKE '$c_name'";
+ $result = db_query( $query );
+
+ if ( 0 == db_num_rows( $result ) ) {
+ return false;
+ }
+ $row = db_fetch_array( $result );
+
+ return $row;
+ }
+
+ function tag_get_field( $p_tag_id, $p_field_name ) {
+ $row = tag_get( $p_tag_id );
+
+ if ( isset( $row[$p_field_name] ) ) {
+ return $row[$p_field_name];
+ } else {
+ error_parameters( $p_field_name );
+ trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
+ return '';
+ }
+ }
+
+ function tag_create( $p_name, $p_user_id, $p_description='' ) {
+
+ tag_ensure_name_is_valid( $p_name );
+ tag_ensure_unique( $p_name );
+
+ $c_name = trim( db_prepare_string( $p_name ) );
+ $c_description = db_prepare_string( $p_description );
+ $c_user_id = db_prepare_int( $p_user_id );
+ $c_date_created = db_now();
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+
+ $query = "INSERT INTO $t_tag_table
+ ( user_id,
+ name,
+ description,
+ date_created,
+ date_updated
+ )
+ VALUES
+ ( '$c_user_id',
+ '$c_name',
+ '$c_description',
+ ".$c_date_created.",
+ ".$c_date_created."
+ )";
+
+ db_query( $query );
+ return db_insert_id( $t_tag_table );
+ }
+
+ function tag_update( $p_tag_id, $p_name, $p_user_id, $p_description ) {
+ tag_ensure_exists( $p_tag_id );
+ user_ensure_exists( $p_user_id );
+
+ tag_ensure_name_is_valid( $p_name );
+
+ $t_tag_name = tag_get_field( $p_tag_id, 'name' );
+
+ $t_rename = false;
+ if ( strtolower($p_name) != strtolower($t_tag_name) ) {
+ tag_ensure_unique( $p_name );
+ $t_rename = true;
+ }
+
+ $c_tag_id = trim( db_prepare_int( $p_tag_id ) );
+ $c_user_id = db_prepare_string( $p_user_id );
+ $c_name = db_prepare_string( $p_name );
+ $c_description = db_prepare_string( $p_description );
+ $c_date_updated = db_now();
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+
+ $query = "UPDATE $t_tag_table
+ SET user_id='$c_user_id',
+ name='$c_name',
+ description='$c_description',
+ date_updated=".$c_date_updated."
+ WHERE id='$c_tag_id'";
+ db_query( $query );
+
+ if ( $t_rename ) {
+ $t_bugs = tag_get_bugs_attached( $p_tag_id );
+
+ foreach ( $t_bugs as $t_bug_id ) {
+ history_log_event_special( $t_bug_id, TAG_RENAMED, $t_tag_name, $c_name );
+ }
+ }
+
+ return true;
+ }
+
+ function tag_delete( $p_tag_id ) {
+ tag_ensure_exists( $p_tag_id );
+
+ $t_bugs = tag_get_bugs_attached( $p_tag_id );
+ foreach ( $t_bugs as $t_bug_id ) {
+ tag_bug_detach( $p_tag_id, $t_bug_id );
+ }
+
+ $c_tag_id = db_prepare_int( $p_tag_id );
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+ $t_bug_tag_table = config_get( 'mantis_bug_tag_table' );
+
+ $query = "DELETE FROM $t_tag_table
+ WHERE id='$c_tag_id'";
+ db_query( $query );
+
+ return true;
+ }
+
+ # Associative
+
+ function tag_bug_is_attached( $p_tag_id, $p_bug_id ) {
+ $c_tag_id = db_prepare_int( $p_tag_id );
+ $c_bug_id = db_prepare_int( $p_bug_id );
+
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "SELECT * FROM $t_bug_tag_table
+ WHERE tag_id='$c_tag_id' AND bug_id='$c_bug_id'";
+ $result = db_query( $query );
+ return ( db_num_rows( $result ) > 0 );
+ }
+
+ function tag_bug_get_row( $p_tag_id, $p_bug_id ) {
+ $c_tag_id = db_prepare_int( $p_tag_id );
+ $c_bug_id = db_prepare_int( $p_bug_id );
+
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "SELECT * FROM $t_bug_tag_table
+ WHERE tag_id='$c_tag_id' AND bug_id='$c_bug_id'";
+ $result = db_query( $query );
+
+ if ( db_num_rows( $result ) == 0 ) {
+ trigger_error( TAG_NOT_ATTACHED, ERROR );
+ }
+ return db_fetch_array( $result );
+ }
+
+ function tag_bug_get_attached( $p_bug_id ) {
+ $c_bug_id = db_prepare_int( $p_bug_id );
+
+ $t_tag_table = config_get( 'mantis_tag_table' );
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "SELECT t.*, b.user_id as user_attached, b.date_attached
+ FROM $t_tag_table as t
+ LEFT JOIN $t_bug_tag_table as b
+ on t.id=b.tag_id
+ WHERE b.bug_id='$c_bug_id'";
+ $result = db_query( $query );
+
+ $rows = array();
+ while ( $row = db_fetch_array( $result ) ) {
+ $rows[] = $row;
+ }
+
+ usort( $rows, "tag_cmp_name" );
+ return $rows;
+ }
+
+ function tag_get_bugs_attached( $p_tag_id ) {
+ $c_tag_id = db_prepare_int( $p_tag_id );
+
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "SELECT bug_id FROM $t_bug_tag_table
+ WHERE tag_id='$c_tag_id'";
+ $result = db_query( $query );
+
+ $bugs = array();
+ while ( $row = db_fetch_array( $result ) ) {
+ $bugs[] = $row['bug_id'];
+ }
+
+ return $bugs;
+ }
+
+ function tag_bug_attach( $p_tag_id, $p_bug_id, $p_user_id ) {
+ tag_ensure_exists( $p_tag_id );
+ bug_ensure_exists( $p_bug_id );
+ user_ensure_exists( $p_user_id );
+
+ if ( tag_bug_is_attached( $p_tag_id, $p_bug_id ) ) {
+ trigger_error( TAG_ALREADY_ATTACHED, ERROR );
+ }
+
+ $c_tag_id = db_prepare_int( $p_tag_id );
+ $c_bug_id = db_prepare_int( $p_bug_id );
+ $c_user_id = db_prepare_int( $p_user_id );
+ $c_date_attached= db_now();
+
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "INSERT INTO $t_bug_tag_table
+ ( tag_id,
+ bug_id,
+ user_id,
+ date_attached
+ )
+ VALUES
+ ( '$c_tag_id',
+ '$c_bug_id',
+ '$c_user_id',
+ ".$c_date_attached."
+ )";
+ db_query( $query );
+
+ $t_tag_name = tag_get_field( $p_tag_id, 'name' );
+ history_log_event_special( $p_bug_id, TAG_ATTACHED, $t_tag_name );
+
+ return true;
+ }
+
+ function tag_bug_detach( $p_tag_id, $p_bug_id ) {
+ tag_ensure_exists( $p_tag_id );
+ bug_ensure_exists( $p_bug_id );
+
+ if ( !tag_bug_is_attached( $p_tag_id, $p_bug_id ) ) {
+ trigger_error( TAG_NOT_ATTACHED, ERROR );
+ }
+
+ $c_tag_id = db_prepare_int( $p_tag_id );
+ $c_bug_id = db_prepare_int( $p_bug_id );
+
+ $t_bug_tag_table= config_get( 'mantis_bug_tag_table' );
+
+ $query = "DELETE FROM $t_bug_tag_table
+ WHERE tag_id='$c_tag_id' AND bug_id='$c_bug_id'";
+ db_query( $query );
+
+ $t_tag_name = tag_get_field( $p_tag_id, 'name' );
+ history_log_event_special( $p_bug_id, TAG_DETACHED, $t_tag_name );
+
+ return true;
+ }
+
+ # Display
+
+ function tag_display_link( $p_tag_row, $p_bug_id=0 ) {
+ if ( auth_get_current_user_id() == $p_tag_row[user_attached] ) {
+ $t_detach = config_get( 'tag_detach_own_threshold' );
+ } else {
+ $t_detach = config_get( 'tag_detach_threshold' );
+ }
+
+ $t_name = string_display_line( $p_tag_row['name'] );
+ $t_description = string_display_line( $p_tag_row['description'] );
+
+ echo "$t_name";
+
+ if ( access_has_global_level($t_detach) ) {
+ $t_tooltip = sprintf( lang_get( 'tag_detach' ), $t_name );
+ echo " [x]";
+ }
+
+ return true;
+ }
+
+ function tag_display_attached( $p_bug_id ) {
+ $t_tag_rows = tag_bug_get_attached( $p_bug_id );
+
+ if ( count( $t_tag_rows ) == 0 ) {
+ echo lang_get( 'tag_none_attached' );
+ } else {
+ $i = 0;
+ foreach ( $t_tag_rows as $t_tag ) {
+ echo ( $i > 0 ? config_get('tag_separator')." " : "" );
+ tag_display_link( $t_tag, $p_bug_id );
+ $i++;
+ }
+ }
+
+ return true;
+ }
+
+ # Statistics
+
+ function tag_stats_attached( $p_tag_id ) {
+ $c_tag_id = db_prepare_int( $p_tag_id );
+ $t_bug_tag_table = config_get( 'mantis_bug_tag_table' );
+
+ $query = "SELECT bug_id FROM $t_bug_tag_table
+ WHERE tag_id='$c_tag_id'";
+ $result = db_query( $query );
+
+ return db_num_rows( $result );
+ }
+
+ function tag_stats_related( $p_tag_id, $p_limit=5 ) {
+ $t_tag_table = config_get( 'mantis_tag_table' );
+ $t_bug_tag_table = config_get( 'mantis_bug_tag_table' );
+ $c_tag_id = db_prepare_int( $p_tag_id );
+
+ $query = "SELECT * FROM $t_bug_tag_table
+ WHERE tag_id != $c_tag_id
+ AND bug_id IN ( SELECT bug_id FROM $t_bug_tag_table
+ WHERE tag_id=$c_tag_id ) ";
+ $result = db_query( $query );
+
+ $t_tag_counts = array();
+ while ( $row = db_fetch_array( $result ) ) {
+ $t_tag_counts[$row['tag_id']]++;
+ }
+
+ asort( $t_tag_counts );
+
+ $t_tags = array();
+ $i = 1;
+ foreach ( $t_tag_counts as $t_tag_id => $t_count ) {
+ $t_tag_row = tag_get($t_tag_id);
+ $t_tag_row['count'] = $t_count;
+ $t_tags[] = $t_tag_row;
+ $i++;
+ if ( $i > $p_limit ) { break; }
+ }
+
+ return $t_tags;
+ }
Binary files mantis-cvs/core/.tag_api.php.swp and mantis-tagging/core/.tag_api.php.swp differ
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/core/xmlhttprequest_api.php mantis-tagging/core/xmlhttprequest_api.php
--- mantis-cvs/core/xmlhttprequest_api.php 2007-08-07 10:47:13.000000000 -0400
+++ mantis-tagging/core/xmlhttprequest_api.php 2007-08-16 13:48:44.000000000 -0400
@@ -31,6 +31,15 @@
echo '';
}
+ function xmlhttprequest_user_combobox() {
+ $f_user_id = gpc_get_int( 'user_id' );
+ $f_user_access = gpc_get_int( 'access_level' );
+
+ echo '';
+ }
+
# ---------------
# Echos a serialized list of platforms starting with the prefix specified in the $_POST
function xmlhttprequest_platform_get_with_prefix() {
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/javascript/common.js mantis-tagging/javascript/common.js
--- mantis-cvs/javascript/common.js 2007-08-14 10:12:43.000000000 -0400
+++ mantis-tagging/javascript/common.js 2007-08-16 14:57:40.000000000 -0400
@@ -163,3 +163,16 @@
setDisplay( idTag, (document.getElementById(idTag).style.display == 'none')?1:0 );
}
+/* Tag functionality */
+function tag_string_append( p_string ) {
+ t_tag_separator = document.getElementById('tag_separator').value;
+ t_tag_string = document.getElementById('tag_string');
+ t_tag_select = document.getElementById('tag_select');
+ if ( t_tag_string.value != '' ) {
+ t_tag_string.value = t_tag_string.value + t_tag_separator + p_string;
+ } else {
+ t_tag_string.value = t_tag_string.value + p_string;
+ }
+ t_tag_select.selectedIndex=0;
+}
+
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/lang/strings_english.txt mantis-tagging/lang/strings_english.txt
--- mantis-cvs/lang/strings_english.txt 2007-08-16 13:24:00.000000000 -0400
+++ mantis-tagging/lang/strings_english.txt 2007-08-17 16:59:16.000000000 -0400
@@ -275,6 +275,11 @@
$MANTIS_ERROR[ERROR_USER_CHANGE_LAST_ADMIN] = 'You cannot change the access level of the only ADMINISTRATOR in the system.';
$MANTIS_ERROR[ERROR_PAGE_REDIRECTION] = 'Page redirection error, ensure that there are no spaces outside the PHP block (<?php ?>) in config_inc.php or custom_*.php files.';
$MANTIS_ERROR[ERROR_TWITTER_NO_CURL_EXT] = 'Twitter integration requires PHP CURL extension which is not installed.';
+$MANTIS_ERROR[ERROR_TAG_NOT_FOUND] = 'Could not find a tag with that name.';
+$MANTIS_ERROR[ERROR_TAG_DUPLICATE] = 'A tag already exists with that name.';
+$MANTIS_ERROR[ERROR_TAG_NAME_INVALID] = 'That tag name is invalid.';
+$MANTIS_ERROR[ERROR_TAG_NOT_ATTACHED] = 'That tag is not attached to that bug.';
+$MANTIS_ERROR[ERROR_TAG_ALREADY_ATTACHED] = 'That tag already attached to that bug.';
$s_login_error = 'Your account may be disabled or blocked or the username/password you entered is incorrect.';
$s_login_cookies_disabled = 'Your browser either doesn\'t know how to handle cookies, or refuses to handle them.';
@@ -1347,6 +1352,38 @@
# wiki related strings
$s_wiki = 'Wiki';
+# Tagging
+$s_tags = 'Tags';
+$s_tag_details = 'Tag Details: %s';
+$s_tag_id = 'Tag ID';
+$s_tag_name = 'Name';
+$s_tag_creator = 'Creator';
+$s_tag_created = 'Date Created';
+$s_tag_updated = 'Last Updated';
+$s_tag_description = 'Tag Description';
+$s_tag_statistics = 'Usage Statistics';
+$s_tag_update = 'Update Tag: %s';
+$s_tag_update_return = 'Back to Tag';
+$s_tag_update_button = 'Update Tag';
+$s_tag_delete_button = 'Delete Tag';
+$s_tag_delete_message = 'Are you sure you wish to delete this tag?';
+$s_tag_existing = 'Existing tags';
+$s_tag_none_attached = 'No tags attached.';
+$s_tag_attach = 'Attach';
+$s_tag_attach_long = 'Attach Tags';
+$s_tag_attach_failed = 'Tag attachment failed.';
+$s_tag_detach = 'Detach %s';
+$s_tag_separate_by = "(Separate by '%s')";
+$s_tag_invalid_name = 'Invalid tag name.';
+$s_tag_create_denied = 'Create permission denied.';
+$s_tag_filter_default = 'Attached Issues (%s)';
+$s_tag_history_attached = 'Tag Attached';
+$s_tag_history_detached = 'Tag Detached';
+$s_tag_history_renamed = 'Tag Renamed';
+$s_tag_related = 'Related Tags';
+$s_tag_related_issues = 'Shared Issues';
+$s_tag_stats_attached = 'Issues attached: %s';
+
# Time Tracking
$s_time_tracking_billing_link = 'Billing';
$s_time_tracking = 'Time tracking';
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/tag_attach.php mantis-tagging/tag_attach.php
--- mantis-cvs/tag_attach.php 1969-12-31 19:00:00.000000000 -0500
+++ mantis-tagging/tag_attach.php 2007-08-17 11:30:39.000000000 -0400
@@ -0,0 +1,103 @@
+ 0 ) {
+ html_page_top1( lang_get( 'tag_attach_long' ).' '.bug_format_summary( $f_bug_id, SUMMARY_CAPTION ) );
+ html_page_top2();
+?>
+
+
+
+ |
+
+ |
+';
+ if ( -1 == $t_tag_row['id'] ) {
+ echo '',lang_get( 'tag_invalid_name' ),' | ';
+ } elseif ( -2 == $t_tag_row['id'] ) {
+ echo '',lang_get( 'tag_create_denied' ),' | ';
+ }
+ echo '',$t_tag_row['name'],' | ';
+
+ if ( "" != $t_tag_string ) {
+ $t_tag_string .= config_get( 'tag_separator' );
+ }
+ $t_tag_string .= $t_tag_row['name'];
+ }
+?>
+ |
+ >
+ |
+
+
+ |
+
+
+
+
+
+
+
+
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/tag_update.php mantis-tagging/tag_update.php
--- mantis-cvs/tag_update.php 1969-12-31 19:00:00.000000000 -0500
+++ mantis-tagging/tag_update.php 2007-08-16 13:48:44.000000000 -0400
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+>
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+ |
+
+
+
+>
+ |
+ |
+
+
+
+';
+ echo '',lang_get( 'tag_related' ),' | ';
+
+ $i = 0;
+ foreach( $t_tags_related as $t_tag ) {
+ $t_name = string_display_line( $t_tag['name'] );
+ $t_description = string_display_line( $t_tag['description'] );
+ $t_count = $t_tag['count'];
+
+ echo ( $i > 0 ? '' : '' );
+ echo "$t_name | \n";
+ echo '';
+ print_bracket_link( "search.php?hide_status_is=90&tag_string=+$t_tag_row[name]".config_get('tag_separator')."+$t_name", lang_get( 'tag_related_issues' ) );
+ echo ' |
';
+
+ $i++;
+ }
+ }
+?>
+
+
+
+
+
+ |
+
+
+
+
Binary files mantis-cvs/.tag_view_page.php.swp and mantis-tagging/.tag_view_page.php.swp differ
diff -urN --exclude=CVS --exclude=.svn --exclude=.swp --exclude='.git*' --exclude=config_inc.php mantis-cvs/view_all_set.php mantis-tagging/view_all_set.php
--- mantis-cvs/view_all_set.php 2007-08-07 10:47:14.000000000 -0400
+++ mantis-tagging/view_all_set.php 2007-08-16 16:27:27.000000000 -0400
@@ -203,6 +203,8 @@
$f_do_filter_by_date = gpc_get_bool( 'do_filter_by_date' );
$f_view_state = gpc_get_int( 'view_state', META_FILTER_ANY );
+ $f_tag_string = gpc_get_string( 'tag_string', '' );
+
$t_custom_fields = custom_field_get_ids(); # @@@ (thraxisp) This should really be the linked ids, but we don't know the project
$f_custom_fields_data = array();
if ( is_array( $t_custom_fields ) && ( sizeof( $t_custom_fields ) > 0 ) ) {
@@ -414,6 +416,7 @@
$t_setting_arr['platform'] = $f_platform;
$t_setting_arr['os'] = $f_os;
$t_setting_arr['os_build'] = $f_os_build;
+ $t_setting_arr['tag_string'] = $f_tag_string;
break;
# Set the sort order and direction
case '2':