PHPPspell::getSupportedLanguages()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpSpellcheck\Spellchecker;
6
7
use PhpSpellcheck\Exception\RuntimeException;
8
use PhpSpellcheck\Misspelling;
9
use PhpSpellcheck\MisspellingInterface;
10
use Webmozart\Assert\Assert;
11
12
class PHPPspell implements SpellcheckerInterface
13
{
14
    /**
15
     * @var int
16
     */
17
    private $mode;
18
19
    /**
20
     * @var int
21
     */
22
    private $numberOfCharactersLowerLimit;
23
24
    /**
25
     * @var Aspell
26
     */
27
    private $aspell;
28
29
    /**
30
     * @see http://php.net/manual/en/function.pspell-config-mode.php
31
     * @see http://php.net/manual/en/function.pspell-config-ignore.php
32 3
     *
33
     * @param int|null $mode the mode parameter is the mode in which the spellchecker will work
34 3
     * @param int $numberOfCharactersLowerLimit Words less than n characters will be skipped
35
     * @param Aspell|null $aspell Aspell spellchecker that pspell extension is using underneath. Used to help retrieve supported languages
36
     */
37
    public function __construct(
38 3
        ?int $mode = null,
39
        int $numberOfCharactersLowerLimit = 0,
40 3
        Aspell $aspell = null
41 3
    ) {
42 3
        if (!\extension_loaded('pspell')) {
43
            throw new RuntimeException('Pspell extension must be loaded to use the PHPPspell spellchecker');
44
        }
45
46
        if ($mode === null) {
47 2
            $mode = PSPELL_FAST;
48
        }
49
50
        Assert::greaterThanEq($numberOfCharactersLowerLimit, 0);
51
52
        $this->mode = $mode;
53 2
        $this->numberOfCharactersLowerLimit = $numberOfCharactersLowerLimit;
54 2
        $this->aspell = $aspell ?? Aspell::create();
55
    }
56 1
57 1
    /**
58 1
     * {@inheritdoc}
59 1
     */
60
    public function check(
61 1
        string $text,
62 1
        array $languages,
63 1
        array $context
64 1
    ): iterable {
65 1
        if (PHP_VERSION_ID < 80100) {
66 1
            return $this->checkBefore81($text, $languages, $context);
67
        }
68
69
        return $this->checkAfter81($text, $languages, $context);
70 1
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 1
    public function getSupportedLanguages(): iterable
76
    {
77 1
        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
90
    ): iterable {
91
        Assert::count($languages, 1, 'PHPPspell spellchecker doesn\'t support multi-language check');
92
93
        $chosenLanguage = current($languages);
94
        $pspellConfig = \Safe\pspell_config_create(current($languages));
95
        \Safe\pspell_config_mode($pspellConfig, $this->mode);
96
        \Safe\pspell_config_ignore($pspellConfig, $this->numberOfCharactersLowerLimit);
97
        $dictionary = \Safe\pspell_new_config($pspellConfig);
98
99
        $lines = explode(PHP_EOL, $text);
100
101
        /** @var string $line */
102
        foreach ($lines as $lineNumber => $line) {
103
            $words = explode(' ', \Safe\preg_replace("/(?!['’-])(\p{P}|\+|--)/u", '', $line));
104
            foreach ($words as $word) {
105
                if (!pspell_check($dictionary, $word)) {
106
                    $suggestions = pspell_suggest($dictionary, $word);
107
                    Assert::isArray(
108
                        $suggestions,
109
                        \Safe\sprintf('pspell_suggest method failed with language "%s" and word "%s"', $chosenLanguage, $word)
0 ignored issues
show
Deprecated Code introduced by
The function Safe\sprintf() has been deprecated: The Safe version of this function is no longer needed in PHP 8.0+ ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

109
                        /** @scrutinizer ignore-deprecated */ \Safe\sprintf('pspell_suggest method failed with language "%s" and word "%s"', $chosenLanguage, $word)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
110
                    );
111
112
                    yield new Misspelling($word, 0, $lineNumber + 1, $suggestions, $context);
113
                }
114
            }
115
        }
116
    }
117
118
    /**
119
     * @param array<mixed> $context
120
     * @param array<string> $languages
121
     *
122
     * @return iterable<MisspellingInterface>
123
     */
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)
0 ignored issues
show
Deprecated Code introduced by
The function Safe\sprintf() has been deprecated: The Safe version of this function is no longer needed in PHP 8.0+ ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

147
                        /** @scrutinizer ignore-deprecated */ \Safe\sprintf('pspell_suggest method failed with language "%s" and word "%s"', $chosenLanguage, $word)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
148
                    );
149
150
                    yield new Misspelling($word, 0, $lineNumber + 1, $suggestions, $context);
151
                }
152
            }
153
        }
154
    }
155
}
156