mirror of
https://github.com/roundcube/roundcubemail.git
synced 2026-02-20 01:21:20 +01:00
Code improvements in the spellchecker classes
This commit is contained in:
@@ -1850,46 +1850,6 @@ parameters:
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_smtp.php
|
||||
|
||||
-
|
||||
message: "#^Foreach overwrites \\$word with its value variable\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Negated boolean expression is always true\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset mixed does not exist on array\\{\\}\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset mixed on array\\{\\} in empty\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset non\\-falsy\\-string does not exist on array\\{\\}\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset non\\-falsy\\-string on array\\{\\} in empty\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset string does not exist on array\\{\\}\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Offset string on array\\{\\} in empty\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/rcube_spellchecker.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
@@ -2145,56 +2105,6 @@ parameters:
|
||||
count: 1
|
||||
path: program/lib/Roundcube/session/redis.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_atd\\:\\:check\\(\\) should return bool but returns array\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/atd.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_atd\\:\\:check\\(\\) should return bool but returns array\\<int, array\\<int, array\\<int, string\\>\\|bool\\|int\\|string\\|null\\>\\>\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/atd.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_array\\(\\) with array will always evaluate to true\\.$#"
|
||||
count: 3
|
||||
path: program/lib/Roundcube/spellchecker/enchant.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_enchant\\:\\:check\\(\\) should return bool but returns array\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/enchant.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_enchant\\:\\:check\\(\\) should return bool but returns array\\<int, array\\<int, array\\|int\\|string\\|null\\>\\>\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/enchant.php
|
||||
|
||||
-
|
||||
message: "#^Foreach overwrites \\$m with its value variable\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/googie.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_googie\\:\\:check\\(\\) should return bool but returns array\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/googie.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_googie\\:\\:check\\(\\) should return bool but returns array\\<int\\<0, max\\>, array\\<string\\>\\>\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/googie.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_pspell\\:\\:check\\(\\) should return bool but returns array\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/pspell.php
|
||||
|
||||
-
|
||||
message: "#^Method rcube_spellchecker_pspell\\:\\:check\\(\\) should return bool but returns array\\<int, array\\<int, array\\|bool\\|int\\|string\\|null\\>\\>\\.$#"
|
||||
count: 1
|
||||
path: program/lib/Roundcube/spellchecker/pspell.php
|
||||
|
||||
-
|
||||
message: "#^Property rcube\\:\\:\\$storage \\(rcube_storage\\|null\\) does not accept StorageMock\\.$#"
|
||||
count: 1
|
||||
@@ -2205,11 +2115,6 @@ parameters:
|
||||
count: 1
|
||||
path: tests/Actions/Mail/Index.php
|
||||
|
||||
-
|
||||
message: "#^Foreach overwrites \\$expected with its value variable\\.$#"
|
||||
count: 1
|
||||
path: tests/Browser/Components/App.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$browser \\(Tests\\\\Browser\\\\Browser\\) of method Tests\\\\Browser\\\\Components\\\\App\\:\\:assert\\(\\) should be contravariant with parameter \\$browser \\(Laravel\\\\Dusk\\\\Browser\\) of method Laravel\\\\Dusk\\\\Component\\:\\:assert\\(\\)$#"
|
||||
count: 1
|
||||
@@ -2244,8 +2149,3 @@ parameters:
|
||||
message: "#^Parameter \\#1 \\$browser \\(Tests\\\\Browser\\\\Browser\\) of method Tests\\\\Browser\\\\Components\\\\Toolbarmenu\\:\\:assert\\(\\) should be contravariant with parameter \\$browser \\(Laravel\\\\Dusk\\\\Browser\\) of method Laravel\\\\Dusk\\\\Component\\:\\:assert\\(\\)$#"
|
||||
count: 1
|
||||
path: tests/Browser/Components/Toolbarmenu.php
|
||||
|
||||
-
|
||||
message: "#^Return type \\(bool\\|string\\) of method Installer\\:\\:getUrl\\(\\) should be covariant with return type \\(string\\) of method Laravel\\\\Dusk\\\\Console\\\\ChromeDriverCommand\\:\\:getUrl\\(\\)$#"
|
||||
count: 1
|
||||
path: tests/Browser/install.php
|
||||
|
||||
@@ -9,11 +9,6 @@ parameters:
|
||||
excludePaths:
|
||||
- vendor
|
||||
|
||||
scanFiles:
|
||||
# https://github.com/pear/pear-core-minimal/pull/15
|
||||
# remove once new release (1.10.15) is tagged - https://github.com/pear/pear-core-minimal/tags
|
||||
- vendor/pear/pear-core-minimal/src/PEAR.php
|
||||
|
||||
ignoreErrors:
|
||||
# relax strict rules
|
||||
- '~^Only booleans are allowed in .+, .+ given( on the (left|right) side)?\.~'
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
class rcube_spellchecker
|
||||
{
|
||||
private $matches = [];
|
||||
private $options = [];
|
||||
private $content;
|
||||
private $engine;
|
||||
@@ -90,16 +89,19 @@ class rcube_spellchecker
|
||||
$languages = [];
|
||||
foreach ($langs as $lang) {
|
||||
$langc = strtolower(substr($lang, 0, 2));
|
||||
$alias = !empty($rcube_language_aliases[$langc]) ? $rcube_language_aliases[$langc] : null;
|
||||
|
||||
if (!$alias) {
|
||||
// @phpstan-ignore-next-line
|
||||
if (array_key_exists($langc, $rcube_language_aliases)) {
|
||||
$alias = $rcube_language_aliases[$langc];
|
||||
} else {
|
||||
$alias = $langc . '_' . strtoupper($langc);
|
||||
}
|
||||
if (!empty($rcube_languages[$lang])) {
|
||||
|
||||
if (array_key_exists($lang, $rcube_languages)) { // @phpstan-ignore-line
|
||||
$languages[$lang] = $rcube_languages[$lang];
|
||||
} elseif (preg_match('/^en_([A-Z]+)/', $lang, $m)) {
|
||||
$languages[$lang] = sprintf('English (%s)', strtoupper($m[1]));
|
||||
} elseif (!empty($rcube_languages[$alias])) {
|
||||
} elseif (array_key_exists($alias, $rcube_languages)) { // @phpstan-ignore-line
|
||||
$languages[$lang] = $rcube_languages[$alias];
|
||||
} else {
|
||||
$languages[$lang] = ucfirst($lang);
|
||||
@@ -107,7 +109,7 @@ class rcube_spellchecker
|
||||
}
|
||||
|
||||
// remove possible duplicates (#1489395)
|
||||
$languages = array_unique($languages);
|
||||
$languages = array_unique(array_filter($languages));
|
||||
|
||||
asort($languages);
|
||||
|
||||
@@ -141,10 +143,10 @@ class rcube_spellchecker
|
||||
$this->content = preg_replace_callback('~(^|\s)(www.\S+|[a-z]+://\S+)~', $callback, $this->content);
|
||||
|
||||
if ($this->backend) {
|
||||
$this->matches = $this->backend->check($this->content);
|
||||
return $this->backend->check($this->content);
|
||||
}
|
||||
|
||||
return $this->found() == 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +156,7 @@ class rcube_spellchecker
|
||||
*/
|
||||
public function found()
|
||||
{
|
||||
return count($this->matches);
|
||||
return $this->backend ? count($this->backend->matches) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +206,8 @@ class rcube_spellchecker
|
||||
// send output
|
||||
$out = '<?xml version="1.0" encoding="' . RCUBE_CHARSET . '"?><spellresult charschecked="' . mb_strlen($this->content) . '">';
|
||||
|
||||
foreach ((array) $this->matches as $item) {
|
||||
$matches = $this->backend ? $this->backend->matches : [];
|
||||
foreach ($matches as $item) {
|
||||
$out .= '<c o="' . $item[1] . '" l="' . $item[2] . '">';
|
||||
$out .= is_array($item[4]) ? implode("\t", $item[4]) : $item[4];
|
||||
$out .= '</c>';
|
||||
@@ -223,8 +226,9 @@ class rcube_spellchecker
|
||||
public function get()
|
||||
{
|
||||
$result = [];
|
||||
$matches = $this->backend ? $this->backend->matches : [];
|
||||
|
||||
foreach ((array) $this->matches as $item) {
|
||||
foreach ($matches as $item) {
|
||||
if ($this->engine == 'pspell') {
|
||||
$word = $item[0];
|
||||
} else {
|
||||
@@ -252,7 +256,7 @@ class rcube_spellchecker
|
||||
*/
|
||||
public function error()
|
||||
{
|
||||
return $this->error ?: ($this->backend ? $this->backend->error() : false);
|
||||
return $this->error ?: ($this->backend ? $this->backend->error : false);
|
||||
}
|
||||
|
||||
private function html2text($text)
|
||||
@@ -312,10 +316,10 @@ class rcube_spellchecker
|
||||
{
|
||||
$this->load_dict();
|
||||
|
||||
foreach (explode(' ', $word) as $word) {
|
||||
foreach (explode(' ', $word) as $w) {
|
||||
// sanity check
|
||||
if (strlen($word) < 512) {
|
||||
$this->dict[] = $word;
|
||||
if (strlen($w) < 512) {
|
||||
$this->dict[] = $w;
|
||||
$valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ class rcube_spellchecker_atd extends rcube_spellchecker_engine
|
||||
public const SERVICE_HOST = 'service.afterthedeadline.com';
|
||||
public const SERVICE_PORT = 80;
|
||||
|
||||
private $matches = [];
|
||||
private $content;
|
||||
private $langhosts = [
|
||||
'fr' => 'fr.',
|
||||
@@ -128,7 +127,7 @@ class rcube_spellchecker_atd extends rcube_spellchecker_engine
|
||||
$result = new SimpleXMLElement($response);
|
||||
} catch (Exception $e) {
|
||||
$this->error = 'Unexpected response from server: ' . $response;
|
||||
return [];
|
||||
return false;
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
@@ -161,7 +160,7 @@ class rcube_spellchecker_atd extends rcube_spellchecker_engine
|
||||
|
||||
$this->matches = $matches;
|
||||
|
||||
return $matches;
|
||||
return count($matches) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,10 +170,10 @@ class rcube_spellchecker_atd extends rcube_spellchecker_engine
|
||||
*/
|
||||
public function get_suggestions($word)
|
||||
{
|
||||
$matches = $word ? $this->check($word) : $this->matches;
|
||||
$this->check($word);
|
||||
|
||||
if (!empty($matches[0][4])) {
|
||||
return $matches[0][4];
|
||||
if (!empty($this->matches[0][4])) {
|
||||
return $this->matches[0][4];
|
||||
}
|
||||
|
||||
return [];
|
||||
@@ -188,15 +187,14 @@ class rcube_spellchecker_atd extends rcube_spellchecker_engine
|
||||
public function get_words($text = null)
|
||||
{
|
||||
if ($text) {
|
||||
$matches = $this->check($text);
|
||||
$this->check($text);
|
||||
} else {
|
||||
$matches = $this->matches;
|
||||
$text = $this->content;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($matches as $m) {
|
||||
foreach ($this->matches as $m) {
|
||||
$result[] = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ class rcube_spellchecker_enchant extends rcube_spellchecker_engine
|
||||
{
|
||||
private $enchant_broker;
|
||||
private $enchant_dictionary;
|
||||
private $matches = [];
|
||||
|
||||
/**
|
||||
* Return a list of languages supported by this backend
|
||||
@@ -82,7 +81,7 @@ class rcube_spellchecker_enchant extends rcube_spellchecker_engine
|
||||
$this->init();
|
||||
|
||||
if (!$this->enchant_dictionary) {
|
||||
return [];
|
||||
return true;
|
||||
}
|
||||
|
||||
// tokenize
|
||||
@@ -101,7 +100,7 @@ class rcube_spellchecker_enchant extends rcube_spellchecker_engine
|
||||
} elseif (!enchant_dict_check($this->enchant_dictionary, $word)) {
|
||||
$suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
|
||||
|
||||
if (is_array($suggestions) && count($suggestions) > self::MAX_SUGGESTIONS) {
|
||||
if (count($suggestions) > self::MAX_SUGGESTIONS) {
|
||||
$suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
|
||||
}
|
||||
|
||||
@@ -112,7 +111,8 @@ class rcube_spellchecker_enchant extends rcube_spellchecker_engine
|
||||
}
|
||||
|
||||
$this->matches = $matches;
|
||||
return $matches;
|
||||
|
||||
return count($matches) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,11 +130,11 @@ class rcube_spellchecker_enchant extends rcube_spellchecker_engine
|
||||
|
||||
$suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
|
||||
|
||||
if (is_array($suggestions) && count($suggestions) > self::MAX_SUGGESTIONS) {
|
||||
if (count($suggestions) > self::MAX_SUGGESTIONS) {
|
||||
$suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
|
||||
}
|
||||
|
||||
return is_array($suggestions) ? $suggestions : [];
|
||||
return $suggestions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,8 +25,10 @@ abstract class rcube_spellchecker_engine
|
||||
{
|
||||
public const MAX_SUGGESTIONS = 10;
|
||||
|
||||
public $matches = [];
|
||||
public $error;
|
||||
|
||||
protected $lang;
|
||||
protected $error;
|
||||
protected $dictionary;
|
||||
protected $options = [];
|
||||
protected $separator = '/[\s\r\n\t\(\)\/\[\]{}<>\"]+|[:;?!,\.](?=\W|$)/';
|
||||
@@ -75,14 +77,4 @@ abstract class rcube_spellchecker_engine
|
||||
* @return array List of misspelled words
|
||||
*/
|
||||
abstract public function get_words($text = null);
|
||||
|
||||
/**
|
||||
* Returns error message
|
||||
*
|
||||
* @return string Error message
|
||||
*/
|
||||
public function error()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
{
|
||||
public const GOOGIE_HOST = 'https://spell.roundcube.net';
|
||||
|
||||
private $matches = [];
|
||||
private $content;
|
||||
|
||||
/**
|
||||
@@ -54,12 +53,12 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
{
|
||||
$this->content = $text;
|
||||
|
||||
$matches = [];
|
||||
|
||||
if (empty($text)) {
|
||||
return $this->matches = $matches;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->matches = $matches = [];
|
||||
|
||||
$rcube = rcube::get_instance();
|
||||
$client = $rcube->get_http_client();
|
||||
|
||||
@@ -105,8 +104,8 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $response_body, $matches, \PREG_SET_ORDER);
|
||||
|
||||
// skip exceptions (if appropriate options are enabled)
|
||||
foreach ($matches as $idx => $m) {
|
||||
$word = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
|
||||
foreach ($matches as $idx => $match) {
|
||||
$word = mb_substr($text, $match[1], $match[2], RCUBE_CHARSET);
|
||||
// skip exceptions
|
||||
if ($this->dictionary->is_exception($word)) {
|
||||
unset($matches[$idx]);
|
||||
@@ -114,7 +113,9 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
}
|
||||
}
|
||||
|
||||
return $this->matches = $matches;
|
||||
$this->matches = $matches;
|
||||
|
||||
return count($this->matches) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +125,10 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
*/
|
||||
public function get_suggestions($word)
|
||||
{
|
||||
$matches = $word ? $this->check($word) : $this->matches;
|
||||
$this->check($word);
|
||||
|
||||
if (!empty($matches[0][4])) {
|
||||
$suggestions = explode("\t", $matches[0][4]);
|
||||
if (!empty($this->matches[0][4])) {
|
||||
$suggestions = explode("\t", $this->matches[0][4]);
|
||||
if (count($suggestions) > self::MAX_SUGGESTIONS) {
|
||||
$suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
|
||||
}
|
||||
@@ -146,15 +147,14 @@ class rcube_spellchecker_googie extends rcube_spellchecker_engine
|
||||
public function get_words($text = null)
|
||||
{
|
||||
if ($text) {
|
||||
$matches = $this->check($text);
|
||||
$this->check($text);
|
||||
} else {
|
||||
$matches = $this->matches;
|
||||
$text = $this->content;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($matches as $m) {
|
||||
foreach ($this->matches as $m) {
|
||||
$result[] = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
class rcube_spellchecker_pspell extends rcube_spellchecker_engine
|
||||
{
|
||||
private $plink;
|
||||
private $matches = [];
|
||||
|
||||
/**
|
||||
* Return a list of languages supported by this backend
|
||||
@@ -87,7 +86,7 @@ class rcube_spellchecker_pspell extends rcube_spellchecker_engine
|
||||
$this->init();
|
||||
|
||||
if (!$this->plink) {
|
||||
return [];
|
||||
return false;
|
||||
}
|
||||
|
||||
// tokenize
|
||||
@@ -116,7 +115,9 @@ class rcube_spellchecker_pspell extends rcube_spellchecker_engine
|
||||
$diff += (strlen($word) - $len);
|
||||
}
|
||||
|
||||
return $this->matches = $matches;
|
||||
$this->matches = $matches;
|
||||
|
||||
return count($this->matches) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,8 +38,7 @@ class App extends Component
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
];
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,8 +51,8 @@ class App extends Component
|
||||
public function assertEnv($browser, $key, $expected = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $name => $expected) {
|
||||
Assert::assertEquals($expected, $browser->getEnv($name));
|
||||
foreach ($key as $name => $value) {
|
||||
Assert::assertEquals($value, $browser->getEnv($name));
|
||||
}
|
||||
} else {
|
||||
Assert::assertEquals($expected, $browser->getEnv($key));
|
||||
|
||||
@@ -64,11 +64,11 @@ class Installer extends ChromeDriverCommand
|
||||
*
|
||||
* @param string $url URL
|
||||
*
|
||||
* @return string|bool
|
||||
* @return string
|
||||
*/
|
||||
protected function getUrl(string $url)
|
||||
{
|
||||
return file_get_contents($url);
|
||||
return file_get_contents($url) ?: '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,6 @@ class Rcmail_RcmailUtils extends ActionTestCase
|
||||
*/
|
||||
public function test_mod_pref()
|
||||
{
|
||||
// FIXME: The test hangs for some reason, probably related with the extra DB connection
|
||||
// $this->markTestIncomplete();
|
||||
|
||||
self::initDB('init');
|
||||
|
||||
$db = rcmail::get_instance()->get_dbh();
|
||||
|
||||
Reference in New Issue
Block a user