Completed
Push — master ( a20241...2c1d12 )
by Oscar
13s queued 10s
created

PhpCode::fromFileMultiple()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
dl 7
loc 7
c 0
b 0
f 0
cc 2
nc 2
nop 3
rs 10
1
<?php
2
3
namespace Gettext\Extractors;
4
5
use Exception;
6
use Gettext\Translations;
7
use Gettext\Utils\PhpFunctionsScanner;
8
9
/**
10
 * Class to get gettext strings from php files returning arrays.
11
 */
12
class PhpCode extends Extractor implements ExtractorInterface, ExtractorMultiInterface
13
{
14
    public static $options = [
15
        // - false: to not extract comments
16
        // - empty string: to extract all comments
17
        // - non-empty string: to extract comments that start with that string
18
        // - array with strings to extract comments format.
19
        'extractComments' => false,
20
21
        'constants' => [],
22
23
        'functions' => [
24
            'gettext' => 'gettext',
25
            '__' => 'gettext',
26
            'ngettext' => 'ngettext',
27
            'n__' => 'ngettext',
28
            'pgettext' => 'pgettext',
29
            'p__' => 'pgettext',
30
            'dgettext' => 'dgettext',
31
            'd__' => 'dgettext',
32
            'dngettext' => 'dngettext',
33
            'dn__' => 'dngettext',
34
            'dpgettext' => 'dpgettext',
35
            'dp__' => 'dpgettext',
36
            'npgettext' => 'npgettext',
37
            'np__' => 'npgettext',
38
            'dnpgettext' => 'dnpgettext',
39
            'dnp__' => 'dnpgettext',
40
            'noop' => 'noop',
41
            'noop__' => 'noop',
42
        ],
43
    ];
44
45
    /**
46
     * {@inheritdoc}
47
     * @throws Exception
48
     */
49
    public static function fromString($string, Translations $translations, array $options = [])
50
    {
51
        self::fromStringMultiple($string, [$translations], $options);
52
    }
53
54
    /**
55
     * @inheritDoc
56
     * @throws Exception
57
     */
58
    public static function fromStringMultiple($string, array $translations, array $options = [])
59
    {
60
        $options += static::$options;
61
62
        $functions = new PhpFunctionsScanner($string);
63
64
        if ($options['extractComments'] !== false) {
65
            $functions->enableCommentsExtraction($options['extractComments']);
66
        }
67
68
        $functions->saveGettextFunctions($translations, $options);
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74 View Code Duplication
    public static function fromFileMultiple($file, array $translations, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
    {
76
        foreach (self::getFiles($file) as $file) {
77
            $options['file'] = $file;
78
            static::fromStringMultiple(self::readFile($file), $translations, $options);
79
        }
80
    }
81
82
83
    /**
84
     * Decodes a T_CONSTANT_ENCAPSED_STRING string.
85
     *
86
     * @param string $value
87
     *
88
     * @return string
89
     */
90
    public static function convertString($value)
91
    {
92
        if (strpos($value, '\\') === false) {
93
            return substr($value, 1, -1);
94
        }
95
96
        if ($value[0] === "'") {
97
            return strtr(substr($value, 1, -1), ['\\\\' => '\\', '\\\'' => '\'']);
98
        }
99
100
        $value = substr($value, 1, -1);
101
102
        return preg_replace_callback(
103
            '/\\\(n|r|t|v|e|f|\$|"|\\\|x[0-9A-Fa-f]{1,2}|u{[0-9a-f]{1,6}}|[0-7]{1,3})/',
104
            function ($match) {
105
                switch ($match[1][0]) {
106
                    case 'n':
107
                        return "\n";
108
                    case 'r':
109
                        return "\r";
110
                    case 't':
111
                        return "\t";
112
                    case 'v':
113
                        return "\v";
114
                    case 'e':
115
                        return "\e";
116
                    case 'f':
117
                        return "\f";
118
                    case '$':
119
                        return '$';
120
                    case '"':
121
                        return '"';
122
                    case '\\':
123
                        return '\\';
124
                    case 'x':
125
                        return chr(hexdec(substr($match[0], 1)));
126
                    case 'u':
127
                        return self::unicodeChar(hexdec(substr($match[0], 1)));
128
                    default:
129
                        return chr(octdec($match[0]));
130
                }
131
            },
132
            $value
133
        );
134
    }
135
136
    /**
137
     * @param $dec
138
     * @return string|null
139
     * @see http://php.net/manual/en/function.chr.php#118804
140
     */
141
    private static function unicodeChar($dec)
142
    {
143
        if ($dec < 0x80) {
144
            return chr($dec);
145
        }
146
147
        if ($dec < 0x0800) {
148
            return chr(0xC0 + ($dec >> 6))
149
                . chr(0x80 + ($dec & 0x3f));
150
        }
151
152
        if ($dec < 0x010000) {
153
            return chr(0xE0 + ($dec >> 12))
154
                . chr(0x80 + (($dec >> 6) & 0x3f))
155
                . chr(0x80 + ($dec & 0x3f));
156
        }
157
158
        if ($dec < 0x200000) {
159
            return chr(0xF0 + ($dec >> 18))
160
                . chr(0x80 + (($dec >> 12) & 0x3f))
161
                . chr(0x80 + (($dec >> 6) & 0x3f))
162
                . chr(0x80 + ($dec & 0x3f));
163
        }
164
165
        return null;
166
    }
167
}
168