Browse Source

! A couple of minor CSS changes that probably won't make any difference but were bothering me
! More doc changes (some with search & replace... don't hurt me)
! More doc changes
+ Added the other 2/3's of Slammeddime's hooks
+ Add two more hooks to add methods to SSI.php and credits to ?action=credits [bug 4782]
! parsesmileys() creates a regex too complex (Subs.php) [bug 3839]
+ Added str_ireplace to Subs-Compat.php from a post (http://www.simplemachines.org/community/index.php?msg=2420295) made by [Unknown]
! Rewrite censorTxt() so it does less preg parsing.
- Revert part of REV 10710. It was producing an undefined index
! Fix "Undefined index: group_inherit" in ManageMembergroups.php [Bug 4760]
! Small @todo in QueryString.php
! Missing closing div [Bug 4784]
! Change "Attachments and other options" to "Other options" when the attachments are not allowed [Bug 4729]
! DumpDatabase.php should output after 65k bytes. Not fixing but from http://www.simplemachines.org/community/index.php?topic=323594

Spuds 12 years ago
parent
commit
b698494cdd
54 changed files with 478 additions and 249 deletions
  1. 5 1
      SSI.php
  2. 1 3
      Sources/Admin.php
  3. 4 2
      Sources/DumpDatabase.php
  4. 20 19
      Sources/Load.php
  5. 14 1
      Sources/ManageAttachments.php
  6. 3 8
      Sources/ManageBans.php
  7. 13 0
      Sources/ManageBoards.php
  8. 4 0
      Sources/ManageCalendar.php
  9. 3 9
      Sources/ManageLanguages.php
  10. 5 0
      Sources/ManageMail.php
  11. 4 0
      Sources/ManageMaintenance.php
  12. 1 1
      Sources/ManageMembergroups.php
  13. 7 3
      Sources/ManageMembers.php
  14. 5 0
      Sources/ManagePaid.php
  15. 11 0
      Sources/ManagePermissions.php
  16. 17 0
      Sources/ManagePosts.php
  17. 6 0
      Sources/ManageRegistration.php
  18. 2 0
      Sources/ManageScheduledTasks.php
  19. 2 1
      Sources/ManageServer.php
  20. 39 2
      Sources/ManageSettings.php
  21. 6 0
      Sources/ManageSmileys.php
  22. 1 1
      Sources/Packages.php
  23. 8 9
      Sources/Post.php
  24. 3 3
      Sources/Recent.php
  25. 5 5
      Sources/Reminder.php
  26. 1 1
      Sources/Security.php
  27. 1 1
      Sources/SplitTopics.php
  28. 4 4
      Sources/Subs-Admin.php
  29. 1 1
      Sources/Subs-Auth.php
  30. 4 4
      Sources/Subs-Boards.php
  31. 165 96
      Sources/Subs-Calendar.php
  32. 26 0
      Sources/Subs-Compat.php
  33. 3 3
      Sources/Subs-Editor.php
  34. 4 0
      Sources/Subs-Membergroups.php
  35. 5 5
      Sources/Subs-Members.php
  36. 3 3
      Sources/Subs-OpenID.php
  37. 4 3
      Sources/Subs-Package.php
  38. 11 11
      Sources/Subs-Post.php
  39. 1 1
      Sources/Subs-Recent.php
  40. 19 15
      Sources/Subs.php
  41. 5 5
      Sources/Themes.php
  42. 3 1
      Sources/Who.php
  43. 1 1
      Themes/default/Errors.template.php
  44. 2 2
      Themes/default/ManagePermissions.template.php
  45. 1 1
      Themes/default/ModerationCenter.template.php
  46. 3 3
      Themes/default/PersonalMessage.template.php
  47. 4 4
      Themes/default/Post.template.php
  48. 2 2
      Themes/default/Themes.template.php
  49. 2 2
      Themes/default/Wireless.template.php
  50. 8 7
      Themes/default/css/index.css
  51. 1 1
      Themes/default/languages/ManagePaid.english.php
  52. 2 1
      Themes/default/languages/Post.english.php
  53. 1 1
      Themes/default/languages/index.english.php
  54. 2 2
      index.php

+ 5 - 1
SSI.php

@@ -63,6 +63,7 @@ require_once($sourcedir . '/QueryString.php');
 require_once($sourcedir . '/Session.php');
 require_once($sourcedir . '/Subs.php');
 require_once($sourcedir . '/Errors.php');
+require_once($sourcedir . '/Logging.php');
 require_once($sourcedir . '/Load.php');
 require_once($sourcedir . '/Security.php');
 
@@ -174,6 +175,9 @@ if (isset($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['is_cli']) && session_id()
 if (!isset($_SESSION['USER_AGENT']) && (!isset($_GET['ssi_function']) || $_GET['ssi_function'] !== 'pollVote'))
 	$_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
 
+// Have the ability to easily add functions to SSI.
+call_integration_hook('integrate_SSI');
+
 // Call a function passed by GET.
 if (isset($_GET['ssi_function']) && function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest']))
 {
@@ -636,7 +640,7 @@ function ssi_topTopics($type = 'replies', $num_topics = 10, $output_method = 'ec
 
 	if ($modSettings['totalMessages'] > 100000)
 	{
-		// !!! Why don't we use {query(_wanna)_see_board}?
+		// @todo Why don't we use {query(_wanna)_see_board}?
 		$request = $smcFunc['db_query']('', '
 			SELECT id_topic
 			FROM {db_prefix}topics

+ 1 - 3
Sources/Admin.php

@@ -638,9 +638,7 @@ function DisplayAdminFile()
 	list ($file_data, $filetype) = $smcFunc['db_fetch_row']($request);
 	$smcFunc['db_free_result']($request);
 
-	/**
-	 * @todo Temp
-	 */
+	// @todo Temp
 	// Figure out if sesc is still being used.
 	if (strpos($file_data, ';sesc=') !== false)
 		$file_data = '

+ 4 - 2
Sources/DumpDatabase.php

@@ -52,12 +52,12 @@ function DumpDatabase2()
 	{
 		// Make sure we're gzipping output, but then say we're not in the header ^_^.
 		if (empty($modSettings['enableCompressedOutput']))
-			@ob_start('ob_gzhandler');
+			@ob_start('ob_gzhandler', 65536);
 		// Try to clean any data already outputted.
 		elseif (ob_get_length() != 0)
 		{
 			ob_end_clean();
-			@ob_start('ob_gzhandler');
+			@ob_start('ob_gzhandler', 65536);
 		}
 
 		// Send faked headers so it will just save the compressed output as a gzip.
@@ -167,6 +167,8 @@ function DumpDatabase2()
 			$crlf,
 			$get_rows,
 			'-- --------------------------------------------------------', $crlf;
+
+		unset($get_rows);
 	}
 
 	echo

+ 20 - 19
Sources/Load.php

@@ -537,9 +537,7 @@ function loadBoard()
 
 	if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3))
 	{
-		/**
-		 * @todo SLOW?
-		 */
+		// @todo SLOW?
 		if (!empty($topic))
 			$temp = cache_get_data('topic_board-' . $topic, 120);
 		else
@@ -647,9 +645,7 @@ function loadBoard()
 
 			if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3))
 			{
-				/**
-				 * @todo SLOW?
-				 */
+				// @todo SLOW?
 				if (!empty($topic))
 					cache_put_data('topic_board-' . $topic, $board_info, 120);
 				cache_put_data('board-' . $board, $board_info, 120);
@@ -2106,42 +2102,47 @@ function getLanguages($use_cache = true, $favor_utf8 = true)
  *  - if the theme setting allow_no_censored is on, and the theme option
  *  	  show_no_censored is enabled, does not censor - unless force is set.
  *  - it caches the list of censored words to reduce parsing.
- * @todo what is this function doing here?
  * 
  * @param string &$text
- * @param bool $force
+ * @param bool $force = false
  * @return string The censored text
  */
-function &censorText(&$text, $force = false)
+// Replace all vulgar words with respective proper words. (substring or whole words..)
+function censorText(&$text, $force = false)
 {
 	global $modSettings, $options, $settings, $txt;
 	static $censor_vulgar = null, $censor_proper;
 
-	if ((!empty($options['show_no_censored']) && $settings['allow_no_censored'] && !$force) || empty($modSettings['censor_vulgar']))
+	if ((!empty($options['show_no_censored']) && $settings['allow_no_censored'] && !$force) || empty($modSettings['censor_vulgar']) || trim($text) === '')
 		return $text;
 
 	// If they haven't yet been loaded, load them.
-	if ($censor_vulgar == null)
+	if ($censor_vulgar === null)
 	{
 		$censor_vulgar = explode("\n", $modSettings['censor_vulgar']);
 		$censor_proper = explode("\n", $modSettings['censor_proper']);
 
 		// Quote them for use in regular expressions.
-		for ($i = 0, $n = count($censor_vulgar); $i < $n; $i++)
+		if (!empty($modSettings['censorWholeWord']))
 		{
-			$censor_vulgar[$i] = strtr(preg_quote($censor_vulgar[$i], '/'), array('\\\\\\*' => '[*]', '\\*' => '[^\s]*?', '&' => '&amp;'));
-			$censor_vulgar[$i] = (empty($modSettings['censorWholeWord']) ? '/' . $censor_vulgar[$i] . '/' : '/(?<=^|\W)' . $censor_vulgar[$i] . '(?=$|\W)/') . (empty($modSettings['censorIgnoreCase']) ? '' : 'i') . ((empty($modSettings['global_character_set']) ? $txt['lang_character_set'] : $modSettings['global_character_set']) === 'UTF-8' ? 'u' : '');
-
-			if (strpos($censor_vulgar[$i], '\'') !== false)
+			for ($i = 0, $n = count($censor_vulgar); $i < $n; $i++)
 			{
-				$censor_proper[count($censor_vulgar)] = $censor_proper[$i];
-				$censor_vulgar[count($censor_vulgar)] = strtr($censor_vulgar[$i], array('\'' => '&#039;'));
+				$censor_vulgar[$i] = str_replace(array('\\\\\\*', '\\*', '&', '\''), array('[*]', '[^\s]*?', '&amp;', '&#039;'), preg_quote($censor_vulgar[$i], '/'));
+				$censor_vulgar[$i] = '/(?<=^|\W)' . $censor_vulgar[$i] . '(?=$|\W)/' . (empty($modSettings['censorIgnoreCase']) ? '' : 'i') . ((empty($modSettings['global_character_set']) ? $txt['lang_character_set'] : $modSettings['global_character_set']) === 'UTF-8' ? 'u' : '');
+
+				// @todo I'm thinking the old way is some kind of bug and this is actually fixing it.
+				//if (strpos($censor_vulgar[$i], '\'') !== false)
+					//$censor_vulgar[$i] = str_replace('\'', '&#039;', $censor_vulgar[$i]);
 			}
 		}
 	}
 
 	// Censoring isn't so very complicated :P.
-	$text = preg_replace($censor_vulgar, $censor_proper, $text);
+	if (empty($modSettings['censorWholeWord']))
+		$text = empty($modSettings['censorIgnoreCase']) ? str_ireplace($censor_vulgar, $censor_proper, $text) : str_replace($censor_vulgar, $censor_proper, $text);
+	else
+		$text = preg_replace($censor_vulgar, $censor_proper, $text);
+
 	return $text;
 }
 

+ 14 - 1
Sources/ManageAttachments.php

@@ -53,6 +53,8 @@ function ManageAttachments()
 		'removeall' => 'RemoveAllAttachments'
 	);
 
+	call_integration_hook('integrate_manage_attachments', array(&$subActions));
+
 	// Pick the correct sub-action.
 	if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
 		$context['sub_action'] = $_REQUEST['sa'];
@@ -123,6 +125,8 @@ function ManageAttachmentSettings($return_config = false)
 			array('text', 'attachmentThumbHeight', 6),
 	);
 
+	call_integration_hook('integrate_modify_attachment_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -135,6 +139,8 @@ function ManageAttachmentSettings($return_config = false)
 	{
 		checkSession();
 
+		call_integration_hook('integrate_save_attachment_settings');
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=manageattachments;sa=attachments');
 	}
@@ -202,10 +208,13 @@ function ManageAvatarSettings($return_config = false)
 			array('text', 'custom_avatar_url', 40),
 	);
 
+	call_integration_hook('integrate_modify_avatar_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
 	// We need these files for the inline permission settings, and the settings template.
+	// @todo is this really needed?
 	require_once($sourcedir . '/ManagePermissions.php');
 	require_once($sourcedir . '/ManageServer.php');
 
@@ -218,6 +227,8 @@ function ManageAvatarSettings($return_config = false)
 		if (isset($_POST['custom_avatar_enabled']) && $_POST['custom_avatar_enabled'] == 1 && (empty($_POST['custom_avatar_dir']) || empty($_POST['custom_avatar_url'])))
 			$_POST['custom_avatar_enabled'] = 0;
 
+		call_integration_hook('integrate_save_avatar_settings');
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=manageattachments;sa=avatars');
 	}
@@ -1555,7 +1566,7 @@ function ApproveAttach()
 /**
  * Approve an attachment, or maybe even more - no permission check!
  *
- * @param $attachments
+ * @param array $attachments
  */
 function ApproveAttachments($attachments)
 {
@@ -1607,6 +1618,8 @@ function ApproveAttachments($attachments)
 			'attachments' => $attachments,
 		)
 	);
+
+	call_integration_hook('integrate_approve_attachments', array($attachments));
 }
 
 /**

+ 3 - 8
Sources/ManageBans.php

@@ -44,6 +44,8 @@ function Ban()
 		'log' => 'BanLog',
 	);
 
+	call_integration_hook('integrate_manage_bans', array(&$subActions));
+
 	// Default the sub-action to 'view ban list'.
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'list';
 
@@ -109,14 +111,7 @@ function BanList()
 
 		// Unban them all!
 		$smcFunc['db_query']('', '
-			DELETE FROM {db_prefix}ban_groups
-			WHERE id_ban_group IN ({array_int:ban_list})',
-			array(
-				'ban_list' => $_POST['remove'],
-			)
-		);
-		$smcFunc['db_query']('', '
-			DELETE FROM {db_prefix}ban_items
+			DELETE FROM {db_prefix}ban_groups, {db_prefix}ban_items
 			WHERE id_ban_group IN ({array_int:ban_list})',
 			array(
 				'ban_list' => $_POST['remove'],

+ 13 - 0
Sources/ManageBoards.php

@@ -45,6 +45,8 @@ function ManageBoards()
 		'settings' => array('EditBoardSettings', 'admin_forum'),
 	);
 
+	call_integration_hook('integrate_manage_boards', array(&$subActions));
+
 	// Default to sub action 'main' or 'settings' depending on permissions.
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('manage_boards') ? 'main' : 'settings');
 
@@ -195,6 +197,8 @@ function ManageBoardsMain()
 		}
 	}
 
+	call_integration_hook('integrate_boards_main');
+
 	$context['page_title'] = $txt['boards_and_cats'];
 	$context['can_manage_permissions'] = allowedTo('manage_permissions');
 }
@@ -287,6 +291,8 @@ function EditCategory()
 
 	// Create a special token.
 	createToken('admin-bc-' . $_REQUEST['cat']);
+
+	call_integration_hook('integrate_edit_category');
 }
 
 /**
@@ -564,6 +570,8 @@ function EditBoard()
 
 	// Create a special token.
 	createToken('admin-be-' . $_REQUEST['boardid']);
+
+	call_integration_hook('integrate_edit_board');
 }
 
 /**
@@ -780,10 +788,13 @@ function EditBoardSettings($return_config = false)
 			array('check', 'allow_ignore_boards'),
 	);
 
+	call_integration_hook('integrate_board_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
 	// Needed for the settings template and inline permission functions.
+	// @todo is this file really needed?
 	require_once($sourcedir . '/ManagePermissions.php');
 	require_once($sourcedir . '/ManageServer.php');
 
@@ -810,6 +821,8 @@ function EditBoardSettings($return_config = false)
 	{
 		checkSession();
 
+		call_integration_hook('integrate_save_board_settings');
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=manageboards;sa=settings');
 	}

+ 4 - 0
Sources/ManageCalendar.php

@@ -41,6 +41,8 @@ function ManageCalendar()
 		'settings' => 'ModifyCalendarSettings'
 	);
 
+	call_integration_hook('integrate_manage_calendar', array(&$subActions));
+
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'holidays';
 
 	// Set up the two tabs here...
@@ -334,6 +336,7 @@ function ModifyCalendarSettings($return_config = false)
 			array('int', 'cal_maxspan'),
 	);
 
+	call_integration_hook('integrate_modify_calendar_settings', array(&$config_vars));
 	if ($return_config)
 		return $config_vars;
 
@@ -352,6 +355,7 @@ function ModifyCalendarSettings($return_config = false)
 	if (isset($_GET['save']))
 	{
 		checkSession();
+		call_integration_hook('integrate_save_calendar_settings');
 		saveDBSettings($config_vars);
 
 		// Update the stats in case.

+ 3 - 9
Sources/ManageLanguages.php

@@ -836,9 +836,7 @@ function ModifyLanguage()
 			if (preg_match('~^([A-Za-z]+)\.' . $context['lang_id'] . '\.php$~', $entry, $matches) == 0)
 				continue;
 
-			/**
-			 * @todo Temp!
-			 */
+			// @todo Temp!
 			if ($matches[1] == 'EmailTemplates')
 				continue;
 
@@ -864,9 +862,7 @@ function ModifyLanguage()
 		checkSession();
 		validateToken('admin-mlang');
 
-		/**
-		 * @todo FTP Controls?
-		 */
+		// @todo Todo: FTP Controls?
 		require_once($sourcedir . '/Subs-Package.php');
 
 		// First, Make a backup?
@@ -1108,9 +1104,7 @@ function ModifyLanguage()
 				// Saving?
 				if (isset($save_strings[$entryKey]) && $save_strings[$entryKey] != $entryValue['entry'])
 				{
-					/**
-					 * @todo Fix this properly.
-					 */
+					// @todo Fix this properly.
 					if ($save_strings[$entryKey] == '')
 						$save_strings[$entryKey] = '\'\'';
 

+ 5 - 0
Sources/ManageMail.php

@@ -43,6 +43,8 @@ function ManageMail()
 		'settings' => 'ModifyMailSettings',
 	);
 
+	call_integration_hook('integrate_manage_mail', array(&$subActions));
+
 	// By default we want to browse
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'browse';
 	$context['sub_action'] = $_REQUEST['sa'];
@@ -302,6 +304,8 @@ function ModifyMailSettings($return_config = false)
 			'birthday_body' => array('var_message', 'birthday_body', 'var_message' => nl2br($body), 'disabled' => true, 'size' => ceil(strlen($body) / 25)),
 	);
 
+	call_integration_hook('integrate_modify_mail_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -318,6 +322,7 @@ function ModifyMailSettings($return_config = false)
 
 		// We don't want to save the subject and body previews.
 		unset($config_vars['birthday_subject'], $config_vars['birthday_body']);
+		call_integration_hook('integrate_save_mail_settings');
 
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=mailqueue;sa=settings');

+ 4 - 0
Sources/ManageMaintenance.php

@@ -88,6 +88,8 @@ function ManageMaintenance()
 		),
 	);
 
