Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.82% covered (warning)
81.82%
27 / 33
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Language
81.82% covered (warning)
81.82%
27 / 33
0.00% covered (danger)
0.00%
0 / 2
14.02
0.00% covered (danger)
0.00%
0 / 1
 __construct
61.54% covered (warning)
61.54%
8 / 13
0.00% covered (danger)
0.00%
0 / 1
11.64
 detect
95.00% covered (success)
95.00%
19 / 20
0.00% covered (danger)
0.00%
0 / 1
5
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Localization\LanguageDetection
8 * @author    Patrick Schur <patrick_schur@outlook.de>
9 * @copyright Patrick Schur
10 * @license   https://opensource.org/licenses/mit-license.html MIT
11 * @link      https://github.com/patrickschur/language-detection
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Localization\LanguageDetection;
16
17/**
18 * Langauge detection class
19 *
20 * @package phpOMS\Localization\LanguageDetection
21 * @license https://opensource.org/licenses/mit-license.html MIT
22 * @link    https://github.com/patrickschur/language-detection
23 * @since   1.0.0
24 */
25class Language extends NgramParser
26{
27    /**
28     * Tokens
29     *
30     * @var array
31     * @since 1.0.0
32     */
33    protected array $tokens = [];
34
35    /**
36     * Constructor.
37     *
38     * @param array  $lang    List of ISO 639-1 codes, that should be used in the detection phase
39     * @param string $dirname Name of the directory where the translations files are located
40     *
41     * @throws \InvalidArgumentException
42     *
43     * @since 1.0.0
44     */
45    public function __construct(array $lang = [], string $dirname = '')
46    {
47        if (empty($dirname)) {
48            $dirname = __DIR__ . '/resources/*/*.php';
49        } elseif (!\is_dir($dirname) || !\is_readable($dirname)) {
50            throw new \InvalidArgumentException('Provided directory could not be found or is not readable');
51        } else {
52            $dirname  = \rtrim($dirname, '/');
53            $dirname .= '/*/*.php';
54        }
55
56        $isEmpty = empty($lang);
57
58        $files = \glob($dirname);
59        if ($files === false) {
60            $files = [];
61        }
62
63        foreach ($files as $file) {
64            if ($isEmpty || \in_array(\basename($file, '.php'), $lang)) {
65                $this->tokens += require $file;
66            }
67        }
68    }
69
70    /**
71     * Detects the language from a given text string
72     *
73     * @param string $str String to use for detection
74     *
75     * @return LanguageResult
76     *
77     * @since 1.0.0
78     */
79    public function detect(string $str) : LanguageResult
80    {
81        $str     = \mb_strtolower($str);
82        $samples = $this->getNgrams($str);
83        $result  = [];
84
85        if (empty($samples)) {
86            return new LanguageResult($result);
87        }
88
89        foreach ($this->tokens as $lang => $value) {
90            $index = 0;
91            $sum   = 0;
92            $value = \array_flip($value);
93
94            foreach ($samples as $v) {
95                if (isset($value[$v])) {
96                    $x    = $index++ - $value[$v];
97                    $y    = $x >> (\PHP_INT_SIZE * 8);
98                    $sum += ($x + $y) ^ $y;
99
100                    continue;
101                }
102
103                $sum += $this->maxNgrams;
104                ++$index;
105            }
106
107            $result[$lang] = 1 - ($sum / ($this->maxNgrams * $index));
108        }
109
110        \arsort($result, \SORT_NUMERIC);
111
112        return new LanguageResult($result);
113    }
114}