Browse Source

Merge pull request #57 from live627/profile_hooks

Profile hooks and logging changes
emanuele45 12 years ago
parent
commit
8a2d637373
6 changed files with 155 additions and 102 deletions
  1. 105 76
      Sources/Logging.php
  2. 2 2
      Sources/MoveTopic.php
  3. 3 5
      Sources/Profile-Actions.php
  4. 13 10
      Sources/Profile-Modify.php
  5. 15 2
      Sources/Profile.php
  6. 17 7
      Sources/Subs-Members.php

+ 105 - 76
Sources/Logging.php

@@ -162,22 +162,22 @@ function writeLog($force = false)
 function logLastDatabaseError()
 {
 	global $boarddir;
-	
+
 	// Make a note of the last modified time in case someone does this before us
 	$last_db_error_change = @filemtime($boarddir . '/db_last_error.php');
-	
+
 	// save the old file before we do anything
 	$file = $boarddir . '/db_last_error.php';
 	$dberror_backup_fail = !@is_writable($boarddir . '/db_last_error_bak.php') || !@copy($file, $boarddir . '/db_last_error_bak.php');
 	$dberror_backup_fail = !$dberror_backup_fail ? (!file_exists($boarddir . '/db_last_error_bak.php') || filesize($boarddir . '/db_last_error_bak.php') === 0) : $dberror_backup_fail;
-	
+
 	clearstatcache();
 	if (filemtime($boarddir . '/db_last_error.php') === $last_db_error_change)
 	{
-		// Write the change 
+		// Write the change
 		$write_db_change =  '<' . '?' . "php\n" . '$db_last_error = ' . time() . ';' . "\n" . '?' . '>';
 		$written_bytes = file_put_contents($boarddir . '/db_last_error.php', $write_db_change, LOCK_EX);
-		
+
 		// survey says ...
 		if ($written_bytes !== strlen($write_db_change) && !$dberror_backup_fail)
 		{
@@ -248,14 +248,14 @@ function displayDebug()
 	', $txt['debug_language_files'], count($context['debug']['language_files']), ': <em>', implode('</em>, <em>', $context['debug']['language_files']), '</em>.<br />
 	', $txt['debug_stylesheets'], count($context['debug']['sheets']), ': <em>', implode('</em>, <em>', $context['debug']['sheets']), '</em>.<br />
 	', $txt['debug_files_included'], count($files), ' - ', round($total_size / 1024), $txt['debug_kb'], ' (<a href="javascript:void(0);" onclick="document.getElementById(\'debug_include_info\').style.display = \'inline\'; this.style.display = \'none\'; return false;">', $txt['debug_show'], '</a><span id="debug_include_info" style="display: none;"><em>', implode('</em>, <em>', $files), '</em></span>)<br />';
-	
+
 	// What tokens are active?
 	if (isset($_SESSION['token']))
 	{
 		$token_list = array();
 		foreach ($_SESSION['token'] as $key => $data)
 			$token_list[] = $key;
-		
+
 		echo $txt['debug_tokens'] . '<em>' . implode(',</em> <em>', $token_list), '</em>.<br />';
 	}
 
@@ -384,102 +384,134 @@ function trackStats($stats = array())
 
 /**
  * This function logs an action in the respective log. (database log)
+ * You should use {@link logActions()} instead.
  * @example logAction('remove', array('starter' => $id_member_started));
  *
+ * @deprecated deprecated since version 2.1
  * @param string $action
  * @param array $extra = array()
  * @param string $log_type, options 'moderate', 'admin', ...etc.
  */
 function logAction($action, $extra = array(), $log_type = 'moderate')
+{
+	return logActions(array(array(
+		'action' => $action,
+		'log_type' => $log_type,
+		'extra' => $extra,
+	)));
+}
+
+/**
+ * Log changes to the forum, such as moderation events or administrative changes.
+ * This behaves just like logAction() in SMF 2.0, except that it is designed to log multiple actions at once.
+ *
+ * @param array $logs
+ * @return the last logged ID
+ */
+function logActions($logs)
 {
 	global $modSettings, $user_info, $smcFunc, $sourcedir;
 
+	$inserts = array();
 	$log_types = array(
 		'moderate' => 1,
 		'user' => 2,
 		'admin' => 3,
 	);
 
+	call_integration_hook('integrate_log_types', array($log_types));
+
 	// No point in doing anything, if the log isn't even enabled.
-	if (empty($modSettings['modlog_enabled']) || !isset($log_types[$log_type]))
+	if (empty($modSettings['modlog_enabled']))
 		return false;
 
-	if (!is_array($extra))
-		trigger_error('logAction(): data is not an array with action \'' . $action . '\'', E_USER_NOTICE);
-
-	// Pull out the parts we want to store separately, but also make sure that the data is proper
-	if (isset($extra['topic']))
+	foreach ($logs as $log)
 	{
-		if (!is_numeric($extra['topic']))
-			trigger_error('logAction(): data\'s topic is not a number', E_USER_NOTICE);
-		$topic_id = empty($extra['topic']) ? '0' : (int)$extra['topic'];
-		unset($extra['topic']);
-	}
-	else
-		$topic_id = '0';
+		if (!isset($log_types[$log['log_type']]))
+			return false;
 
-	if (isset($extra['message']))
-	{
-		if (!is_numeric($extra['message']))
-			trigger_error('logAction(): data\'s message is not a number', E_USER_NOTICE);
-		$msg_id = empty($extra['message']) ? '0' : (int)$extra['message'];
-		unset($extra['message']);
-	}
-	else
-		$msg_id = '0';
+		if (!is_array($log['extra']))
+			trigger_error('logActions(): data is not an array with action \'' . $action . '\'', E_USER_NOTICE);
 
-	// @todo cache this?
-	// Is there an associated report on this?
-	if (in_array($action, array('move', 'remove', 'split', 'merge')))
-	{
-		$request = $smcFunc['db_query']('', '
-			SELECT id_report
-			FROM {db_prefix}log_reported
-			WHERE {raw:column_name} = {int:reported}
-			LIMIT 1',
-			array(
-				'column_name' => !empty($msg_id) ? 'id_msg' : 'id_topic',
-				'reported' => !empty($msg_id) ? $msg_id : $topic_id,
-		));
+		// Pull out the parts we want to store separately, but also make sure that the data is proper
+		if (isset($log['extra']['topic']))
+		{
+			if (!is_numeric($log['extra']['topic']))
+				trigger_error('logActions(): data\'s topic is not a number', E_USER_NOTICE);
+			$topic_id = empty($log['extra']['topic']) ? 0 : (int) $log['extra']['topic'];
+			unset($log['extra']['topic']);
+		}
+		else
+			$topic_id = 0;
 
-		// Alright, if we get any result back, update open reports.
-		if ($smcFunc['db_num_rows']($request) > 0)
+		if (isset($log['extra']['message']))
 		{
-			require_once($sourcedir . '/ModerationCenter.php');
-			updateSettings(array('last_mod_report_action' => time()));
-			recountOpenReports();
+			if (!is_numeric($log['extra']['message']))
+				trigger_error('logActions(): data\'s message is not a number', E_USER_NOTICE);
+			$msg_id = empty($log['extra']['message']) ? 0 : (int) $log['extra']['message'];
+			unset($log['extra']['message']);
 		}
-		$smcFunc['db_free_result']($request);
-	}
+		else
+			$msg_id = 0;
 
-	if (isset($extra['member']) && !is_numeric($extra['member']))
-		trigger_error('logAction(): data\'s member is not a number', E_USER_NOTICE);
+		// @todo cache this?
+		// Is there an associated report on this?
+		if (in_array($log['action'], array('move', 'remove', 'split', 'merge')))
+		{
+			$request = $smcFunc['db_query']('', '
+				SELECT id_report
+				FROM {db_prefix}log_reported
+				WHERE {raw:column_name} = {int:reported}
+				LIMIT 1',
+				array(
+					'column_name' => !empty($msg_id) ? 'id_msg' : 'id_topic',
+					'reported' => !empty($msg_id) ? $msg_id : $topic_id,
+			));
 
-	if (isset($extra['board']))
-	{
-		if (!is_numeric($extra['board']))
-			trigger_error('logAction(): data\'s board is not a number', E_USER_NOTICE);
-		$board_id = empty($extra['board']) ? '0' : (int)$extra['board'];
-		unset($extra['board']);
-	}
-	else
-		$board_id = '0';
+			// Alright, if we get any result back, update open reports.
+			if ($smcFunc['db_num_rows']($request) > 0)
+			{
+				require_once($sourcedir . '/ModerationCenter.php');
+				updateSettings(array('last_mod_report_action' => time()));
+				recountOpenReports();
+			}
+			$smcFunc['db_free_result']($request);
+		}
 
-	if (isset($extra['board_to']))
-	{
-		if (!is_numeric($extra['board_to']))
-			trigger_error('logAction(): data\'s board_to is not a number', E_USER_NOTICE);
-		if (empty($board_id))
+		if (isset($log['extra']['member']) && !is_numeric($log['extra']['member']))
+			trigger_error('logActions(): data\'s member is not a number', E_USER_NOTICE);
+
+		if (isset($log['extra']['board']))
 		{
-			$board_id = empty($extra['board_to']) ? '0' : (int)$extra['board_to'];
-			unset($extra['board_to']);
+			if (!is_numeric($log['extra']['board']))
+				trigger_error('logActions(): data\'s board is not a number', E_USER_NOTICE);
+			$board_id = empty($log['extra']['board']) ? 0 : (int) $log['extra']['board'];
+			unset($log['extra']['board']);
 		}
-	}
+		else
+			$board_id = 0;
 
-	if (isset($extra['member_affected']))
-		$memID = $extra['member_affected'];
-	else
-		$memID = $user_info['id'];
+		if (isset($log['extra']['board_to']))
+		{
+			if (!is_numeric($log['extra']['board_to']))
+				trigger_error('logActions(): data\'s board_to is not a number', E_USER_NOTICE);
+			if (empty($board_id))
+			{
+				$board_id = empty($log['extra']['board_to']) ? 0 : (int) $log['extra']['board_to'];
+				unset($log['extra']['board_to']);
+			}
+		}
+
+		if (isset($log['extra']['member_affected']))
+			$memID = $log['extra']['member_affected'];
+		else
+			$memID = $user_info['id'];
+
+		$inserts[] = array(
+			time(), $log_types[$log['log_type']], $memID, $user_info['ip'], $log['action'],
+			$board_id, $topic_id, $msg_id, serialize($log['extra']),
+		);
+	}
 
 	$smcFunc['db_insert']('',
 		'{db_prefix}log_actions',
@@ -487,10 +519,7 @@ function logAction($action, $extra = array(), $log_type = 'moderate')
 			'log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string',
 			'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534',
 		),
-		array(
-			time(), $log_types[$log_type], $memID, $user_info['ip'], $action,
-			$board_id, $topic_id, $msg_id, serialize($extra),
-		),
+		$inserts,
 		array('id_action')
 	);
 

+ 2 - 2
Sources/MoveTopic.php

@@ -296,7 +296,7 @@ function MoveTopic2()
 			$txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]',
 			$txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'
 		));
