Browse Source

Merge pull request #1126 from Arantor/release-2.1

Group requests should be permanently logged and accountable
Arantor 11 years ago
parent
commit
ff12ed12ef

+ 38 - 11
Sources/Groups.php

@@ -452,8 +452,10 @@ function GroupRequests()
 		isAllowedTo('manage_membergroups');
 
 	// Normally, we act normally...
-	$where = $user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq'];
-	$where_parameters = array();
+	$where = ($user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']) . ' AND lgr.status = {int:status_open}';
+	$where_parameters = array(
+		'status_open' => 0,
+	);
 
 	// We've submitted?
 	if (isset($_POST[$context['session_var']]) && !empty($_POST['groupr']) && !empty($_POST['req_action']))
@@ -465,6 +467,8 @@ function GroupRequests()
 		foreach ($_POST['groupr'] as $k => $request)
 			$_POST['groupr'][$k] = (int) $request;
 
+		$log_changes = array();
+
 		// If we are giving a reason (And why shouldn't we?), then we don't actually do much.
 		if ($_POST['req_action'] == 'reason')
 		{
@@ -476,6 +480,9 @@ function GroupRequests()
 
 			$context['group_requests'] = list_getGroupRequests(0, $modSettings['defaultMaxMessages'], 'lgr.id_request', $where, $where_parameters);
 
+			// Need to make another token for this.
+			createToken('mod-gr');
+
 			// Let obExit etc sort things out.
 			obExit();
 		}
@@ -495,6 +502,7 @@ function GroupRequests()
 				ORDER BY mem.lngfile',
 				array(
 					'request_list' => $_POST['groupr'],
+					'status_open' => 0,
 				)
 			);
 			$email_details = array();
@@ -503,6 +511,16 @@ function GroupRequests()
 			{
 				$row['lngfile'] = empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'];
 
+				if (!isset($log_changes[$row['id_request']]))
+					$log_changes[$row['id_request']] = array(
+						'id_request' => $row['id_request'],
+						'status' => $_POST['req_action'] == 'approve' ? 1 : 2, // 1 = approved, 2 = rejected
+						'id_member_acted' => $user_info['id'],
+						'member_name_acted' => $user_info['name'],
+						'time_acted' => time(),
+						'act_reason' => $_POST['req_action'] != 'approve' && !empty($_POST['groupreason']) && !empty($_POST['groupreason'][$row['id_request']]) ? $smcFunc['htmlspecialchars']($_POST['groupreason'][$row['id_request']], ENT_QUOTES) : '',
+					);
+
 				// If we are approving work out what their new group is.
 				if ($_POST['req_action'] == 'approve')
 				{
@@ -546,15 +564,6 @@ function GroupRequests()
 			}
 			$smcFunc['db_free_result']($request);
 
-			// Remove the evidence...
-			$smcFunc['db_query']('', '
-				DELETE FROM {db_prefix}log_group_requests
-				WHERE id_request IN ({array_int:request_list})',
-				array(
-					'request_list' => $_POST['groupr'],
-				)
-			);
-
 			// Ensure everyone who is online gets their changes right away.
 			updateSettings(array('settings_updated' => time()));
 
@@ -622,6 +631,24 @@ function GroupRequests()
 				}
 			}
 
+			// Some changes to log?
+			if (!empty($log_changes))
+			{
+				foreach ($log_changes as $id_request => $details)
+				{
+					$smcFunc['db_query']('', '
+						UPDATE {db_prefix}log_group_requests
+						SET status = {int:status},
+							id_member_acted = {int:id_member_acted},
+							member_name_acted = {string:member_name_acted},
+							time_acted = {int:time_acted},
+							act_reason = {string:act_reason}
+						WHERE id_request = {int:id_request}',
+						$details
+					);
+				}
+			}
+
 			// Restore the current language.
 			loadLanguage('ModerationCenter');
 		}

+ 2 - 0
Sources/ModerationCenter.php

@@ -514,9 +514,11 @@ function ModBlockGroupRequests()
 			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member)
 			INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group)
 		WHERE ' . ($user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']) . '
+			AND lgr.status = {int:status_open}
 		ORDER BY lgr.id_request DESC
 		LIMIT 10',
 		array(
+			'status_open' => 0,
 		)
 	);
 	for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i ++)

