Browse Source

Merge branch 'release-2.1' of https://github.com/SimpleMachines/SMF2.1 into n

Peter Spicer 11 years ago
parent
commit
eb972e1090

+ 1 - 1
Sources/ManagePosts.php

@@ -194,7 +194,7 @@ function ModifyPostSettings($return_config = false)
 			array('check', 'removeNestedQuotes'),
 			array('check', 'enableEmbeddedFlash', 'subtext' => $txt['enableEmbeddedFlash_warning']),
 			// Note show the warning as read if pspell not installed!
-			array('check', 'enableSpellChecking', 'subtext' => (function_exists('pspell_new') ? $txt['enableSpellChecking_warning'] : ('<span class="alert">' . $txt['enableSpellChecking_warning'] . '</span>'))),
+			array('check', 'enableSpellChecking', 'subtext' => ((function_exists('pspell_new') || function_exists('enchant_broker_init')) ? $txt['enableSpellChecking_warning'] : ('<span class="alert">' . $txt['enableSpellChecking_warning'] . '</span>'))),
 			array('check', 'disable_wysiwyg'),
 		'',
 			// Posting limits...

+ 50 - 47
Sources/ManageSettings.php

@@ -577,58 +577,61 @@ function ModifyAntispamSettings($return_config = false)
 						$changes['delete'][] = $q_id;
 
 			// Now let's see if there are new questions or ones that need updating.
-			foreach ($_POST['question'][$lang_id] as $q_id => $question)
+			if (isset($_POST['question'][$lang_id]))
 			{
-				// Ignore junky ids.
-				$q_id = (int) $q_id;
-				if ($q_id <= 0)
-					continue;
-
-				// Check the question isn't empty (because they want to delete it?)
-				if (empty($question) || trim($question) == '')
+				foreach ($_POST['question'][$lang_id] as $q_id => $question)
 				{
-					if (isset($context['question_answers'][$q_id]))
-						$changes['delete'][] = $q_id;
-					continue;
-				}
-				$question = $smcFunc['htmlspecialchars'](trim($question));
+					// Ignore junky ids.
+					$q_id = (int) $q_id;
+					if ($q_id <= 0)
+						continue;
 
-				// Get the answers. Firstly check there actually might be some.
-				if (!isset($_POST['answer'][$lang_id][$q_id]) || !is_array($_POST['answer'][$lang_id][$q_id]))
-				{
-					if (isset($context['question_answers'][$q_id]))
-						$changes['delete'][] = $q_id;
-					continue;
-				}
-				// Now get them and check that they might be viable.
-				$answers = array();
-				foreach ($_POST['answer'][$lang_id][$q_id] as $answer)
-					if (!empty($answer) && trim($answer) !== '')
-						$answers[] = $smcFunc['htmlspecialchars'](trim($answer));
-				if (empty($answers))
-				{
-					if (isset($context['question_answers'][$q_id]))
-						$changes['delete'][] = $q_id;
-					continue;
-				}
-				$answers = serialize($answers);
+					// Check the question isn't empty (because they want to delete it?)
+					if (empty($question) || trim($question) == '')
+					{
+						if (isset($context['question_answers'][$q_id]))
+							$changes['delete'][] = $q_id;
+						continue;
+					}
+					$question = $smcFunc['htmlspecialchars'](trim($question));
 
-				// At this point we know we have a question and some answers. What are we doing with it?
-				if (!isset($context['question_answers'][$q_id]))
-				{
-					// New question. Now, we don't want to randomly consume ids, so we'll set those, rather than trusting the browser's supplied ids.
-					$changes['insert'][] = array($lang_id, $question, $answers);
-				}
-				else
-				{
-					// It's an existing question. Let's see what's changed, if anything.
-					if ($lang_id != $context['question_answers'][$q_id]['lngfile'] || $question != $context['question_answers'][$q_id]['question'] || $answers != $context['question_answers'][$q_id]['answers'])
-						$changes['replace'][$q_id] = array('lngfile' => $lang_id, 'question' => $question, 'answers' => $answers);
-				}
+					// Get the answers. Firstly check there actually might be some.
+					if (!isset($_POST['answer'][$lang_id][$q_id]) || !is_array($_POST['answer'][$lang_id][$q_id]))
+					{
+						if (isset($context['question_answers'][$q_id]))
+							$changes['delete'][] = $q_id;
+						continue;
+					}
+					// Now get them and check that they might be viable.
+					$answers = array();
+					foreach ($_POST['answer'][$lang_id][$q_id] as $answer)
+						if (!empty($answer) && trim($answer) !== '')
+							$answers[] = $smcFunc['htmlspecialchars'](trim($answer));
+					if (empty($answers))
+					{
+						if (isset($context['question_answers'][$q_id]))
+							$changes['delete'][] = $q_id;
+						continue;
+					}
+					$answers = serialize($answers);
 
-				if (!isset($qs_per_lang[$lang_id]))
-					$qs_per_lang[$lang_id] = 0;
-				$qs_per_lang[$lang_id]++;
+					// At this point we know we have a question and some answers. What are we doing with it?
+					if (!isset($context['question_answers'][$q_id]))
+					{
+						// New question. Now, we don't want to randomly consume ids, so we'll set those, rather than trusting the browser's supplied ids.
+						$changes['insert'][] = array($lang_id, $question, $answers);
+					}
+					else
+					{
+						// It's an existing question. Let's see what's changed, if anything.
+						if ($lang_id != $context['question_answers'][$q_id]['lngfile'] || $question != $context['question_answers'][$q_id]['question'] || $answers != $context['question_answers'][$q_id]['answers'])
+							$changes['replace'][$q_id] = array('lngfile' => $lang_id, 'question' => $question, 'answers' => $answers);
+					}
+	
+					if (!isset($qs_per_lang[$lang_id]))
+						$qs_per_lang[$lang_id] = 0;
+					$qs_per_lang[$lang_id]++;
+				}
 			}
 		}
 

