/**
     * Main class of Spell Checker plugin for Typo3 CMS
     *
     * @return	string		content produced by the plugin
     */
    function main()
    {
        $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
        // Setting start time
        $time_start = microtime(true);
        $this->pspell_is_available = in_array('pspell', get_loaded_extensions());
        $this->AspellDirectory = trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['AspellDirectory']) ? trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['AspellDirectory']) : '/usr/bin/aspell';
        $this->forceCommandMode = trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['forceCommandMode']) ? trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['forceCommandMode']) : 0;
        $safe_mode_is_enabled = t3lib_utility_PhpOptions::isSafeModeEnabled();
        if ($safe_mode_is_enabled && !$this->pspell_is_available) {
            echo 'Configuration problem: Spell checking cannot be performed';
        }
        if ($safe_mode_is_enabled && $this->forceCommandMode) {
            echo 'Configuration problem: Spell checking cannot be performed in command mode';
        }
        if (!$safe_mode_is_enabled && (!$this->pspell_is_available || $this->forceCommandMode)) {
            $AspellVersionString = explode('Aspell', shell_exec($this->AspellDirectory . ' -v'));
            $AspellVersion = substr($AspellVersionString[1], 0, 4);
            if (doubleval($AspellVersion) < doubleval('0.5') && (!$this->pspell_is_available || $this->forceCommandMode)) {
                echo 'Configuration problem: Aspell version ' . $AspellVersion . ' too old. Spell checking cannot be performed in command mode';
            }
            $this->defaultAspellEncoding = trim(shell_exec($this->AspellDirectory . ' config encoding'));
        }
        // Setting the list of dictionaries
        if (!$safe_mode_is_enabled && (!$this->pspell_is_available || $this->forceCommandMode)) {
            $dictionaryList = shell_exec($this->AspellDirectory . ' dump dicts');
            $dictionaryList = implode(',', t3lib_div::trimExplode(LF, $dictionaryList, 1));
        }
        if (empty($dictionaryList)) {
            $dictionaryList = t3lib_div::_POST('showDictionaries');
            // Applying EM variable DEPRECATED as of TYPO3 4.3.0
            $dictionaryList = $dictionaryList ? $dictionaryList : trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['dictionaryList']);
        }
        $dictionaryArray = t3lib_div::trimExplode(',', $dictionaryList, 1);
        $restrictToDictionaries = t3lib_div::_POST('restrictToDictionaries');
        if ($restrictToDictionaries) {
            $dictionaryArray = array_intersect($dictionaryArray, t3lib_div::trimExplode(',', $restrictToDictionaries, 1));
        }
        if (!count($dictionaryArray)) {
            $dictionaryArray[] = 'en';
        }
        $this->dictionary = t3lib_div::_POST('dictionary');
        // Applying EM variable DEPRECATED as of TYPO3 4.3.0
        $defaultDictionary = $this->dictionary ? $this->dictionary : trim($TYPO3_CONF_VARS['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['defaultDictionary']);
        if (!$defaultDictionary || !in_array($defaultDictionary, $dictionaryArray)) {
            $defaultDictionary = 'en';
        }
        uasort($dictionaryArray, 'strcoll');
        $dictionaryList = implode(',', $dictionaryArray);
        // Setting the dictionary
        if (empty($this->dictionary) || !in_array($this->dictionary, $dictionaryArray)) {
            $this->dictionary = 'en';
        }
        // Setting the pspell suggestion mode
        $this->pspellMode = t3lib_div::_POST('pspell_mode') ? t3lib_div::_POST('pspell_mode') : $this->pspellMode;
        // Now sanitize $this->pspellMode
        $this->pspellMode = t3lib_div::inList('ultra,fast,normal,bad-spellers', $this->pspellMode) ? $this->pspellMode : 'normal';
        switch ($this->pspellMode) {
            case 'ultra':
            case 'fast':
                $pspellModeFlag = PSPELL_FAST;
                break;
            case 'bad-spellers':
                $pspellModeFlag = PSPELL_BAD_SPELLERS;
                break;
            case 'normal':
            default:
                $pspellModeFlag = PSPELL_NORMAL;
                break;
        }
        // Setting the charset
        if (t3lib_div::_POST('pspell_charset')) {
            $this->charset = trim(t3lib_div::_POST('pspell_charset'));
        }
        if (strtolower($this->charset) == 'iso-8859-1') {
            $this->parserCharset = strtolower($this->charset);
        }
        // In some configurations, Aspell uses 'iso8859-1' instead of 'iso-8859-1'
        $this->aspellEncoding = $this->parserCharset;
        if ($this->parserCharset == 'iso-8859-1' && strstr($this->defaultAspellEncoding, '8859-1')) {
            $this->aspellEncoding = $this->defaultAspellEncoding;
        }
        // However, we are going to work only in the parser charset
        if ($this->pspell_is_available && !$this->forceCommandMode) {
            $this->pspell_link = pspell_new($this->dictionary, '', '', $this->parserCharset, $pspellModeFlag);
        }
        // Setting the path to user personal dicts, if any
        if (t3lib_div::_POST('enablePersonalDicts') == 'true' && TYPO3_MODE == 'BE' && is_object($GLOBALS['BE_USER'])) {
            $this->userUid = 'BE_' . $GLOBALS['BE_USER']->user['uid'];
            if ($this->userUid) {
                $this->personalDictPath = t3lib_div::getFileAbsFileName($this->uploadFolder . $this->userUid);
                if (!is_dir($this->personalDictPath)) {
                    t3lib_div::mkdir($this->personalDictPath);
                }
                // escape here for later use
                $this->personalDictsArg = ' --home-dir=' . escapeshellarg($this->personalDictPath);
            }
        }
        $cmd = t3lib_div::_POST('cmd');
        if ($cmd == 'learn' && !$safe_mode_is_enabled) {
            // Only availble for BE_USERS, die silently if someone has gotten here by accident
            if (TYPO3_MODE != 'BE' || !is_object($GLOBALS['BE_USER'])) {
                die('');
            }
            // Updating the personal word list
            $to_p_dict = t3lib_div::_POST('to_p_dict');
            $to_p_dict = $to_p_dict ? $to_p_dict : array();
            $to_r_list = t3lib_div::_POST('to_r_list');
            $to_r_list = $to_r_list ? $to_r_list : array();
            header('Content-Type: text/plain; charset=' . strtoupper($this->parserCharset));
            header('Pragma: no-cache');
            if ($to_p_dict || $to_r_list) {
                $tmpFileName = t3lib_div::tempnam($this->filePrefix);
                if ($filehandle = fopen($tmpFileName, 'wb')) {
                    foreach ($to_p_dict as $personal_word) {
                        $cmd = '&' . $personal_word . LF;
                        echo $cmd;
                        fwrite($filehandle, $cmd, strlen($cmd));
                    }
                    foreach ($to_r_list as $replace_pair) {
                        $cmd = '$$ra ' . $replace_pair[0] . ' , ' . $replace_pair[1] . LF;
                        echo $cmd;
                        fwrite($filehandle, $cmd, strlen($cmd));
                    }
                    $cmd = "#\n";
                    echo $cmd;
                    fwrite($filehandle, $cmd, strlen($cmd));
                    fclose($filehandle);
                    // $this->personalDictsArg has already been escapeshellarg()'ed above, it is an optional paramter and might be empty here
                    $AspellCommand = 'cat ' . escapeshellarg($tmpFileName) . ' | ' . $this->AspellDirectory . ' -a --mode=none' . $this->personalDictsArg . ' --lang=' . escapeshellarg($this->dictionary) . ' --encoding=' . escapeshellarg($this->aspellEncoding) . ' 2>&1';
                    print $AspellCommand . LF;
                    print shell_exec($AspellCommand);
                    t3lib_div::unlink_tempfile($tmpFileName);
                    echo 'Personal word list was updated.';
                } else {
                    echo 'SpellChecker tempfile open error.';
                }
            } else {
                echo 'Nothing to add to the personal word list.';
            }
            flush();
            exit;
        } else {
            // Check spelling content
            // Initialize output
            $this->result = '<?xml version="1.0" encoding="' . $this->parserCharset . '"?>
<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . substr($this->dictionary, 0, 2) . '" lang="' . substr($this->dictionary, 0, 2) . '">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=' . $this->parserCharset . '" />
<link rel="stylesheet" type="text/css" media="all" href="' . (TYPO3_MODE == 'BE' ? '../' : '') . t3lib_extMgm::siteRelPath($this->extKey) . '/htmlarea/plugins/SpellChecker/spell-check-style.css" />
<script type="text/javascript">
/*<![CDATA[*/
<!--
';
            // Getting the input content
            $content = t3lib_div::_POST('content');
            // Parsing the input HTML
            $parser = xml_parser_create(strtoupper($this->parserCharset));
            xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
            xml_set_object($parser, $this);
            if (!xml_set_element_handler($parser, 'startHandler', 'endHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_set_character_data_handler($parser, 'collectDataHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_set_default_handler($parser, 'defaultHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_parse($parser, '<?xml version="1.0" encoding="' . $this->parserCharset . '"?><spellchecker> ' . preg_replace('/&nbsp;/' . ($this->parserCharset == 'utf-8' ? 'u' : ''), ' ', $content) . ' </spellchecker>')) {
                echo 'Bad parsing';
            }
            if (xml_get_error_code($parser)) {
                die('Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)));
            }
            xml_parser_free($parser);
            if ($this->pspell_is_available && !$this->forceCommandMode) {
                pspell_clear_session($this->pspell_link);
            }
            $this->result .= 'var suggestedWords = {' . $this->suggestedWords . '};
var dictionaries = "' . $dictionaryList . '";
var selectedDictionary = "' . $this->dictionary . '";
';
            // Calculating parsing and spell checkting time
            $time = number_format(microtime(true) - $time_start, 2, ',', ' ');
            // Insert spellcheck info
            $this->result .= 'var spellcheckInfo = { "Total words":"' . $this->wordCount . '","Misspelled words":"' . sizeof($this->misspelled) . '","Total suggestions":"' . $this->suggestionCount . '","Total words suggested":"' . $this->suggestedWordCount . '","Spelling checked in":"' . $time . '" };
// -->
/*]]>*/
</script>
</head>
';
            $this->result .= '<body onload="window.parent.RTEarea[\'' . t3lib_div::_POST('editorId') . '\'].editor.getPlugin(\'SpellChecker\').spellCheckComplete();">';
            $this->result .= preg_replace('/' . preg_quote('<?xml') . '.*' . preg_quote('?>') . '[' . preg_quote(LF . CR . chr(32)) . ']*/' . ($this->parserCharset == 'utf-8' ? 'u' : ''), '', $this->text);
            $this->result .= '<div style="display: none;">' . $dictionaries . '</div>';
            // Closing
            $this->result .= '
</body></html>';
            // Outputting
            header('Content-Type: text/html; charset=' . strtoupper($this->parserCharset));
            echo $this->result;
        }
    }
Пример #2
0
    /**
     * Main class of Spell Checker plugin for Typo3 CMS
     *
     * @return string content produced by the plugin
     */
    public function main()
    {
        $this->csConvObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Charset\CharsetConverter::class);
        // Setting start time
        $time_start = microtime(TRUE);
        $this->pspell_is_available = in_array('pspell', get_loaded_extensions());
        $this->AspellDirectory = trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['AspellDirectory']) ?: '/usr/bin/aspell';
        // Setting command mode if requested and available
        $this->forceCommandMode = trim($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['plugins']['SpellChecker']['forceCommandMode']) ?: 0;
        if (!$this->pspell_is_available || $this->forceCommandMode) {
            $AspellVersionString = explode('Aspell', shell_exec($this->AspellDirectory . ' -v'));
            $AspellVersion = substr($AspellVersionString[1], 0, 4);
            if (doubleval($AspellVersion) < doubleval('0.5') && (!$this->pspell_is_available || $this->forceCommandMode)) {
                echo 'Configuration problem: Aspell version ' . $AspellVersion . ' too old. Spell checking cannot be performed in command mode.';
            }
            $this->defaultAspellEncoding = trim(shell_exec($this->AspellDirectory . ' config encoding'));
        }
        // Setting the list of dictionaries
        $dictionaryList = shell_exec($this->AspellDirectory . ' dump dicts');
        $dictionaryList = implode(',', GeneralUtility::trimExplode(LF, $dictionaryList, TRUE));
        $dictionaryArray = GeneralUtility::trimExplode(',', $dictionaryList, TRUE);
        $restrictToDictionaries = GeneralUtility::_POST('restrictToDictionaries');
        if ($restrictToDictionaries) {
            $dictionaryArray = array_intersect($dictionaryArray, GeneralUtility::trimExplode(',', $restrictToDictionaries, 1));
        }
        if (!count($dictionaryArray)) {
            $dictionaryArray[] = 'en';
        }
        $this->dictionary = GeneralUtility::_POST('dictionary');
        $defaultDictionary = $this->dictionary;
        if (!$defaultDictionary || !in_array($defaultDictionary, $dictionaryArray)) {
            $defaultDictionary = 'en';
        }
        uasort($dictionaryArray, 'strcoll');
        $dictionaryList = implode(',', $dictionaryArray);
        // Setting the dictionary
        if (empty($this->dictionary) || !in_array($this->dictionary, $dictionaryArray)) {
            $this->dictionary = 'en';
        }
        // Setting the pspell suggestion mode
        $this->pspellMode = GeneralUtility::_POST('pspell_mode') ? GeneralUtility::_POST('pspell_mode') : $this->pspellMode;
        // Now sanitize $this->pspellMode
        $this->pspellMode = GeneralUtility::inList('ultra,fast,normal,bad-spellers', $this->pspellMode) ? $this->pspellMode : 'normal';
        switch ($this->pspellMode) {
            case 'ultra':
            case 'fast':
                $pspellModeFlag = PSPELL_FAST;
                break;
            case 'bad-spellers':
                $pspellModeFlag = PSPELL_BAD_SPELLERS;
                break;
            case 'normal':
            default:
                $pspellModeFlag = PSPELL_NORMAL;
        }
        // Setting the charset
        if (GeneralUtility::_POST('pspell_charset')) {
            $this->charset = trim(GeneralUtility::_POST('pspell_charset'));
        }
        if (strtolower($this->charset) == 'iso-8859-1') {
            $this->parserCharset = strtolower($this->charset);
        }
        // In some configurations, Aspell uses 'iso8859-1' instead of 'iso-8859-1'
        $this->aspellEncoding = $this->parserCharset;
        if ($this->parserCharset == 'iso-8859-1' && strstr($this->defaultAspellEncoding, '8859-1')) {
            $this->aspellEncoding = $this->defaultAspellEncoding;
        }
        // However, we are going to work only in the parser charset
        if ($this->pspell_is_available && !$this->forceCommandMode) {
            $this->pspell_link = pspell_new($this->dictionary, '', '', $this->parserCharset, $pspellModeFlag);
        }
        // Setting the path to main dictionary
        $this->setMainDictionaryPath();
        // Setting the path to user personal dictionary, if any
        $this->setPersonalDictionaryPath();
        $this->fixPersonalDictionaryCharacterSet();
        $cmd = GeneralUtility::_POST('cmd');
        if ($cmd == 'learn') {
            // Only availble for BE_USERS, die silently if someone has gotten here by accident
            if (TYPO3_MODE !== 'BE' || !is_object($GLOBALS['BE_USER'])) {
                die('');
            }
            // Updating the personal word list
            $to_p_dict = GeneralUtility::_POST('to_p_dict');
            $to_p_dict = $to_p_dict ? $to_p_dict : array();
            $to_r_list = GeneralUtility::_POST('to_r_list');
            $to_r_list = $to_r_list ? $to_r_list : array();
            header('Content-Type: text/plain; charset=' . strtoupper($this->parserCharset));
            header('Pragma: no-cache');
            if ($to_p_dict || $to_r_list) {
                $tmpFileName = GeneralUtility::tempnam($this->filePrefix);
                $filehandle = fopen($tmpFileName, 'wb');
                if ($filehandle) {
                    // Get the character set of the main dictionary
                    // We need to convert the input into the character set of the main dictionary
                    $mainDictionaryCharacterSet = $this->getMainDictionaryCharacterSet();
                    // Write the personal words addition commands to the temporary file
                    foreach ($to_p_dict as $personal_word) {
                        $cmd = '&' . $this->csConvObj->conv($personal_word, $this->parserCharset, $mainDictionaryCharacterSet) . LF;
                        fwrite($filehandle, $cmd, strlen($cmd));
                    }
                    // Write the replacent pairs addition commands to the temporary file
                    foreach ($to_r_list as $replace_pair) {
                        $cmd = '$$ra ' . $this->csConvObj->conv($replace_pair[0], $this->parserCharset, $mainDictionaryCharacterSet) . ' , ' . $this->csConvObj->conv($replace_pair[1], $this->parserCharset, $mainDictionaryCharacterSet) . LF;
                        fwrite($filehandle, $cmd, strlen($cmd));
                    }
                    $cmd = '#' . LF;
                    $result = fwrite($filehandle, $cmd, strlen($cmd));
                    if ($result === FALSE) {
                        GeneralUtility::sysLog('SpellChecker tempfile write error: ' . $tmpFileName, $this->extKey, GeneralUtility::SYSLOG_SEVERITY_ERROR);
                    } else {
                        // Assemble the Aspell command
                        $aspellCommand = (TYPO3_OS === 'WIN' ? 'type ' : 'cat ') . escapeshellarg($tmpFileName) . ' | ' . $this->AspellDirectory . ' -a --mode=none' . ($this->personalDictionaryPath ? ' --home-dir=' . escapeshellarg($this->personalDictionaryPath) : '') . ' --lang=' . escapeshellarg($this->dictionary) . ' --encoding=' . escapeshellarg($mainDictionaryCharacterSet) . ' 2>&1';
                        $aspellResult = shell_exec($aspellCommand);
                        // Close and delete the temporary file
                        fclose($filehandle);
                        GeneralUtility::unlink_tempfile($tmpFileName);
                    }
                } else {
                    GeneralUtility::sysLog('SpellChecker tempfile open error: ' . $tmpFileName, $this->extKey, GeneralUtility::SYSLOG_SEVERITY_ERROR);
                }
            }
            flush();
            die;
        } else {
            // Check spelling content
            // Initialize output
            $this->result = '<?xml version="1.0" encoding="' . $this->parserCharset . '"?>
<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . substr($this->dictionary, 0, 2) . '" lang="' . substr($this->dictionary, 0, 2) . '">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=' . $this->parserCharset . '" />
<link rel="stylesheet" type="text/css" media="all" href="' . (TYPO3_MODE == 'BE' ? '../' : '') . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey) . '/Resources/Public/Css/Skin/Plugins/spell-checker-iframe.css" />
<script type="text/javascript">
/*<![CDATA[*/
<!--
';
            // Getting the input content
            $content = GeneralUtility::_POST('content');
            // Parsing the input HTML
            $parser = xml_parser_create(strtoupper($this->parserCharset));
            xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
            xml_set_object($parser, $this);
            if (!xml_set_element_handler($parser, 'startHandler', 'endHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_set_character_data_handler($parser, 'collectDataHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_set_default_handler($parser, 'defaultHandler')) {
                echo 'Bad xml handler setting';
            }
            if (!xml_parse($parser, '<?xml version="1.0" encoding="' . $this->parserCharset . '"?><spellchecker> ' . preg_replace('/&nbsp;/' . ($this->parserCharset == 'utf-8' ? 'u' : ''), ' ', $content) . ' </spellchecker>')) {
                echo 'Bad parsing';
            }
            if (xml_get_error_code($parser)) {
                throw new \UnexpectedException('Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)), 1294585788);
            }
            xml_parser_free($parser);
            if ($this->pspell_is_available && !$this->forceCommandMode) {
                pspell_clear_session($this->pspell_link);
            }
            $this->result .= 'var suggestedWords = {' . $this->suggestedWords . '};
var dictionaries = "' . $dictionaryList . '";
var selectedDictionary = "' . $this->dictionary . '";
';
            // Calculating parsing and spell checkting time
            $time = number_format(microtime(TRUE) - $time_start, 2, ',', ' ');
            // Insert spellcheck info
            $this->result .= 'var spellcheckInfo = { "Total words":"' . $this->wordCount . '","Misspelled words":"' . sizeof($this->misspelled) . '","Total suggestions":"' . $this->suggestionCount . '","Total words suggested":"' . $this->suggestedWordCount . '","Spelling checked in":"' . $time . '" };
// -->
/*]]>*/
</script>
</head>
';
            $this->result .= '<body onload="window.parent.RTEarea[\'' . GeneralUtility::_POST('editorId') . '\'].editor.getPlugin(\'SpellChecker\').spellCheckComplete();">';
            $this->result .= preg_replace('/' . preg_quote('<?xml') . '.*' . preg_quote('?>') . '[' . preg_quote(LF . CR . chr(32)) . ']*/' . ($this->parserCharset == 'utf-8' ? 'u' : ''), '', $this->text);
            $this->result .= '<div style="display: none;">' . $dictionaries . '</div>';
            // Closing
            $this->result .= '
</body></html>';
            // Outputting
            header('Content-Type: text/html; charset=' . strtoupper($this->parserCharset));
            echo $this->result;
        }
    }
Пример #3
0
 function checkSpl()
 {
     if (isset($this->pot)) {
         $potFile = $this->pot;
     } else {
         return;
     }
     $lang = $this->lang;
     $data = array();
     if (false && $this->lang) {
         $suggestEnabled = $this->lang != "hu";
         $suggestEnabled = $suggestEnabled && $this->lang != "de";
         echo "<!--";
         $pspell_link = pspell_new($this->lang, "", "", "utf-8", PSPELL_FAST);
         $pspell_links = array();
         echo "LLLLL";
         foreach ($this->spellDictFiles as $spellDictFile) {
             echo "<br />\n" . $spellDictFile . "<br />\n";
             $pspell_link_local = pspell_new_personal($spellDictFiles . "1", $this->lang, "", "", "utf-8");
             if ($pspell_link_local) {
                 $word = "Aktionsskript";
                 //                  $word="Aktionsskript";
                 echo "\n{$pspell_link_local}: {$spellDictFile} : {$word} =";
                 echo pspell_check($pspell_link_local, $word);
                 $word = "COM";
                 echo "\n{$pspell_link_local}: {$spellDictFile} : {$word} =";
                 echo pspell_check($pspell_link_local, $word);
                 $word = "BASE";
                 echo "\n{$pspell_link_local}: {$spellDictFile} : {$word} =";
                 echo pspell_check($pspell_link_local, $word);
                 $word = "Diff";
                 echo "\n{$pspell_link_local}: {$spellDictFile} : {$word} =";
                 echo pspell_check($pspell_link_local, $word);
                 $word = "BABE";
                 echo "\n{$pspell_link_local}: {$spellDictFile} : {$word} =";
                 echo pspell_check($pspell_link_local, $word);
                 $pspell_links[] = $pspell_link_local;
             }
         }
         echo "-->";
         $regexp = "/[A-Za-z0-9\\x{80}-\\x{ffff}]+/u";
         $regexp2 = "/^[A-Za-z]*\$/";
         $regexp3 = "/\\b{$word}\\b/i";
         $preprocessSearch = array("&", "<", ">", "\\n", "\\r", "\\t", "%s", "%d", "%ld", "/");
         $preprocessReplace = array("", " < ", " > ", " \\n ", " \\r ", " \\t ", " %s ", " %d ", " %ld ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ");
         $postprocessSearch = array("\\n");
         $postprocessReplace = array("\\n<br />");
         if ($pspell_link) {
             foreach ($potFile->dictionary as $key => $value) {
                 $orig = $key;
                 if (!isset($orig) || $orig == "") {
                     continue;
                 }
                 $native = $this->dictionary[$key]["text"];
                 if (!isset($native) || $native == "") {
                     continue;
                 }
                 $native = str_replace($preprocessSearch, $preprocessReplace, $native);
                 $orig = str_replace($preprocessSearch, $preprocessReplace, $orig);
                 $natMatch = preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
                 //                  $string=$native;
                 if ($natMatch) {
                     $match = true;
                     for ($i = 0; $i < count($matchesOnNat[0]); $i++) {
                         $word = $matchesOnNat[0][$i][0];
                         //                          if (!preg_match($regexp2, $word)) {
                         //                              continue;
                         //                          }
                         $wordOk = pspell_check($pspell_link, $word);
                         if (!$wordOk) {
                             //                              echo "<b>$word</b><br />";
                             foreach ($pspell_links as $pspell_link_local) {
                                 $wordOk = pspell_check($pspell_link_local, $word);
                                 //                                  echo "<!--$pspell_link_local, $word = $wordOk --!>\n";
                                 //                                  echo "<!-- DUMP:";
                                 //                                  var_dump($pspell_link_local);
                                 //                                  echo " --!>\n";
                                 //                                  echo "<!-- SET:".isset($pspell_link_local)." --!>\n";
                                 if ($wordOk) {
                                     echo "<!--OK --!>\n";
                                     break;
                                 }
                             }
                         }
                         if (!$wordOk) {
                             if ($suggestEnabled) {
                                 $suggestArr = pspell_suggest($pspell_link, $word);
                                 $suggestStr = implode(", ", $suggestArr);
                                 $matchesOnNat[0][$i]['sugestion'] = 'suggest:' . $suggestStr;
                             }
                             //                              if (strpos($orig, $word)!==false) {
                             //                              $regexp3="/\\b".$word."[$.^A-Za-z0-9]/i";
                             $regexp3 = "/\\b" . $word . "\\b/i";
                             if (preg_match($regexp3, $orig)) {
                                 $mark = MARK_WARNING;
                             } else {
                                 $mark = MARK_ERROR;
                                 $match = false;
                             }
                         } else {
                             $mark = MARK_OK;
                         }
                         $matchesOnNat[0][$i][2] = $mark;
                     }
                     if (!$match) {
                         for ($i = count($matchesOnNat[0]) - 1; $i >= 0; $i--) {
                             if (!isset($matchesOnNat[0][$i][2])) {
                                 continue;
                             }
                             $param = $matchesOnNat[0][$i][0];
                             $pos = $matchesOnNat[0][$i][1];
                             if ($param == "n" && $pos && $native[$pos - 1] == "\\") {
                                 continue;
                             }
                             switch ($matchesOnNat[0][$i][2]) {
                                 case MARK_OK:
                                     $class = "elmark";
                                     break;
                                 case MARK_ERROR:
                                     $class = "elerror";
                                     break;
                                 case MARK_WARNING:
                                     $class = "elwarning";
                                     break;
                             }
                             $replaceStr = "<font class=\"{$class}\">" . $param . "</font>";
                             if (isset($matchesOnNat[0][$i]['sugestion'])) {
                                 $replaceStr = "<acronym title=\"" . $matchesOnNat[0][$i]['sugestion'] . "\">{$replaceStr}</acronym>";
                             }
                             $native = substr($native, 0, $pos) . $replaceStr . substr($native, $pos + strlen($param));
                         }
                         $orig = str_replace($postprocessSearch, $postprocessReplace, $orig);
                         $native = str_replace($postprocessSearch, $postprocessReplace, $native);
                         $lineN = $this->dictionary[$key]["line"];
                         $lineE = $potFile->dictionary[$key]["line"];
                         if (isset($this->dictionary[$key]["flag"]["fuzzy"])) {
                             $lineN .= "(Fuzzy)";
                         }
                         $data[] = array(count($data) + 1, $lineE, $orig, $lineN, $native);
                     }
                     flush();
                 }
             }
             pspell_clear_session($pspell_link);
             $table = new Table();
             $table->name = "Spell check";
             $table->description = "<p>Testing spelling of translation. We use ASPELL dictionaris for PSPELL. <b><i>in development</i></b> </p>";
             $table->header = array("Index", "Line", "English", "Line", "Native");
             $table->data = $data;
             $this->report["spl"] = $table;
         } else {
             $this->report["spl"]["error"] = "Dictionary not found.";
         }
     } else {
         $this->report["spl"]["error"] = "Internal error";
     }
 }