+	call_integration_hook('integrate_manage_maintenance', array(&$subActions));
+
 	// Yep, sub-action time!
 	if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
 		$subAction = $_REQUEST['sa'];
@@ -654,6 +656,8 @@ function ConvertUtf8()
 	}
 	$smcFunc['db_free_result']($queryTables);
 
+	call_integration_hook('integrate_convert_utf8');
+
 	// Let the settings know we have a new character set.
 	updateSettings(array('global_character_set' => 'UTF-8', 'previousCharacterSet' => (empty($translation_tables[$_POST['src_charset']])) ? $charsets[$_POST['src_charset']] : $translation_tables[$_POST['src_charset']]));
 

+ 1 - 1
Sources/ManageMembergroups.php

@@ -663,7 +663,7 @@ function EditMembergroup()
 		validateToken('admin-mmg');
 
 		// Can they really inherit from this group?
-		if ($_POST['group_inherit'] != -2 && !allowedTo('admin_forum'))
+		if (isset($_POST['group_inherit']) && $_POST['group_inherit'] != -2 && !allowedTo('admin_forum'))
 		{
 			$request = $smcFunc['db_query']('', '
 				SELECT group_type

+ 7 - 3
Sources/ManageMembers.php

@@ -37,6 +37,8 @@ function ViewMembers()
 		'query' => array('ViewMemberlist', 'moderate_forum'),
 	);
 
+	call_integration_hook('integrate_manage_members', array(&$subActions));
+
 	// Default to sub action 'index' or 'settings' depending on permissions.
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'all';
 
@@ -280,9 +282,9 @@ function ViewMemberlist()
 			'++' => '>'
 		);
 
-		/**
-		 * @todo Validate a little more.
-		 */
+		call_integration_hook('integrate_view_members_params', array(&$params));
+
+		// @todo Validate a little more.
 
 		// Loop through every field of the form.
 		$query_parts = array();
@@ -599,6 +601,8 @@ function ViewMemberlist()
 	if (!allowedTo('profile_remove_any'))
 		unset($listOptions['cols']['check'], $listOptions['form'], $listOptions['additional_rows']);
 
+	call_integration_hook('integrate_view_members_list', array(&$listOptions));
+
 	require_once($sourcedir . '/Subs-List.php');
 	createList($listOptions);
 

+ 5 - 0
Sources/ManagePaid.php

@@ -40,6 +40,8 @@ function ManagePaidSubscriptions()
 		'viewsub' => array('ViewSubscribedUsers', 'admin_forum'),
 	);
 
+	call_integration_hook('integrate_manage_subscriptions', array(&$subActions));
+
 	// Default the sub-action to 'view subscriptions', but only if they have already set things up..
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (!empty($modSettings['paid_currency_symbol']) ? 'view' : 'settings');
 
@@ -354,6 +356,8 @@ function ModifySubscription()
 			)
 		);
 
+		call_integration_hook('integrate_delete_subscription', array($context['sub_id']));
+
 		redirectexit('action=admin;area=paidsubscribe;view');
 	}
 
@@ -465,6 +469,7 @@ function ModifySubscription()
 				)
 			);
 		}