+ 7 - 2
Sources/Profile-Modify.php

@@ -3491,7 +3491,7 @@ function groupMembership($memID)
 		SELECT mg.id_group, mg.group_name, mg.description, mg.group_type, mg.online_color, mg.hidden,
 			IFNULL(lgr.id_member, 0) AS pending
 		FROM {db_prefix}membergroups AS mg
-			LEFT JOIN {db_prefix}log_group_requests AS lgr ON (lgr.id_member = {int:selected_member} AND lgr.id_group = mg.id_group)
+			LEFT JOIN {db_prefix}log_group_requests AS lgr ON (lgr.id_member = {int:selected_member} AND lgr.id_group = mg.id_group AND lgr.status = {int:status_open})
 		WHERE (mg.id_group IN ({array_int:group_list})
 			OR mg.group_type > {int:nonjoin_group_id})
 			AND mg.min_posts = {int:min_posts}
@@ -3500,6 +3500,7 @@ function groupMembership($memID)
 		array(
 			'group_list' => $groups,
 			'selected_member' => $memID,
+			'status_open' => 0,
 			'nonjoin_group_id' => 1,
 			'min_posts' => -1,
 			'moderator_group' => 3,
@@ -3691,10 +3692,12 @@ function groupMembership2($profile_vars, $post_errors, $memID)
 			SELECT id_member
 			FROM {db_prefix}log_group_requests
 			WHERE id_member = {int:selected_member}
-				AND id_group = {int:selected_group}',
+				AND id_group = {int:selected_group}
+				AND status = {int:status_open}',
 			array(
 				'selected_member' => $memID,
 				'selected_group' => $group_id,
+				'status_open' => 0,
 			)
 		);
 		if ($smcFunc['db_num_rows']($request) != 0)
@@ -3706,9 +3709,11 @@ function groupMembership2($profile_vars, $post_errors, $memID)
 			'{db_prefix}log_group_requests',
 			array(
 				'id_member' => 'int', 'id_group' => 'int', 'time_applied' => 'int', 'reason' => 'string-65534',
+				'status' => 'int', 'id_member_acted' => 'int', 'member_name_acted' => 'string', 'time_acted' => 'int', 'act_reason' => 'string',
 			),
 			array(
 				$memID, $group_id, time(), $_POST['reason'],
+				0, 0, '', 0, '',
 			),
 			array('id_request')
 		);

+ 188 - 11
Sources/Profile-View.php

@@ -1310,17 +1310,18 @@ function tracking($memID)
 	global $sourcedir, $context, $txt, $scripturl, $modSettings, $user_profile;
 
 	$subActions = array(
-		'activity' => array('trackActivity', $txt['trackActivity']),
-		'ip' => array('TrackIP', $txt['trackIP']),
-		'edits' => array('trackEdits', $txt['trackEdits']),
-		'logins' => array('TrackLogins', $txt['trackLogins']),
+		'activity' => array('trackActivity', $txt['trackActivity'], 'moderate_forum'),
+		'ip' => array('TrackIP', $txt['trackIP'], 'moderate_forum'),
+		'edits' => array('trackEdits', $txt['trackEdits'], 'moderate_forum'),
+		'groupreq' => array('trackGroupReq', $txt['trackGroupRequests'], 'approve_group_requests'),
+		'logins' => array('TrackLogins', $txt['trackLogins'], 'moderate_forum'),
 	);
 
-	$context['tracking_area'] = isset($_GET['sa']) && isset($subActions[$_GET['sa']]) ? $_GET['sa'] : 'activity';
-
-	// @todo what is $types? it is never set so this will never be true
-	if (isset($types[$context['tracking_area']][1]))
-		require_once($sourcedir . '/' . $types[$context['tracking_area']][1]);
+	foreach ($subActions as $sa => $action)
+	{
+		if (!allowedTo($action[2]))
+			unset($subActions[$sa]);
+	}
 
 	// Create the tabs for the template.
 	$context[$context['profile_menu_name']]['tab_data'] = array(
@@ -1331,12 +1332,25 @@ function tracking($memID)
 			'activity' => array(),
 			'ip' => array(),
 			'edits' => array(),
+			'groupreq' => array(),
+			'logins' => array(),
 		),
 	);
 
 	// Moderation must be on to track edits.
