Browse Source

! Cleanup, many files (sync of in / out changes)
! Some more documentation changes
! recursive sendmail call did not honor the is_private setting
! Add an integration hook for actions which don't track stats.
! Sanitize parameters in package options page (admin-only) (Packages.php). (Reported by Luis Santana.)
! ! duplicate ID if openID active in registration, config_var with multiple=true [Bug 4891], couple of things in Subs-Members
! bbc added to load settings

Spuds 12 years ago
parent
commit
906795f52e

+ 0 - 7
Sources/Help.php

@@ -16,13 +16,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*
-
-
-	void ShowAdminHelp()
-
-*/
-
 /**
  * Redirect to the user help ;).
  * It loads information needed for the help section.

+ 1 - 0
Sources/ManagePosts.php

@@ -136,6 +136,7 @@ function SetCensor()
 	if (isset($_POST['censortest']))
 	{
 		$censorText = htmlspecialchars($_POST['censortest'], ENT_QUOTES);
+		preparsecode($censorText);
 		$context['censor_test'] = strtr(censorText($censorText), array('"' => '"'));
 	}
 

+ 1 - 0
Sources/ManageServer.php

@@ -417,6 +417,7 @@ function ModifyLoadBalancingSettings($return_config = false)
 		'loadavg_allunread' => '2.0',
 		'loadavg_unreadreplies' => '3.5',
 		'loadavg_show_posts' => '2.0',
+		'loadavg_bbc' => '25.0',
 		'loadavg_forum' => '40.0',
 	);
 

+ 1 - 1
Sources/Notify.php

@@ -127,7 +127,7 @@ function BoardNotify()
 		// We're gonna need the notify template...
 		loadTemplate('Notify');
 
-		// Find out if they have notification set for this topic already.
+		// Find out if they have notification set for this board already.
 		$request = $smcFunc['db_query']('', '
 			SELECT id_member
 			FROM {db_prefix}log_notify

+ 3 - 3
Sources/Packages.php

@@ -1439,9 +1439,9 @@ function PackageOptions()
 		checkSession('post');
 
 		updateSettings(array(
-			'package_server' => $_POST['pack_server'],
-			'package_port' => $_POST['pack_port'],
-			'package_username' => $_POST['pack_user'],
+			'package_server' => trim($smcFunc['htmlspecialchars']($_POST['pack_server'])),
+			'package_port' => trim($smcFunc['htmlspecialchars']($_POST['pack_port'])),
+			'package_username' => trim($smcFunc['htmlspecialchars']($_POST['pack_user'])),
 			'package_make_backups' => !empty($_POST['package_make_backups']),
 			'package_make_full_backups' => !empty($_POST['package_make_full_backups'])
 		));

+ 0 - 1
Sources/Poll.php

@@ -218,7 +218,6 @@ function Vote()
 	redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
 }
 
-//
 /**
  * Lock the voting for a poll.
  * Must be called with a topic specified in the URL.

+ 57 - 67
Sources/Post.php

@@ -1,6 +1,9 @@
 <?php
 
 /**
+ * The job of this file is to handle everything related to posting replies,
+ * new topics, quotes, and modifications to existing posts.  It also handles
+ * quoting posts by way of javascript.
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,71 +17,15 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	The job of this file is to handle everything related to posting replies,
-	new topics, quotes, and modifications to existing posts.  It also handles
-	quoting posts by way of javascript.
-
-	void Post()
-		- handles showing the post screen, loading the post to be modified, and
-		  loading any post quoted.
-		- additionally handles previews of posts.
-		- uses the Post template and language file, main sub template.
-		- allows wireless access using the protocol_post sub template.
-		- requires different permissions depending on the actions, but most
-		  notably post_new, post_reply_own, and post_reply_any.
-		- shows options for the editing and posting of calendar events and
-		  attachments, as well as the posting of polls.
-		- accessed from ?action=post.
-
-	void Post2()
-		- actually posts or saves the message composed with Post().
-		- requires various permissions depending on the action.
-		- handles attachment, post, and calendar saving.
-		- sends off notifications, and allows for announcements and moderation.
-		- accessed from ?action=post2.
-
-	void AnnounceTopic()
-		- handle the announce topic function (action=announce).
-		- checks the topic announcement permissions and loads the announcement
-		  template.
-		- requires the announce_topic permission.
-		- uses the ManageMembers template and Post language file.
-		- call the right function based on the sub-action.
-
-	void AnnouncementSelectMembergroup()
-		- lets the user select the membergroups that will receive the topic
-		  announcement.
-
-	void AnnouncementSend()
-		- splits the members to be sent a topic announcement into chunks.
-		- composes notification messages in all languages needed.
-		- does the actual sending of the topic announcements in chunks.
-		- calculates a rough estimate of the percentage items sent.
-
-	void notifyMembersBoard(notifyData)
-		- notifies members who have requested notification for new topics
-		  posted on a board of said posts.
-		- receives data on the topics to send out notifications to by the passed in array.
-		- only sends notifications to those who can *currently* see the topic
-		  (it doesn't matter if they could when they requested notification.)
-		- loads the Post language file multiple times for each language if the
-		  userLanguage setting is set.
-
-	void getTopic()
-		- gets a summary of the most recent posts in a topic.
-		- depends on the topicSummaryPosts setting.
-		- if you are editing a post, only shows posts previous to that post.
-
-	void QuoteFast()
-		- loads a post an inserts it into the current editing text box.
-		- uses the Post language file.
-		- uses special (sadly browser dependent) javascript to parse entities
-		  for internationalization reasons.
-		- accessed with ?action=quotefast.
-
-	void JavaScriptModify()
-*/
-
+/**
+ * handles showing the post screen, loading the post to be modified, and loading any post quoted.
+ * additionally handles previews of posts.
+ * @uses the Post template and language file, main sub template.
+ * allows wireless access using the protocol_post sub template.
+ * requires different permissions depending on the actions, but most notably post_new, post_reply_own, and post_reply_any.
+ * shows options for the editing and posting of calendar events and attachments, as well as the posting of polls.
+ * accessed from ?action=post.
+ */
 function Post()
 {
 	global $txt, $scripturl, $topic, $modSettings, $board;
@@ -1217,6 +1164,13 @@ function Post()
 		loadTemplate('Post');
 }
 
+/**
+ * actually posts or saves the message composed with Post().
+ * requires various permissions depending on the action.
+ * handles attachment, post, and calendar saving.
+ * sends off notifications, and allows for announcements and moderation.
+ * accessed from ?action=post2.
+ */
 function Post2()
 {
 	global $board, $topic, $txt, $modSettings, $sourcedir, $context;
@@ -2115,6 +2069,13 @@ function Post2()
 }
 
 // General function for topic announcements.
+/**
+ * handle the announce topic function (action=announce).
+ * checks the topic announcement permissions and loads the announcement template.
+ * requires the announce_topic permission.
+ * uses the ManageMembers template and Post language file.
+ * call the right function based on the sub-action.
+ */
 function AnnounceTopic()
 {
 	global $context, $txt, $topic;
@@ -2140,7 +2101,10 @@ function AnnounceTopic()
 	$subActions[isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'selectgroup']();
 }
 
-// Allow a user to chose the membergroups to send the announcement to.
+/**
+ * Allow a user to chose the membergroups to send the announcement to.
+ * lets the user select the membergroups that will receive the topic announcement.
+ */
 function AnnouncementSelectMembergroup()
 {
 	global $txt, $context, $topic, $board, $board_info, $smcFunc;
@@ -2216,6 +2180,12 @@ function AnnouncementSelectMembergroup()
 }
 
 // Send the announcement in chunks.
+/**
+ * splits the members to be sent a topic announcement into chunks.
+ * composes notification messages in all languages needed.
+ * does the actual sending of the topic announcements in chunks.
+ * calculates a rough estimate of the percentage items sent.
+ */
 function AnnouncementSend()
 {
 	global $topic, $board, $board_info, $context, $modSettings;
@@ -2340,6 +2310,15 @@ function AnnouncementSend()
 }
 
 // Notify members of a new post.
+/**
+ * notifies members who have requested notification for new topics
+ * * posted on a board of said posts.
+ * receives data on the topics to send out notifications to by the passed in array.
+ * only sends notifications to those who can *currently* see the topic (it doesn't matter if they could when they requested notification.)
+ * loads the Post language file multiple times for each language if the
+ * * userLanguage setting is set.
+ * @param array &$topicData
+ */
 function notifyMembersBoard(&$topicData)
 {
 	global $txt, $scripturl, $language, $user_info;
@@ -2488,7 +2467,12 @@ function notifyMembersBoard(&$topicData)
 	);
 }
 
-// Get the topic for display purposes.
+/**
+ * Get the topic for display purposes.
+ * gets a summary of the most recent posts in a topic.
+ * depends on the topicSummaryPosts setting.
+ * if you are editing a post, only shows posts previous to that post.
+ */
 function getTopic()
 {
 	global $topic, $modSettings, $context, $smcFunc, $counter, $options;
@@ -2543,6 +2527,12 @@ function getTopic()
 	$smcFunc['db_free_result']($request);
 }
 