+		call_integration_hook('integrate_save_subscription', array(($context['action_type'] == 'add' ? $smcFunc['db_insert_id']('{db_prefix}subscriptions', 'id_subscribe') : $context['sub_id']), $_POST['name'], $_POST['desc'], $isActive, $span, $cost, $_POST['prim_group'], $addgroups, $isRepeatable, $allowpartial, $emailComplete, $reminder));
 
 		redirectexit('action=admin;area=paidsubscribe;view');
 	}

+ 11 - 0
Sources/ManagePermissions.php

@@ -44,6 +44,8 @@ function ModifyPermissions()
 		'settings' => array('GeneralPermissionSettings', 'admin_forum'),
 	);
 
+	call_integration_hook('integrate_manage_permissions', array(&$subActions));
+
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('manage_permissions') ? 'index' : 'settings');
 	isAllowedTo($subActions[$_REQUEST['sa']][1]);
 
@@ -973,6 +975,8 @@ function GeneralPermissionSettings($return_config = false)
 			array('check', 'permission_enable_postgroups', 0, $txt['permission_settings_enable_postgroups'], 'help' => 'permissions_postgroups'),
 	);
 
+	call_integration_hook('integrate_modify_permission_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -990,6 +994,7 @@ function GeneralPermissionSettings($return_config = false)
 	if (isset($_GET['save']))
 	{
 		checkSession('post');
+		call_integration_hook('integrate_save_permission_settings');
 		saveDBSettings($config_vars);
 
 		// Clear all deny permissions...if we want that.
@@ -2170,6 +2175,8 @@ function loadIllegalPermissions()
 		$context['illegal_permissions'][] = 'manage_membergroups';
 	if (!allowedTo('manage_permissions'))
 		$context['illegal_permissions'][] = 'manage_permissions';
+
+	call_integration_hook('integrate_load_illegal_permissions');
 }
 
 /**
@@ -2212,6 +2219,8 @@ function loadIllegalGuestPermissions()
 		'send_mail',
 		'approve_posts',
 	);
+
+	call_integration_hook('integrate_load_illegal_guest_permissions');
 }
 
 /**
@@ -2239,6 +2248,8 @@ function ModifyPostModeration()
 		'attachment' => array('post_attachment', 'post_unapproved_attachments'),
 	);
 
+	call_integration_hook('integrate_post_moderation_mapping', array(&$mappings));
+
 	// Start this with the guests/members.
 	$context['profile_groups'] = array(
 		-1 => array(

+ 17 - 0
Sources/ManagePosts.php

@@ -38,6 +38,8 @@ function ManagePostSettings()
 		'topics' => 'ModifyTopicSettings',
 	);
 
+	call_integration_hook('integrate_manage_posts', array(&$subActions));
+
 	// Default the sub-action to 'posts'.
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'posts';
 
@@ -126,6 +128,8 @@ function SetCensor()
 			'censorIgnoreCase' => empty($_POST['censorIgnoreCase']) ? '0' : '1',
 		);
 
+		call_integration_hook('integrate_save_censors', array(&$updates));
+
 		updateSettings($updates);
 	}
 
@@ -152,6 +156,8 @@ function SetCensor()
 		$context['censored_words'][htmlspecialchars(trim($censor_vulgar[$i]))] = isset($censor_proper[$i]) ? htmlspecialchars($censor_proper[$i]) : '';
 	}
 
+	call_integration_hook('integrate_censors');
+
 	$context['sub_template'] = 'edit_censored';
 	$context['page_title'] = $txt['admin_censored_words'];
 
@@ -190,6 +196,8 @@ function ModifyPostSettings($return_config = false)
 			array('int', 'edit_disable_time', 'subtext' => $txt['edit_disable_time_zero'], 'postinput' => $txt['manageposts_minutes']),
 	);
 
+	call_integration_hook('integrate_modify_post_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -242,6 +250,8 @@ function ModifyPostSettings($return_config = false)
 			}
 		}
 
+		call_integration_hook('integrate_save_post_settings');
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=postsettings;sa=posts');
 	}
@@ -275,6 +285,8 @@ function ModifyBBCSettings($return_config = false)
 			array('bbc', 'disabledBBC'),
 	);
 
+	call_integration_hook('integrate_modify_bbc_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -303,6 +315,8 @@ function ModifyBBCSettings($return_config = false)
 		// Work out what is actually disabled!
 		$_POST['disabledBBC'] = implode(',', array_diff($bbcTags, $_POST['disabledBBC_enabledTags']));
 
+		call_integration_hook('integrate_save_bbc_settings', array($bbcTags));
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=postsettings;sa=bbc');
 	}
@@ -347,6 +361,8 @@ function ModifyTopicSettings($return_config = false)
 
 	);
 
+	call_integration_hook('integrate_modify_topic_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -361,6 +377,7 @@ function ModifyTopicSettings($return_config = false)
 	if (isset($_GET['save']))
 	{
 		checkSession();
+		call_integration_hook('integrate_save_topic_settings');
 
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=postsettings;sa=topics');

+ 6 - 0
Sources/ManageRegistration.php

@@ -41,6 +41,8 @@ function RegCenter()
 		'settings' => array('ModifyRegistrationSettings', 'admin_forum'),
 	);
 
+	call_integration_hook('integrate_manage_registrations', array(&$subActions));
+
 	// Work out which to call...
 	$context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' : 'settings');
 
@@ -289,6 +291,8 @@ function ModifyRegistrationSettings($return_config = false)
 			array('text', 'coppaPhone'),
 	);
 
+	call_integration_hook('integrate_modify_registration_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -307,6 +311,8 @@ function ModifyRegistrationSettings($return_config = false)
 		// Post needs to take into account line breaks.
 		$_POST['coppaPost'] = str_replace("\n", '<br />', empty($_POST['coppaPost']) ? '' : $_POST['coppaPost']);
 
+		call_integration_hook('integrate_save_registration_settings');
+
 		saveDBSettings($config_vars);
 
 		redirectexit('action=admin;area=regcenter;sa=settings');

+ 2 - 0
Sources/ManageScheduledTasks.php

@@ -39,6 +39,8 @@ function ManageScheduledTasks()
 		'tasks' => 'ScheduledTasks',
 	);
 
+	call_integration_hook('integrate_manage_scheduled_tasks', array(&$subActions));
+
 	// We need to find what's the action.
 	if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
 		$context['sub_action'] = $_REQUEST['sa'];

+ 2 - 1
Sources/ManageServer.php

@@ -253,7 +253,7 @@ function ModifyDatabaseSettings($return_config = false)
 /**
  * This function handles cookies settings modifications.
  *
- * @param $return_config
+ * @param bool $return_config = false
  */
 function ModifyCookieSettings($return_config = false)
 {
@@ -660,6 +660,7 @@ function prepareDBSettingContext(&$config_vars)
 		}
 	}
 
+	call_integration_hook('integrate_prepare_server_settings', array(&$config_vars));
 	createToken('admin-dbsc');
 }
 

+ 39 - 2
Sources/ManageSettings.php

@@ -61,6 +61,8 @@ function ModifyFeatureSettings()
 		'profileedit' => 'EditCustomProfiles',
 	);
 
+	call_integration_hook('integrate_modify_features', array(&$subActions));
+
 	loadGeneralSettingParameters($subActions, 'basic');
 
 	// Load up all the tabs...
@@ -103,6 +105,8 @@ function ModifySecuritySettings()
 		'moderation' => 'ModifyModerationSettings',
 	);
 
+	call_integration_hook('integrate_modify_security', array(&$subActions));
+
 	loadGeneralSettingParameters($subActions, 'general');
 
 	// Load up all the tabs...
@@ -469,6 +473,8 @@ function ModifyBasicSettings($return_config = false)
 	else
 		unset($config_vars['default_timezone']);
 
+	call_integration_hook('integrate_basic_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -481,6 +487,8 @@ function ModifyBasicSettings($return_config = false)
 		if (isset($_POST['lastActive']))
 			$_POST['lastActive'] = min((int) $_POST['lastActive'], 1440);
 
+		call_integration_hook('integrate_save_basic_settings');
+
 		saveDBSettings($config_vars);
 
 		writeLog();
@@ -526,6 +534,8 @@ function ModifyGeneralSecuritySettings($return_config = false)
 			array('check', 'enableReportPM'),
 	);
 
+	call_integration_hook('integrate_general_security_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -536,6 +546,8 @@ function ModifyGeneralSecuritySettings($return_config = false)
 
 		saveDBSettings($config_vars);
 
+		call_integration_hook('integrate_save_general_security_settings');
+
 		writeLog();
 		redirectexit('action=admin;area=securitysettings;sa=general');
 	}
@@ -574,6 +586,8 @@ function ModifyLayoutSettings($return_config = false)
 			array('check', 'timeLoadPageEnable'),
 	);
 
+	call_integration_hook('integrate_layout_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -582,6 +596,8 @@ function ModifyLayoutSettings($return_config = false)
 	{
 		checkSession();
 
+		call_integration_hook('integrate_save_layout_settings');
+
 		saveDBSettings($config_vars);
 		writeLog();
 
@@ -617,6 +633,8 @@ function ModifyKarmaSettings($return_config = false)
 			array('text', 'karmaSmiteLabel'),
 	);
 
+	call_integration_hook('integrate_karma_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -625,6 +643,8 @@ function ModifyKarmaSettings($return_config = false)
 	{
 		checkSession();
 
+		call_integration_hook('integrate_save_karma_settings');
+
 		saveDBSettings($config_vars);
 		redirectexit('action=admin;area=featuresettings;sa=karma');
 	}
@@ -638,7 +658,7 @@ function ModifyKarmaSettings($return_config = false)
 /**
  * Moderation type settings - although there are fewer than we have you believe ;)
  *
- * @param $return_config
+ * @param bool $return_config = false
  */
 function ModifyModerationSettings($return_config = false)
 {
@@ -654,6 +674,8 @@ function ModifyModerationSettings($return_config = false)
 			array('select', 'warning_show', array($txt['setting_warning_show_mods'], $txt['setting_warning_show_user'], $txt['setting_warning_show_all'])),
 	);
 
+	call_integration_hook('integrate_moderation_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -686,6 +708,8 @@ function ModifyModerationSettings($return_config = false)
 		$save_vars[] = array('text', 'warning_settings');
 		unset($save_vars['rem1'], $save_vars['rem2']);
 
+		call_integration_hook('integrate_save_karma_settings', array(&$save_vars));
+
 		saveDBSettings($save_vars);
 		redirectexit('action=admin;area=securitysettings;sa=moderation');
 	}
@@ -701,7 +725,7 @@ function ModifyModerationSettings($return_config = false)
 
 /**
  * Let's try keep the spam to a minimum ah Thantos?
- * @param $return_config
+ * @param bool $return_config = false
  */
 function ModifySpamSettings($return_config = false)
 {
@@ -734,6 +758,8 @@ function ModifySpamSettings($return_config = false)
 				array('callback', 'question_answer_list'),
 	);
 
+	call_integration_hook('integrate_spam_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -843,6 +869,8 @@ function ModifySpamSettings($return_config = false)
 		if (empty($count_questions) || $_POST['qa_verification_number'] > $count_questions)
 			$_POST['qa_verification_number'] = $count_questions;
 
+		call_integration_hook('integrate_save_spam_settings', array(&$save_vars));
+
 		// Now save.
 		saveDBSettings($save_vars);
 
@@ -918,6 +946,8 @@ function ModifySignatureSettings($return_config = false)
 			array('bbc', 'signature_bbc'),
 	);
 
+	call_integration_hook('integrate_signature_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -1135,6 +1165,7 @@ function ModifySignatureSettings($return_config = false)
 				}
 
 				$sig = strtr($sig, array("\n" => '<br />'));
+				call_integration_hook('integrate_apply_signature_settings', array(&$sig, $sig_limits, $disabledTags));
 				if ($sig != $row['signature'])
 					$changes[$row['id_member']] = $sig;
 			}
@@ -1208,6 +1239,8 @@ function ModifySignatureSettings($return_config = false)
 				$sig_limits[] = !empty($_POST['signature_' . $key]) ? max(1, (int) $_POST['signature_' . $key]) : 0;
 		}
 
+		call_integration_hook('integrate_save_signature_settings', array(&$sig_limits, &$bbcTags));
+
 		$_POST['signature_settings'] = implode(',', $sig_limits) . ':' . implode(',', array_diff($bbcTags, $_POST['signature_bbc_enabledTags']));
 
 		// Even though we have practically no settings let's keep the convention going!
@@ -1996,6 +2029,8 @@ function ModifyPruningSettings($return_config = false)
 			// Mod Developers: Do NOT use the pruningOptions master variable for this as SMF Core may overwrite your setting in the future!
 	);
 
+	call_integration_hook('integrate_prune_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -2081,6 +2116,8 @@ function ModifyGeneralModSettings($return_config = false)
 
 		$save_vars = $config_vars;
 
+		call_integration_hook('integrate_save_general_mod_settings', array(&$save_vars));
+
 		// This line is to help mod authors do a search/add after if you want to add something here. Keyword: FOOT TAPPING SUCKS!
 		saveDBSettings($save_vars);
 

+ 6 - 0
Sources/ManageSmileys.php

@@ -42,6 +42,8 @@ function ManageSmileys()
 		'install' => 'InstallSmileySet'
 	);
 
+	call_integration_hook('integrate_manage_smileys', array(&$subActions));
+
 	// Default the sub-action to 'edit smiley settings'.
 	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'editsets';
 
@@ -127,6 +129,8 @@ function EditSmileySettings($return_config = false)
 			array('check', 'messageIcons_enable', 'subtext' => $txt['setting_messageIcons_enable_note']),
 	);
 
+	call_integration_hook('integrate_modify_smiley_settings', array(&$config_vars));
+
 	if ($return_config)
 		return $config_vars;
 
@@ -150,6 +154,8 @@ function EditSmileySettings($return_config = false)
 		if (isset($_POST['smiley_enable']))
 			sortSmileyTable();
 
+		call_integration_hook('integrate_save_smiley_settings');
+
 		saveDBSettings($config_vars);
 
 		cache_put_data('parsing_smileys', null, 480);

+ 1 - 1
Sources/Packages.php

@@ -23,7 +23,7 @@ function Packages()
 {
 	global $txt, $scripturl, $sourcedir, $context;
 
-	//@todo Remove this!
+	// @todo Remove this!
 	if (isset($_GET['get']) || isset($_GET['pgdownload']))
 	{
 		require_once($sourcedir . '/PackageGet.php');

+ 8 - 9
Sources/Post.php

@@ -196,9 +196,8 @@ function Post()
 		}
 
 		$locked = 0;
-		/**
-		 * @todo These won't work if you're making an event.
-		 */
+
+		// @todo These won't work if you're making an event.
 		$context['can_lock'] = allowedTo(array('lock_any', 'lock_own'));
 		$context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
 
@@ -206,9 +205,7 @@ function Post()
 		$context['sticky'] = !empty($_REQUEST['sticky']);
 	}
 
-	/**
-	 * @todo These won't work if you're posting an event!
-	 */
+	// @todo These won't work if you're posting an event!
 	$context['can_notify'] = allowedTo('mark_any_notify');
 	$context['can_move'] = allowedTo('move_any');
 	$context['move'] = !empty($_REQUEST['move']);
@@ -1674,6 +1671,10 @@ function Post2()
 	// Check if they are trying to delete any current attachments....
 	if (isset($_REQUEST['msg'], $_POST['attach_del']) && (allowedTo('post_attachment') || ($modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))))
 	{
+		// @todo check attach_del; this will be executed when:
+		// modify a post with attachments; try to remove one, but receive an error
+		// (i.e. body empty); then check back the attachment
+
 		$del_temp = array();
 		foreach ($_POST['attach_del'] as $i => $dummy)
 			$del_temp[$i] = (int) $dummy;
@@ -2435,9 +2436,7 @@ function notifyMembersBoard(&$topicData)
 		foreach ($boards[$rowmember['id_board']] as $key)
 		{
 			// Don't notify the guy who started the topic!
-			/**
-			 * @todo In this case actually send them a "it's approved hooray" email
-			 */
+			// @todo In this case actually send them a "it's approved hooray" email :P
 			if ($topicData[$key]['poster'] == $rowmember['id_member'])
 				continue;
 

+ 3 - 3
Sources/Recent.php

@@ -220,7 +220,7 @@ function RecentPosts()
 		$query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 100 - $_REQUEST['start'] * 6);
 		$query_parameters['recycle_board'] = $modSettings['recycle_board'];
 
-		// !!! This isn't accurate because we ignore the recycle bin.
+		// @todo This isn't accurate because we ignore the recycle bin.
 		$context['page_index'] = constructPageIndex($scripturl . '?action=recent', $_REQUEST['start'], min(100, $modSettings['totalMessages']), 10, false);
 	}
 
@@ -236,7 +236,7 @@ function RecentPosts()
 		while (!$done)
 		{
 			// Find the 10 most recent messages they can *view*.
-			// !!!SLOW This query is really slow still, probably?
+			// @todoSLOW This query is really slow still, probably?
 			$request = $smcFunc['db_query']('', '
 				SELECT m.id_msg
 				FROM {db_prefix}messages AS m
@@ -731,7 +731,7 @@ function UnreadTopics()
 		}
 	}
 
-	// !!! Add modified_time in for log_time check?
+	// @todo Add modified_time in for log_time check?
 
 	if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics'])
 	{

+ 5 - 5
Sources/Reminder.php

@@ -22,19 +22,19 @@ if (!defined('SMF'))
 		- uses the Profile language files and Reminder template.
 
 	void RemindMail()
-		// !!!
+		// @todo
 
 	void setPassword()
-		// !!!
+		// @todo
 
 	void setPassword2()
-		// !!!
+		// @todo
 
 	void SecretAnswerInput()
-		// !!!
+		// @todo
 
 	void SecretAnswer2()
-		// !!!
+		// @todo
 */
 
 // Forgot 'yer password?

+ 1 - 1
Sources/Security.php

@@ -531,7 +531,7 @@ function banPermissions()
 		$user_info['permissions'] = array_diff($user_info['permissions'], array_keys($permission_change));
 	}
 
-	//!!! Find a better place to call this? Needs to be after permissions loaded!
+	// @todo Find a better place to call this? Needs to be after permissions loaded!
 	// Finally, some bits we cache in the session because it saves queries.
 	if (isset($_SESSION['mc']) && $_SESSION['mc']['time'] > $modSettings['settings_updated'] && $_SESSION['mc']['id'] == $user_info['id'])
 		$user_info['mod_cache'] = $_SESSION['mc'];

+ 1 - 1
Sources/SplitTopics.php

@@ -779,7 +779,7 @@ function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
 	);
 
 	// Copy log topic entries.
-	// !!! This should really be chunked.
+	// @todo This should really be chunked.
 	$request = $smcFunc['db_query']('', '
 		SELECT id_member, id_msg
 		FROM {db_prefix}log_topics

+ 4 - 4
Sources/Subs-Admin.php

@@ -2,7 +2,7 @@
 
 /**
  * This file contains functions that are specifically done by administrators.
- * 
+ *
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -219,7 +219,7 @@ function getFileVersions(&$versionOptions)
 
 /**
  * Update the Settings.php file.
- * 
+ *
  * The most important function in this file for mod makers happens to be the
  * updateSettingsFile() function, but it shouldn't be used often anyway.
  * updates the Settings.php file with the changes in config_vars.
@@ -229,7 +229,7 @@ function getFileVersions(&$versionOptions)
  * preserves case, formatting, and additional options in file.
  * writes nothing if the resulting file would be less than 10 lines
  * in length (sanity check for read lock.)
- * 
+ *
  * @param array $config_vars
  */
 function updateSettingsFile($config_vars)
@@ -254,7 +254,7 @@ function updateSettingsFile($config_vars)
 		$temp = trim(implode("\n", $settingsArray));
 		if (substr($temp, 0, 5) != '<?php' || substr($temp, -2) != '?' . '>')
 			return;
-		if (strpos($temp, 'sourcedir') === false || strpos($temp, 'boarddir') === false || strpos($temp, 'cookiename') === false)
+		if (strpos($temp, 'sourcedir') === false || strpos($temp, 'boarddir') === false)
 			return;
 	}
 

+ 1 - 1
Sources/Subs-Auth.php

@@ -652,7 +652,7 @@ function validatePassword($password, $username, $restrict_in = array())
 	elseif ($smcFunc['strpos']($password, $username) !== false)
 		return 'restricted_words';
 
-	// !!! If pspell is available, use it on the word, and return restricted_words if it doesn't give "bad spelling"?
+	// @todo If pspell is available, use it on the word, and return restricted_words if it doesn't give "bad spelling"?
 
 	// If just medium, we're done.
 	if ($modSettings['password_strength'] == 1)

+ 4 - 4
Sources/Subs-Boards.php

@@ -19,10 +19,10 @@ if (!defined('SMF'))
 	the following list of functions:
 
 	void MarkRead()
-		// !!!
+		// @todo
 
 	int getMsgMemberID(int id_msg)
-		// !!!
+		// @todo
 
 	void modifyBoard(int board_id, array boardOptions)
 		- general function to modify the settings and position of a board.
@@ -159,7 +159,7 @@ function markBoardsRead($boards, $unread = false)
 	if (empty($lowest_topic))
 		return;
 
