tigitz / php-spellchecker

@@ -6,6 +6,7 @@
Loading
6 6
7 7
use PhpSpellcheck\Exception\RuntimeException;
8 8
use PhpSpellcheck\Misspelling;
9 +
use PhpSpellcheck\MisspellingInterface;
9 10
use Webmozart\Assert\Assert;
10 11
11 12
class PHPPspell implements SpellcheckerInterface
@@ -29,9 +30,9 @@
Loading
29 30
     * @see http://php.net/manual/en/function.pspell-config-mode.php
30 31
     * @see http://php.net/manual/en/function.pspell-config-ignore.php
31 32
     *
32 -
     * @param int $mode the mode parameter is the mode in which the spellchecker will work
33 +
     * @param int|null $mode the mode parameter is the mode in which the spellchecker will work
33 34
     * @param int $numberOfCharactersLowerLimit Words less than n characters will be skipped
34 -
     * @param Aspell|null $aspell Aspell spellchecker that pspell extension is using underneath. Used to help retrieving supported languages
35 +
     * @param Aspell|null $aspell Aspell spellchecker that pspell extension is using underneath. Used to help retrieve supported languages
35 36
     */
36 37
    public function __construct(
37 38
        ?int $mode = null,
@@ -60,9 +61,36 @@
Loading
60 61
        string $text,
61 62
        array $languages,
62 63
        array $context
64 +
    ): iterable {
65 +
        if (PHP_VERSION_ID < 80100) {
66 +
            return $this->checkBefore81($text, $languages, $context);
67 +
        }
68 +
69 +
        return $this->checkAfter81($text, $languages, $context);
70 +
    }
71 +
72 +
    /**
73 +
     * {@inheritdoc}
74 +
     */
75 +
    public function getSupportedLanguages(): iterable
76 +
    {
77 +
        return $this->aspell->getSupportedLanguages();
78 +
    }
79 +
80 +
    /**
81 +
     * @param array<mixed> $context
82 +
     * @param array<string> $languages
83 +
     *
84 +
     * @return iterable<MisspellingInterface>
85 +
     */
86 +
    private function checkBefore81(
87 +
        string $text,
88 +
        array $languages,
89 +
        array $context
63 90
    ): iterable {
64 91
        Assert::count($languages, 1, 'PHPPspell spellchecker doesn\'t support multi-language check');
65 92
93 +
        $chosenLanguage = current($languages);
66 94
        $pspellConfig = \Safe\pspell_config_create(current($languages));
67 95
        \Safe\pspell_config_mode($pspellConfig, $this->mode);
68 96
        \Safe\pspell_config_ignore($pspellConfig, $this->numberOfCharactersLowerLimit);
@@ -73,13 +101,12 @@
Loading
73 101
        /** @var string $line */
74 102
        foreach ($lines as $lineNumber => $line) {
75 103
            $words = explode(' ', \Safe\preg_replace("/(?!['’-])(\p{P}|\+|--)/u", '', $line));
76 -
            foreach ($words as $key => $word) {
104 +
            foreach ($words as $word) {
77 105
                if (!pspell_check($dictionary, $word)) {
78 106
                    $suggestions = pspell_suggest($dictionary, $word);
79 -
80 107
                    Assert::isArray(
81 108
                        $suggestions,
82 -
                        \Safe\sprintf('pspell_suggest method failed with dictionary "%s" and word "%s"', $dictionary, $word)
109 +
                        \Safe\sprintf('pspell_suggest method failed with language "%s" and word "%s"', $chosenLanguage, $word)
83 110
                    );
84 111
85 112
                    yield new Misspelling($word, 0, $lineNumber + 1, $suggestions, $context);
@@ -89,10 +116,40 @@
Loading
89 116
    }
90 117
91 118
    /**
92 -
     * {@inheritdoc}
119 +
     * @param array<mixed> $context
120 +
     * @param array<string> $languages
121 +
     *
122 +
     * @return iterable<MisspellingInterface>
93 123
     */
94 -
    public function getSupportedLanguages(): iterable
95 -
    {
96 -
        return $this->aspell->getSupportedLanguages();
124 +
    private function checkAfter81(
125 +
        string $text,
126 +
        array $languages,
127 +
        array $context
128 +
    ): iterable {
129 +
        Assert::count($languages, 1, 'PHPPspell spellchecker doesn\'t support multi-language check');
130 +
131 +
        $chosenLanguage = current($languages);
132 +
        $pspellConfig = pspell_config_create($chosenLanguage);
133 +
        pspell_config_mode($pspellConfig, $this->mode);
134 +
        pspell_config_ignore($pspellConfig, $this->numberOfCharactersLowerLimit);
135 +
        $dictionary = pspell_new_config($pspellConfig);
136 +
137 +
        $lines = explode(PHP_EOL, $text);
138 +
139 +
        /** @var string $line */
140 +
        foreach ($lines as $lineNumber => $line) {
141 +
            $words = explode(' ', \Safe\preg_replace("/(?!['’-])(\p{P}|\+|--)/u", '', $line));
142 +
            foreach ($words as $word) {
143 +
                if (!pspell_check($dictionary, $word)) {
144 +
                    $suggestions = pspell_suggest($dictionary, $word);
145 +
                    Assert::isArray(
146 +
                        $suggestions,
147 +
                        \Safe\sprintf('pspell_suggest method failed with language "%s" and word "%s"', $chosenLanguage, $word)
148 +
                    );
149 +
150 +
                    yield new Misspelling($word, 0, $lineNumber + 1, $suggestions, $context);
151 +
                }
152 +
            }
153 +
        }
97 154
    }
98 155
}

@@ -16,13 +16,6 @@
Loading
16 16
     */
17 17
    public static function run(Process $process, $timeout = null, callable $callback = null, array $env = []): Process
18 18
    {
19 -
        if (method_exists($process, 'inheritEnvironmentVariables')) {
20 -
            // Symfony 3.2+
21 -
            $process->inheritEnvironmentVariables(true);
22 -
        } else {
23 -
            // Symfony < 3.2
24 -
            $process->setEnv(['LANG' => getenv('LANG')]);
25 -
        }
26 19
        $process->setTimeout($timeout);
27 20
28 21
        try {
Files Complexity Coverage
src 171 89.54%
Project Totals (23 files) 171 89.54%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading