* Copyright 2001-2010 Strangecode, LLC * * This file is part of The Strangecode Codebase. * * The Strangecode Codebase is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your option) * any later version. * * The Strangecode Codebase is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * The Strangecode Codebase. If not, see . */ /** * SpellCheck.inc.php * * Interface to PHP's pspell functions. * * @author Quinn Comendant * @version 1.1 */ /* Implementation example: -------------------------------------------------------------------------------- include_once dirname(__FILE__) . '/_config.inc.php'; include 'codebase/lib/SpellCheck.inc.php'; // Instantiate with parameters. In this example we'll set the language and the path to the personal wordlist file. $spell = new SpellCheck(array( 'language' => 'en', 'personal_wordlist' => '/tmp/my_custom_dict' )); // Just for the heck of it add a new word to persistent personal wordlist file. $spell->add('mealworm'); $text_to_check = 'donky rinds taste like mealworm paste'; if (!$spell->checkString($text_to_check)) { $suggestions = $spell->getStringSuggestions($text_to_check); echo 'Spelling errors! Here are suggested alternatives:'; print_r($suggestions); } else { echo 'No spelling errors'; } // Save added words to persistent custom wordlist file. $spell->save(); -------------------------------------------------------------------------------- */ class SpellCheck { var $_params = array( 'language' => 'en', 'personal_wordlist' => '', // Text file to save custom words to. 'skip_length' => 3, // Words with this many chars or less will not be checked. 'mode' => PSPELL_NORMAL, // PSPELL_FAST, PSPELL_NORMAL, or PSPELL_BAD_SPELLERS. 'highlight_start' => '', 'highlight_end' => '', ); var $_pspell_cfg_handle; var $_pspell_handle; var $_use_personal_wordlist = false; var $_errors = array(); /** * Constructor. * * @param array $params Array of parameters (key => val pairs). */ function SpellCheck($params) { $app =& App::getInstance(); if (!extension_loaded('pspell')) { trigger_error('Pspell module not installed', E_USER_ERROR); } if (!is_array($params) || empty($params)) { trigger_error('SpellCheck parameters not set properly', E_USER_ERROR); } $this->setParam($params); $this->_pspell_cfg_handle = pspell_config_create($this->getParam('language')); pspell_config_ignore($this->_pspell_cfg_handle, $this->getParam('skip_length')); pspell_config_mode($this->_pspell_cfg_handle, $this->getParam('mode')); if ('' != $this->getParam('personal_wordlist')) { if (!is_writable(dirname($this->getParam('personal_wordlist'))) || !is_writable($this->getParam('personal_wordlist'))) { $app->logMsg(sprintf('Personal wordlist file not writable: %s', $this->getParam('personal_wordlist')), LOG_WARNING, __FILE__, __LINE__); } else { pspell_config_personal($this->_pspell_cfg_handle, $this->getParam('personal_wordlist')); $this->_use_personal_wordlist = true; $app->logMsg(sprintf('Using personal wordlist: %s', $this->getParam('personal_wordlist')), LOG_DEBUG, __FILE__, __LINE__); } } $this->_pspell_handle = pspell_new_config($this->_pspell_cfg_handle); } /** * Set (or overwrite existing) parameters by passing an array of new parameters. * * @access public * @param array $params Array of parameters (key => val pairs). */ function setParam($params) { $app =& App::getInstance(); if (isset($params) && is_array($params)) { // Merge new parameters with old overriding only those passed. $this->_params = array_merge($this->_params, $params); } else { $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__); } } /** * Return the value of a parameter, if it exists. * * @access public * @param string $param Which parameter to return. * @return mixed Configured parameter value. */ function getParam($param) { $app =& App::getInstance(); if (isset($this->_params[$param])) { return $this->_params[$param]; } else { $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__); return null; } } /** * Check whether any errors have been triggered. * * @return bool True if any errors were found, false otherwise. */ function anyErrors() { return (sizeof($this->_errors) > 0); } /** * Reset the error list. */ function resetErrorList() { $this->_errors = array(); } /** * Check one word. * * @access public * @param string $word * @return bool True if word is correct. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 18:23:51 */ function check($word) { if (pspell_check($this->_pspell_handle, $word)) { return true; } else { $this->_errors[] = $word; return false; } } /** * Suggest the correct spelling for one misspelled word. * * @access public * @param string $word * @return array Word suggestions. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 18:23:51 */ function suggest($word) { return pspell_suggest($this->_pspell_handle, $word); } /** * Add a word to a personal list. * * @access public * @param string $word * @return array Word suggestions. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 18:23:51 */ function add($word) { $app =& App::getInstance(); if ($this->_use_personal_wordlist) { if (pspell_add_to_personal($this->_pspell_handle, $word)) { $app->logMsg(sprintf('Added "%s" to personal wordlist: %s', $word, $this->getParam('personal_wordlist')), LOG_DEBUG, __FILE__, __LINE__); return true; } else { $app->logMsg(sprintf('Failed adding "%s" to personal wordlist: %s', $word, $this->getParam('personal_wordlist')), LOG_WARNING, __FILE__, __LINE__); return false; } } } /** * Save personal list to file. * * @access public * @param string $word * @return array Word suggestions. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 18:23:51 */ function save() { $app =& App::getInstance(); if ($this->_use_personal_wordlist) { if (pspell_save_wordlist($this->_pspell_handle)) { $app->logMsg(sprintf('Saved personal wordlist: %s', $this->getParam('personal_wordlist')), LOG_DEBUG, __FILE__, __LINE__); return true; } else { $app->logMsg(sprintf('Failed saving personal wordlist: %s', $this->getParam('personal_wordlist')), LOG_ERR, __FILE__, __LINE__); return false; } } } /** * Returns an array of suggested words for each misspelled word in the given text. * The first word of the returned array is the (possibly) misspelled word. * * @access public * @param string $string String to get suggestions for. * @return mixed Array of suggested words or false if none. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 21:29:49 */ function getStringSuggestions($string) { $corrections = array(); $words = preg_split('/([\W]+?)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE); // Remove non-word elements. $words = preg_grep('/\w+/', $words); if (is_array($words) && !empty($words)) { foreach ($words as $i => $word) { if (!$this->check($word)) { $corrections[$i] = $this->suggest($word); // Keep the original spelling as one of the suggestions. array_unshift($corrections[$i], $word); array_unique($corrections[$i]); } } } if (is_array($corrections) && !empty($corrections)) { return $corrections; } else { return false; } } /** * Checks all words in a given string. * * @access public * @param string $string String to check. * @return void * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 22:11:27 */ function checkString($string) { $errors = array(); $words = preg_split('/([\W]+?)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE); // Remove non-word elements. $check_words = preg_grep('/\w+/', $words); if (is_array($check_words) && !empty($check_words)) { foreach ($check_words as $i => $word) { if (!$this->check($word)) { $errors[] = $word; } } } if (empty($errors)) { return true; } else { $this->_errors = $errors + $this->_errors; return false; } } /** * Returns a given string with misspelled words highlighted. * * @access public * @param string $string Text to highlight. * @return string Highlighted text. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 21:29:49 */ function getStringHighlighted($string, $show_footnote=false) { $words = preg_split('/([\W]+?)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE); $check_words = preg_grep('/\w+/', $words); $cnt = 0; if (is_array($check_words) && !empty($check_words)) { foreach ($check_words as $i => $word) { if (!$this->check($word)) { $footnote = $show_footnote ? '' . ++$cnt . '' : ''; $words[$i] = $this->getParam('highlight_start') . $word . $this->getParam('highlight_end') . $footnote; } } } return join('', $words); } /** * Prints the HTML for correcting all misspellings found in the text of one $_FORM element. * * @access public * @param string $form_name Name of the form to check. * @return void * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 21:29:49 */ function printCorrectionForm($form_name) { ?> getStringSuggestions(getFormData($form_name)); if (is_array($form_words) && !empty($form_words)) { ?>
    $words) { ?>
  1. _use_personal_wordlist) { ?>
* @version 1.0 * @since 09 Jun 2005 23:15:35 */ function anyFormCorrections() { return (false !== getFormData('spelling_suggestions', false)) || (false !== getFormData('spelling_corrections', false)); } /** * Replace the misspelled words in the text of a specified form with the corrections. * * @access public * @param string $form_name Name of form to apply corrections to. * @return string Corrected form text. * @author Quinn Comendant * @version 1.0 * @since 09 Jun 2005 23:18:51 */ function applyFormCorrections($form_name) { $form_words = preg_split('/([\W]+?)/', getFormData($form_name), -1, PREG_SPLIT_DELIM_CAPTURE); $suggestions = getFormData('spelling_suggestions'); $corrections = getFormData('spelling_corrections'); $form_words = array_diff($corrections[$form_name], array('')) + $suggestions[$form_name] + $form_words; ksort($form_words); if ($this->_use_personal_wordlist) { $save_to_personal_wordlist = getFormData('save_to_personal_wordlist'); if (is_array($save_to_personal_wordlist) && !empty($save_to_personal_wordlist)) { foreach ($save_to_personal_wordlist as $cust) { $this->add($form_words[$cust]); } } $this->save(); } if (is_array($form_words) && !empty($form_words)) { return join('', $form_words); } else { return getFormData($form_name); } } } // End. ?>