From 696c7e223968f7c0298ef5819996188a680a1dd4 Mon Sep 17 00:00:00 2001
From: Damien Regad <dregad@mantisbt.org>
Date: Wed, 5 Jun 2019 15:09:30 +0200
Subject: [PATCH] Add monitors to a bug by selecting users from list

This is more user friendly than having to type the the username,
particularly when Mantis is configured to display Realnames

Fixes #12557
---
 bug_monitor_add.php           | 30 +++++-----------
 bug_monitor_list_view_inc.php | 66 ++++++++++++++++++++++++++++++-----
 lang/strings_english.txt      |  2 +-
 3 files changed, 67 insertions(+), 31 deletions(-)

diff --git a/bug_monitor_add.php b/bug_monitor_add.php
index b5c18ff5d..f6d252f27 100644
--- a/bug_monitor_add.php
+++ b/bug_monitor_add.php
@@ -15,7 +15,7 @@
 # along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * This file turns monitoring on or off for a bug for the current user
+ * This file adds the current or specified user(s) to a bug's monitoring list
  *
  * @package MantisBT
  * @copyright Copyright 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
@@ -23,44 +23,32 @@
  * @link http://www.mantisbt.org
  *
  * @uses core.php
- * @uses access_api.php
  * @uses form_api.php
  * @uses gpc_api.php
- * @uses helper_api.php
  * @uses print_api.php
- * @uses utility_api.php
  */
 
 require_once( 'core.php' );
-require_api( 'error_api.php' );
 require_api( 'form_api.php' );
 require_api( 'gpc_api.php' );
-require_api( 'helper_api.php' );
 require_api( 'print_api.php' );
-require_api( 'utility_api.php' );
 
 form_security_validate( 'bug_monitor_add' );
 
 $f_bug_id = gpc_get_int( 'bug_id' );
-$f_usernames = trim( gpc_get_string( 'username', '' ) );
-
-$t_payload = array();
-
-if( !is_blank( $f_usernames ) ) {
-	$t_usernames = preg_split( '/[,|]/', $f_usernames, -1, PREG_SPLIT_NO_EMPTY );
-	$t_users = array();
-	foreach( $t_usernames as $t_username ) {
-		$t_users[] = array( 'name_or_realname' => trim( $t_username ) );
-	}
-
-	$t_payload['users'] = $t_users;
-}
+$f_user_ids = gpc_get_int_array( 'user_id', array() );
 
 $t_data = array(
 	'query' => array( 'issue_id' => $f_bug_id ),
-	'payload' => $t_payload,
 );
 
+if( $f_user_ids ) {
+	foreach( $f_user_ids as $t_user_id ) {
+		$t_users[] = array( 'id' => $t_user_id );
+	}
+	$t_data['payload'] = array( 'users' => $t_users );
+}
+
 $t_command = new MonitorAddCommand( $t_data );
 $t_command->execute();
 
diff --git a/bug_monitor_list_view_inc.php b/bug_monitor_list_view_inc.php
index 8b41e48ec..ebbcedb09 100644
--- a/bug_monitor_list_view_inc.php
+++ b/bug_monitor_list_view_inc.php
@@ -119,17 +119,65 @@ if( $t_can_see_monitors || $t_can_add_others ) {
 								</div>
 <?php
 	if( $t_can_add_others ) {
+		# Build list of users who can monitor the bug, excluding those already monitoring it
+		# @@@ Code is mostly based on print_user_option_list - maybe modify that slightly, to avoid code duplication
+		$t_users_can_monitor = project_get_all_user_rows( $g_project_override, config_get( 'monitor_bug_threshold' ) );
+
+		$t_display = array();
+		$t_sort = array();
+		$t_show_realname = ( ON == config_get( 'show_realname' ) );
+		$t_sort_by_last_name = ( ON == config_get( 'sort_by_last_name' ) );
+
+		foreach( $t_users_can_monitor as $key => $t_user ) {
+
+			# If user is already monitoring the issue, remove them from list
+			if( in_array( $t_user['id'], $t_users ) ) {
+				unset( $t_users_can_monitor[$key] );
+				continue;
+			}
+
+			$t_user_name = string_attribute( $t_user['username'] );
+			$t_sort_name = mb_strtolower( $t_user_name );
+			if( $t_show_realname && ( $t_user['realname'] <> '' ) ) {
+				$t_user_name = string_attribute( $t_user['realname'] );
+				if( $t_sort_by_last_name ) {
+					$t_sort_name_bits = explode( ' ', mb_strtolower( $t_user_name ), 2 );
+					$t_sort_name = ( isset( $t_sort_name_bits[1] ) ? $t_sort_name_bits[1] . ', ' : '' ) . $t_sort_name_bits[0];
+				} else {
+					$t_sort_name = mb_strtolower( $t_user_name );
+				}
+			}
+			$t_display[] = $t_user_name;
+			$t_sort[] = $t_sort_name;
+		}
+
+		# Display form only if there are users who can monitor the bug
+		if( count( $t_users_can_monitor ) > 0 ) {
+			array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users_can_monitor, $t_display );
+?>
+            <div class="space-10"></div>
+            <form method="get" action="bug_monitor_add.php">
+            <?php echo form_security_field( 'bug_monitor_add' ) ?>
+                <input type="hidden" name="bug_id" value="<?php echo (integer)$f_bug_id; ?>" />
+                <select name="user_id[]" class="input-sm" multiple>
+                    <option value="0"><?php echo '[' . lang_get( 'myself' ) . ']'; ?></option>";
+<?php
+						# Build selection list with all users who can monitor this bug
+						foreach( $t_users_can_monitor as $key => $t_user ) {
+							echo '<option value="' . $t_user['id'] . '" ';
+							echo '>' . string_attribute( $t_display[$key] ) . '</option>';
+						}
 ?>
+                </select>
 
-		<div class="space-10"></div>
-		<form method="get" action="bug_monitor_add.php" class="form-inline noprint">
-			<?php echo form_security_field( 'bug_monitor_add' ) ?>
-			<input type="hidden" name="bug_id" value="<?php echo (integer)$f_bug_id; ?>" />
-			<label for="bug_monitor_list_username"><?php echo lang_get( 'username' ) ?></label>
-			<input type="text" class="input-sm" id="bug_monitor_list_username" name="username" />
-			<input type="submit" class="btn btn-primary btn-sm btn-white btn-round" value="<?php echo lang_get( 'add_user_to_monitor' ) ?>" />
-		</form>
-<?php } ?>
+                <button class="btn btn-primary btn-sm btn-white btn-round">
+                    <?php echo lang_get( 'add_user_to_monitor' ) ?>
+                </button>
+            </form>
+<?php
+        }
+    }
+?>
 							</td>
 						</tr>
 					</table>
diff --git a/lang/strings_english.txt b/lang/strings_english.txt
index 11d04b9bc..a2f9bdc1c 100644
--- a/lang/strings_english.txt
+++ b/lang/strings_english.txt
@@ -1284,7 +1284,7 @@ $s_close_bug_button = 'Close';
 $s_move_bug_button = 'Move';
 $s_attached_files = 'Attached Files';
 $s_publish = 'Publish';
-$s_add_user_to_monitor = 'Add';
+$s_add_user_to_monitor = 'Start Monitoring';
 $s_browser_does_not_support_audio = 'Your browser does not support audio tag.';
 $s_browser_does_not_support_video = 'Your browser does not support video tag.';
 
-- 
2.17.1