+/**
+ * loads a post an inserts it into the current editing text box.
+ * uses the Post language file.
+ * uses special (sadly browser dependent) javascript to parse entities for internationalization reasons.
+ * accessed with ?action=quotefast.
+ */
 function QuoteFast()
 {
 	global $modSettings, $user_info, $txt, $settings, $context;

+ 9 - 8
Sources/PostModeration.php

@@ -17,15 +17,13 @@ if (!defined('SMF'))
 	die('Hacking attempt...');
 
 /**
- * This is a handling function for all things post moderation...
+ * This is a handling function for all things post moderation.
  */
 function PostModerationMain()
 {
 	global $sourcedir;
 
-	/**
-	 * @todo We'll shift these later bud.
-	 */
+	 // @todo We'll shift these later bud.
 	loadLanguage('ModerationCenter');
 	loadTemplate('ModerationCenter');
 
@@ -515,9 +513,9 @@ function ApproveMessage()
 /**
  * Approve a batch of posts (or topics in their own right)
  *
- * @param $messages
- * @param $messageDetails
- * @param $current_view
+ * @param array $messages
+ * @param array $messageDetails
+ * @param (string) $current_view = replies
  */
 function approveMessages($messages, $messageDetails, $current_view = 'replies')
 {
@@ -597,11 +595,14 @@ function approveAllData()
  *
  * @param array $messages
  * @param array $messageDetails
- * @param string $current_view
+ * @param string $current_view = replies
  */
 function removeMessages($messages, $messageDetails, $current_view = 'replies')
 {
 	global $sourcedir, $modSettings;
+
+	// @todo something's not right, removeMessage() does check permissions,
+	// removeTopics() doesn't
 	require_once($sourcedir . '/RemoveTopic.php');
 	if ($current_view == 'topics')
 	{

+ 3 - 1
Sources/Profile-Actions.php

@@ -19,7 +19,7 @@ if (!defined('SMF'))
 /**
  * Activate an account.
  *
- * @param int $memID, the member ID
+ * @param int $memID the member ID
  */
 function activateAccount($memID)
 {
@@ -328,6 +328,7 @@ function issueWarning($memID)
  * Get the number of warnings a user has.
  *
  * @param int $memID
+ * @return int Total number of warnings for the user
  */
 function list_getUserWarningCount($memID)
 {
@@ -356,6 +357,7 @@ function list_getUserWarningCount($memID)
  * @param int $items_per_page
  * @param string $sort
  * @param int $memID, the member ID
+ * @return array the preview warnings
  */
 function list_getUserWarnings($start, $items_per_page, $sort, $memID)
 {

+ 1 - 1
Sources/Profile-View.php

@@ -629,7 +629,7 @@ function showAttachments($memID)
 }
 
 /**
- * @todo needs a description
+ * Gets the user stats for display
  * 
  * @param int $memID id_member
  */

+ 5 - 24
Sources/Reminder.php

@@ -1,6 +1,7 @@
 <?php
 
 /**
+ * Handle sending out reminders, and checking the secret answer and question.  It uses just a few functions to do this, which are:
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,30 +15,10 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file deals with sending out reminders, and checking the secret answer
-	and question.  It uses just a few functions to do this, which are:
-
-	void RemindMe()
-		- this is just the controlling delegator.
-		- 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?
+/**
+ * This is the controlling delegator
+ * @uses Profile language files and Reminder template
+ */
 function RemindMe()
 {
 	global $txt, $context;

+ 6 - 49
Sources/Reports.php

@@ -7,6 +7,10 @@
  * will fill context with relevant data. Secondly, the choice of sub-template
  * will determine how this data is shown to the user
  * 
+ * Functions ending with "Report" are responsible for generating data for reporting.
+ * They are all called from ReportsMain.
+ * Never access the context directly, but use the data handling functions to do so.
+ * 
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -20,52 +24,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	. It has the following
-	functions:
-
-	void xxxxxxReport()
- * functions ending with "Report" are responsible for generating data
- * for reporting.
- * they are all called from ReportsMain.
- * never access the context directly, but use the data handling
- * functions to do so.
-
-void addData(array inc_data, int custom_table = null)
- * adds an array of data into an existing table.
- * if there are no existing tables, will create one with default
- * attributes.
- * if custom_table isn't specified, it will use the last table created,
- * if it is specified and doesn't exist the function will return false.
- * if a set of keys have been specified, the function will check each
- * required key is present in the incoming data. If this data is missing
- * the current tables default value will be used.
- * if any key in the incoming data begins with '#sep#', the function
- * will add a separator accross the table at this point.
- * once the incoming data has been sanitized, it is added to the table.
-
-void addSeparator(string title = '', int custom_table = null)
-	 * adds a separator with title given by attribute "title" after the
-	 * current row in the table.
-	 * if there are no existing tables, will create one with default
-	 * attributes.
-	 * if custom_table isn't specified, it will use the last table created,
-	 * if it is specified and doesn't exist the function will return false.
-	 * if the table is currently having data added by column this may have
-	 * unpredictable visual results.
-
-void finishTables()
- * is (unfortunately) required to create some useful variables for
- * templates.
- * foreach data table created, it will count the number of rows and
- * columns in the table.
- * will also create a max_width variable for the table, to give an
- * estimate width for the whole table * * if it can.
-
-void setKeys(string method = 'rows', array keys = array(),
-	bool reverse = false)
-)
-*/
-
 /**
  * Handling function for generating reports.
  * Requires the admin_forum permission.
@@ -943,8 +901,7 @@ function addSeparator($title = '', $custom_table = null)
 
 /**
  * This does the necessary count of table data before displaying them.
- * is (unfortunately) required to create some useful variables for
- * templates.
+ * is (unfortunately) required to create some useful variables for templates.
  * foreach data table created, it will count the number of rows and
  * columns in the table.
  * will also create a max_width variable for the table, to give an
@@ -987,7 +944,7 @@ function finishTables()
  * if reverse is set to true, then the values of the variable "keys"
  * are used as oppossed to the keys(!
  * 
- * @param string $rows = 'rows' rows or cols
+ * @param string $method = 'rows' rows or cols
  * @param array $keys = array()
  * @param bool $reverse = false
  */

+ 2 - 42
Sources/ScheduledTasks.php

@@ -1,6 +1,8 @@
 <?php
 
 /**
+ * This file is automatically called and handles all manner of scheduled things.
+ * 
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,48 +16,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file is automatically called and handles all manner of scheduled things.
-
-	void AutoTask()
-		//!!!
-
-	void scheduled_approval_notification()
-		// !!!
-
-	void scheduled_daily_maintenance()
-		// !!!
-
-	void scheduled_auto_optimize()
-		// !!!
-
-	void scheduled_daily_digest()
-		// !!!
-
-	void scheduled_weekly_digest()
-		// !!!
-
-	void scheduled_paid_subscriptions()
-		// !!!
-
-	void ReduceMailQueue(int number, bool override)
-		// !!!
-
-	void CalculateNextTrigger(array tasks)
-		// !!!
-
-	int next_time(int regularity, char unit, int offset)
-		// !!!
-
-	void loadEssentialThemeData()
-		// !!!
-
-	void scheduled_fetchSMfiles()
-		// !!!
-
-	void scheduled_birthdayemails()
-		// !!!
-*/
-
 // This function works out what to do!
 function AutoTask()
 {

+ 14 - 14
Sources/Search.php

@@ -27,13 +27,13 @@ $GLOBALS['search_versions'] = array(
 /**
  * Ask the user what they want to search for.
  * What it does:
-		- shows the screen to search forum posts (action=search), and uses the
-		  simple version if the simpleSearch setting is enabled.
-		- uses the main sub template of the Search template.
-		- uses the Search language file.
-		- requires the search_posts permission.
-		- decodes and loads search parameters given in the URL (if any).
-		- the form redirects to index.php?action=search2.
+ * * shows the screen to search forum posts (action=search), and uses the
+ *   simple version if the simpleSearch setting is enabled.
+ * * uses the main sub template of the Search template.
+ * * uses the Search language file.
+ * * requires the search_posts permission.
+ * * decodes and loads search parameters given in the URL (if any).
+ * * the form redirects to index.php?action=search2.
  */
 function PlushSearch1()
 {
@@ -234,13 +234,13 @@ function PlushSearch1()
 /**
  * Gather the results and show them.
  * What it does:
-		- checks user input and searches the messages table for messages
-		  matching the query.
-		- requires the search_posts permission.
-		- uses the results sub template of the Search template.
-		- uses the Search language file.
-		- stores the results into the search cache.
-		- show the results of the search query.
+ * * checks user input and searches the messages table for messages
+ *   matching the query.
+ * * requires the search_posts permission.
+ * * uses the results sub template of the Search template.
+ * * uses the Search language file.
+ * * stores the results into the search cache.
+ * * show the results of the search query.
  */
 function PlushSearch2()
 {

+ 8 - 8
Sources/SearchAPI-Custom.php

@@ -14,13 +14,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*
-	int searchSort(string $wordA, string $wordB)
-		- callback function for usort used to sort the fulltext results.
-		- the order of sorting is: large words, small words, large words that
-		  are excluded from the search, small words that are excluded.
-*/
-
 class custom_search
 {
 	// This is the last version of SMF that this was tested on, to protect against API changes.
@@ -87,7 +80,14 @@ class custom_search
 		return !empty($modSettings['search_custom_index_config']);
 	}
 
-	// This function compares the length of two strings plus a little.
+	/**
+	 * callback function for usort used to sort the fulltext results.
+	 * the order of sorting is: large words, small words, large words that
+	 * are excluded from the search, small words that are excluded.
+	 * @param string $a Word A
+	 * @param string $b Word B
+	 * @return int
+	 */
 	public function searchSort($a, $b)
 	{
 		global $modSettings, $excludedWords;

+ 8 - 8
Sources/SearchAPI-Fulltext.php

@@ -14,13 +14,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*
-	int searchSort(string $wordA, string $wordB)
-		- callback function for usort used to sort the fulltext results.
-		- the order of sorting is: large words, small words, large words that
-		  are excluded from the search, small words that are excluded.
-*/
-
 class fulltext_search
 {
 	// This is the last version of SMF that this was tested on, to protect against API changes.
@@ -100,7 +93,14 @@ class fulltext_search
 		return $min_word_length;
 	}
 
-	// This function compares the length of two strings plus a little.
+	/**
+	 * callback function for usort used to sort the fulltext results.
+	 * the order of sorting is: large words, small words, large words that
+	 * are excluded from the search, small words that are excluded.
+	 * @param string $a Word A
+	 * @param string $b Word B
+	 * @return int
+	 */
 	public function searchSort($a, $b)
 	{
 		global $modSettings, $excludedWords;

+ 97 - 102
Sources/SplitTopics.php

@@ -1,6 +1,8 @@
 <?php
 
 /**
+ * Handle merging and splitting of topics
+ * 
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -9,104 +11,20 @@
  * @license http://www.simplemachines.org/about/smf/license.php BSD
  *
  * @version 2.1 Alpha 1
+ * 
+ * Original module by Mach8 - We'll never forget you.
  */
 
-// Original module by Mach8 - We'll never forget you.
-
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file handles merging and splitting topics... it does this with:
-
-	void SplitTopics()
-		- splits a topic into two topics.
-		- delegates to the other functions (based on the URL parameter 'sa').
-		- loads the SplitTopics template.
-		- requires the split_any permission.
-		- is accessed with ?action=splittopics.
-
-	void SplitIndex()
-		- screen shown before the actual split.
-		- is accessed with ?action=splittopics;sa=index.
-		- default sub action for ?action=splittopics.
-		- uses 'ask' sub template of the SplitTopics template.
-		- redirects to SplitSelectTopics if the message given turns out to be
-		  the first message of a topic.
-		- shows the user three ways to split the current topic.
-
-	void SplitExecute()
-		- do the actual split.
-		- is accessed with ?action=splittopics;sa=execute.
-		- uses the main SplitTopics template.
-		- supports three ways of splitting:
-		   (1) only one message is split off.
-		   (2) all messages after and including a given message are split off.
-		   (3) select topics to split (redirects to SplitSelectTopics()).
-		- uses splitTopic function to do the actual splitting.
-
-	void SplitSelectTopics()
-		- allows the user to select the messages to be split.
-		- is accessed with ?action=splittopics;sa=selectTopics.
-		- uses 'select' sub template of the SplitTopics template or (for
-		  XMLhttp) the 'split' sub template of the Xml template.
-		- supports XMLhttp for adding/removing a message to the selection.
-		- uses a session variable to store the selected topics.
-		- shows two independent page indexes for both the selected and
-		  not-selected messages (;topic=1.x;start2=y).
-
-	void SplitSelectionExecute()
-		- do the actual split of a selection of topics.
-		- is accessed with ?action=splittopics;sa=splitSelection.
-		- uses the main SplitTopics template.
-		- uses splitTopic function to do the actual splitting.
-
-	int splitTopic(int topicID, array messagesToBeSplit, string newSubject)
-		- general function to split off a topic.
-		- creates a new topic and moves the messages with the IDs in
-		  array messagesToBeSplit to the new topic.
-		- the subject of the newly created topic is set to 'newSubject'.
-		- marks the newly created message as read for the user splitting it.
-		- updates the statistics to reflect a newly created topic.
-		- logs the action in the moderation log.
-		- a notification is sent to all users monitoring this topic.
-		- returns the topic ID of the new split topic.
-
-	void MergeTopics()
-		- merges two or more topics into one topic.
-		- delegates to the other functions (based on the URL parameter sa).
-		- loads the SplitTopics template.
-		- requires the merge_any permission.
-		- is accessed with ?action=mergetopics.
-
-	void MergeIndex()
-		- allows to pick a topic to merge the current topic with.
-		- is accessed with ?action=mergetopics;sa=index
-		- default sub action for ?action=mergetopics.
-		- uses 'merge' sub template of the SplitTopics template.
-		- allows to set a different target board.
-
-	void MergeExecute(array topics = request)
-		- set merge options and do the actual merge of two or more topics.
-		- the merge options screen:
-			- shows topics to be merged and allows to set some merge options.
-			- is accessed by ?action=mergetopics;sa=options.and can also
-			  internally be called by QuickModeration() (Subs-Boards.php).
-			- uses 'merge_extra_options' sub template of the SplitTopics
-			  template.
-		- the actual merge:
-			- is accessed with ?action=mergetopics;sa=execute.
-			- updates the statistics to reflect the merge.
-			- logs the action in the moderation log.
-			- sends a notification is sent to all users monitoring this topic.
-			- redirects to ?action=mergetopics;sa=done.
-
-	void MergeDone()
-		- shows a 'merge completed' screen.
-		- is accessed with ?action=mergetopics;sa=done.
-		- uses 'merge_done' sub template of the SplitTopics template.
-*/
-
-// Split a topic into two separate topics... in case it got offtopic, etc.
+/**
+ * splits a topic into two topics.
+ * delegates to the other functions (based on the URL parameter 'sa').
+ * loads the SplitTopics template.
+ * requires the split_any permission.
+ * is accessed with ?action=splittopics.
+ */
 function SplitTopics()
 {
 	global $topic, $sourcedir;
@@ -138,7 +56,15 @@ function SplitTopics()
 		$subActions[$_REQUEST['sa']]();
 }
 
-// Part 1: General stuff.
+/**
+ * screen shown before the actual split.
+ * is accessed with ?action=splittopics;sa=index.
+ * default sub action for ?action=splittopics.
+ * uses 'ask' sub template of the SplitTopics template.
+ * redirects to SplitSelectTopics if the message given turns out to be
+ * the first message of a topic.
+ * shows the user three ways to split the current topic.
+ */
 function SplitIndex()
 {
 	global $txt, $topic, $context, $smcFunc, $modSettings;
@@ -192,7 +118,16 @@ function SplitIndex()
 	$context['page_title'] = $txt['split'];
 }
 
-// Alright, you've decided what you want to do with it.... now to do it.
+/**
+ * do the actual split.
+ * is accessed with ?action=splittopics;sa=execute.
+ * uses the main SplitTopics template.
+ * supports three ways of splitting:
+ * (1) only one message is split off.
+ * (2) all messages after and including a given message are split off.
+ * (3) select topics to split (redirects to SplitSelectTopics()).
+ * uses splitTopic function to do the actual splitting.
+ */
 function SplitExecute()
 {
 	global $txt, $board, $topic, $context, $user_info, $smcFunc, $modSettings;
@@ -243,7 +178,16 @@ function SplitExecute()
 	$context['page_title'] = $txt['split'];
 }
 
-// Get a selective list of topics...
+/**
+ * allows the user to select the messages to be split.
+ * is accessed with ?action=splittopics;sa=selectTopics.
+ * uses 'select' sub template of the SplitTopics template or (for 
+ * XMLhttp) the 'split' sub template of the Xml template.
+ * supports XMLhttp for adding/removing a message to the selection.
+ * uses a session variable to store the selected topics.
+ * shows two independent page indexes for both the selected and 
+ * not-selected messages (;topic=1.x;start2=y).
+ */
 function SplitSelectTopics()
 {
 	global $txt, $scripturl, $topic, $context, $modSettings, $original_msgs, $smcFunc, $options;
@@ -507,7 +451,13 @@ function SplitSelectTopics()
 	}
 }
 
-// Actually and selectively split the topics out.
+/**
+ * do the actual split of a selection of topics.
+ * is accessed with ?action=splittopics;sa=splitSelection.
+ * uses the main SplitTopics template.
+ * uses splitTopic function to do the actual splitting.
+
+ */
 function SplitSelectionExecute()
 {
 	global $txt, $board, $topic, $context, $user_info;
@@ -528,7 +478,21 @@ function SplitSelectionExecute()
 	$context['page_title'] = $txt['split'];
 }
 
-// Split a topic in two topics.
+/**
+	int splitTopic(int topicID, array messagesToBeSplit, string newSubject)
+ * general function to split off a topic.
+ * creates a new topic and moves the messages with the IDs in
+ * array messagesToBeSplit to the new topic.
+ * the subject of the newly created topic is set to 'newSubject'.
+ * marks the newly created message as read for the user splitting it.
+ * updates the statistics to reflect a newly created topic.
+ * logs the action in the moderation log.
+ * a notification is sent to all users monitoring this topic.
+ * @param int $split1_ID_TOPIC
+ * @param array $splitMessages
+ * @param string $new_subject
+ * @return int the topic ID of the new split topic.
+ */
 function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
 {
 	global $user_info, $topic, $board, $modSettings, $smcFunc, $txt;
@@ -823,7 +787,13 @@ function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
 	return $split2_ID_TOPIC;
 }
 
-// Merge two topics into one topic... useful if they have the same basic subject.
+/**
+ * merges two or more topics into one topic.
+ * delegates to the other functions (based on the URL parameter sa).
+ * loads the SplitTopics template.
+ * requires the merge_any permission.
+ * is accessed with ?action=mergetopics.
+ */
 function MergeTopics()
 {
 	// Load the template....
@@ -843,7 +813,13 @@ function MergeTopics()
 		$subActions[$_REQUEST['sa']]();
 }
 
-// Merge two topics together.
+/**
+ * allows to pick a topic to merge the current topic with.
+ * is accessed with ?action=mergetopics;sa=index
+ * default sub action for ?action=mergetopics.
+ * uses 'merge' sub template of the SplitTopics template.
+ * allows to set a different target board.
+ */
 function MergeIndex()
 {
 	global $txt, $board, $context, $smcFunc;
@@ -979,7 +955,22 @@ function MergeIndex()
 	$context['sub_template'] = 'merge';
 }
 
-// Now that the topic IDs are known, do the proper merging.
+/**
+ * set merge options and do the actual merge of two or more topics.
+ * 
+ * the merge options screen:
+ * * shows topics to be merged and allows to set some merge options.
+ * * is accessed by ?action=mergetopics;sa=options.and can also internally be called by QuickModeration() (Subs-Boards.php).
+ * * uses 'merge_extra_options' sub template of the SplitTopics template.
+ * 
+ * the actual merge:
+ * * is accessed with ?action=mergetopics;sa=execute.
+ * * updates the statistics to reflect the merge.
+ * * logs the action in the moderation log.
+ * * sends a notification is sent to all users monitoring this topic.
+ * * redirects to ?action=mergetopics;sa=done.
+ * @param array $topics = array()
+ */
 function MergeExecute($topics = array())
 {
 	global $user_info, $txt, $context, $scripturl, $sourcedir;
@@ -1584,7 +1575,11 @@ function MergeExecute($topics = array())
 	redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board);
 }
 
-// Tell the user the move was done properly.
+/**
+ * Shows a 'merge completed' screen.
+ * is accessed with ?action=mergetopics;sa=done.
+ * uses 'merge_done' sub template of the SplitTopics template.
+ */
 function MergeDone()
 {
 	global $txt, $context;

+ 49 - 1
Sources/Subs-Compat.php

@@ -310,4 +310,52 @@ if (!function_exists('str_ireplace'))
 	}
 }
 
-?>
+/**
+ * Load a < PHP 5 class file
+ * 
+ * @param string $filename
+ */
+function loadOldClassFile($filename)
+{
+	global $sourcedir;
+	static $files_included = array();
+
+	// Check if it was included before.
+	if (in_array($filename, $files_included))
+		return;
+
+	// Make sure we don't include it again.
+	$files_included[] = $filename;
+
+	// Do some replacements to make it PHP 4 compatible.
+	eval('?' . '>' . preg_replace(array(
+		'~class\s+([\w-_]+)([^}]+)function\s+__construct\s*\(~',
+		'~([\s\t]+)public\s+\$~',
+		'~([\s\t]+)private\s+\$~',
+		'~([\s\t]+)protected\s+\$~',
+		'~([\s\t]+)public\s+function\s+~',
+		'~([\s\t]+)private\s+function\s+~',
+		'~([\s\t]+)protected\s+function\s+~',
+	), array(
+		'class $1$2function $1(',
+		'$1var $',
+		'$1var $',
+		'$1var $',
+		'$1function ',
+		'$1function ',
+		'$1function ',
+	), rtrim(file_get_contents($sourcedir . '/' . $filename))));
+}
+
+/**
+ * PHP 4 didn't have bcpowmod.
+ */
+if (!function_exists('bcpowmod') && function_exists('bcpow'))
+{
+	function bcpowmod($num1, $num2, $num3)
+	{
+		return bcmod(bcpow($num1, $num2), $num3);
+	}
+}
+
+?>

+ 5 - 2
Sources/Subs-List.php

@@ -1,6 +1,7 @@
 <?php
 
 /**
+ * This file contains a standard way of displaying lists for SMF.
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,8 +15,10 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file contains a standard way of displaying lists for SMF.
-*/
+/**
+ * Create a new list
+ * @param array $listOptions
+ */
 
 function createList($listOptions)
 {

+ 0 - 1
Sources/Subs-Menu.php

@@ -16,7 +16,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-// ..
 /**
  * Create a menu.
  * @param array $menuData

+ 0 - 9
Sources/Subs-OpenID.php

@@ -653,13 +653,4 @@ function binary_xor($num1, $num2)
 	return $return;
 }
 
-// PHP 4 didn't have bcpowmod.
-if (!function_exists('bcpowmod') && function_exists('bcpow'))
-{
-	function bcpowmod($num1, $num2, $num3)
-	{
-		return bcmod(bcpow($num1, $num2), $num3);
-	}
-}
-
 ?>

+ 164 - 145
Sources/Subs-Package.php

@@ -19,140 +19,11 @@ if (!defined('SMF'))
 	files, as well as a simple xml parser to handle the xml package stuff.
 	Not to mention a few functions to make file handling easier.
 
-	array read_tgz_file(string filename, string destination,
-			bool single_file = false, bool overwrite = false, array files_to_extract = null)
-		- reads a .tar.gz file, filename, in and extracts file(s) from it.
-		- essentially just a shortcut for read_tgz_data().
-
-	array read_tgz_data(string data, string destination,
-			bool single_file = false, bool overwrite = false, array files_to_extract = null)
-		- extracts a file or files from the .tar.gz contained in data.
-		- detects if the file is really a .zip file, and if so returns the
-		  result of read_zip_data
-		- if destination is null, returns a list of files in the archive.
-		- if single_file is true, returns the contents of the file specified
-		  by destination, if it exists, or false.
-		- if single_file is true, destination can start with * and / to
-		  signify that the file may come from any directory.
-		- destination should not begin with a / if single_file is true.
-		- overwrites existing files with newer modification times if and
-		  only if overwrite is true.
-		- creates the destination directory if it doesn't exist, and is
-		  is specified.
-		- requires zlib support be built into PHP.
-		- returns an array of the files extracted.
-		- if files_to_extract is not equal to null only extracts file within this array.
-
-	array read_zip_data(string data, string destination,
-			bool single_file = false, bool overwrite = false, array files_to_extract = null)
-		- extracts a file or files from the .zip contained in data.
-		- if destination is null, returns a list of files in the archive.
-		- if single_file is true, returns the contents of the file specified
-		  by destination, if it exists, or false.
-		- if single_file is true, destination can start with * and / to
-		  signify that the file may come from any directory.
-		- destination should not begin with a / if single_file is true.
-		- overwrites existing files with newer modification times if and
-		  only if overwrite is true.
-		- creates the destination directory if it doesn't exist, and is
-		  is specified.
-		- requires zlib support be built into PHP.
-		- returns an array of the files extracted.
-		- if files_to_extract is not equal to null only extracts file within this array.
-
-	bool url_exists(string url)
-		- checks to see if url is valid, and returns a 200 status code.
-		- will return false if the file is "moved permanently" or similar.
-		- returns true if the remote url exists.
-
-	array loadInstalledPackages()
-		- loads and returns an array of installed packages.
-		- gets this information from Packages/installed.list.
-		- returns the array of data.
-
-	array getPackageInfo(string filename)
-		- loads a package's information and returns a representative array.
-		- expects the file to be a package in Packages/.
-		- returns a error string if the package-info is invalid.
-		- returns a basic array of id, version, filename, and similar
-		  information.
-		- in the array returned, an xmlArray is available in 'xml'.
-
-	void packageRequireFTP(string destination_url, array files = none, bool return = false)
-
-	array parsePackageInfo(xmlArray &package, bool testing_only = true,
-			string method = 'install', string previous_version = '')
-		- parses the actions in package-info.xml files from packages.
-		- package should be an xmlArray with package-info as its base.
-		- testing_only should be true if the package should not actually be
-		   applied.
-		- method is upgrade, install, or uninstall.  Its default is install.
-		- previous_version should be set to the previous installed version
-		   of this package, if any.
-		- does not handle failure terribly well; testing first is always
-		   better.
-		- returns an array of those changes made.
-
-	bool matchPackageVersion(string version, string versions)
-		- checks if version matches any of the versions in versions.
-		- supports comma separated version numbers, with or without
-		  whitespace.
-		- supports lower and upper bounds. (1.0-1.2)
-		- returns true if the version matched.
-
-	int compareVersions(string version1, string version2)
-		- compares two versions.
-		- returns 0 if version1 is equal to version2.
-		- returns -1 if version1 is lower than version2.
-		- returns 1 if version1 is higher than version2.
-
-	string parse_path(string path)
-		- parses special identifiers out of the specified path.
-		- returns the parsed path.
-
-	void deltree(string path, bool delete_directory = true)
-		- deletes a directory, and all the files and direcories inside it.
-		- requires access to delete these files.
-
-	bool mktree(string path, int mode)
-		- creates the specified tree structure with the mode specified.
-		- creates every directory in path until it finds one that already
-		  exists.
-		- returns true if successful, false otherwise.
-
-	void copytree(string source, string destination)
-		- copies one directory structure over to another.
-		- requires the destination to be writable.
-
-	void listtree(string path, string sub_path = none)
-
-	array parseModification(string file, bool testing = true, bool undo = false, array theme_paths = array())
-		- parses a xml-style modification file (file).
-		- testing tells it the modifications shouldn't actually be saved.
-		- undo specifies that the modifications the file requests should be
-		  undone; this doesn't work with everything (regular expressions.)
-		- returns an array of those changes made.
-
-	array parseBoardMod(string file, bool testing = true, bool undo = false, array theme_paths = array())
-		- parses a boardmod-style modification file (file).
-		- testing tells it the modifications shouldn't actually be saved.
-		- undo specifies that the modifications the file requests should be
-		  undone.
-		- returns an array of those changes made.
-
-	int package_put_contents(string filename, string data)
-		- writes data to a file, almost exactly like the file_put_contents()
-		  function.
-		- uses FTP to create/chmod the file when necessary and available.
-		- uses text mode for text mode file extensions.
-		- returns the number of bytes written.
-
-	void package_chmod(string filename)
-
-	string package_crypt(string password)
-
-	string fetch_web_data(string url, string post_data = '',
-			bool keep_alive = false)
+	string package_crypt(
+
+
+	string fetch_web_data(
+
 
 	Creating your own package server:
 	---------------------------------------------------------------------------
@@ -161,7 +32,15 @@ if (!defined('SMF'))
 	---------------------------------------------------------------------------
 */
 
-// Get the data from the file and extract it.
+/**
+ * Reads a .tar.gz file, filename, in and extracts file(s) from it.
+ * essentially just a shortcut for read_tgz_data().
+ * @param string $filename
+ * @param string $destination
+ * @param bool $single_file = false
+ * @param bool $overwrite = false
+ * @param array $files_to_extract = null
+ */
 function read_tgz_file($gzfilename, $destination, $single_file = false, $overwrite = false, $files_to_extract = null)
 {
 	if (strpos($gzfilename, 'http://') === 0)
@@ -182,7 +61,25 @@ function read_tgz_file($gzfilename, $destination, $single_file = false, $overwri
 	return read_tgz_data($data, $destination, $single_file, $overwrite, $files_to_extract);
 }
 
-// Extract tar.gz data.  If destination is null, return a listing.
+/**
+ * Extracts a file or files from the .tar.gz contained in data.
+ * detects if the file is really a .zip file, and if so returns the result of read_zip_data
+ * if destination is null, returns a list of files in the archive.
+ * if single_file is true, returns the contents of the file specified by destination, if it exists, or false.
+ * if single_file is true, destination can start with * and / to signify that the file may come from any directory.
+ * destination should not begin with a / if single_file is true.
+ * overwrites existing files with newer modification times if and only if overwrite is true.
+ * creates the destination directory if it doesn't exist, and is is specified.
+ * requires zlib support be built into PHP.
+ * returns an array of the files extracted.
+ * if files_to_extract is not equal to null only extracts file within this array.
+ * @param string data, 
+ * @param string destination, 
+ * @param bool single_file = false, 
+ * @param bool overwrite = false, 
+ * @param array files_to_extract = null
+ * @return array
+ */
 function read_tgz_data($data, $destination, $single_file = false, $overwrite = false, $files_to_extract = null)
 {
 	// Make sure we have this loaded.
@@ -445,7 +342,12 @@ function read_zip_data($data, $destination, $single_file = false, $overwrite = f
 		return $return;
 }
 
-// Checks the existence of a remote file since file_exists() does not do remote.
+/**
+ * Checks the existence of a remote file since file_exists() does not do remote.
+ * will return false if the file is "moved permanently" or similar.
+ * @param string url
+ * @return bool true if the remote url exists.
+ */
 function url_exists($url)
 {
 	$a_url = parse_url($url);
@@ -466,7 +368,12 @@ function url_exists($url)
 	return preg_match('~^HTTP/.+\s+(20[01]|30[127])~i', $head) == 1;
 }
 
-// Load the installed packages.
+/**
+ * Loads and returns an array of installed packages.
+ * gets this information from Packages/installed.list.
+ * returns the array of data.
+ * @return array
+ */
 function loadInstalledPackages()
 {
 	global $boarddir, $smcFunc;
@@ -520,6 +427,15 @@ function loadInstalledPackages()
 	return $installed;
 }
 
+/**
+ * Loads a package's information and returns a representative array.
+ * expects the file to be a package in Packages/.
+ * returns a error string if the package-info is invalid.
+ * returns a basic array of id, version, filename, and similar information.
+ * in the array returned, an xmlArray is available in 'xml'.
+ * @param string $filename
+ * @return array
+ */
 function getPackageInfo($gzfilename)
 {
 	global $boarddir;
@@ -868,6 +784,11 @@ function create_chmod_control($chmodFiles = array(), $chmodOptions = array(), $r
 	return $return_data;
 }
 
+/**
+ * @param string $destination_url
+ * @param array $files = none
+ * @param bool $return = false
+ */
 function packageRequireFTP($destination_url, $files = null, $return = false)
 {
 	global $context, $modSettings, $package_ftp, $boarddir, $txt;
@@ -1057,7 +978,19 @@ function packageRequireFTP($destination_url, $files = null, $return = false)
 	return $files;
 }
 
-// Parses a package-info.xml file - method can be 'install', 'upgrade', or 'uninstall'.
+/**
+ * Parses the actions in package-info.xml files from packages.
+ * package should be an xmlArray with package-info as its base.
+ * testing_only should be true if the package should not actually be applied.
+ * method is upgrade, install, or uninstall.  Its default is install.
+ * previous_version should be set to the previous installed version of this package, if any.
+ * does not handle failure terribly well; testing first is always better.
+ * @param xmlArray &$package
+ * @param bool $testing_only = true
+ * @param string $method = 'install' ('install', 'upgrade', or 'uninstall')
+ * @param string $previous_version = ''
+ * @return array an array of those changes made.
+ */
 function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install', $previous_version = '')
 {
 	global $boarddir, $forum_version, $context, $temp_path, $language;
@@ -1440,7 +1373,15 @@ function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install
 	return $not_done;
 }
 
-// This function tries to match $version into any of the ranges given in $versions
+/**
+ * Checks if version matches any of the versions in versions.
+ * supports comma separated version numbers, with or without whitespace.
+ * supports lower and upper bounds. (1.0-1.2)
+ * returns true if the version matched.
+ * @param string $version 
+ * @param string $versions
+ * @return bool
+ */
 function matchPackageVersion($version, $versions)
 {
 	// Make sure everything is lowercase and clean of spaces and unpleasant history.
@@ -1475,7 +1416,12 @@ function matchPackageVersion($version, $versions)
 	return false;
 }
 
-// The geek version of versioning checks for dummies, which basically compares two versions.
+/**
+ * Compares two versions.
+ * @param string version1
+ * @param string version2
+ * @return int (-1 if version1 is lower than version2, 0 if version1 is equal to version2; 1 if version1 is higher than version2)
+ */
 function compareVersions($version1, $version2)
 {
 	static $categories;
@@ -1529,6 +1475,11 @@ function compareVersions($version1, $version2)
 	return 0;
 }
 
+/**
+ * Parses special identifiers out of the specified path.
+ * @param string $path
+ * @return string The parsed path
+ */
 function parse_path($path)
 {
 	global $modSettings, $boarddir, $sourcedir, $settings, $temp_path;
@@ -1558,6 +1509,12 @@ function parse_path($path)
 	return strtr($path, $dirs);
 }
 
+/**
+ * Deletes a directory, and all the files and direcories inside it.
+ * requires access to delete these files.
+ * @param string $path
+ * @param bool $delete_directory = true
+ */
 function deltree($dir, $delete_dir = true)
 {
 	global $package_ftp;
@@ -1626,6 +1583,13 @@ function deltree($dir, $delete_dir = true)
 	}
 }
 
+/**
+ * Creates the specified tree structure with the mode specified.
+ * creates every directory in path until it finds one that already exists.
+ * @param string $path
+ * @param int $mode
+ * @return bool true if successful, false otherwise
+ */
 function mktree($strPath, $mode)
 {
 	global $package_ftp;
@@ -1688,6 +1652,12 @@ function mktree($strPath, $mode)
 	}
 }
 
+/**
+ * Copies one directory structure over to another.
+ * requires the destination to be writable.
+ * @param string $source
+ * @param string $destination
+ */
 function copytree($source, $destination)
 {
 	global $package_ftp;
@@ -1730,6 +1700,11 @@ function copytree($source, $destination)
 	closedir($current_dir);
 }
 
+/**
+ * @param string $path
+ * @param string $sub_path = ''
+ * @return array
+ */
 function listtree($path, $sub_path = '')
 {
 	$data = array();
@@ -1756,7 +1731,14 @@ function listtree($path, $sub_path = '')
 	return $data;
 }
 
-// Parse an xml based modification file.
+/**
+ * Parses a xml-style modification file (file).
+ * @param string $file
+ * @param bool $testing = true tells it the modifications shouldn't actually be saved.
+ * @param bool $undo = false specifies that the modifications the file requests should be undone; this doesn't work with everything (regular expressions.)
+ * @param array $theme_paths = array()
+ * @return array an array of those changes made.
+ */
 function parseModification($file, $testing = true, $undo = false, $theme_paths = array())
 {
 	global $boarddir, $sourcedir, $settings, $txt, $modSettings, $package_ftp;
@@ -2131,7 +2113,14 @@ function parseModification($file, $testing = true, $undo = false, $theme_paths =
 	return $actions;
 }
 
-// Parses a BoardMod format mod file...
+/**
+ * Parses a boardmod-style modification file (file).
+ * @param string $file
+ * @param bool $testing = true tells it the modifications shouldn't actually be saved.
+ * @param bool $undo = false specifies that the modifications the file requests should be undone.
+ * @param array $theme_paths = array()
+ * @return array an array of those changes made.
+ */
 function parseBoardMod($file, $testing = true, $undo = false, $theme_paths = array())
 {
 	global $boarddir, $sourcedir, $settings, $txt, $modSettings;
@@ -2458,6 +2447,15 @@ function package_get_contents($filename)
 		return $package_cache[$filename];
 }
 
+/**
+ * Writes data to a file, almost exactly like the file_put_contents() function.
+ * uses FTP to create/chmod the file when necessary and available.
+ * uses text mode for text mode file extensions.
+ * returns the number of bytes written.
+ * @param string $filename
+ * @param string $data
+ * @return int
+ */
 function package_put_contents($filename, $data, $testing = false)
 {
 	global $package_ftp, $package_cache, $modSettings;
@@ -2556,7 +2554,13 @@ function package_flush_cache($trash = false)
 	$package_cache = array();
 }
 
-// Try to make a file writable. Return true if it worked, false if it didn't.
+/**
+ * Try to make a file writable.
+ * @param string $filename
+ * @param string $perm_state = 'writable'
+ * @param bool $track_change = false
+ * @return bool True if it worked, false if it didn't
+ */
 function package_chmod($filename, $perm_state = 'writable', $track_change = false)
 {
 	global $package_ftp;
@@ -2684,6 +2688,10 @@ function package_chmod($filename, $perm_state = 'writable', $track_change = fals
 	return false;
 }
 
+/**
+ * @param string $pass
+ * @return string The encrypted password
+ */
 function package_crypt($pass)
 {
 	$n = strlen($pass);
@@ -2698,6 +2706,10 @@ function package_crypt($pass)
 	return $pass;
 }
 
+/**
+ * @todo Document this
+ * @param string $id
+ */
 function package_create_backup($id = 'backup')
 {
 	global $sourcedir, $boarddir, $smcFunc;
@@ -2827,7 +2839,14 @@ function package_create_backup($id = 'backup')
 	$fclose($output);
 }
 
-// Get the contents of a URL, irrespective of allow_url_fopen.
+/**
+ * Get the contents of a URL, irrespective of allow_url_fopen.
+ * @param string $url
+ * @param string $post_data = ''
+ * @param bool $keep_alive = false
+ * @param $redirection_level = 0
+ * @return string
+ */
 function fetch_web_data($url, $post_data = '', $keep_alive = false, $redirection_level = 0)
 {
 	global $webmaster_email;

+ 44 - 104
Sources/Subs.php

@@ -1,6 +1,8 @@
 <?php
 
 /**
+ * This file has all the main functions in it that relate to, well, everything.
+ * 
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,97 +16,6 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file has all the main functions in it that relate to, well,
-	everything.  It provides all of the following functions:
-
-	void updateStats(string statistic, string condition = '1')
-
-
-	void updateMemberData(int id_member, array data)
-
-	void updateSettings(array changeArray, use_update = false)
-
-	string constructPageIndex(string base_url, int &start, int max_value,
-
-	string comma_format(float number)
-
-	string timeformat(int time, bool show_today = true, string offset_type = false)
-
-	string un_htmlspecialchars(string text)
-
-	string shorten_subject(string regular_subject, int length)
-
-	int forum_time(bool use_user_offset = true)
- * returns the current time with offsets.
- * always applies the offset in the time_offset setting.
- * if use_user_offset is true, applies the user's offset as well.
- * returns seconds since the unix epoch.
-
-	array permute(array input)
- * 
-
-	
-
-	void parsesmileys(string &message)
- * the smiley parsing function which makes pretty faces appear :).
- * if custom smiley sets are turned off by smiley_enable, the default
- *  set of smileys will be used.
- * these are specifically not parsed in code tags [url=mailto:[email protected]]
- * caches the smileys from the database or array in memory.
- * doesn't return anything, but rather modifies message directly.
-
-	string highlight_php_code(string code)
- * Uses PHP's highlight_string() to highlight PHP syntax
- * does special handling to keep the tabs in the code available.
- * used to parse PHP code from inside [code] and [php] tags.
- * returns the code with highlighted HTML.
-
-	void redirectexit(string setLocation = '', bool use_refresh = false)
-
-	void obExit(bool do_header = true, bool do_footer = do_header)
-
-	void determineTopicClass(array &topic_context)
-
-	void setupThemeContext(bool force_reload = false)
-
-	void template_rawdata()
-
-	void template_header()
-
-	void theme_copyright(bool get_it = false)
-
-	void template_footer()
-
-	array ip2range(string $fullip)
- * converts a given IP string to an array.
- * internal function used to convert a user-readable format to
- *  a format suitable for the database.
- * returns 'unknown' if the ip in the input was '255.255.255.255'.
-
-	string host_from_ip(string ip_address)
-
-	string create_button(string filename, string alt, string label, bool custom = '')
-
-	void clean_cache(type = '')
- * clean the cache directory ($cachedir, if any and in use)
- * it may only remove the files of a certain type
- *  (if the $type parameter is given)
-
-	array call_integration_hook(string hook, array parameters = array())
- * calls all functions of the given hook.
- * supports static class method calls.
- * returns the results of the functions as an array.
-
-	void add_integration_function(string hook, string function, bool permanent = true)
- * adds the given function to the given hook.
- * does nothing if the functions is already added.
- * if permanent parameter is true, updates the value in settings table.
-
-	void remove_integration_function(string hook, string function)
- * removes the given function from the given hook.
- * does nothing if the functions is not available.
-*/
-
 /**
  * Update some basic statistics.
  * 
@@ -329,9 +240,9 @@ function updateStats($type, $parameter1 = null, $parameter2 = null)
 }
 
 /**
+ * Updates the columns in the members table.
  * Assumes the data has been htmlspecialchar'd.
  * 
- * updates the columns in the members table.
  * id_member is either an int or an array of ints to be updated.
  * data is an associative array of the columns to be updated and their
  *  respective values.
@@ -342,7 +253,6 @@ function updateStats($type, $parameter1 = null, $parameter2 = null)
  * this function should be used whenever member data needs to be
  *  updated in place of an UPDATE query.
  * 
- * Enter description here ...
  * @param mixed $members An array of integers
  * @param array $data
  */
@@ -802,12 +712,11 @@ function timeformat($log_time, $show_today = true, $offset_type = false)
  * Removes special entities from strings.  Compatibility...
  * 
  * removes the base entities (&lt;, &quot;, etc.) from text.
- * should be used instead of html_entity_decode for PHP version
- *  compatibility reasons.
+ * Should be used instead of html_entity_decode for PHP version compatibility reasons.
  * additionally converts &nbsp; and &#039;.
- * returns the string without entities.
- * 
+ * returns .
  * @param string $string
+ * @return the string without entities
  */
 function un_htmlspecialchars($string)
 {
@@ -844,9 +753,11 @@ function shorten_subject($subject, $len)
 }
 
 /**
- * The current time with offset.
- * @param bool $use_user_offset = true
+ * Get the current time with offset.
+ * Always applies the offset in the time_offset setting.
+ * @param bool $use_user_offset = true if use_user_offset is true, applies the user's offset as well
  * @param int $timestamp = null
+ * @return int seconds since the unix epoch
  */
 function forum_time($use_user_offset = true, $timestamp = null)
 {
@@ -921,6 +832,13 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 	if ($message === '')
 		return '';
 
+	// If the load average is too high, don't parse the BBC.
+	// I placed this below the empty $message check because it is slower
+	if (!empty($context['load_average']) && !empty($modSettings['bbc']) && $context['load_average'] >= $modSettings['bbc'])
+	{
+		$context['disabled_parse_bbc'] = true;
+		return $message;
+	}
 	// Never show smileys for wireless clients.  More bytes, can't see it anyway :P.
 	if (WIRELESS)
 		$smileys = false;
@@ -2471,6 +2389,13 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
 
 /**
  * Parse smileys in the passed message.
+ * The smiley parsing function which makes pretty faces appear :).
+ * If custom smiley sets are turned off by smiley_enable, the default
+ *  set of smileys will be used.
+ * These are specifically not parsed in code tags [url=mailto:[email protected]]
+ * Caches the smileys from the database or array in memory.
+ * Doesn't return anything, but rather modifies message directly.
+ * 
  * @param string &$message
  */
 function parsesmileys(&$message)
@@ -2549,7 +2474,11 @@ function parsesmileys(&$message)
 
 /**
  * Highlight any code.
+ * Uses PHP's highlight_string() to highlight PHP syntax
+ * does special handling to keep the tabs in the code available.
+ * used to parse PHP code from inside [code] and [php] tags.
  * @param string $code
+ * @return string the code with highlighted HTML.
  */
 function highlight_php_code($code)
 {
@@ -3202,6 +3131,9 @@ function getLegacyAttachmentFilename($filename, $attachment_id, $dir = null, $ne
 
 /**
  * Convert a single IP to a ranged IP.
+ * internal function used to convert a user-readable format to a format suitable for the database.
+ * @param string $fullip
+ * @return array|string 'unknown' if the ip in the input was '255.255.255.255'
  */
 function ip2range($fullip)
 {
@@ -3258,6 +3190,7 @@ function ip2range($fullip)
 
 /**
  * Lookup an IP; try shell_exec first because we can do a timeout on it.
+ * @param string $ip
  */
 function host_from_ip($ip)
 {
@@ -3313,6 +3246,9 @@ function host_from_ip($ip)
 
 /**
  * Chops a string into words and prepares them to be inserted into (or searched from) the database.
+ * @param string $text
+ * @param int $max_chars = 20
+ * @param bool $encrypt = false
  */
 function text2words($text, $max_chars = 20, $encrypt = false)
 {
@@ -3407,10 +3343,8 @@ function clean_cache($type = '')
 	// ... as long as Load.php can be modified, anyway.
 	@touch($sourcedir . '/' . 'Load.php');
 	clearstatcache();
-}
-
-/**
  * Load classes that are both (E_STRICT) PHP 4 and PHP 5 compatible.
+ * @param string $filename
  */
 function loadClassFile($filename)
 {
@@ -3752,6 +3686,7 @@ function smf_seed_generator()
 		updateSettings(array('rand_seed' => $modSettings['rand_seed']));
 	}
 
+	// @todo remove this or move it to Subs-Compat.php
 	if (version_compare(PHP_VERSION, '4.2.0', '<'))
 	{
 		$seed = ($modSettings['rand_seed'] + ((double) microtime() * 1000003)) & 0x7fffffff;
@@ -3764,9 +3699,11 @@ function smf_seed_generator()
 
 /**
  * Process functions of an integration hook.
+ * calls all functions of the given hook.
+ * supports static class method calls.
  * @param string $hook
  * @param array $paramaters = array()
- * @return array
+ * @return array the results of the functions
  */
 function call_integration_hook($hook, $parameters = array())
 {
@@ -3794,9 +3731,10 @@ function call_integration_hook($hook, $parameters = array())
 
 /**
  * Add a function for integration hook.
+ * does nothing if the function is already added.
  * @param string $hook
  * @param string $function
- * @param bool $permanent = true
+ * @param bool $permanent = true if true, updates the value in settings table
  */
 function add_integration_function($hook, $function, $permanent = true)
 {
@@ -3843,6 +3781,8 @@ function add_integration_function($hook, $function, $permanent = true)
 
 /**
  * Remove an integration hook function.
+ * Removes the given function from the given hook.
+ * Does nothing if the function is not available.
  * @param string $hook
  * @param string $function
  */

+ 11 - 12
Sources/ViewQuery.php

@@ -1,6 +1,8 @@
 <?php
 
 /**
+ * Functions concerned with viewing queries, and is used for debugging.
+ *
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -14,18 +16,15 @@
 if (!defined('SMF'))
 	die('Hacking attempt...');
 
-/*	This file is concerned with viewing queries, and is used for debugging.
-	It contains only one function:
-
-	void ViewQuery()
-		- toggles the session variable 'view_queries'.
-		- views a list of queries and analyzes them.
-		- requires the admin_forum permission.
-		- is accessed via ?action=viewquery.
-		- strings in this function have not been internationalized.
-*/
-
-// See the queries....
+/**
+ * Show the database queries for debugging
+ * What this does:
+ * * Toggles the session variable 'view_queries'.
+ * * Views a list of queries and analyzes them.
+ * * Requires the admin_forum permission.
+ * * Is accessed via ?action=viewquery.
+ * * Strings in this function have not been internationalized.
+ */
 function ViewQuery()
 {
 	global $scripturl, $user_info, $settings, $context, $db_connection, $modSettings, $boarddir, $smcFunc, $txt, $db_show_debug;

+ 3 - 1
Sources/index.php

@@ -1,6 +1,8 @@
 <?php
 
-// This file is here solely to protect your Sources directory.
+/**
+ * This file is here solely to protect your Sources directory.
+ */
 
 // Look for Settings.php....
 if (file_exists(dirname(dirname(__FILE__)) . '/Settings.php'))

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

@@ -72,8 +72,8 @@ function template_main()
 			oThemeOptions: {
 				bUseThemeSettings: ', $context['user']['is_guest'] ? 'false' : 'true', ',
 				sOptionName: \'collapse_news_fader\',
-				sSessionVar: ', JavaScriptEscape($context['session_var']), ',
-				sSessionId: ', JavaScriptEscape($context['session_id']), '
+				sSessionVar: smf_session_var,
+				sSessionId: smf_session_id
 			},
 			oCookieOptions: {
 				bUseCookie: ', $context['user']['is_guest'] ? 'true' : 'false', ',

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

@@ -235,8 +235,8 @@ function template_control_richedit($editor_id, $smileyContainer = null, $bbcCont
 		// Now it's all drawn out we'll actually setup the box.
 		echo '
 				var oEditorHandle_', $editor_id, ' = new smc_Editor({
-					sSessionId: ', JavaScriptEscape($context['session_id']), ',
-					sSessionVar: ', JavaScriptEscape($context['session_var']), ',
+					sSessionId: smf_session_id,
+					sSessionVar: smf_session_var,
 					sFormId: ', JavaScriptEscape($editor_context['form']), ',
 					sUniqueId: ', JavaScriptEscape($editor_id), ',
 					bRTL: ', $txt['lang_rtl'] ? 'true' : 'false', ',

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

@@ -258,8 +258,8 @@ function template_ban_edit()
 		echo '
 			var oAddMemberSuggest = new smc_AutoSuggest({
 			sSelf: \'oAddMemberSuggest\',
-			sSessionId: \'', $context['session_id'], '\',
-			sSessionVar: \'', $context['session_var'], '\',
+			sSessionId: smf_session_id,
+			sSessionVar: smf_session_var,
 			sSuggestId: \'user\',
 			sControlId: \'user\',
 			sSearchType: \'member\',
@@ -347,8 +347,8 @@ function template_ban_edit_trigger()
 	<script type="text/javascript"><!-- // --><![CDATA[
 		var oAddMemberSuggest = new smc_AutoSuggest({
 			sSelf: \'oAddMemberSuggest\',
-			sSessionId: \'', $context['session_id'], '\',
-			sSessionVar: \'', $context['session_var'], '\',
+			sSessionId: smf_session_id,
+			sSessionVar: smf_session_var,
 			sSuggestId: \'username\',
 			sControlId: \'user\',
 			sSearchType: \'member\',

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

@@ -357,8 +357,8 @@ function template_maintain_members()
 	<script type="text/javascript"><!-- // --><![CDATA[
 		var oAttributeMemberSuggest = new smc_AutoSuggest({
 			sSelf: \'oAttributeMemberSuggest\',
-			sSessionId: \'', $context['session_id'], '\',
-			sSessionVar: \'', $context['session_var'], '\',
+			sSessionId: smf_session_id,
+			sSessionVar: smf_session_var,
 			sSuggestId: \'attributeMember\',
 			sControlId: \'to\',
 			sSearchType: \'member\',

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

@@ -15,24 +15,6 @@ function template_modify_subscription()
 {
 	global $context, $settings, $options, $scripturl, $txt, $modSettings;
 
-	// Javascript for the duration stuff.
-	echo '
-		<script type="text/javascript"><!-- // --><![CDATA[
-			function toggleDuration(toChange)
-			{
-				if (toChange == \'fixed\')
-				{
-					document.getElementById("fixed_area").style.display = "inline";
-					document.getElementById("flexible_area").style.display = "none";
-				}
-				else
-				{
-					document.getElementById("fixed_area").style.display = "none";
-					document.getElementById("flexible_area").style.display = "inline";
-				}
-			}
-		// ]]></script>';
-
 	echo '
 	<div id="admincenter">
 		<form action="', $scripturl, '?action=admin;area=paidsubscribe;sa=modify;sid=', $context['sub_id'], '" method="post">
@@ -253,28 +235,6 @@ function template_modify_user_subscription()
 	echo '
 	<script type="text/javascript"><!-- // --><![CDATA[
 			var monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-
-			function generateDays(offset)
-			{
-				var days = 0, selected = 0;
-				var dayElement = document.getElementById("day" + offset), yearElement = document.getElementById("year" + offset), monthElement = document.getElementById("month" + offset);
-
-				monthLength[1] = 28;
-				if (yearElement.options[yearElement.selectedIndex].value % 4 == 0)
-					monthLength[1] = 29;
-
-				selected = dayElement.selectedIndex;
-				while (dayElement.options.length)
-					dayElement.options[0] = null;
-
-				days = monthLength[monthElement.value - 1];
-
-				for (i = 1; i <= days; i++)
-					dayElement.options[dayElement.length] = new Option(i, i);
-
-				if (selected < days)
-					dayElement.selectedIndex = selected;
-			}
 		// ]]></script>';
 
 	echo '
@@ -392,8 +352,8 @@ function template_modify_user_subscription()
 		<script type="text/javascript"><!-- // --><![CDATA[
 		var oAddMemberSuggest = new smc_AutoSuggest({
 			sSelf: \'oAddMemberSuggest\',
-			sSessionId: \'', $context['session_id'], '\',
-			sSessionVar: \'', $context['session_var'], '\',
+			sSessionId: smf_session_id,
+			sSessionVar: smf_session_var,
 			sSuggestId: \'name_subscriber\',
 			sControlId: \'name_control\',
 			sSearchType: \'member\',

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

@@ -212,8 +212,8 @@ function template_permission_index()
 			oThemeOptions: {
 				bUseThemeSettings: ', $context['user']['is_guest'] ? 'false' : 'true', ',
 				sOptionName: \'admin_preferences\',
-				sSessionVar: ', JavaScriptEscape($context['session_var']), ',
-				sSessionId: ', JavaScriptEscape($context['session_id']), ',
+				sSessionVar: smf_session_var,
+				sSessionId: smf_session_id,
 				sThemeId: \'1\',
 				sAdditionalVars: \';admin_key=app\'
 			}
@@ -699,24 +699,6 @@ function template_modify_group_simple($type)
 		// Only show this once.
 		$context['simple_javascript_displayed'] = true;
 
-		// Manually toggle the breakdown.
-		echo '
-	function toggleBreakdown(id_group, forcedisplayType)
-	{
-		displayType = document.getElementById("group_hr_div_" + id_group).style.display == "none" ? "" : "none";
-		if (typeof(forcedisplayType) != "undefined")
-			displayType = forcedisplayType;
-
-		for (i = 0; i < groupPermissions[id_group].length; i++)
-		{
-			document.getElementById("perm_div_" + id_group + "_" + groupPermissions[id_group][i]).style.display = displayType
-		}
-		document.getElementById("group_hr_div_" + id_group).style.display = displayType
-		document.getElementById("group_toggle_img_" + id_group).src = "', $settings['images_url'], '/" + (displayType == "none" ? "selected" : "sort_down") + ".gif";
-
-		return false;
-	}';
-
 		// This function decides what to do when ANYTHING is touched!
 		echo '
 		var groupPermissions = new Array();

+ 0 - 32
Themes/default/MessageIndex.template.php

@@ -428,38 +428,6 @@ function template_main()
 	document.onclick = modify_topic_click;
 
 	var mouse_on_div;
-	function modify_topic_click()
-	{
-		if (in_edit_mode == 1 && mouse_on_div == 0)
-			modify_topic_save("', $context['session_id'], '", "', $context['session_var'], '");
-	}
-
-	function modify_topic_keypress(oEvent)
-	{
-		if (typeof(oEvent.keyCode) != "undefined" && oEvent.keyCode == 13)
-		{
-			modify_topic_save("', $context['session_id'], '", "', $context['session_var'], '");
-			if (typeof(oEvent.preventDefault) == "undefined")
-				oEvent.returnValue = false;
-			else
-				oEvent.preventDefault();
-		}
-	}
-
-	// For templating, shown when an inline edit is made.
-	function modify_topic_show_edit(subject)
-	{
-		// Just template the subject.
-		setInnerHTML(cur_subject_div, \'<input type="text" name="subject" value="\' + subject + \'" size="60" style="width: 95%;" maxlength="80" onkeypress="modify_topic_keypress(event)" class="input_text" /><input type="hidden" name="topic" value="\' + cur_topic_id + \'" /><input type="hidden" name="msg" value="\' + cur_msg_id.substr(4) + \'" />\');
-	}
-
-	// And the reverse for hiding it.
-	function modify_topic_hide_edit(subject)
-	{
-		// Re-template the subject!
-		setInnerHTML(cur_subject_div, \'<a href="', $scripturl, '?topic=\' + cur_topic_id + \'.0">\' + subject + \'<\' +\'/a>\');
-	}
-
 // ]]></script>';
 }
 

+ 1 - 29
Themes/default/Search.template.php

@@ -71,11 +71,6 @@ function template_main()
 					<strong>', $txt['search_for'], ':</strong>
 					<input type="text" name="search"', !empty($context['search_params']['search']) ? ' value="' . $context['search_params']['search'] . '"' : '', ' maxlength="', $context['search_string_limit'], '" size="40" class="input_text" />
 					<script type="text/javascript"><!-- // --><![CDATA[
-						function initSearch()
-						{
-							if (document.forms.searchform.search.value.indexOf("%u") != -1)
-								document.forms.searchform.search.value = unescape(document.forms.searchform.search.value);
-						}
 						createEventListener(window);
 						window.addEventListener("load", initSearch, false);
 					// ]]></script>
@@ -200,30 +195,7 @@ function template_main()
 	}
 
 	echo '
-	</form>
-
-	<script type="text/javascript"><!-- // --><![CDATA[
-		function selectBoards(ids)
-		{
-			var toggle = true;
-
-			for (i = 0; i < ids.length; i++)
-				toggle = toggle & document.forms.searchform["brd" + ids[i]].checked;
-
-			for (i = 0; i < ids.length; i++)
-				document.forms.searchform["brd" + ids[i]].checked = !toggle;
-		}
-
-		function expandCollapseBoards()
-		{
-			var current = document.getElementById("searchBoardsExpand").style.display != "none";
-
-			document.getElementById("searchBoardsExpand").style.display = current ? "none" : "";
-			document.getElementById("expandBoardsIcon").src = smf_images_url + (current ? "/expand.gif" : "/collapse.gif");
-		}';
-
-	echo '
-	// ]]></script>';
+	</form>';
 }
 
 function template_results()

+ 0 - 13
Themes/default/SplitTopics.template.php

@@ -177,19 +177,6 @@ function template_select()
 				else
 					return true;
 			}
-			function applyWindowClasses(oList)
-			{
-				var bAlternate = false;
-				oListItems = oList.getElementsByTagName("LI");
-				for (i = 0; i < oListItems.length; i++)
-				{
-					// Skip dummies.
-					if (oListItems[i].id == "")
-						continue;
-					oListItems[i].className = "windowbg" + (bAlternate ? "2" : "");
-					bAlternate = !bAlternate;
-				}
-			}
 			function onDocReceived(XMLDoc)
 			{
 				var i, j, pageIndex;

+ 4 - 1
index.php

@@ -191,8 +191,10 @@ function smf_main()
 	if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest']))
 		fatal_lang_error('not_a_topic', false);
 
+	$no_stat_actions = array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile');
+	call_integration_hook('integrate_pre_log_stats', &$no_stat_actions);
 	// Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc.
-	if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile')))
+	if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], $no_stat_actions))
 	{
 		// Log this user as online.
 		writeLog();
@@ -201,6 +203,7 @@ function smf_main()
 		if (!empty($modSettings['hitStats']))
 			trackStats(array('hits' => '+'));
 	}
+	unset($no_stat_actions);
 
 	// Is the forum in maintenance mode? (doesn't apply to administrators.)
 	if (!empty($maintenance) && !allowedTo('admin_forum'))