-		
+
 		// auto remove this MOVED redirection topic in the future?
 		$redirect_expires = !empty($_POST['redirect_expires']) ? ((int) ($_POST['redirect_expires'] * 60) + time()) : 0;
 
@@ -392,7 +392,7 @@ function moveTopics($topics, $toBoard)
 	// Empty array?
 	if (empty($topics))
 		return;
-		
+
 	// Only a single topic.
 	if (is_numeric($topics))
 		$topics = array($topics);

+ 3 - 5
Sources/Profile-Actions.php

@@ -538,11 +538,9 @@ function deleteAccount($memID)
 /**
  * Actually delete an account.
  *
- * @param $profile_vars
- * @param $post_errors
  * @param int $memID, the member ID
  */
-function deleteAccount2($profile_vars, $post_errors, $memID)
+function deleteAccount2($memID)
 {
 	global $user_info, $sourcedir, $context, $cur_profile, $modSettings, $smcFunc;
 
@@ -648,7 +646,7 @@ function deleteAccount2($profile_vars, $post_errors, $memID)
 			deleteMembers($memID);
 	}
 	// Do they need approval to delete?
-	elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum'))
+	elseif (!empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum'))
 	{
 		// Setup their account for deletion ;)
 		updateMemberData($memID, array('is_activated' => 4));
@@ -656,7 +654,7 @@ function deleteAccount2($profile_vars, $post_errors, $memID)
 		updateSettings(array('unapprovedMembers' => true), true);
 	}
 	// Also check if you typed your password correctly.
-	elseif (empty($post_errors))
+	else
 	{
 		deleteMembers($memID);
 

+ 13 - 10
Sources/Profile-Modify.php

@@ -673,6 +673,8 @@ function loadProfileFields($force_reload = false)
 	
 	call_integration_hook('integrate_profile_fields', array(&$profile_fields));
 
+	call_integration_hook('integrate_load_profile_fields', array($profile_fields));
+
 	$disabled_fields = !empty($modSettings['disabled_profile_fields']) ? explode(',', $modSettings['disabled_profile_fields']) : array();
 	// For each of the above let's take out the bits which don't apply - to save memory and security!
 	foreach ($profile_fields as $key => $field)
@@ -1263,6 +1265,8 @@ function makeCustomFieldChanges($memID, $area, $sanitize = true)
 	}
 	$smcFunc['db_free_result']($request);
 
+	call_integration_hook('integrate_save_custom_profile_fields', array($changes, $log_changes, $memID, $area, $sanitize));
+
 	// Make those changes!
 	if (!empty($changes) && empty($context['password_auth_failed']))
 	{
@@ -1275,8 +1279,7 @@ function makeCustomFieldChanges($memID, $area, $sanitize = true)
 		if (!empty($log_changes) && !empty($modSettings['modlog_enabled']))
 		{
 			require_once($sourcedir . '/Logging.php');
-			foreach ($log_changes as $log_change)
-				logAction($log_change['action'], $log_change['extra'], $log_change['log_type']);
+			logActions($log_changes);
 		}
 	}
 }