-	if (empty($modSettings['modlog_enabled']))
-		unset($context[$context['profile_menu_name']]['tab_data']['edits']);
+	if (empty($modSettings['userlog_enabled']))
+		unset($context[$context['profile_menu_name']]['tab_data']['edits'], $subActions['edits']);
+
+	// Group requests must be active to show it...
+	if (empty($modSettings['show_group_membership']))
+		unset($context[$context['profile_menu_name']]['tab_data']['groupreq'], $subActions['groupreq']);
+
+	if (empty($subActions))
+		fatal_lang_error('no_access', false);
+
+	$keys = array_keys($subActions);
+	$default = array_shift($keys);
+	$context['tracking_area'] = isset($_GET['sa']) && isset($subActions[$_GET['sa']]) ? $_GET['sa'] : $default;
 
 	// Set a page title.
 	$context['page_title'] = $txt['trackUser'] . ' - ' . $subActions[$context['tracking_area']][1] . ' - ' . $user_profile[$memID]['real_name'];
@@ -2347,6 +2361,169 @@ function list_getProfileEdits($start, $items_per_page, $sort, $memID)
 	return $edits;
 }
 
+/**
+ * Display the history of group requests made by the user whose profile we are viewing.
+ *
+ * @param int $memID id_member
+ */
+function trackGroupReq($memID)
+{
+	global $scripturl, $txt, $modSettings, $sourcedir, $context;
+
+	require_once($sourcedir . '/Subs-List.php');
+
+	// Set the options for the error lists.
+	$listOptions = array(
+		'id' => 'request_list',
+		'title' => sprintf($txt['trackGroupRequests_title'], $context['member']['name']),
+		'items_per_page' => $modSettings['defaultMaxMessages'],
+		'no_items_label' => $txt['requested_none'],
+		'base_href' => $scripturl . '?action=profile;area=tracking;sa=groupreq;u=' . $memID,
+		'default_sort_col' => 'time_applied',
+		'get_items' => array(
+			'function' => 'list_getGroupRequests',
+			'params' => array(
+				$memID,
+			),
+		),
+		'get_count' => array(
+			'function' => 'list_getGroupRequestsCount',
+			'params' => array(
+				$memID,
+			),
+		),
+		'columns' => array(
+			'group' => array(
+				'header' => array(
+					'value' => $txt['requested_group'],
+				),
+				'data' => array(
+					'db' => 'group_name',
+				),
+			),
+			'group_reason' => array(
+				'header' => array(
+					'value' => $txt['requested_group_reason'],
+				),
+				'data' => array(
+					'db' => 'group_reason',
+				),
+			),
+			'time_applied' => array(
+				'header' => array(
+					'value' => $txt['requested_group_time'],
+				),
+				'data' => array(
+					'db' => 'time_applied',
+					'timeformat' => true,
+				),
+				'sort' => array(
+					'default' => 'time_applied DESC',
+					'reverse' => 'time_applied',
+				),
+			),
+			'outcome' => array(
+				'header' => array(
+					'value' => $txt['requested_group_outcome'],
+				),
+				'data' => array(
+					'db' => 'outcome',
+				),
+			),
+		),
+	);
+
+	// Create the error list.
+	createList($listOptions);
+
+	$context['sub_template'] = 'show_list';
+	$context['default_list'] = 'request_list';
+}
+
+/**
+ * How many edits?
+ *
+ * @param int $memID id_member
+ * @return string number of profile edits
+ */
+function list_getGroupRequestsCount($memID)
+{
+	global $smcFunc, $user_info;
+
+	$request = $smcFunc['db_query']('', '
+		SELECT COUNT(*) AS req_count
+		FROM {db_prefix}log_group_requests AS lgr
+		WHERE id_member = {int:memID}
+			AND ' . ($user_info['mod_cache']['gq'] == '1=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']),
+		array(
+			'memID' => $memID,
+		)
+	);
+	list ($report_count) = $smcFunc['db_fetch_row']($request);
+	$smcFunc['db_free_result']($request);
+
+	return (int) $report_count;
+}
+
+/**
+ * @todo needs a description
+ *
+ * @param int $start
+ * @param int $items_per_page
+ * @param string $sort
+ * @param int $memID
+ * @return array
+ */
+function list_getGroupRequests($start, $items_per_page, $sort, $memID)
+{
+	global $smcFunc, $txt, $scripturl, $user_info;
+
+	$groupreq = array();
+
+	$request = $smcFunc['db_query']('', '
+		SELECT
+			lgr.id_group, mg.group_name, mg.online_color, lgr.time_applied, lgr.reason, lgr.status,
+			ma.id_member AS id_member_acted, IFNULL(ma.member_name, lgr.member_name_acted) AS act_name, lgr.time_acted, lgr.act_reason
+		FROM {db_prefix}log_group_requests AS lgr
+			LEFT JOIN {db_prefix}members AS ma ON (lgr.id_member_acted = ma.id_member)
+			INNER JOIN {db_prefix}membergroups AS mg ON (lgr.id_group = mg.id_group)
+		WHERE lgr.id_member = {int:memID}
+			AND ' . ($user_info['mod_cache']['gq'] == '1=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']) . '
+		ORDER BY ' . $sort . '
+		LIMIT ' . $start . ', ' . $items_per_page,
+		array(
+			'memID' => $memID,
+		)
+	);
+	while ($row = $smcFunc['db_fetch_assoc']($request))
+	{
+		$this_req = array(
+			'group_name' => empty($row['online_color']) ? $row['group_name'] : '<span style="color:' . $row['online_color'] . '">' . $row['group_name'] . '</span>',
+			'group_reason' => $row['reason'],
+			'time_applied' => $row['time_applied'],
+		);
+		switch ($row['status'])
+		{
+			case 0:
+				$this_req['outcome'] = $txt['outcome_pending'];
+				break;
+			case 1:
+				$member_link = empty($row['id_member_acted']) ? $row['act_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_acted'] . '">' . $row['act_name'] . '</a>';
+				$this_req['outcome'] = sprintf($txt['outcome_approved'], $member_link, timeformat($row['time_acted']));
+				break;
+			case 2:
+				$member_link = empty($row['id_member_acted']) ? $row['act_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_acted'] . '">' . $row['act_name'] . '</a>';
+				$this_req['outcome'] = sprintf(!empty($row['act_reason']) ? $txt['outcome_refused_reason'] : $txt['outcome_refused'], $member_link, timeformat($row['time_acted']), $row['act_reason']);
+				break;
+		}
+
+		$groupreq[] = $this_req;
+	}
+	$smcFunc['db_free_result']($request);
+
+	return $groupreq;
+}
+
 /**
  * @todo needs a description
  *

+ 9 - 3
Sources/Profile.php

@@ -65,6 +65,11 @@ function ModifyProfile($post_errors = array())
 	// Is this the profile of the user himself or herself?
 	$context['user']['is_owner'] = $memID == $user_info['id'];
 
+	// Group management isn't actually a permission. But we need it to be for this, so we need a phantom permission.
+	// And we care about what the current user can do, not what the user whose profile it is.
+	if ($user_info['mod_cache']['gq'] != '0=1')
+		$user_info['permissions'][] = 'approve_group_requests';
+
 	/* Define all the sections within the profile area!
 		We start by defining the permission required - then SMF takes this and turns it into the relevant context ;)
 		Possible fields:
@@ -170,11 +175,12 @@ function ModifyProfile($post_errors = array())
 						'activity' => array($txt['trackActivity'], 'moderate_forum'),
 						'ip' => array($txt['trackIP'], 'moderate_forum'),
 						'edits' => array($txt['trackEdits'], 'moderate_forum', 'enabled' => !empty($modSettings['userlog_enabled'])),
-						'logins' => array($txt['trackLogins'], array('is_not_guest', 'moderate_forum')),
+						'groupreq' => array($txt['trackGroupRequests'], 'approve_group_requests', 'enabled' => !empty($modSettings['show_group_membership'])),
+						'logins' => array($txt['trackLogins'], 'moderate_forum'),
 					),
 					'permission' => array(
-						'own' => 'moderate_forum',
-						'any' => 'moderate_forum',
+						'own' => array('moderate_forum', 'approve_group_requests'),
+						'any' => array('moderate_forum', 'approve_group_requests'),
 					),
 				),
 				'viewwarning' => array(

+ 1 - 0
Themes/default/ManageMembergroups.template.php

@@ -730,6 +730,7 @@ function template_group_request_reason()
 					<input type="submit" name="go" value="', $txt['mc_groupr_submit'], '" class="button_submit" />
 					<input type="hidden" name="req_action" value="got_reason" />
 					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
+					<input type="hidden" name="', $context['mod-gr_token_var'], '" value="', $context['mod-gr_token'], '" />
 				</div>
 			</div>
 		</form>

+ 11 - 0
Themes/default/languages/Profile.english.php

@@ -514,4 +514,15 @@ $txt['trackEdit_action_email_address'] = 'Email Address';
 $txt['trackEdit_action_id_group'] = 'Primary Membergroup';
 $txt['trackEdit_action_additional_groups'] = 'Additional Membergroups';
 
+$txt['trackGroupRequests'] = 'Group Requests';
+$txt['trackGroupRequests_title'] = 'Group Requests for %1$s';
+$txt['requested_group'] = 'Requested Group';
+$txt['requested_group_reason'] = 'Reason Given';
+$txt['requested_group_time'] = 'Date';
+$txt['requested_group_outcome'] = 'Outcome';
+$txt['requested_none'] = 'There are no requests made by this user.';
+$txt['outcome_pending'] = 'Open';
+$txt['outcome_approved'] = 'Approved by %1$s on %2$s';
+$txt['outcome_refused'] = 'Refused by %1$s on %2$s';
+$txt['outcome_refused_reason'] = 'Refused by %1$s on %2$s, reason given: %3$s';
 ?>

+ 6 - 1
other/install_2-1_mysql.sql

@@ -879,8 +879,13 @@ CREATE TABLE {$db_prefix}log_group_requests (
   id_group smallint(5) unsigned NOT NULL default '0',
   time_applied int(10) unsigned NOT NULL default '0',
   reason text NOT NULL,
+  status tinyint(3) unsigned NOT NULL default '0',
+  id_member_acted mediumint(8) unsigned NOT NULL default '0',
+  member_name_acted varchar(255) NOT NULL default '',
+  time_acted int(10) unsigned NOT NULL default '0',
+  act_reason text NOT NULL,
   PRIMARY KEY (id_request),
-  UNIQUE id_member (id_member, id_group)
+  KEY id_member (id_member, id_group)
 ) ENGINE=MyISAM;
 
 #

+ 6 - 1
other/install_2-1_postgresql.sql

@@ -1150,6 +1150,11 @@ CREATE TABLE {$db_prefix}log_group_requests (
   id_group smallint NOT NULL default '0',
   time_applied int NOT NULL default '0',
   reason text NOT NULL,
+  status smallint NOT NULL default '0',
+  id_member_acted int NOT NULL default '0',
+  member_name_acted varchar(255) NOT NULL,
+  time_acted int NOT NULL default '0',
+  act_reason text NOT NULL,
   PRIMARY KEY (id_request)
 );
 
@@ -1157,7 +1162,7 @@ CREATE TABLE {$db_prefix}log_group_requests (
 # Indexes for table `log_group_requests`
 #
 
-CREATE UNIQUE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
+CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
 
 #
 # Table structure for table `log_karma`

+ 7 - 2
other/install_2-1_sqlite.sql

@@ -917,14 +917,19 @@ CREATE TABLE {$db_prefix}log_group_requests (
   id_member int NOT NULL default '0',
   id_group smallint NOT NULL default '0',
   time_applied int NOT NULL default '0',
-  reason text NOT NULL
+  reason text NOT NULL,
+  status smallint NOT NULL default '0',
+  id_member_acted int NOT NULL default '0',
+  member_name_acted varchar(255) NOT NULL,
+  time_acted int NOT NULL default '0',
+  act_reason text NOT NULL
 );
 
 #
 # Indexes for table `log_group_requests`
 #
 
-CREATE UNIQUE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
+CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
 
 #
 # Table structure for table `log_karma`

+ 7 - 2
other/install_2-1_sqlite3.sql

@@ -917,14 +917,19 @@ CREATE TABLE {$db_prefix}log_group_requests (
   id_member int NOT NULL default '0',
   id_group smallint NOT NULL default '0',
   time_applied int NOT NULL default '0',
-  reason text NOT NULL
+  reason text NOT NULL,
+  status smallint NOT NULL default '0',
+  id_member_acted int NOT NULL default '0',
+  member_name_acted varchar(255) NOT NULL,
+  time_acted int NOT NULL default '0',
+  act_reason text NOT NULL
 );
 
 #
 # Indexes for table `log_group_requests`
 #
 
-CREATE UNIQUE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
+CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
 
 #
 # Table structure for table `log_karma`

+ 19 - 0
other/upgrade_2-1_mysql.sql

@@ -188,6 +188,25 @@ CHANGE ip_low4 ip_low4 smallint(255) unsigned NOT NULL DEFAULT '0',
 CHANGE ip_high4 ip_high4 smallint(255) unsigned NOT NULL DEFAULT '0';
 ---#
 
+/******************************************************************************/
+--- Adding support for logging who fulfils a group request.
+/******************************************************************************/
+
+---# Adding new columns to log_group_requests
+ALTER TABLE {$db_prefix}log_group_requests
+ADD COLUMN status tinyint(3) unsigned NOT NULL default '0',
+ADD COLUMN id_member_acted mediumint(8) unsigned NOT NULL default '0',
+ADD COLUMN member_name_acted varchar(255) NOT NULL default '',
+ADD COLUMN time_acted int(10) unsigned NOT NULL default '0',
+ADD COLUMN act_reason text NOT NULL;
+---#
+
+---# Adjusting the indexes for log_group_requests
+ALTER TABLE {$db_prefix}log_group_requests
+DROP INDEX `id_member`,
+ADD INDEX `id_member` (`id_member`, `id_group`);
+---#
+
 /******************************************************************************/
 --- Adding support for <credits> tag in package manager
 /******************************************************************************/

