Completed
Push — v5-dev ( a42eb3 )
by Oscar
01:56
created

PhpScanner::checkArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Gettext\Scanner;
5
6
use Exception;
7
use Gettext\Translations;
8
use Gettext\Translation;
9
use Gettext\Scanner\ParsedFunction;
10
use Gettext\Scanner\PhpFunctionsScanner;
11
use Gettext\Scanner\FunctionsScannerInterface;
12
13
/**
14
 * Class to scan php files and get gettext translations
15
 */
16
class PhpScanner extends Scanner
17
{
18
    protected $functionsScanner;
19
20
    protected $functionsHandlers = [
21
        'gettext' => 'gettext',
22
        '__' => 'gettext',
23
        'ngettext' => 'ngettext',
24
        'n__' => 'ngettext',
25
        'pgettext' => 'pgettext',
26
        'p__' => 'pgettext',
27
        'dgettext' => 'dgettext',
28
        'd__' => 'dgettext',
29
        'dngettext' => 'dngettext',
30
        'dn__' => 'dngettext',
31
        'dpgettext' => 'dpgettext',
32
        'dp__' => 'dpgettext',
33
        'npgettext' => 'npgettext',
34
        'np__' => 'npgettext',
35
        'dnpgettext' => 'dnpgettext',
36
        'dnp__' => 'dnpgettext',
37
        'noop' => 'gettext',
38
        'noop__' => 'gettext',
39
    ];
40
41
    public function scanString(string $string, string $filename = null): void
42
    {
43
        $functionsScanner = $this->getFunctionsScanner();
44
        $functions = $functionsScanner->scan($string, $filename);
45
46
        foreach ($functions as $function) {
47
            $this->handleFunction($function);
48
        }
49
    }
50
51
    public function setFunctionsScanner(FunctionsScannerInterface $functionsScanner): void
52
    {
53
        $this->functionsScanner = $functionsScanner;
54
    }
55
56
    public function getFunctionsScanner(): FunctionsScannerInterface
57
    {
58
        if (!isset($this->functionsScanner)) {
59
            $this->functionsScanner = new PhpFunctionsScanner();
60
        }
61
62
        return $this->functionsScanner;
63
    }
64
65
    public function setFunctionsHandlers(array $functionsHandlers): void
66
    {
67
        $this->functionsHandlers = $functionsHandlers;
68
    }
69
70
    public function getFunctionsHandlers(): array
71
    {
72
        return $this->functionsHandlers;
73
    }
74
75
    protected function handleFunction(ParsedFunction $function)
76
    {
77
        $name = $function->getName();
78
        $handler = $this->functionsHandlers[$name] ?? null;
79
80
        if (is_null($handler)) {
81
            return;
82
        }
83
84
        $translation = call_user_func([$this, $handler], $function);
85
86
        if ($translation) {
87
            $translation->getReferences()->add($function->getFilename(), $function->getLine());
88
        }
89
    }
90
91
    protected function gettext(ParsedFunction $function): ?Translation
92
    {
93
        static::checkArguments($function, 1);
94
        list($original) = $function->getArguments();
95
96
        return $this->saveTranslation(null, null, $original);
97
    }
98
99
    protected function ngettext(ParsedFunction $function): ?Translation
100
    {
101
        static::checkArguments($function, 2);
102
        list($original, $plural) = $function->getArguments();
103
        
104
        return $this->saveTranslation(null, null, $original, $plural);
105
    }
106
107
    protected function pgettext(ParsedFunction $function): ?Translation
108
    {
109
        static::checkArguments($function, 2);
110
        list($context, $original) = $function->getArguments();
111
        
112
        return $this->saveTranslation(null, $context, $original);
113
    }
114
115
    protected function dgettext(ParsedFunction $function): ?Translation
116
    {
117
        static::checkArguments($function, 2);
118
        list($domain, $original) = $function->getArguments();
119
        
120
        return $this->saveTranslation($domain, null, $original);
121
    }
122
123
    protected function dpgettext(ParsedFunction $function): ?Translation
124
    {
125
        static::checkArguments($function, 3);
126
        list($domain, $context, $original) = $function->getArguments();
127
        
128
        return $this->saveTranslation($domain, $context, $original);
129
    }
130
131
    protected function npgettext(ParsedFunction $function): ?Translation
132
    {
133
        static::checkArguments($function, 3);
134
        list($context, $original, $plural) = $function->getArguments();
135
        
136
        return $this->saveTranslation(null, $context, $original, $plural);
137
    }
138
139
    protected function dngettext(ParsedFunction $function): ?Translation
140
    {
141
        static::checkArguments($function, 3);
142
        list($domain, $original, $plural) = $function->getArguments();
143
        
144
        return $this->saveTranslation($domain, null, $original, $plural);
145
    }
146
147
    protected function dnpgettext(ParsedFunction $function): ?Translation
148
    {
149
        static::checkArguments($function, 4);
150
        list($domain, $context, $original, $plural) = $function->getArguments();
151
        
152
        return $this->saveTranslation($domain, $context, $original, $plural);
153
    }
154
155
    protected static function checkArguments(ParsedFunction $function, int $minLength)
156
    {
157
        if ($function->countArguments() < $minLength) {
158
            throw new Exception(
159
                sprintf(
160
                    'Invalid gettext function in %s:%d. At least %d arguments are required', 
161
                    $function->getFilename(), 
162
                    $function->getLine(), 
163
                    $minLength
164
                )
165
            );
166
        }
167
        
168
        $arguments = array_slice($function->getArguments(), 0, $minLength);
169
170
        if (in_array(null, $arguments, true)) {
171
            throw new Exception(
172
                sprintf(
173
                    'Invalid gettext function in %s:%d. Some required arguments are not valid', 
174
                    $function->getFilename(), 
175
                    $function->getLine()
176
                )
177
            );
178
        }
179
    }
180
}
181