@@ -2887,21 +2890,21 @@ function profileValidateSignature(&$value)
 		$disabledTags = !empty($sig_bbc) ? explode(',', $sig_bbc) : array();
 
 		$unparsed_signature = strtr(un_htmlspecialchars($value), array("\r" => '', '&#039' => '\''));
-		
+
 		// Too many lines?
 		if (!empty($sig_limits[2]) && substr_count($unparsed_signature, "\n") >= $sig_limits[2])
 		{
 			$txt['profile_error_signature_max_lines'] = sprintf($txt['profile_error_signature_max_lines'], $sig_limits[2]);
 			return 'signature_max_lines';
 		}
-		
+
 		// Too many images?!
 		if (!empty($sig_limits[3]) && (substr_count(strtolower($unparsed_signature), '[img') + substr_count(strtolower($unparsed_signature), '<img')) > $sig_limits[3])
 		{
 			$txt['profile_error_signature_max_image_count'] = sprintf($txt['profile_error_signature_max_image_count'], $sig_limits[3]);
 			return 'signature_max_image_count';
 		}
-		
+
 		// What about too many smileys!
 		$smiley_parsed = $unparsed_signature;
 		parsesmileys($smiley_parsed);
@@ -2913,7 +2916,7 @@ function profileValidateSignature(&$value)
 			$txt['profile_error_signature_max_smileys'] = sprintf($txt['profile_error_signature_max_smileys'], $sig_limits[4]);
 			return 'signature_max_smileys';
 		}