+ 1 - 1
Sources/Subs-Editor.php

@@ -1489,7 +1489,7 @@ function create_control_richedit($editorOptions)
 			loadJavascriptFile($scripturl . '?action=loadeditorlocale', array(), 'sceditor_language');
 
 		$context['shortcuts_text'] = $txt['shortcuts' . (!empty($context['drafts_save']) ? '_drafts' : '') . (isBrowser('is_firefox') ? '_firefox' : '')];
-		$context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
+		$context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && (function_exists('pspell_new') || function_exists('enchant_broker_init'));
 		if ($context['show_spellchecking'])
 		{
 			loadJavascriptFile('spellcheck.js', array('default_theme' => true));

+ 133 - 21
Sources/Subs-Post.php

@@ -1445,7 +1445,7 @@ function server_parse($message, $socket, $response)
 
 /**
  * Spell checks the post for typos ;).
- * It uses the pspell library, which MUST be installed.
+ * It uses the pspell or enchant library, one of which MUST be installed.
  * It has problems with internationalization.
  * It is accessed via ?action=spellcheck.
  */
@@ -1459,24 +1459,10 @@ function SpellCheck()
 	loadLanguage('Post');
 	loadTemplate('Post');
 
-	// Okay, this looks funny, but it actually fixes a weird bug.
-	ob_start();
-	$old = error_reporting(0);
+	// Create a pspell or enchant dictionary resource
+	$dict = spell_init();
 
-	// See, first, some windows machines don't load pspell properly on the first try.  Dumb, but this is a workaround.
-	pspell_new('en');
-
-	// Next, the dictionary in question may not exist. So, we try it... but...
-	$pspell_link = pspell_new($txt['lang_dictionary'], $txt['lang_spelling'], '', strtr($context['character_set'], array('iso-' => 'iso', 'ISO-' => 'iso')), PSPELL_FAST | PSPELL_RUN_TOGETHER);
-
-	// Most people don't have anything but English installed... So we use English as a last resort.
-	if (!$pspell_link)
-		$pspell_link = pspell_new('en', '', '', '', PSPELL_FAST | PSPELL_RUN_TOGETHER);
-
-	error_reporting($old);
-	ob_end_clean();
-
-	if (!isset($_POST['spellstring']) || !$pspell_link)
+	if (!isset($_POST['spellstring']) || !$dict)
 		die;
 
 	// Construct a bit of Javascript code.
@@ -1495,7 +1481,7 @@ function SpellCheck()
 		$check_word = explode('|', $alphas[$i]);
 
 		// If the word is a known word, or spelled right...
-		if (in_array($smcFunc['strtolower']($check_word[0]), $known_words) || pspell_check($pspell_link, $check_word[0]) || !isset($check_word[2]))
+		if (in_array($smcFunc['strtolower']($check_word[0]), $known_words) || spell_check($dict, $check_word[0]) || !isset($check_word[2]))
 			continue;
 
 		// Find the word, and move up the "last occurance" to here.
@@ -1506,7 +1492,7 @@ function SpellCheck()
 			new misp("' . strtr($check_word[0], array('\\' => '\\\\', '"' => '\\"', '<' => '', '&gt;' => '')) . '", ' . (int) $check_word[1] . ', ' . (int) $check_word[2] . ', [';
 
 		// If there are suggestions, add them in...
-		$suggestions = pspell_suggest($pspell_link, $check_word[0]);
+		$suggestions = spell_suggest($dict, $check_word[0]);
 		if (!empty($suggestions))
 		{
 			// But first check they aren't going to be censored - no naughty words!
@@ -1531,6 +1517,13 @@ function SpellCheck()
 	// And instruct the template system to just show the spellcheck sub template.
 	$context['template_layers'] = array();
 	$context['sub_template'] = 'spellcheck';
+
+	// Free resources for enchant...
+	if (isset($context['enchant_broker']))
+	{
+		enchant_broker_free_dict($dict);
+		enchant_broker_free($context['enchant_broker']);
+	}
 }
 
 /**
@@ -2971,4 +2964,123 @@ function user_info_callback($matches)
 	return $use_ref ? $ref : $matches[0];
 }
 
-?>
+
+/**
+ * spell_init()
+ * 
+ * Sets up a dictionary resource handle. Tries enchant first then falls through to pspell.
+ * 
+ * @return resource|bool An enchant or pspell dictionary resource handle or false if the dictionary couldn't be loaded
+ */
+function spell_init()
+{
+	global $context, $txt;
+
+	// Try enchant first since PSpell is (supposedly) deprecated as of PHP 5.3
+	if (function_exists('enchant_broker_init'))
+	{
+		// We'll need this to free resources later...
+		$context['enchant_broker'] = enchant_broker_init();
+
+		// Try locale first, then general...
+		if (!empty($txt['lang_locale']) && enchant_broker_dict_exists($context['enchant_broker'], $txt['lang_locale']))
+		{
+			$enchant_link = enchant_broker_request_dict($context['enchant_broker'], $txt['lang_locale']);
+		}
+		elseif (enchant_broker_dict_exists($context['enchant_broker'], $txt['lang_dictionary']))
+		{
+			$enchant_link = enchant_broker_request_dict($context['enchant_broker'], $txt['lang_dictionary']);
+		}
+
+		// Success
+		if ($enchant_link)
+		{
+			$context['provider'] = 'enchant';
+			return $enchant_link;
+		}
+		else
+		{
+			// Free up any resources used...
+			@enchant_broker_free($context['enchant_broker']);
+		}
+	}
+
+	// Fall through to pspell if enchant didn't work
+	if (function_exists('pspell_new'))
+	{
+		// Okay, this looks funny, but it actually fixes a weird bug.
+		ob_start();
+		$old = error_reporting(0);
+
+		// See, first, some windows machines don't load pspell properly on the first try.  Dumb, but this is a workaround.
+		pspell_new('en');
+
+		// Next, the dictionary in question may not exist. So, we try it... but...
+		$pspell_link = pspell_new($txt['lang_dictionary'], $txt['lang_spelling'], '', strtr($context['character_set'], array('iso-' => 'iso', 'ISO-' => 'iso')), PSPELL_FAST | PSPELL_RUN_TOGETHER);
+
+		// Most people don't have anything but English installed... So we use English as a last resort.
+		if (!$pspell_link)
+			$pspell_link = pspell_new('en', '', '', '', PSPELL_FAST | PSPELL_RUN_TOGETHER);
+
+		error_reporting($old);
+		ob_end_clean();
+
+		// If we have pspell, exit now...
+		if ($pspell_link)
+		{
+			$context['provider'] = 'pspell';
+			return $pspell_link;
+		}
+	}
+
+	// If we get this far, we're doomed
+	return false;
+}
+
+/**
+ * spell_check()
+ * 
+ * Determines whether or not the specified word is spelled correctly
+ * 
+ * @param resource $dict An enchant or pspell dictionary resource set up by {@link spell_init()}
+ * @param string $word A word to check the spelling of
+ * @return bool Whether or not the specified word is spelled properly
+ */
+function spell_check($dict, $word)
+{
+	global $context;
+
+	// Enchant or pspell?
+	if ($context['provider'] == 'enchant')
+	{
+		return enchant_dict_check($dict, $word);
+	}
+	elseif ($context['provider'] == 'pspell')
+	{
+		return pspell_check($dict, $word);
+	}
+}
+
+/**
+ * spell_suggest()
+ * 
+ * Returns an array of suggested replacements for the specified word
+ * 
+ * @param resource $dict An enchant or pspell dictioary resource
+ * @param string $word A misspelled word
+ * @return array An array of suggested replacements for the misspelled word
+ */
+function spell_suggest($dict, $word)
+{
+	global $context;
+
+	if ($context['provider'] == 'enchant')
+	{
+		return enchant_dict_suggest($dict, $word);
+	}
+	elseif ($context['provider'] == 'pspell')
+	{
+		return pspell_suggest($dict, $word);
+	}
+}
+?>

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

@@ -420,7 +420,7 @@ $helptxt['edit_wait_time'] = 'Number of seconds allowed for a post to be edited
 $helptxt['edit_disable_time'] = 'Number of minutes allowed to pass before a user can no longer edit a post they have made. Set to 0 disable. <br /><br /><em>Note: This will not affect any user who has permission to edit other people\'s posts.</em>';
 $helptxt['preview_characters'] = 'This option sets the number of available characters for the first and last message topic preview.  <strong>Note</strong> this only makes the information available to the theme, the theme must support the message_index_preview setting';
 $helptxt['posts_require_captcha'] = 'This setting will force users to pass anti-spam bot verification each time they make a post to a board. Only users with a post count below the number set will need to enter the code - this should help combat automated spamming scripts.';
-$helptxt['enableSpellChecking'] = 'Enable spell checking. You MUST have the pspell library installed on your server and your PHP configuration set up to use the pspell library. Your server ' . (function_exists('pspell_new') ? 'DOES' : 'DOES NOT') . ' appear to have this set up.';
+$helptxt['enableSpellChecking'] = 'Enable spell checking. You MUST have the pspell or enchant library installed on your server and your PHP configuration set up to use the installed library. Your server ' . ((function_exists('pspell_new') || function_exists('enchant_broker_init')) ? 'DOES' : 'DOES NOT') . ' appear to have this set up.';
 $helptxt['disable_wysiwyg'] = 'This setting disallows all users from using the WYSIWYG (&quot;What You See Is What You Get&quot;) editor on the post page.';
 $helptxt['lastActive'] = 'Set the number of minutes to show people are active in X number of minutes on the board index. Default is 15 minutes.';
 

+ 2 - 2
Themes/default/scripts/spellcheck.js

@@ -18,7 +18,7 @@ function spellCheck(formName, fieldName)
 	var aWordCharacters = ['-', '\''];
 
 	var aWords = new Array(), aResult = new Array();
-	var sText = $('#' + fieldName).data("sceditor").getTextareaValue(false);
+	var sText = $('#' + fieldName).data("sceditor").getText(false);
 	var bInCode = false;
 	var iOffset1, iOffset2;
 
@@ -294,7 +294,7 @@ function openSpellWin(width, height)
 
 function spellCheckGetText(editorID)
 {
-	return $("#" + editorID).data("sceditor").getTextareaValue(false);
+	return $("#" + editorID).data("sceditor").getText(false);
 }
 function spellCheckSetText(text, editorID)
 {

+ 11 - 9
other/upgrade_2-1_mysql.sql

@@ -40,7 +40,7 @@ if (!isset($modSettings['allow_no_censored']))
 	");
 	
 	// Is it set for either "default" or the one they've set as default?
-	while ($row = mysql_fetch_assoc($request))
+	while ($row = $smcFunc['db_fetch_assoc']($request))
 	{
 		if ($row['value'] == 1)
 		{
@@ -293,10 +293,12 @@ if (file_exists($GLOBALS['boarddir'] . '/Themes/core'))
 			AND value ='$core_dir'");
 
 	// Don't do anything if this theme is already uninstalled
-	if (smf_mysql_num_rows($theme_request) == 1)
+	if ($smcFunc['db_num_rows']($theme_request) == 1)
 	{
-		$id_theme = mysql_result($theme_request, 0);
-		mysql_free_result($theme_request);
+		// Only one row, so no loop needed
+		$row = $smcFunc['db_fetch_array']($theme_request);
+		$id_theme = $row[0];
+		$smcFunc['db_free_result']($theme_request);
 
 		$known_themes = explode(', ', $modSettings['knownThemes']);
 
@@ -374,12 +376,12 @@ if (@$modSettings['smfVersion'] < '2.1')
 		FROM {$db_prefix}board_permissions
 		WHERE permission = 'post_unapproved_topics'");
 	$inserts = array();
-	while ($row = smf_mysql_fetch_assoc($request))
+	while ($row = $smcFunc['db_fetch_assoc']($request))
 	{
 		$inserts[] = "($row[id_group], $row[id_board], 'post_draft', $row[add_deny])";
 		$inserts[] = "($row[id_group], $row[id_board], 'post_autosave_draft', $row[add_deny])";
 	}
-	smf_mysql_free_result($request);
+	$smcFunc['db_free_result']($request);
 
 	if (!empty($inserts))
 		upgrade_query("
@@ -394,12 +396,12 @@ if (@$modSettings['smfVersion'] < '2.1')
 		FROM {$db_prefix}permissions
 		WHERE permission = 'pm_send'");
 	$inserts = array();
-	while ($row = smf_mysql_fetch_assoc($request))
+	while ($row = $smcFunc['db_fetch_assoc']($request))
 	{
 		$inserts[] = "($row[id_group], 'pm_draft', $row[add_deny])";
 		$inserts[] = "($row[id_group], 'pm_autosave_draft', $row[add_deny])";
 	}
-	smf_mysql_free_result($request);
+	$smcFunc['db_free_result']($request);
 
 	if (!empty($inserts))
 		upgrade_query("
@@ -830,7 +832,7 @@ ADD COLUMN modified_reason varchar(255) NOT NULL;
 	$smcFunc['db_query']('', '
 		DELETE FROM {db_prefix}permissions
 		WHERE id_group = {int:guests}
-		AND permission IN ({array_string:illegal_perms}',
+		AND permission IN ({array_string:illegal_perms})',
 		array(
 			'guests' => -1,
 			'illegal_perms' => $illegal_permissions,

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

@@ -913,7 +913,7 @@ ADD COLUMN modified_reason varchar(255) NOT NULL default '';
 	$smcFunc['db_query']('', '
 		DELETE FROM {db_prefix}permissions
 		WHERE id_group = {int:guests}
-		AND permission IN ({array_string:illegal_perms}',
+		AND permission IN ({array_string:illegal_perms})',
 		array(
 			'guests' => -1,
 			'illegal_perms' => $illegal_permissions,

+ 2 - 2
other/upgrade_2-1_sqlite.sql

@@ -40,7 +40,7 @@ if (!isset($modSettings['allow_no_censored']))
 	");
 	
 	// Is it set for either "default" or the one they've set as default?
-	while ($row = mysql_fetch_assoc($request))
+	while ($row = $smcFunc['db_fetch_assoc']($request))
 	{
 		if ($row['value'] == 1)
 		{
@@ -886,7 +886,7 @@ ADD COLUMN modified_reason varchar(255) NOT NULL default '';
 	$smcFunc['db_query']('', '
 		DELETE FROM {db_prefix}permissions
 		WHERE id_group = {int:guests}
-		AND permission IN ({array_string:illegal_perms}',
+		AND permission IN ({array_string:illegal_perms})',
 		array(
 			'guests' => -1,
 			'illegal_perms' => $illegal_permissions,