-	// !!!SLOW This query seems to eat it sometimes.
+	// @todoSLOW This query seems to eat it sometimes.
 	$result = $smcFunc['db_query']('', '
 		SELECT lt.id_topic
 		FROM {db_prefix}log_topics AS lt
@@ -865,7 +865,7 @@ function deleteBoards($boards_to_remove, $moveChildrenTo = null)
 	{
 		foreach ($boards_to_remove as $id_board)
 		{
-			// !!! Separate category?
+			// @todo Separate category?
 			if ($moveChildrenTo === 0)
 				fixChildren($id_board, 0, 0);
 			else

+ 165 - 96
Sources/Subs-Calendar.php

@@ -1,6 +1,9 @@
 <?php
 
 /**
+ * This file contains several functions for retrieving and manipulating
+ *  calendar events, birthdays and holidays.
+ * 
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,94 +17,66 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file contains several functions for retrieving and manipulating
-	calendar events, birthdays and holidays.
-
-	array getBirthdayRange(string earliest_date, string latest_date)
-		- finds all the birthdays in the specified range of days.
-		- earliest_date and latest_date are inclusive, and should both be in
-		  the YYYY-MM-DD format.
-		- works with birthdays set for no year, or any other year, and
-		  respects month and year boundaries.
-		- returns an array of days, each of which an array of birthday
-		  information for the context.
-
-	array getEventRange(string earliest_date, string latest_date,
-			bool use_permissions = true)
-		- finds all the posted calendar events within a date range.
-		- both the earliest_date and latest_date should be in the standard
-		  YYYY-MM-DD format.
-		- censors the posted event titles.
-		- uses the current user's permissions if use_permissions is true,
-		  otherwise it does nothing "permission specific".
-		- returns an array of contextual information if use_permissions is
-		  true, and an array of the data needed to build that otherwise.
-
-	array getHolidayRange(string earliest_date, string latest_date)
-		- finds all the applicable holidays for the specified date range.
-		- earliest_date and latest_date should be YYYY-MM-DD.
-		- returns an array of days, which are all arrays of holiday names.
-
-	void canLinkEvent()
-		- checks if the current user can link the current topic to the
-		  calendar, permissions et al.
-		- this requires the calendar_post permission, a forum moderator, or a
-		  topic starter.
-		- expects the $topic and $board variables to be set.
-		- if the user doesn't have proper permissions, an error will be shown.
-
-	array getTodayInfo()
-		- returns an array with the current date, day, month, and year.
-		- takes the users time offset into account.
-
-	array getCalendarGrid(int month, int year, array calendarOptions)
-		- returns an array containing all the information needed to show a
-		  calendar grid for the given month.
-		- also provides information (link, month, year) about the previous and
-		  next month.
-
-	array getCalendarWeek(int month, int year, int day, array calendarOptions)
-		- as for getCalendarGrid but provides information relating to the week
-		  within which the passed date sits.
-
-	array cache_getOffsetIndependentEvents(int days_to_index)
-		- cache callback function used to retrieve the birthdays, holidays, and
-		  events between now and now + days_to_index.
-		- widens the search range by an extra 24 hours to support time offset
-		  shifts.
-		- used by the cache_getRecentEvents function to get the information
-		  needed to calculate the events taking the users time offset into
-		  account.
-
-	array cache_getRecentEvents(array eventOptions)
-		- cache callback function used to retrieve the upcoming birthdays,
-		  holidays, and events within the given period, taking into account
-		  the users time offset.
-		- used by the board index and SSI to show the upcoming events.
-
-	void validateEventPost()
-		- checks if the calendar post was valid.
-
-	int getEventPoster(int event_id)
-		- gets the member_id of an event identified by event_id.
-		- returns false if the event was not found.
-
-	void insertEvent(array eventOptions)
-		- inserts the passed event information into the calendar table.
-		- allows to either set a time span (in days) or an end_date.
-		- does not check any permissions of any sort.
-
-	void modifyEvent(int event_id, array eventOptions)
-		- modifies an event.
-		- allows to either set a time span (in days) or an end_date.
-		- does not check any permissions of any sort.
-
-	void removeEvent(int event_id)
-		- removes an event.
-		- does no permission checks.
+/*	
+
+ array getCalendarGrid(int month, int year, array calendarOptions)
+ * returns an array containing all the information needed to show a
+ *  calendar grid for the given month.
+ * also provides information (link, month, year) about the previous and
+ *  next month.
+
+ array getCalendarWeek(int month, int year, int day, array calendarOptions)
+ * as for getCalendarGrid but provides information relating to the week
+ *  within which the passed date sits.
+
+ array cache_getOffsetIndependentEvents(int days_to_index)
+ * cache callback function used to retrieve the birthdays, holidays, and
+ *  events between now and now + days_to_index.
+ * widens the search range by an extra 24 hours to support time offset
+ *  shifts.
+ * used by the cache_getRecentEvents function to get the information
+ *  needed to calculate the events taking the users time offset into
+ *  account.
+
+ array cache_getRecentEvents(array eventOptions)
+ * cache callback function used to retrieve the upcoming birthdays,
+ *  holidays, and events within the given period, taking into account
+ *  the users time offset.
+ * used by the board index and SSI to show the upcoming events.
+
+ void validateEventPost()
+ * checks if the calendar post was valid.
+
+ int getEventPoster(int event_id)
+ * gets the member_id of an event identified by event_id.
+ * returns false if the event was not found.
+
+ void insertEvent(array eventOptions)
+ * inserts the passed event information into the calendar table.
+ * allows to either set a time span (in days) or an end_date.
+ * does not check any permissions of any sort.
+
+ void modifyEvent(int event_id, array eventOptions)
+ * modifies an event.
+ * allows to either set a time span (in days) or an end_date.
+ * does not check any permissions of any sort.
+
+ void removeEvent(int event_id)
+ * removes an event.
+ * does no permission checks.
 */
 
-// Get all birthdays within the given time range.
+/** 
+ * Get all birthdays within the given time range.
+ * array getBirthdayRange(string earliest_date, string latest_date)
+ * finds all the birthdays in the specified range of days.
+ * earliest_date and latest_date are inclusive, and should both be in
+ *  the YYYY-MM-DD format.
+ * works with birthdays set for no year, or any other year, and
+ *  respects month and year boundaries.
+ * returns an array of days, each of which an array of birthday
+ *  information for the context.
+ */
 function getBirthdayRange($low_date, $high_date)
 {
 	global $scripturl, $modSettings, $smcFunc;
@@ -159,7 +134,19 @@ function getBirthdayRange($low_date, $high_date)
 	return $bday;
 }
 
-// Get all events within the given time range.
+/**
+ * Get all events within the given time range.
+ * array getEventRange(string earliest_date, string latest_date,
+			bool use_permissions = true)
+		- finds all the posted calendar events within a date range.
+		- both the earliest_date and latest_date should be in the standard
+		  YYYY-MM-DD format.
+		- censors the posted event titles.
+		- uses the current user's permissions if use_permissions is true,
+		  otherwise it does nothing "permission specific".
+		- returns an array of contextual information if use_permissions is
+		  true, and an array of the data needed to build that otherwise.
+ */
 function getEventRange($low_date, $high_date, $use_permissions = true)
 {
 	global $scripturl, $modSettings, $user_info, $smcFunc, $context;
@@ -190,7 +177,7 @@ function getEventRange($low_date, $high_date, $use_permissions = true)
 	while ($row = $smcFunc['db_fetch_assoc']($result))
 	{
 		// If the attached topic is not approved then for the moment pretend it doesn't exist
-		//!!! This should be fixed to show them all and then sort by approval state later?
+		// @todo This should be fixed to show them all and then sort by approval state later?
 		if (!empty($row['id_first_msg']) && $modSettings['postmod_active'] && !$row['approved'])
 			continue;
 
@@ -206,7 +193,7 @@ function getEventRange($low_date, $high_date, $use_permissions = true)
 		for ($date = $start_date; $date <= $end_date; $date += 86400)
 		{
 			// Attempt to avoid DST problems.
-			//!!! Resolve this properly at some point.
+			// @todo Resolve this properly at some point.
 			if (strftime('%Y-%m-%d', $date) == $lastDate)
 				$date += 3601;
 			$lastDate = strftime('%Y-%m-%d', $date);
@@ -256,7 +243,15 @@ function getEventRange($low_date, $high_date, $use_permissions = true)
 	return $events;
 }
 
-// Get all holidays within the given time range.
+/**
+ * Get all holidays within the given time range.
+ * 
+ * $low_date and $high_date should be YYYY-MM-DD.
+ * 
+ * @param string $low_date
+ * @param string $high_date
+ * @return array an array of days, which are all arrays of holiday names.
+ */
 function getHolidayRange($low_date, $high_date)
 {
 	global $smcFunc;
@@ -299,6 +294,15 @@ function getHolidayRange($low_date, $high_date)
 }
 
 // Does permission checks to see if an event can be linked to a board/topic.
+/**
+ *  void canLinkEvent()
+ * checks if the current user can link the current topic to the
+ *  calendar, permissions et al.
+ * this requires the calendar_post permission, a forum moderator, or a
+ *  topic starter.
+ * expects the $topic and $board variables to be set.
+ * if the user doesn't have proper permissions, an error will be shown.
+ */
 function canLinkEvent()
 {
 	global $user_info, $topic, $board, $smcFunc;
@@ -339,6 +343,11 @@ function canLinkEvent()
 }
 
 // Returns date information about 'today' relative to the users time offset.
+/**
+ * array getTodayInfo()
+ * returns an array with the current date, day, month, and year.
+ * takes the users time offset into account.
+ */
 function getTodayInfo()
 {
 	return array(
@@ -349,7 +358,13 @@ function getTodayInfo()
 	);
 }
 
-// Returns the information needed to show a calendar grid for the given month.
+/**
+ * Returns the information needed to show a calendar grid for the given month.
+ * 
+ * @param int $month
+ * @param int $year
+ * @param array $calendarOptions
+ */
 function getCalendarGrid($month, $year, $calendarOptions)
 {
 	global $scripturl, $modSettings;
@@ -373,7 +388,7 @@ function getCalendarGrid($month, $year, $calendarOptions)
 			'month' => $month == 12 ? 1 : $month + 1,
 			'disabled' => $modSettings['cal_maxyear'] < ($month == 12 ? $year + 1 : $year),
 		),
-		//!!! Better tweaks?
+		// @todo Better tweaks?
 		'size' => isset($calendarOptions['size']) ? $calendarOptions['size'] : 'large',
 	);
 
@@ -499,7 +514,13 @@ function getCalendarGrid($month, $year, $calendarOptions)
 	return $calendarGrid;
 }
 
-// Returns the information needed to show a calendar for the given week.
+/**
+ * Returns the information needed to show a calendar for the given week.
+ * @param int $month
+ * @param int $year
+ * @param int $day
+ * @param array $calendarOptions
+ */
 function getCalendarWeek($month, $year, $day, $calendarOptions)
 {
 	global $scripturl, $modSettings;
@@ -619,7 +640,12 @@ function getCalendarWeek($month, $year, $day, $calendarOptions)
 	return $calendarGrid;
 }
 
-// Retrieve all events for the given days, independently of the users offset.
+// 
+/**
+ * Retrieve all events for the given days, independently of the users offset.
+ * 
+ * @param int $days_to_index
+ */
 function cache_getOffsetIndependentEvents($days_to_index)
 {
 	global $sourcedir;
@@ -639,6 +665,11 @@ function cache_getOffsetIndependentEvents($days_to_index)
 }
 
 // Called from the BoardIndex to display the current day's events on the board index.
+/**
+ * 
+ * Enter description here ...
+ * @param array $eventOptions
+ */
 function cache_getRecentEvents($eventOptions)
 {
 	global $modSettings, $user_info, $scripturl;
@@ -755,6 +786,10 @@ function cache_getRecentEvents($eventOptions)
 }
 
 // Makes sure the calendar post is valid.
+/**
+ * 
+ * Enter description here ...
+ */
 function validateEventPost()
 {
 	global $modSettings, $txt, $sourcedir, $smcFunc;
@@ -810,7 +845,11 @@ function validateEventPost()
 	}
 }
 
-// Get the event's poster.
+/**
+ * Get the event's poster.
+ * 
+ * @param int $event_id
+ */
 function getEventPoster($event_id)
 {
 	global $smcFunc;
@@ -836,7 +875,11 @@ function getEventPoster($event_id)
 	return $poster;
 }
 
-// Consolidating the various INSERT statements into this function.
+/**
+ * Consolidating the various INSERT statements into this function.
+ * 
+ * @param array $eventOptions
+ */
 function insertEvent(&$eventOptions)
 {
 	global $modSettings, $smcFunc;
@@ -882,6 +925,11 @@ function insertEvent(&$eventOptions)
 	));
 }
 