-		
+
 		// Maybe we are abusing font sizes?
 		if (!empty($sig_limits[7]) && preg_match_all('~\[size=([\d\.]+)?(px|pt|em|x-large|larger)~i', $unparsed_signature, $matches) !== false && isset($matches[2]))
 		{
@@ -2937,7 +2940,7 @@ function profileValidateSignature(&$value)
 				}
 			}
 		}
-		
+
 		// The difficult one - image sizes! Don't error on this - just fix it.
 		if ((!empty($sig_limits[5]) || !empty($sig_limits[6])))
 		{
@@ -3022,7 +3025,7 @@ function profileValidateSignature(&$value)
 					$value = str_replace(array_keys($replaces), array_values($replaces), $value);
 			}
 		}
-		
+
 		// Any disabled BBC?
 		$disabledSigBBC = implode('|', $disabledTags);
 		if (!empty($disabledSigBBC))
@@ -3037,7 +3040,7 @@ function profileValidateSignature(&$value)
 	}
 
 	preparsecode($value);
-	
+
 	// Too long?
 	if (!allowedTo('admin_forum') && !empty($sig_limits[1]) && $smcFunc['strlen'](str_replace('<br />', "\n", $value)) > $sig_limits[1])
 	{
@@ -3080,7 +3083,7 @@ function profileValidateEmail($email, $memID = 0)
 			'email_address' => $email,
 		)
 	);
