Index: D:/Internet/mantis/bug_view_advanced_page.php =================================================================== --- D:/Internet/mantis/bug_view_advanced_page.php (revision 5156) +++ D:/Internet/mantis/bug_view_advanced_page.php (working copy) @@ -556,6 +556,9 @@ \ No newline at end of file Index: D:/Internet/mantis/css/default.css =================================================================== --- D:/Internet/mantis/css/default.css (revision 5156) +++ D:/Internet/mantis/css/default.css (working copy) @@ -162,3 +162,11 @@ .progress400 { position: relative; width: 400px; border: 1px solid #d7d7d7; margin-top: 1em; margin-bottom: 1em; padding: 1px; } .progress400 .bar { display: block; position: relative; background: #6bba70; text-align: center; font-weight: normal; color: #333; height: 2em; line-height: 2em; } + +.votesNegative, .votesPositive, .votesBalance{color:#fff; padding: 2px;} +.votesPositive{background-color: #18592E;} +.votesNegative{background-color: #C33039;} +.votesBalance{background-color: #000080;} +.voteRow{float: right;} +.votesBalance.positiveBalance{background-color: #008000 !important;} +.votesBalance.negativeBalance{background-color: #FF0000 !important;} Index: D:/Internet/mantis/admin/schema.php =================================================================== --- D:/Internet/mantis/admin/schema.php (revision 5156) +++ D:/Internet/mantis/admin/schema.php (working copy) @@ -404,3 +404,16 @@ " ) ); $upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_project_version_table' ), " obsolete L NOTNULL DEFAULT \" '0' \"" ) ); + +# first version of voting +$upgrade[] = Array( 'CreateTableSQL', Array( db_get_table( 'mantis_bug_votes_table' ), " + issue_id I UNSIGNED NOTNULL PRIMARY DEFAULT '0', + user_id I UNSIGNED NOTNULL PRIMARY DEFAULT '0', + weight I NOTNULL DEFAULT '0' + ", Array( 'mysql' => 'TYPE=MyISAM', 'pgsql' => 'WITHOUT OIDS' ) ) ); +$upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_bug_table' ), " + votes_positive I UNSIGNED NOTNULL DEFAULT '0', + votes_negative I UNSIGNED NOTNULL DEFAULT '0', + votes_num_voters I UNSIGNED NOTNULL DEFAULT '0' + " ) ); +$upgrade[] = Array('CreateIndexSQL',Array('idx_votes_num_voters',db_get_table('mantis_bug_table'),'votes_num_voters')); \ No newline at end of file Index: D:/Internet/mantis/config_defaults_inc.php =================================================================== --- D:/Internet/mantis/config_defaults_inc.php (revision 5156) +++ D:/Internet/mantis/config_defaults_inc.php (working copy) @@ -529,22 +529,22 @@ # resolution, fixed_in_version, view_state, os, os_build, build (for product build), platform, version, date_submitted, attachment, # category, sponsorship_total, severity, status, last_updated, summary, bugnotes_count, description, # steps_to_reproduce, additional_information - $g_view_issues_page_columns = array ( 'selection', 'edit', 'priority', 'id', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'last_updated', 'summary' ); + $g_view_issues_page_columns = array ( 'selection', 'edit', 'priority', 'id', 'votes_total', 'votes_num_voters', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'last_updated', 'summary' ); # The default columns to be included in the Print Issues Page. # This can be overriden using Manage -> Manage Configuration -> Manage Columns # Also each user can configure their own columns using My Account -> Manage Columns - $g_print_issues_page_columns = array ( 'selection', 'priority', 'id', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'last_updated', 'summary' ); + $g_print_issues_page_columns = array ( 'selection', 'priority', 'id', 'votes_total', 'votes_num_voters', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'last_updated', 'summary' ); # The default columns to be included in the CSV export. # This can be overriden using Manage -> Manage Configuration -> Manage Columns # Also each user can configure their own columns using My Account -> Manage Columns - $g_csv_columns = array ( 'id', 'project_id', 'reporter_id', 'handler_id', 'priority', 'severity', 'reproducibility', 'version', 'projection', 'category', 'date_submitted', 'eta', 'os', 'os_build', 'platform', 'view_state', 'last_updated', 'summary', 'status', 'resolution', 'fixed_in_version' ); + $g_csv_columns = array ( 'id', 'project_id', 'reporter_id', 'handler_id', 'priority', 'severity', 'reproducibility', 'version', 'projection', 'category', 'date_submitted', 'eta', 'os', 'os_build', 'platform', 'view_state', 'last_updated', 'summary', 'status', 'resolution', 'fixed_in_version', 'votes_positive', 'votes_negative', 'votes_num_voters' ); # The default columns to be included in the Excel export. # This can be overriden using Manage -> Manage Configuration -> Manage Columns # Also each user can configure their own columns using My Account -> Manage Columns - $g_excel_columns = array ( 'id', 'project_id', 'reporter_id', 'handler_id', 'priority', 'severity', 'reproducibility', 'version', 'projection', 'category', 'date_submitted', 'eta', 'os', 'os_build', 'platform', 'view_state', 'last_updated', 'summary', 'status', 'resolution', 'fixed_in_version' ); + $g_excel_columns = array ( 'id', 'project_id', 'reporter_id', 'handler_id', 'priority', 'severity', 'reproducibility', 'version', 'projection', 'category', 'date_submitted', 'eta', 'os', 'os_build', 'platform', 'view_state', 'last_updated', 'summary', 'status', 'resolution', 'fixed_in_version', 'votes_positive', 'votes_negative', 'votes_num_voters' ); # --- show projects when in All Projects mode --- $g_show_bug_project_links = ON; @@ -1419,6 +1419,7 @@ $g_db_table['mantis_config_table'] = '%db_table_prefix%_config%db_table_suffix%'; $g_db_table['mantis_database_table'] = '%db_table_prefix%_database%db_table_suffix%'; $g_db_table['mantis_email_table'] = '%db_table_prefix%_email%db_table_suffix%'; + $g_db_table['mantis_bug_votes_table'] = '%db_table_prefix%_bug_votes%db_table_suffix%'; ########################### # Mantis Enum Strings @@ -1985,6 +1986,36 @@ # management threshold. $g_manage_plugin_threshold = ADMINISTRATOR; + + ############################# + # Voting System + ############################# + + # enable or disable the whole voting feature. + $g_voting_enabled = ON; + + # access level required for users to vote on issues. + $g_voting_place_vote_threshold = REPORTER; + + # access level required for users to view the users who voted and their votes. + $g_voting_view_user_votes_threshold = DEVELOPER; + + # default number of votes allowed per user + $g_voting_default_num_votes = 10; # votes can be set for all user levels as an integer + $g_voting_default_num_votes = array( DEVELOPER => 25 , REPORTER => 10 ); # or you can set votes by user type, if a level is not specified then it will use the next lowest level available + + # default voting weights and thier labels, value needs to be integer, while key is a string eg: '+10 (Highly desired)' + $g_voting_weight_options = array('+1'=>1, '+2'=>2, '+5'=>5, '+10'=>10, '-1'=>1, '-2'=>-2, '-5'=>-5, '-10'=>-10); + + # the maximum weight a user at a given level may use in a single vote + $g_voting_max_vote_weight = 5; #max vote weight can be an integer + $g_voting_max_vote_weight = array( DEVELOPER => 10 , REPORTER => 5 ); # or set by user type, eg: even though a reporter may have 10 votes, they may only use up to weight 5 in a single vote + + # voting weight that should be initially selected when casting a vote, usually the minimum positive vote + $g_voting_weight_default = 1; + + # whether you get your votes counted per project or globally, if ON then you will get $g_voting_default_num_votes per project, if it is OFF your votes are spread across all projects + $g_voting_per_project = ON; ############################# # Mind mapping @@ -1995,4 +2026,4 @@ # Enables or disables the mind mapping features including ability to export Freemind files and # in browser view of generated mindmaps. $g_mindmap_enabled = ON; -?> \ No newline at end of file +?> Index: D:/Internet/mantis/bug_vote_list_view_inc.php =================================================================== --- D:/Internet/mantis/bug_vote_list_view_inc.php (revision 0) +++ D:/Internet/mantis/bug_vote_list_view_inc.php (revision 0) @@ -0,0 +1,146 @@ + 0; + $t_can_view_vote_details = vote_can_view_vote_details($f_bug_id, $t_current_user_id); + $t_can_vote = vote_can_vote($f_bug_id, $t_current_user_id); + + $t_show_votes = $t_votes_exist || $t_can_vote; + + $t_total_positive = bug_get_field( $f_bug_id, 'votes_positive' ); + $t_total_negative = bug_get_field( $f_bug_id, 'votes_negative' ); + $t_total_votes = $t_total_positive - $t_total_negative; + + $t_total_voters = bug_get_field( $f_bug_id, 'votes_num_voters' ); + + $t_button_text = lang_get('vote_cast_button'); + $t_bug_id = string_attribute( $f_bug_id ); + + $t_voting_weight_options = config_get( 'voting_weight_options' ); + asort($t_voting_weight_options); + $t_voting_weight_default = config_get( 'voting_weight_default' ); + + $t_max_votes = vote_max_votes( $t_current_user_id ); + $t_used_votes = vote_used_votes( $t_current_user_id ); + $t_issue_project = bug_get_field( $f_bug_id, 'project_id'); + $t_available_votes = vote_available_votes( $t_current_user_id, $t_issue_project ); + $t_voting_max_vote_weight = vote_max_weight( $t_current_user_id, $t_issue_project ); + +} else { + $t_show_votes = false; +} +?> + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
Vote on issue + $f_bug_id, 'action' => 'DELETE' ) ); + + } + else { # show 'add vote' button + ?> + +
+ 0){ ?> + + + + 0 ?> + + ( , ) + +
+ +
Summary + =
+ =
+ =
+ = + +
Voters List + +
+ =1)?'+'.$userVote['weight']:$userVote['weight'] ?> +
+ +
+ + + + + + + +
+ + ( = , = ) +
+ + Index: D:/Internet/mantis/core/html_api.php =================================================================== --- D:/Internet/mantis/core/html_api.php (revision 5156) +++ D:/Internet/mantis/core/html_api.php (working copy) @@ -70,6 +70,7 @@ require_once( $t_core_dir . 'user_api.php' ); require_once( $t_core_dir . 'rss_api.php' ); require_once( $t_core_dir . 'wiki_api.php' ); + require_once( $t_core_dir . 'vote_api.php' ); $g_rss_feed_url = null; @@ -1265,7 +1266,7 @@ echo ''; html_button_bug_change_status( $p_bug_id ); echo ''; - + # MONITOR/UNMONITOR button echo ''; if ( !current_user_is_anonymous() ) { Index: D:/Internet/mantis/core/bug_api.php =================================================================== --- D:/Internet/mantis/core/bug_api.php (revision 5156) +++ D:/Internet/mantis/core/bug_api.php (working copy) @@ -31,6 +31,7 @@ require_once( $t_core_dir . 'sponsorship_api.php' ); require_once( $t_core_dir . 'twitter_api.php' ); require_once( $t_core_dir . 'tag_api.php' ); + require_once( $t_core_dir . 'vote_api.php' ); # MASC RELATIONSHIP require_once( $t_core_dir.'relationship_api.php' ); @@ -67,6 +68,9 @@ var $summary = ''; var $sponsorship_total = 0; var $sticky = 0; + var $votes_positive = 0; + var $votes_negative = 0; + var $votes_num_voters = 0; # omitted: # var $bug_text_id @@ -752,6 +756,9 @@ # Delete all sponsorships sponsorship_delete( sponsorship_get_all_ids( $p_bug_id ) ); + + # Delete all votes on this bug + vote_delete_issue_votes( $p_bug_id ); # MASC RELATIONSHIP # we delete relationships even if the feature is currently off. Index: D:/Internet/mantis/core/filter_api.php =================================================================== --- D:/Internet/mantis/core/filter_api.php (revision 5156) +++ D:/Internet/mantis/core/filter_api.php (working copy) @@ -47,6 +47,7 @@ define( 'FILTER_PROPERTY_PRODUCT_BUILD', 'show_build' ); define( 'FILTER_PROPERTY_PRODUCT_VERSION', 'show_version' ); define( 'FILTER_PROPERTY_MONITOR_USER_ID', 'user_monitor' ); + define( 'FILTER_PROPERTY_VOTES_USER_ID', 'user_votes'); define( 'FILTER_PROPERTY_HIDE_STATUS_ID', 'hide_status' ); define( 'FILTER_PROPERTY_SORT_FIELD_NAME', 'sort' ); define( 'FILTER_PROPERTY_SORT_DIRECTION', 'dir' ); @@ -98,6 +99,7 @@ define( 'FILTER_SEARCH_OS', 'os' ); define( 'FILTER_SEARCH_OS_BUILD', 'os_build' ); define( 'FILTER_SEARCH_MONITOR_USER_ID', 'monitor_user_id' ); + define( 'FILTER_SEARCH_VOTES_USER_ID' , 'votes_user_id'); define( 'FILTER_SEARCH_PRODUCT_BUILD', 'product_build' ); define( 'FILTER_SEARCH_PRODUCT_VERSION', 'product_version' ); define( 'FILTER_SEARCH_VIEW_STATE_ID', 'view_state_id' ); @@ -203,6 +205,10 @@ if ( !filter_str_field_is_any( $p_custom_filter[FILTER_PROPERTY_MONITOR_USER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_SEARCH_MONITOR_USER_ID, $p_custom_filter[FILTER_PROPERTY_MONITOR_USER_ID] ); } + + if ( !filter_str_field_is_any( $p_custom_filter[FILTER_PROPERTY_VOTES_USER_ID] ) ) { + $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_VOTES_USER_ID, $p_custom_filter[FILTER_PROPERTY_VOTES_USER_ID] ); + } if ( !filter_str_field_is_any( $p_custom_filter[FILTER_PROPERTY_HANDLER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_SEARCH_HANDLER_ID, $p_custom_filter[FILTER_PROPERTY_HANDLER_ID] ); @@ -373,6 +379,7 @@ 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ), 'sort' => 'last_updated', 'dir' => 'DESC', 'per_page' => config_get( 'default_limit_view' ) @@ -418,6 +425,7 @@ $t_bugnote_text_table = db_get_table( 'mantis_bugnote_text_table' ); $t_project_table = db_get_table( 'mantis_project_table' ); $t_bug_monitor_table = db_get_table( 'mantis_bug_monitor_table' ); + $t_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); $t_limit_reporters = config_get( 'limit_reporters' ); $t_bug_relationship_table = db_get_table( 'mantis_bug_relationship_table' ); $t_report_bug_threshold = config_get( 'report_bug_threshold' ); @@ -1136,6 +1144,48 @@ array_push( $t_where_clauses, "( $t_table_name.user_id=" . db_param($t_where_param_count++). " )" ); } } + + # users voting on an issue + $t_select_clauses[] = '(votes_positive - votes_negative) as votes_total'; # @REVIEW is this the correct mantis way to be doing this? votes_total is a derived column + $t_any_found = false; + if ( count( $t_filter['user_votes'] ) == 0 ) { + $t_any_found = true; + } + else + { + foreach( $t_filter['user_votes'] as $t_filter_member ) { + if ( ( META_FILTER_ANY == $t_filter_member ) || ( 0 === $t_filter_member ) ) { + $t_any_found = true; + } + } + } + if ( !$t_any_found ) { + $t_clauses = array(); + $t_table_name = 'user_votes'; + array_push( $t_from_clauses, $t_bug_votes_table ); + array_push( $t_join_clauses, "LEFT JOIN $t_bug_votes_table $t_table_name ON $t_table_name.issue_id = $t_bug_table.id" ); + + foreach( $t_filter['user_votes'] as $t_filter_member ) { + $c_user_monitor = db_prepare_int( $t_filter_member ); + if ( META_FILTER_MYSELF == $c_user_monitor ) { + array_push( $t_clauses, $c_user_id ); + } else { + array_push( $t_clauses, $c_user_monitor ); + } + } + if ( 1 < count( $t_clauses ) ) { + foreach( $t_clauses as $t_clause ) { + $t_where_tmp[] = db_param($t_where_param_count++); + $t_where_params[] = $t_clause; + } + array_push( $t_where_clauses, "( $t_table_name.user_id in (". implode( ', ', $t_where_tmp ) .") )" ); + } else { + $t_where_params[] = $t_clauses[0]; + array_push( $t_where_clauses, "( $t_table_name.user_id=" . db_param($t_where_param_count++). " )" ); + } + } + + # bug relationship $t_any_found = false; $c_rel_type = $t_filter['relationship_type']; @@ -1375,7 +1425,7 @@ $t_id_join $t_id_where"; $t_query_params = array(); - + if ( ( $i == 0 ) || ( !is_blank( $t_filter['search'] ) ) ) { if( $i == 0) { $q1 = "SELECT DISTINCT $t_bug_table.id AS id" . $query; @@ -2484,9 +2534,12 @@ : - + : + + : + 8 ) { echo ' '; } ?> @@ -2507,7 +2560,7 @@ print_multivalue_field( FILTER_PROPERTY_OS_BUILD, $t_filter[FILTER_PROPERTY_OS_BUILD] ); ?> - + + + + + '; + } else { + $t_first_flag = false; + } + $t_output = $t_output . $t_this_name; + } + if ( true == $t_any_found ) { + PRINT lang_get( 'any' ); + } else { + PRINT $t_output; + } + } + ?> + 'string', 'target_version' => 'string', 'user_monitor' => 'int', + 'user_votes' => 'int', 'show_profile' => 'int' ); foreach( $t_multi_select_list as $t_multi_field_name => $t_multi_field_type ) { @@ -3440,6 +3533,24 @@ + + + Index: D:/Internet/mantis/core/excel_api.php =================================================================== --- D:/Internet/mantis/core/excel_api.php (revision 5156) +++ D:/Internet/mantis/core/excel_api.php (working copy) @@ -419,4 +419,14 @@ // field is not linked to project return excel_prepare_string( '' ); } + + function excel_format_votes_positive( $p_votes_positive ) { + return excel_prepare_string( $p_votes_positive ); + } + function excel_format_votes_negative( $p_votes_negative ) { + return excel_prepare_string( $p_votes_negative ); + } + function excel_format_votes_num_voters( $p_votes_num_voters ) { + return excel_prepare_string( $p_votes_num_voters ); + } ?> \ No newline at end of file Index: D:/Internet/mantis/core/user_api.php =================================================================== --- D:/Internet/mantis/core/user_api.php (revision 5156) +++ D:/Internet/mantis/core/user_api.php (working copy) @@ -25,6 +25,7 @@ require_once( $t_core_dir . 'email_api.php' ); require_once( $t_core_dir . 'ldap_api.php' ); + require_once( $t_core_dir . 'vote_api.php' ); ### User API ### @@ -551,6 +552,9 @@ $t_user_table = db_get_table('mantis_user_table'); user_ensure_unprotected( $p_user_id ); + + # Remove any votes the user has made on issues + vote_delete_user_votes( $p_user_id ); # Remove associated profiles user_delete_profiles( $p_user_id ); @@ -1031,7 +1035,6 @@ } $t_filter = unserialize( $t_cookie_detail[1] ); - $t_filter = filter_ensure_valid_filter( $t_filter ); return $t_filter; Index: D:/Internet/mantis/core/columns_api.php =================================================================== --- D:/Internet/mantis/core/columns_api.php (revision 5156) +++ D:/Internet/mantis/core/columns_api.php (working copy) @@ -51,6 +51,9 @@ 'selection', 'severity', 'sponsorship_total', + 'votes_positive', + 'votes_negative', + 'votes_num_voters', 'status', 'steps_to_reproduce', // new 'summary', @@ -782,4 +785,44 @@ echo ''; } + + + function print_column_title_votes_total( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { + echo ''; + print_view_bug_sort_link( lang_get( 'vote_balance' ), 'votes_total', $p_sort, $p_dir, $p_columns_target ); + print_sort_icon( $p_dir, $p_sort, 'votes_total' ); + echo ''; + } + + function print_column_title_votes_num_voters( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { + echo ''; + print_view_bug_sort_link( lang_get( 'vote_num_voters' ), 'votes_num_voters', $p_sort, $p_dir, $p_columns_target ); + print_sort_icon( $p_dir, $p_sort, 'votes_num_voters' ); + echo ''; + } + + function print_column_votes_total( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { + $t_votes_balance = ($p_row['votes_positive']-$p_row['votes_negative']); + if ($t_votes_balance > 0) + { + $t_balance_class = 'positiveBalance'; + } + else if($t_votes_balance < 0) + { + $t_balance_class = 'negativeBalance'; + } + else + { + $t_balance_class = ''; + } + echo '[ '; + echo '+'.$p_row['votes_positive'] . ' / -'. $p_row['votes_negative'] . ' ] = ' . (($t_votes_balance>0)?'+':'') . $t_votes_balance . ""; + echo ''; + } + + function print_column_votes_num_voters( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { + echo ''; + echo $p_row['votes_num_voters']; + echo ''; + } ?> Index: D:/Internet/mantis/core/helper_api.php =================================================================== --- D:/Internet/mantis/core/helper_api.php (revision 5156) +++ D:/Internet/mantis/core/helper_api.php (working copy) @@ -369,6 +369,13 @@ if ( OFF == $t_enable_sponsorship ) { $t_keys_to_remove[] = 'sponsorship_total'; } + + $t_enable_voting = config_get( 'voting_enabled' ); + if ($t_enable_voting == OFF) + { + $t_keys_to_remove[] = 'votes_total'; + $t_keys_to_remove[] = 'votes_num_voters'; + } if ( $p_columns_target == COLUMNS_TARGET_CSV_PAGE || $p_columns_target == COLUMNS_TARGET_EXCEL_PAGE || OFF == config_get( 'show_attachment_indicator' ) ) { Index: D:/Internet/mantis/core/history_api.php =================================================================== --- D:/Internet/mantis/core/history_api.php (revision 5156) +++ D:/Internet/mantis/core/history_api.php (working copy) @@ -427,6 +427,12 @@ $t_note = lang_get( 'tag_history_renamed' ); $t_change = $p_old_value . ' => ' . $p_new_value; break; + case BUGVOTE_ADDED: + $t_note = lang_get( 'bugvote_added' ) . ": " . $p_old_value; + break; + case BUGVOTE_DELETED: + $t_note = lang_get( 'bugvote_deleted' ) . ": " . $p_old_value; + break; } } Index: D:/Internet/mantis/core/vote_api.php =================================================================== --- D:/Internet/mantis/core/vote_api.php (revision 0) +++ D:/Internet/mantis/core/vote_api.php (revision 0) @@ -0,0 +1,320 @@ + $t_vote_max_weight || $p_weight == 0 ) + { + return false; # not allowed to vote more than your limit, or have a vote with weight 0 + } + + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + + $query = "INSERT INTO $t_mantis_bug_votes_table + ( issue_id, user_id, weight ) + VALUES + ( " . db_param(0) . ", " . db_param(1) . ", " . db_param(2) . " )"; + db_query_bound( $query, Array( (int)$p_issue_id, (int)$p_user_id, (int)$p_weight ) ); + + # get bugvote id + $t_bugvote_id = db_insert_id( $t_mantis_bug_votes_table ); + + + if ($p_weight >= 1) { + $t_existing_positive_votes = bug_get_field($p_issue_id,'votes_positive'); + bug_set_field($p_issue_id, 'votes_positive', $t_existing_positive_votes + $p_weight ); + } + else if ($p_weight <= -1) { + $t_existing_negative_votes = bug_get_field($p_issue_id,'votes_negative'); + bug_set_field($p_issue_id, 'votes_negative', $t_existing_negative_votes - $p_weight); + } + $t_existing_num_voters = bug_get_field($p_issue_id, 'votes_num_voters'); + bug_set_field($p_issue_id, 'votes_num_voters', $t_existing_num_voters + 1); + + # log vote history + $t_weight_log = ($p_weight>=1)?('+'.$p_weight):$p_weight; + history_log_event_special( $p_issue_id, BUGVOTE_ADDED, $t_weight_log ); + bug_update_date($p_issue_id); + + return true; +} + +/** + * vote_delete + * should only delete your vote if the bug has not been closed or resolved + * + * @param int $p_issue_id + * @param int $p_user_id + * @return null + */ +function vote_delete( $p_issue_id, $p_user_id ) +{ + if ($p_issue_id < 1 || $p_user_id < 1){return;} + + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + + # decrement vote counts from bugs table, get weight used for vote so we can remove the correct weighting from the summary + $query = "SELECT weight FROM $t_mantis_bug_votes_table WHERE issue_id = " . db_param(0) . " AND user_id = " . db_param(1); + $result = db_query_bound( $query, Array( $p_issue_id, $p_user_id ) ); + $t_weight = $result->fields['weight']; + + if ($t_weight >= 1) { + $t_existing_positive_votes = bug_get_field( $p_issue_id , 'votes_positive' ); + bug_set_field( $p_issue_id , 'votes_positive' , $t_existing_positive_votes - $t_weight ); + } + else if ($t_weight <= -1) { + $t_existing_negative_votes = bug_get_field( $p_issue_id , 'votes_negative' ); + bug_set_field($p_issue_id, 'votes_negative', $t_existing_negative_votes + $t_weight ); + } + $t_existing_num_voters = bug_get_field($p_issue_id, 'votes_num_voters'); + bug_set_field($p_issue_id, 'votes_num_voters', $t_existing_num_voters - 1); + + # now remove all votes from voting table + $query = "DELETE FROM $t_mantis_bug_votes_table WHERE issue_id = " . db_param(0) . " AND user_id = " . db_param(1); + db_query_bound($query, Array( (int)$p_issue_id, (int)$p_user_id )); + + # log vote history + $t_weight_log = ($t_weight>=1)?('+'.$t_weight):$t_weight; + history_log_event_special( $p_issue_id, BUGVOTE_DELETED, $t_weight_log ); + bug_update_date($p_issue_id); +} + +/** + * vote_delete_issue_votes + * Deleting an issue should delete all associated votes. + * + * @param int $p_issue_id issue primary key + * @return null + */ +function vote_delete_issue_votes( $p_issue_id ) +{ + if ($p_issue_id < 1){return;} + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + $query = "DELETE FROM $t_mantis_bug_votes_table WHERE issue_id = " . db_param(0); + db_query_bound($query, Array( (int)$p_issue_id )); +} +/** + * vote_delete_user_votes + * Deleting a user should delete all associated votes. + * + * @param int $p_user_id user primary key + * @return null + */ +function vote_delete_user_votes( $p_user_id ) +{ + if ($p_user_id < 1){return;} + $votes = vote_get_user_votes( $p_user_id ); + foreach($votes as $vote) + { + vote_delete($vote['issue_id'], $p_user_id); + } +} +/** + * vote_get_user_votes + * + * @param int $p_user_id + * @param int $p_project_id + * @return array issues and thier weight array('issue_id'=>$p_user_id, 'weight'=>$p_weight); + */ +function vote_get_user_votes ( $p_user_id, $p_project_id = null) +{ + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + + $query = "SELECT issue_id, weight FROM $t_mantis_bug_votes_table WHERE user_id = " . db_param(0); + $result = db_query_bound($query, Array($p_user_id)); + + $users = array(); + while ( $row = db_fetch_array( $result ) ) { + if ( $p_project_id === null ) + { + $users[] = $row; + } + else + { + $t_issue_project = bug_get_field($row['issue_id'], 'project_id'); + if ( $t_issue_project == $p_project_id ) + { + $users[] = $row; + } + } + } + return $users; +} + +/** + * vote_get_issue_votes + * returns an array of user ids, weight + * + * @param int $p_issue_id issue primary key + * @return array users and thier vote weight array('user_id'=>$p_user_id, 'weight'=>$p_weight); + */ +function vote_get_issue_votes( $p_issue_id ) +{ + if ($p_issue_id < 1){return;} + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + $query = "SELECT user_id, weight FROM $t_mantis_bug_votes_table WHERE issue_id = " . db_param(0); + $result = db_query_bound($query, Array($p_issue_id)); + $t_issue_votes = array(); + while ( $row = db_fetch_array( $result ) ) { + $t_issue_votes[] = $row; + } + return $t_issue_votes; +} +/** + * vote_is_enabled + * + * @param int $p_project_id + * @return bool + */ +function vote_is_enabled( $p_project_id = ALL_PROJECTS ) +{ + $t_enabled = ( config_get( 'voting_enabled', null, null, $p_project_id ) == ON ); + return $t_enabled; +} +/** + * vote_can_vote + * whether or not the user is allowed to vote on an issue + * + * @param int $p_issue_id + * @param int $p_user_id + * @return bool + */ +function vote_can_vote( $p_issue_id, $p_user_id = null ) +{ + $t_can_vote = ( !bug_is_readonly( $p_issue_id ) && access_has_bug_level( config_get( 'voting_place_vote_threshold' ),$p_issue_id , $p_user_id ) ); + return $t_can_vote; +} +/** + * vote_can_view_vote_details + * whether or not the user is allowed to view vote details + * + * @param int $p_issue_id + * @param int $p_user_id + * @return bool + */ +function vote_can_view_vote_details( $p_issue_id, $p_user_id = null ) +{ + $t_has_level = ( access_has_bug_level( config_get( 'voting_view_user_votes_threshold' ), $p_issue_id , $p_user_id ) ); + return $t_has_level; +} +/** + * vote_exists + * + * @param int $p_issue_id + * @param int $p_user_id + * @return bool + */ +function vote_exists ( $p_issue_id, $p_user_id) +{ + $t_mantis_bug_votes_table = db_get_table( 'mantis_bug_votes_table' ); + $query = "SELECT COUNT(*) + FROM $t_mantis_bug_votes_table + WHERE issue_id=" . db_param(0) . " AND user_id = " . db_param(1); + $result = db_query_bound( $query, Array( $p_issue_id, $p_user_id ) ); + + if ( 0 == db_result( $result ) ) { + return false; + } else { + return true; + } +} + +/** + * vote_max_votes + * the maximum number of votes the given user can cast + * @param int $p_user_id + * @return int + */ +function vote_max_votes( $p_user_id ) +{ + $t_default_num_votes = config_get('voting_default_num_votes',10); + + if (is_array($t_default_num_votes)) + { + ksort($t_default_num_votes); # relies on user levels being numeric + $t_user_level = user_get_access_level( $p_user_id ); + foreach($t_default_num_votes as $t_vote_level => $t_votes) + { + if ($t_user_level >= $t_vote_level) + { + $t_default_num_votes = $t_votes; + } + } + } + + return $t_default_num_votes; +} +function vote_available_votes( $p_user_id, $p_project_id ) +{ + return (vote_max_votes( $p_user_id )) - (vote_used_votes( $p_user_id, $p_project_id )); +} +/** + * vote_used_votes + * the number of votes already cast on a given project + * @param int $p_user_id + * @param int $p_project_id + * @return int + */ +function vote_used_votes( $p_user_id, $p_project_id = null ) +{ + $t_per_project = config_get('voting_per_project', ON); + if ($t_per_project == ON) + { + $t_votes = vote_get_user_votes( $p_user_id, $p_project_id ); + } + else + { + $t_votes = vote_get_user_votes( $p_user_id ); + } + + $t_weight_used = 0; + foreach($t_votes as $t_vote) + { + if ($t_vote['weight']>0) + { + $t_weight_used += $t_vote['weight']; + } + else + { + $t_weight_used -= $t_vote['weight']; + } + } + return $t_weight_used; +} +function vote_max_weight( $p_user_id, $p_project_id ) +{ + $t_available_votes = vote_available_votes( $p_user_id, $p_project_id ); + $t_voting_max_vote_weight = config_get('voting_max_vote_weight', 5); + if (is_array($t_voting_max_vote_weight)) + { + ksort($t_voting_max_vote_weight); # relies on user levels being numeric + $t_user_level = user_get_access_level( $p_user_id ); + foreach($t_voting_max_vote_weight as $t_max) + { + if ($t_user_level >= $t_max) + { + $t_voting_max_vote_weight = $t_max; + } + } + } + # return whichever is the lesser, your available votes or you max vote weight + $t_voting_max_vote_weight = ($t_available_votes > $t_voting_max_vote_weight)?$t_voting_max_vote_weight:$t_available_votes; + return $t_voting_max_vote_weight; +} +?> \ No newline at end of file Index: D:/Internet/mantis/core/my_view_inc.php =================================================================== --- D:/Internet/mantis/core/my_view_inc.php (revision 5156) +++ D:/Internet/mantis/core/my_view_inc.php (working copy) @@ -59,7 +59,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_bug_resolved_status_threshold ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['assigned'] = 'handler_id=' . $t_current_user_id . '&hide_status=' . $t_bug_resolved_status_threshold; @@ -74,7 +75,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => META_FILTER_NONE ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['recent_mod'] = 'hide_status=none'; @@ -90,7 +92,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['reported'] = 'reporter_id=' . $t_current_user_id . '&hide_status=' . $t_hide_status_default; @@ -105,7 +108,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['resolved'] = 'show_status=' . $t_bug_resolved_status_threshold . '&hide_status=' . $t_bug_resolved_status_threshold; @@ -120,7 +124,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['unassigned'] = 'handler_id=[none]' . '&hide_status=' . $t_hide_status_default; @@ -135,7 +140,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => $t_current_user_id ) + 'user_monitor' => Array ( '0' => $t_current_user_id ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['monitored'] = 'user_monitor=' . $t_current_user_id . '&hide_status=' . $t_hide_status_default; @@ -151,7 +157,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['feedback'] = 'reporter_id=' . $t_current_user_id . '&show_status=' . FEEDBACK . '&hide_status=' . $t_hide_status_default; @@ -166,7 +173,8 @@ 'show_build' => Array ( '0' => META_FILTER_ANY ), 'show_version' => Array ( '0' => META_FILTER_ANY ), 'hide_status' => Array ( '0' => $t_hide_status_default ), - 'user_monitor' => Array ( '0' => META_FILTER_ANY ) + 'user_monitor' => Array ( '0' => META_FILTER_ANY ), + 'user_votes' => Array ( '0' => META_FILTER_ANY ) ); $url_link_parameters['verify'] = 'reporter_id=' . $t_current_user_id . '&show_status=' . $t_bug_resolved_status_threshold; Index: D:/Internet/mantis/core/constant_inc.php =================================================================== --- D:/Internet/mantis/core/constant_inc.php (revision 5156) +++ D:/Internet/mantis/core/constant_inc.php (working copy) @@ -170,6 +170,8 @@ define( 'TAG_ATTACHED', 25 ); define( 'TAG_DETACHED', 26 ); define( 'TAG_RENAMED', 27 ); + define( 'BUGVOTE_ADDED', 28 ); + define( 'BUGVOTE_DELETED', 29 ); # bug relationship constants define( 'BUG_DUPLICATE', 0 ); Index: D:/Internet/mantis/bug_vote_add.php =================================================================== --- D:/Internet/mantis/bug_vote_add.php (revision 0) +++ D:/Internet/mantis/bug_vote_add.php (revision 0) @@ -0,0 +1,23 @@ + \ No newline at end of file