+/**
+ * 
+ * @param int $event_id
+ * @param array $eventOptions
+ */
 function modifyEvent($event_id, &$eventOptions)
 {
 	global $smcFunc;
@@ -924,6 +972,10 @@ function modifyEvent($event_id, &$eventOptions)
 	));
 }
 
+/**
+ * 
+ * @param int $event_id
+ */
 function removeEvent($event_id)
 {
 	global $smcFunc;
@@ -941,6 +993,10 @@ function removeEvent($event_id)
 	));
 }
 
+/**
+ * 
+ * @param int $event_id
+ */
 function getEventProperties($event_id)
 {
 	global $smcFunc;
@@ -989,6 +1045,12 @@ function getEventProperties($event_id)
 	return $return_value;
 }
 
+/**
+ * 
+ * @param int $start
+ * @param int $items_per_page
+ * @param string $sort
+ */
 function list_getHolidays($start, $items_per_page, $sort)
 {
 	global $smcFunc;
@@ -1010,6 +1072,9 @@ function list_getHolidays($start, $items_per_page, $sort)
 	return $holidays;
 }
 
+/**
+ * 
+ */
 function list_getNumHolidays()
 {
 	global $smcFunc;
@@ -1026,6 +1091,10 @@ function list_getNumHolidays()
 	return $num_items;
 }
 
+/**
+ * 
+ * @param array $holiday_ids
+ */
 function removeHolidays($holiday_ids)
 {
 	global $smcFunc;

+ 26 - 0
Sources/Subs-Compat.php

@@ -287,4 +287,30 @@ if (!function_exists('session_regenerate_id'))
 		return true;
 	}
 }
+
+// @author [Unknown] [email protected]
+// @link http://www.simplemachines.org/community/index.php?msg=2420295
+if (!function_exists('str_ireplace'))
+{
+	function str_ireplace($search, $replace, $subject)
+	{
+		global $context;
+
+		// While preg_replace() has this too, it's also not in PHP 4.
+		if (func_num_args() == 4)
+			trigger_error('str_ireplace(): $count parameter not supported.', E_USER_WARNING);
+
+		// @todo Using preg should give us better Unicode support for case folding.
+		// But technically, this doesn't do the same thing that str_ireplace() does in PHP 5.
+		// Might be better to always omit the u parameter.
+		$endu = '~i' . ($context['utf8'] ? 'u' : '');
+		if (is_array($search))
+			foreach ($search as $k => $pat)
+				$search[$k] = '~' . preg_quote($pat, '~') . $endu;
+		else
+			$search = '~' . preg_quote($search, '~') . $endu;
+
+		return preg_replace($search, $replace, $subject);
+	}
+}
 ?>

+ 3 - 3
Sources/Subs-Editor.php

@@ -39,10 +39,10 @@ if (!defined('SMF'))
 	  each board individually).
 
 	void AutoSuggestHandler(string checkRegistered = null)
-		// !!!
+		// @todo
 
 	void AutoSuggest_Search_Member()
-		// !!!
+		// @todo
 */
 
 /**
@@ -90,7 +90,7 @@ function bbc_to_html($text)
 	$text = strtr($text, array("\r" => '', "\n" => '<br />'));
 
 	// Prevent conversion of all bbcode inside these bbcodes.
-	// !!! Tie in with bbc permissions ?
+	// @todo Tie in with bbc permissions ?
 	foreach (array('code', 'php', 'nobbc') as $code)
 	{
 		if (strpos($text, '['. $code) !== false)

+ 4 - 0
Sources/Subs-Membergroups.php

@@ -105,6 +105,8 @@ function deleteMembergroups($groups)
 		logAction('delete_group', array('group' => $row['group_name']), 'admin');
 	$smcFunc['db_free_result']($request);
 
+	call_integration_hook('integrate_delete_membergroups', array($groups));
+
 	// Remove the membergroups themselves.
 	$smcFunc['db_query']('', '
 		DELETE FROM {db_prefix}membergroups
@@ -595,6 +597,8 @@ function addMembersToGroup($members, $group, $type = 'auto', $permissionCheckDon
 			array('id_action')
 		);
 
+	call_integration_hook('integrate_add_members_to_group', array($log_inserts));	
+
 	return true;
 }
 

+ 5 - 5
Sources/Subs-Members.php

@@ -304,7 +304,7 @@ function deleteMembers($users, $check_not_admin = false)
 	);
 
 	// Make their votes appear as guest votes - at least it keeps the totals right.
-	//!!! Consider adding back in cookie protection.
+	// @todo Consider adding back in cookie protection.
 	$smcFunc['db_query']('', '
 		UPDATE {db_prefix}log_polls
 		SET id_member = {int:guest_id}
@@ -482,7 +482,7 @@ function registerMember(&$regOptions, $return_errors = false)
 	if ($smcFunc['strtolower']($regOptions['username']) === $smcFunc['strtolower']($txt['guest_title']))
 		$reg_errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title']));
 
-	// !!! Separate the sprintf?
+	// @todo Separate the sprintf?
 	if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~', $regOptions['email']) === 0 || strlen($regOptions['email']) > 255)
 		$reg_errors[] = array('done', sprintf($txt['valid_email_needed'], $smcFunc['htmlspecialchars']($regOptions['username'])));
 
@@ -529,7 +529,7 @@ function registerMember(&$regOptions, $return_errors = false)
 	}
 
 	// If they are using an OpenID that hasn't been verified yet error out.
-	// !!! Change this so they can register without having to attempt a login first
+	// @todo Change this so they can register without having to attempt a login first
 	if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid']))
 		$reg_errors[] = array('lang', 'openid_not_verified');
 
@@ -549,7 +549,7 @@ function registerMember(&$regOptions, $return_errors = false)
 			'username' => $regOptions['username'],
 		)
 	);
-	// !!! Separate the sprintf?
+	// @todo Separate the sprintf?
 	if ($smcFunc['db_num_rows']($request) != 0)
 		$reg_errors[] = array('lang', 'email_in_use', false, array(htmlspecialchars($regOptions['email'])));
 	$smcFunc['db_free_result']($request);
@@ -647,7 +647,7 @@ function registerMember(&$regOptions, $return_errors = false)
 	if ($regOptions['require'] == 'coppa')
 	{
 		$regOptions['register_vars']['is_activated'] = 5;
-		// !!! This should be changed.  To what should be it be changed??
+		// @todo This should be changed.  To what should be it be changed??
 		$regOptions['register_vars']['validation_code'] = '';
 	}
 	// Maybe it can be activated right away?

+ 3 - 3
Sources/Subs-OpenID.php

@@ -170,7 +170,7 @@ function smf_openID_makeAssociation($server)
 	$expires = $issued + min((int)$assoc_data['expires_in'], 60);
 	$assoc_type = isset($assoc_data['assoc_type']) ? $assoc_data['assoc_type'] : '';
 
-	// !!! Is this really needed?
+	// @todo Is this really needed?
 	foreach (array('dh_server_public', 'enc_mac_key') as $key)
 		if (isset($assoc_data[$key]))
 			$assoc_data[$key] = str_replace(' ', '+', $assoc_data[$key]);
@@ -226,7 +226,7 @@ function smf_openID_return()
 	if (!isset($_GET['openid_mode']))
 		fatal_lang_error('openid_return_no_mode', false);
 
-	// !!! Check for error status!
+	// @todo Check for error status!
 	if ($_GET['openid_mode'] != 'id_res')
 		fatal_lang_error('openid_not_resolved');
 
@@ -364,7 +364,7 @@ function smf_openID_return()
 
 function smf_openID_canonize($uri)
 {
-	// !!! Add in discovery.
+	// @todo Add in discovery.
 
 	if (strpos($uri, 'http://') !== 0 && strpos($uri, 'https://') !== 0)
 		$uri = 'http://' . $uri;

+ 4 - 3
Sources/Subs-Package.php

@@ -229,7 +229,8 @@ function read_tgz_data($data, $destination, $single_file = false, $overwrite = f
 	$offset = 10;
 	$octdec = array('mode', 'uid', 'gid', 'size', 'mtime', 'checksum', 'type');
 
-	// "Read" the filename and comment. // !!! Might be mussed.
+	// "Read" the filename and comment.
+	// @todo Might be mussed.
 	if ($flags & 12)
 	{
 		while ($flags & 8 && $data{$offset++} != "\0")
@@ -556,7 +557,7 @@ function getPackageInfo($gzfilename)
 	loadClassFile('Class-Package.php');
 	$packageInfo = new xmlArray($packageInfo);
 
-	// !!! Error message of some sort?
+	// @todo Error message of some sort?
 	if (!$packageInfo->exists('package-info[0]'))
 		return 'package_get_error_packageinfo_corrupt';
 
@@ -1162,7 +1163,7 @@ function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install
 				}
 			}
 
-			// !!! TODO: Make sure the file actually exists?  Might not work when testing?
+			// @todo Make sure the file actually exists?  Might not work when testing?
 			if ($action->exists('@type') && $action->fetch('@type') == 'inline')
 			{
 				$filename = $temp_path . '$auto_' . $temp_auto++ . ($actionType == 'readme' || $actionType == 'redirect' ? '.txt' : ($actionType == 'code' || $actionType == 'database' ? '.php' : '.mod'));

+ 11 - 11
Sources/Subs-Post.php

@@ -1911,7 +1911,7 @@ function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
 	}
 
 	// Creating is modifying...in a way.
-	//!!! Why not set id_msg_modified on the insert?
+	// @todo Why not set id_msg_modified on the insert?
 	$smcFunc['db_query']('', '
 		UPDATE {db_prefix}messages
 		SET id_msg_modified = {int:id_msg}
@@ -2573,7 +2573,7 @@ function modifyPost(&$msgOptions, &$topicOptions, &$posterOptions)
  * Approve (or not) some posts... without permission checks...
  *
  * @param array $msgs - array of message ids
- * @param $approve = true
+ * @param bool $approve = true
  */
 function approvePosts($msgs, $approve = true)
 {
@@ -2850,15 +2850,15 @@ function sendApprovalNotifications(&$topicData)
 	$digest_insert = array();
 	foreach ($topicData as $topic => $msgs)
 		foreach ($msgs as $msgKey => $msg)
-	{
-		censorText($topicData[$topic][$msgKey]['subject']);
-		censorText($topicData[$topic][$msgKey]['body']);
-		$topicData[$topic][$msgKey]['subject'] = un_htmlspecialchars($topicData[$topic][$msgKey]['subject']);
-		$topicData[$topic][$msgKey]['body'] = trim(un_htmlspecialchars(strip_tags(strtr(parse_bbc($topicData[$topic][$msgKey]['body'], false), array('<br />' => "\n", '</div>' => "\n", '</li>' => "\n", '&#91;' => '[', '&#93;' => ']')))));
+		{
+			censorText($topicData[$topic][$msgKey]['subject']);
+			censorText($topicData[$topic][$msgKey]['body']);
+			$topicData[$topic][$msgKey]['subject'] = un_htmlspecialchars($topicData[$topic][$msgKey]['subject']);
+			$topicData[$topic][$msgKey]['body'] = trim(un_htmlspecialchars(strip_tags(strtr(parse_bbc($topicData[$topic][$msgKey]['body'], false), array('<br />' => "\n", '</div>' => "\n", '</li>' => "\n", '&#91;' => '[', '&#93;' => ']')))));
 
-		$topics[] = $msg['id'];
-		$digest_insert[] = array($msg['topic'], $msg['id'], 'reply', $user_info['id']);
-	}
+			$topics[] = $msg['id'];
+			$digest_insert[] = array($msg['topic'], $msg['id'], 'reply', $user_info['id']);
+		}
 
 	// These need to go into the digest too...
 	$smcFunc['db_insert']('',
@@ -3030,7 +3030,7 @@ function updateLastMessages($setboards, $id_msg = 0)
 			$parents = getBoardParents($id_board);
 
 		// Ignore any parents on the top child level.
-		//!!! Why?
+		// @todo Why?
 		foreach ($parents as $id => $parent)
 		{
 			if ($parent['level'] != 0)

+ 1 - 1
Sources/Subs-Recent.php

@@ -26,7 +26,7 @@ function getLastPosts($latestPostOptions)
 	global $scripturl, $txt, $user_info, $modSettings, $smcFunc, $context;
 
 	// Find all the posts.  Newer ones will have higher IDs.  (assuming the last 20 * number are accessable...)
-	// !!!SLOW This query is now slow, NEEDS to be fixed.  Maybe break into two?
+	// @todo SLOW This query is now slow, NEEDS to be fixed.  Maybe break into two?
 	$request = $smcFunc['db_query']('substring', '
 		SELECT
 			m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg,

+ 19 - 15
Sources/Subs.php

@@ -702,7 +702,7 @@ function comma_format($number, $override_decimal_count = false)
 	global $txt;
 	static $thousands_separator = null, $decimal_separator = null, $decimal_count = null;
 
-	// !!! Should, perhaps, this just be handled in the language files, and not a mod setting?
+	// @todo Should, perhaps, this just be handled in the language files, and not a mod setting?
 	// (French uses 1 234,00 for example... what about a multilingual forum?)
 
 	// Cache these values...
@@ -1061,7 +1061,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 				'tag' => 'code',
 				'type' => 'unparsed_content',
 				'content' => '<div class="codeheader">' . $txt['code'] . ': <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation">' . $txt['code_select'] . '</a></div>' . ($context['browser']['is_gecko'] || $context['browser']['is_opera'] ? '<pre style="margin: 0; padding: 0;">' : '') . '<code class="bbc_code">$1</code>' . ($context['browser']['is_gecko'] || $context['browser']['is_opera'] ? '</pre>' : ''),
-				// !!! Maybe this can be simplified?
+				// @todo Maybe this can be simplified?
 				'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
 					global $context;
 
@@ -1103,7 +1103,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 				'tag' => 'code',
 				'type' => 'unparsed_equals_content',
 				'content' => '<div class="codeheader">' . $txt['code'] . ': ($2) <a href="#" onclick="return smfSelectText(this);" class="codeoperation">' . $txt['code_select'] . '</a></div>' . ($context['browser']['is_gecko'] || $context['browser']['is_opera'] ? '<pre style="margin: 0; padding: 0;">' : '') . '<code class="bbc_code">$1</code>' . ($context['browser']['is_gecko'] || $context['browser']['is_opera'] ? '</pre>' : ''),
-				// !!! Maybe this can be simplified?
+				// @todo Maybe this can be simplified?
 				'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
 					global $context;
 
@@ -1152,7 +1152,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 				'tag' => 'email',
 				'type' => 'unparsed_content',
 				'content' => '<a href="mailto:$1" class="bbc_email">$1</a>',
-				// !!! Should this respect guest_hideContacts?
+				// @todo Should this respect guest_hideContacts?
 				'validate' => create_function('&$tag, &$data, $disabled', '$data = strtr($data, array(\'<br />\' => \'\'));'),
 			),
 			array(
@@ -1160,7 +1160,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 				'type' => 'unparsed_equals',
 				'before' => '<a href="mailto:$1" class="bbc_email">',
 				'after' => '</a>',
-				// !!! Should this respect guest_hideContacts?
+				// @todo Should this respect guest_hideContacts?
 				'disallow_children' => array('email', 'ftp', 'url', 'iurl'),
 				'disabled_after' => ' ($1)',
 			),
@@ -1669,11 +1669,11 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 		$disabled['email'] = true;
 		$disabled['flash'] = true;
 
-		// !!! Change maybe?
+		// @todo Change maybe?
 		if (!isset($_GET['images']))
 			$disabled['img'] = true;
 
-		// !!! Interface/setting to add more?
+		// @todo Interface/setting to add more?
 	}
 
 	$open_tags = array();
@@ -1792,7 +1792,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 				}
 
 				// Don't go backwards.
-				//!!! Don't think is the real solution....
+				// @todo Don't think is the real solution....
 				$lastAutoPos = isset($lastAutoPos) ? $lastAutoPos : 0;
 				if ($pos < $lastAutoPos)
 					$no_autolink_area = true;
@@ -2210,7 +2210,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 		// No type means 'parsed_content'.
 		if (!isset($tag['type']))
 		{
-			// !!! Check for end tag first, so people can say "I like that [i] tag"?
+			// @todo Check for end tag first, so people can say "I like that [i] tag"?
 			$open_tags[] = $tag;
 			$message = substr($message, 0, $pos) . "\n" . $tag['before'] . "\n" . substr($message, $pos1);
 			$pos += strlen($tag['before']) - 1 + 2;
@@ -2429,7 +2429,7 @@ function parsesmileys(&$message)
 	static $smileyPregSearch = array(), $smileyPregReplacements = array();
 
 	// No smiley set at all?!
-	if ($user_info['smiley_set'] == 'none')
+	if ($user_info['smiley_set'] === 'none' || trim($message) === '')
 		return;
 
 	// If the smiley array hasn't been set, do it now.
@@ -2481,16 +2481,20 @@ function parsesmileys(&$message)
 			$smileyCode = '<img src="' . htmlspecialchars($modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/' . $smileysto[$i]) . '" alt="' . strtr(htmlspecialchars($smileysfrom[$i], ENT_QUOTES), array(':' => '&#58;', '(' => '&#40;', ')' => '&#41;', '$' => '&#36;', '[' => '&#091;')). '" title="' . strtr(htmlspecialchars($smileysdescs[$i]), array(':' => '&#58;', '(' => '&#40;', ')' => '&#41;', '$' => '&#36;', '[' => '&#091;')) . '" class="smiley" />';
 
 			$smileyPregReplacements[$smileysfrom[$i]] = $smileyCode;
-			$smileyPregReplacements[htmlspecialchars($smileysfrom[$i], ENT_QUOTES)] = $smileyCode;
+
 			$searchParts[] = preg_quote($smileysfrom[$i], '~');
-			$searchParts[] = preg_quote(htmlspecialchars($smileysfrom[$i], ENT_QUOTES), '~');
+			if ($smileysfrom[$i] != ($specialChars = htmlspecialchars($smileysfrom[$i], ENT_QUOTES)))
+			{
+				$smileyPregReplacements[$specialChars] = $smileyCode;
+				$searchParts[] = preg_quote($specialChars, '~');
+			}
 		}
 
 		$smileyPregSearch = '~(?<=[>:\?\.\s' . $non_breaking_space . '[\]()*\\\;]|^)(' . implode('|', $searchParts) . ')(?=[^[:alpha:]0-9]|$)~e' . ($context['utf8'] ? 'u' : '');
 	}
 
 	// Replace away!
-	$message = preg_replace($smileyPregSearch, 'isset($smileyPregReplacements[\'$1\']) ? $smileyPregReplacements[\'$1\'] : \'\'', $message);
+	$message = preg_replace($smileyPregSearch, '$smileyPregReplacements[\'$1\']', $message);
 }
 
 // Highlight any code...