+ 18 - 0
other/upgrade_2-1_postgresql.sql

@@ -218,6 +218,24 @@ upgrade_query("
 ---}
 ---#
 
+/******************************************************************************/
+--- Adding support for logging who fulfils a group request.
+/******************************************************************************/
+
+---# Adding new columns to log_group_requests
+ALTER TABLE {$db_prefix}log_group_requests
+ADD COLUMN status smallint NOT NULL default '0',
+ADD COLUMN id_member_acted int NOT NULL default '0',
+ADD COLUMN member_name_acted varchar(255) NOT NULL default '',
+ADD COLUMN time_acted int NOT NULL default '0',
+ADD COLUMN act_reason text NOT NULL;
+---#
+
+---# Adjusting the indexes for log_group_requests
+DROP INDEX {$db_prefix}log_group_requests_id_member;
+CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
+---#
+
 /******************************************************************************/
 --- Adding support for <credits> tag in package manager
 /******************************************************************************/

+ 18 - 0
other/upgrade_2-1_sqlite.sql

@@ -188,6 +188,24 @@ CHANGE ip_low4 ip_low4 smallint(255) unsigned NOT NULL DEFAULT '0',
 CHANGE ip_high4 ip_high4 smallint(255) unsigned NOT NULL DEFAULT '0';
 ---#
 
+/******************************************************************************/
+--- Adding support for logging who fulfils a group request.
+/******************************************************************************/
+
+---# Adding new columns to log_group_requests
+ALTER TABLE {$db_prefix}log_group_requests
+ADD COLUMN status smallint unsigned NOT NULL default '0',
+ADD COLUMN id_member_acted int unsigned NOT NULL default '0',
+ADD COLUMN member_name_acted varchar(255) NOT NULL default '',
+ADD COLUMN time_acted int unsigned NOT NULL default '0',
+ADD COLUMN act_reason text NOT NULL;
+---#
+
+---# Adjusting the indexes for log_group_requests
+DROP INDEX {$db_prefix}log_group_requests_id_member;
+CREATE INDEX {$db_prefix}log_group_requests_id_member ON {$db_prefix}log_group_requests (id_member, id_group);
+---#
+
 /******************************************************************************/
 --- Adding support for <credits> tag in package manager
 /******************************************************************************/