-	
+
 	if ($smcFunc['db_num_rows']($request) > 0)
 		return 'email_taken';
 	$smcFunc['db_free_result']($request);

+ 15 - 2
Sources/Profile.php

@@ -561,7 +561,7 @@ function ModifyProfile($post_errors = array())
 		{
 			if (empty($post_errors))
 			{
-				deleteAccount2($profile_vars, $post_errors, $memID);
+				deleteAccount2($memID);
 				redirectexit();
 			}
 		}
@@ -587,6 +587,8 @@ function ModifyProfile($post_errors = array())
 			saveProfileChanges($profile_vars, $post_errors, $memID);
 		}
 
+		call_integration_hook('integrate_profile_save', array($profile_vars, $post_errors, $memID));
+
 		// There was a problem, let them try to re-enter.
 		if (!empty($post_errors))
 		{
@@ -620,7 +622,16 @@ function ModifyProfile($post_errors = array())
 				$log_changes = array();
 				require_once($sourcedir . '/Logging.php');
 				foreach ($context['log_changes'] as $k => $v)
-					logAction($k, array_merge($v, array('applicator' => $user_info['id'], 'member_affected' => $memID)), 'user');
+					$log_changes[] = array(
+						'action' => $k,
+						'log_type' => 'user',
+						'extra' => array_merge($v, array(
+							'applicator' => $user_info['id'],
+							'member_affected' => $memID,
+						)),
+					);
+
+				logActions($log_changes);
 			}
 
 			// Have we got any post save functions to execute?
@@ -782,6 +793,8 @@ function loadCustomFields($memID, $area = 'summary')
 		);
 	}
 	$smcFunc['db_free_result']($request);
+
+	call_integration_hook('integrate_load_custom_profile_fields', array($memID, $area));
 }
 
 ?>

+ 17 - 7
Sources/Subs-Members.php

@@ -39,7 +39,7 @@ function deleteMembers($users, $check_not_admin = false)
 
 	// Try give us a while to sort this out...
 	@set_time_limit(600);
-	
+
 	// Try to get some more memory.
 	setMemoryLimit('128M');
 
@@ -109,15 +109,19 @@ function deleteMembers($users, $check_not_admin = false)
 	if (empty($users))
 		return;
 
-	require_once($sourcedir . '/Logging.php');
 	// Log the action - regardless of who is deleting it.
-	$log_inserts = array();
+	$log_changes = array();
 	foreach ($user_log_details as $user)
 	{
-		// Integration rocks!
-		call_integration_hook('integrate_delete_member', array($user[0]));
-
-		logAction('delete_member', array('member' => $user[0], 'name' => $user[1], 'member_acted' => $user_info['name']), 'admin');
+		$log_changes[] = array(
+			'action' => 'delete_member',
+			'log_type' => 'admin',
+			'extra' => array(
+				'member' => $user[0],
+				'name' => $user[1],
+				'member_acted' => $user_info['name'],
+			),
+		);
 
 		// Remove any cached data if enabled.
 		if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2)
@@ -392,7 +396,13 @@ function deleteMembers($users, $check_not_admin = false)
 		'calendar_updated' => time(),
 	));
 
+	// Integration rocks!
+	call_integration_hook('integrate_delete_members', array($users));
+
 	updateStats('member');
+
+	require_once($sourcedir . '/Logging.php');
+	logActions($log_changes);
 }
 
 /**