@@ -2560,7 +2564,7 @@ function redirectexit($setLocation = '', $refresh = false)
 	elseif (isset($_GET['debug']))
 		$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\\??/', $scripturl . '?debug;', $setLocation);
 
-	if (!empty($modSettings['queryless_urls']) && (empty($context['server']['is_cgi']) || @ini_get('cgi.fix_pathinfo') == 1 || @get_cfg_var('cgi.fix_pathinfo') == 1) && (!empty($context['server']['is_apache']) || !empty($context['server']['is_lighttpd']] || !empty($context['server']['is_litespeed']))))
+	if (!empty($modSettings['queryless_urls']) && (empty($context['server']['is_cgi']) || @ini_get('cgi.fix_pathinfo') == 1 || @get_cfg_var('cgi.fix_pathinfo') == 1) && (!empty($context['server']['is_apache']) || !empty($context['server']['is_lighttpd']) || !empty($context['server']['is_litespeed'])))
 	{
 		if (defined('SID') && SID != '')
 			$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\?(?:' . SID . '(?:;|&|&amp;))((?:board|topic)=[^#]+?)(#[^"]*?)?$/e', "\$scripturl . '/' . strtr('\$1', '&;=', '//,') . '.html\$2?' . SID", $setLocation);
@@ -2851,7 +2855,7 @@ function setupThemeContext($forceload = false)
 	var window_oldAvatarOnload = window.onload;
 	window.onload = smf_avatarResize;';
 
-		// !!! Move this over to script.js?
+		// @todo Move this over to script.js?
 		$context['html_headers'] .= '
 	// ]]></script>';
 	}

+ 5 - 5
Sources/Themes.php

@@ -70,7 +70,7 @@ function ThemesMain()
 		'copy' => 'CopyTemplate',
 	);
 
-	// !!! Layout Settings?
+	// @todo Layout Settings?
 	if (!empty($context['admin_menu_name']))
 	{
 		$context[$context['admin_menu_name']]['tab_data'] = array(
@@ -614,7 +614,7 @@ function SetThemeOptions()
 	loadTheme($_GET['th'], false);
 
 	loadLanguage('Profile');
-	//!!! Should we just move these options so they are no longer theme dependant?
+	// @todo Should we just move these options so they are no longer theme dependant?
 	loadLanguage('PersonalMessage');
 
 	// Let the theme take care of the settings.
@@ -1519,7 +1519,7 @@ function ThemeInstall()
 				$temp = $smcFunc['db_fetch_assoc']($request);
 				$smcFunc['db_free_result']($request);
 
-				// !!! An error otherwise?
+				// @todo An error otherwise?
 				if (is_array($temp))
 				{
 					$install_info = $temp + $install_info;
@@ -1692,7 +1692,7 @@ function EditTheme()
 {
 	global $context, $settings, $scripturl, $boarddir, $smcFunc;
 
-	// !!! Should this be removed?
+	// @todo Should this be removed?
 	if (isset($_REQUEST['preview']))
 		die('die() with fire');
 
@@ -1869,7 +1869,7 @@ function EditTheme()
 				fwrite($fp, $_POST['entire_file']);
 				fclose($fp);
 
-				// !!! Use fetch_web_data()?
+				// @todo Use fetch_web_data()?
 				$error = @file_get_contents($theme_url . '/tmp_' . session_id() . '.php');
 				if (preg_match('~ <b>(\d+)</b><br( /)?' . '>$~i', $error) != 0)
 					$error_file = $theme_dir . '/tmp_' . session_id() . '.php';

+ 3 - 1
Sources/Who.php

@@ -515,7 +515,7 @@ function determineActions($urls, $preferred_prefix = false)
 /**
  * It prepares credit and copyright information for the credits page or the admin page
  *
- * @param $in_admin = false, if parameter is true the it will not load the sub-template nor the template file
+ * @param bool $in_admin = false, if parameter is true the it will not load the sub-template nor the template file
  */
 function Credits($in_admin = false)
 {
@@ -740,6 +740,8 @@ function Credits($in_admin = false)
 		$context['robot_no_index'] = true;
 		$context['page_title'] = $txt['credits'];
 	}
+
+	call_integration_hook('integrate_credits');
 }
 
 ?>

+ 1 - 1
Themes/default/Errors.template.php

@@ -10,7 +10,7 @@
  * @version 2.0
  */
 
-// !!!
+// @todo
 /*	This template file contains only the sub template fatal_error. It is
 	shown when an error occurs, and should show at least a back button and
 	$context['error_message'].

+ 2 - 2
Themes/default/ManagePermissions.template.php

@@ -546,9 +546,9 @@ function template_modify_group()
 		else
 			template_modify_group_classic('board');
 
-		echo '
-			</div>';
 	}
+	echo '
+		</div>';
 
 	if ($context['profile']['can_modify'])
 		echo '

+ 1 - 1
Themes/default/ModerationCenter.template.php

@@ -68,7 +68,7 @@ function template_latest_news()
 		</div>';
 
 	// This requires a lot of javascript...
-	//!!! Put this in it's own file!!
+	// @todo Put this in it's own file!!
 	echo '
 		<script type="text/javascript" src="', $scripturl, '?action=viewsmfile;filename=current-version.js"></script>
 		<script type="text/javascript" src="', $scripturl, '?action=viewsmfile;filename=latest-news.js"></script>

+ 3 - 3
Themes/default/PersonalMessage.template.php

@@ -817,7 +817,7 @@ function template_search_results()
 				<h3 class="catbg">', $txt['from'], ': ', $message['member']['link'], ', ', $txt['to'], ': ';
 
 				// Show the recipients.
-				// !!! This doesn't deal with the sent item searching quite right for bcc.
+				// @todo This doesn't deal with the sent item searching quite right for bcc.
 				if (!empty($message['recipients']['to']))
 					echo implode(', ', $message['recipients']['to']);
 				// Otherwise, we're just going to say "some people"...
@@ -857,7 +857,7 @@ function template_search_results()
 		// Otherwise just a simple list!
 		else
 		{
-			// !!! No context at all of the search?
+			// @todo No context at all of the search?
 			echo '
 			<tr class="', $alternate ? 'windowbg' : 'windowbg2', '" valign="top">
 				<td>', $message['time'], '</td>
@@ -1280,7 +1280,7 @@ function template_report_message()
 				<dl class="settings">';
 
 	// If there is more than one admin on the forum, allow the user to choose the one they want to direct to.
-	// !!! Why?
+	// @todo Why?
 	if ($context['admin_count'] > 1)
 	{
 		echo '

+ 4 - 4
Themes/default/Post.template.php

@@ -415,7 +415,7 @@ function template_main()
 	if (!empty($settings['additional_options_collapsable']))
 		echo '
 					<div id="postAdditionalOptionsHeader">
-						<img src="', $settings['images_url'], '/collapse.gif" alt="-" id="postMoreExpand" style="display: none;" /> <strong><a href="#" id="postMoreExpandLink">', $txt['post_additionalopt'], '</a></strong>
+						<img src="', $settings['images_url'], '/collapse.gif" alt="-" id="postMoreExpand" style="display: none;" /> <strong><a href="#" id="postMoreExpandLink">', $context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt'], '</a></strong>
 					</div>';
 
 	// Display the check boxes for all the standard options - if they are available to the user!
@@ -581,7 +581,7 @@ function template_main()
 						if (!(\'setRequestHeader\' in test))
 							return submitThisOnce(document.forms.postmodify);
 					}
-					// !!! Currently not sending poll options and option checkboxes.
+					// @todo Currently not sending poll options and option checkboxes.
 					var x = new Array();
 					var textFields = [\'subject\', ', JavaScriptEscape($context['post_box_name']), ', \'icon\', \'guestname\', \'email\', \'evtitle\', \'question\', \'topic\'];
 					var numericFields = [
@@ -767,8 +767,8 @@ function template_main()
 				aSwapLinks: [
 					{
 						sId: \'postMoreExpandLink\',
-						msgExpanded: ', JavaScriptEscape($txt['post_additionalopt']), ',
-						msgCollapsed: ', JavaScriptEscape($txt['post_additionalopt']), '
+						msgExpanded: ', JavaScriptEscape($context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt']), ',
+						msgCollapsed: ', JavaScriptEscape($context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt']), '
 					}
 				]
 			});';

+ 2 - 2
Themes/default/Themes.template.php

@@ -136,7 +136,7 @@ function template_main()
 					<dl class="settings">';
 
 	// Here's a little box for installing a new theme.
-	// !!! Should the value="theme_gz" be there?!
+	// @todo Should the value="theme_gz" be there?!
 	if ($context['can_create_new'])
 		echo '
 						<dt>
@@ -437,7 +437,7 @@ function template_set_settings()
 				</h3>
 			</div>';
 
-	// !!! Why can't I edit the default theme popup.
+	// @todo Why can't I edit the default theme popup.
 	if ($context['theme_settings']['theme_id'] != 1)
 		echo '
 			<div class="cat_bar">

+ 2 - 2
Themes/default/Wireless.template.php

@@ -398,7 +398,7 @@ function template_imode_post()
 {
 	global $context, $settings, $options, $scripturl, $txt, $modSettings;
 
-	// !!! $modSettings['guest_post_no_email']
+	// @todo $modSettings['guest_post_no_email']
 	echo '
 		<form action="', $scripturl, '?action=', $context['destination'], ';board=', $context['current_board'], '.0;imode" method="post">
 			<table border="0" cellspacing="0" cellpadding="0">';
@@ -423,7 +423,7 @@ function template_imode_post()
 				<tr><td><input type="text" name="email" value="', $context['email'], '" class="input_text" /></td></tr>';
 	}
 
-	// !!! Needs a more specific imode template.
+	// @todo Needs a more specific imode template.
 	if ($context['require_verification'])
 		echo '
 				<tr><td>', !empty($context['post_error']['need_qr_verification']) ? '<font color="#cc0000">' . $txt['verification'] . '</font>' : $txt['verification'], ':</td></tr>

+ 8 - 7
Themes/default/css/index.css

@@ -125,12 +125,12 @@ input:focus, textarea:focus, button:focus, select:focus
 }
 
 /* All input elements that are checkboxes or radio buttons shouldn't have a border around them. */
-input.input_check, input.input_radio
+.input_check, .input_radio
 {
 	border: none;
 	background: none;
 }
-h3.catbg input.input_check
+h3.catbg .input_check
 {
 	margin: 9px 7px 0 7px;
 }
@@ -293,7 +293,7 @@ ul.reset, ul.reset li
 ------------------------------------------------------- */
 
 /* A quote, perhaps from another post. */
-blockquote.bbc_standard_quote, blockquote.bbc_alternate_quote
+.bbc_standard_quote, .bbc_alternate_quote
 {
 	font-size: x-small;
 	color: #000;
@@ -307,17 +307,17 @@ blockquote.bbc_standard_quote, blockquote.bbc_alternate_quote
 }
 
 /* Alterate blockquote stylings */
-blockquote.bbc_standard_quote
+.bbc_standard_quote
 {
 	background-color: #d7daec;
 }
-blockquote.bbc_alternate_quote
+.bbc_alternate_quote
 {
 	background-color: #e7eafc;
 }
 
 /* A code block - maybe PHP ;). */
-code.bbc_code
+.bbc_code
 {
 	display: block;
 	font-family: "dejavu sans mono", "monaco", "lucida console", "courier new", monospace;
@@ -787,7 +787,7 @@ h4.catbg a.toggle img
 	vertical-align: middle;
 	margin: -2px 5px 0 5px;
 }
-h4.catbg, h4.catbg2 , h3.catbg , h3.catbg2 , .table_list tbody.header td.catbg
+h4.catbg, h4.catbg2, h3.catbg, h3.catbg2, .table_list tbody.header td.catbg
 {
 	background: url(../images/theme/main_block.png) no-repeat 100% -160px;
 	padding-right: 9px;
@@ -2096,6 +2096,7 @@ img.smiley
 #forumposts .modified
 {
 	float: left;
+	color: #999;
 }
 #forumposts .reportlinks
 {

+ 1 - 1
Themes/default/languages/ManagePaid.english.php

@@ -135,7 +135,7 @@ $txt['edit_subscriber'] = 'Edit Subscriber';
 $txt['delete_selected'] = 'Delete Selected';
 $txt['complete_selected'] = 'Complete Selected';
 
-// !!! These strings are used in conjunction with JavaScript.  Use numeric entities.
+// @todo These strings are used in conjunction with JavaScript.  Use numeric entities.
 $txt['delete_are_sure'] = 'Are you sure you want to delete all records of the selected subscriptions?';
 $txt['complete_are_sure'] = 'Are you sure you want to complete the selected subscriptions?';
 

+ 2 - 1
Themes/default/languages/Post.english.php

@@ -120,7 +120,8 @@ $txt['attach_restrict_attachmentSizeLimit'] = 'maximum individual size %1$dKB';
 $txt['attach_restrict_attachmentNumPerPostLimit'] = '%1$d per post';
 $txt['attach_restrictions'] = 'Restrictions:';
 
-$txt['post_additionalopt'] = 'Attachments and other options';
+$txt['post_additionalopt_attach'] = 'Attachments and other options';
+$txt['post_additionalopt'] = 'Other options';
 $txt['sticky_after'] = 'Sticky this topic.';
 $txt['move_after2'] = 'Move this topic.';
 $txt['back_to_topic'] = 'Return to this topic.';

+ 1 - 1
Themes/default/languages/index.english.php

@@ -701,7 +701,7 @@ $txt['mc_reported_posts'] = 'Reported Posts';
 $txt['modlog_view'] = 'Moderation Log';
 $txt['calendar_menu'] = 'View Calendar';
 
-//!!! Send email strings - should move?
+// @todo Send email strings - should move?
 $txt['send_email'] = 'Send Email';
 $txt['send_email_disclosed'] = 'Note this will be visible to the recipient.';
 $txt['send_email_subject'] = 'Email Subject';

+ 2 - 2
index.php

@@ -59,7 +59,7 @@ if (@version_compare(PHP_VERSION, '5.1') == -1)
 
 // If $maintenance is set specifically to 2, then we're upgrading or something.
 if (!empty($maintenance) && $maintenance == 2)
-	db_fatal_error();
+	display_maintenance_message();
 
 // Create a variable to store some SMF specific functions in.
 $smcFunc = array();
@@ -131,7 +131,7 @@ if (WIRELESS)
 
 	// Some cellphones can't handle output compression...
 	$modSettings['enableCompressedOutput'] = '0';
-	// !!! Do we want these hard coded?
+	// @todo Do we want these hard coded?
 	$modSettings['defaultMaxMessages'] = 5;
 	$modSettings['defaultMaxTopics'] = 9;