Completed
Pull Request — master (#219)
by David
01:14
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 Gettext\Translations;
6
use Gettext\Utils\PhpFunctionsScanner;
7
8
/**
9
 * Class to get gettext strings from php files returning arrays.
10
 */
11
class PhpCode extends Extractor implements ExtractorInterface
12
{
13
    public static $options = [
14
         // - false: to not extract comments
15
         // - empty string: to extract all comments
16
         // - non-empty string: to extract comments that start with that string
17
         // - array with strings to extract comments format.
18
        'extractComments' => false,
19
20
        'constants' => [],
21
22
        'functions' => [
23
            'gettext' => 'gettext',
24
            '__' => 'gettext',
25
            'ngettext' => 'ngettext',
26
            'n__' => 'ngettext',
27
            'pgettext' => 'pgettext',
28
            'p__' => 'pgettext',
29
            'dgettext' => 'dgettext',
30
            'd__' => 'dgettext',
31
            'dngettext' => 'dngettext',
32
            'dn__' => 'dngettext',
33
            'dpgettext' => 'dpgettext',
34
            'dp__' => 'dpgettext',
35
            'npgettext' => 'npgettext',
36
            'np__' => 'npgettext',
37
            'dnpgettext' => 'dnpgettext',
38
            'dnp__' => 'dnpgettext',
39
            'noop' => 'noop',
40
            'noop__' => 'noop',
41
        ],
42
    ];
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public static function fromString($string, Translations $translations, array $options = [])
48
    {
49
        $options += static::$options;
50
51
        $functions = new PhpFunctionsScanner($string);
52
53
        if ($options['extractComments'] !== false) {
54
            $functions->enableCommentsExtraction($options['extractComments']);
55
        }
56
57
        $functions->saveGettextFunctions($translations, $options);
58
    }
59
60
    /**
61
     * Decodes a T_CONSTANT_ENCAPSED_STRING string.
62
     *
63
     * @param string $value
64
     *
65
     * @return string
66
     */
67
    public static function convertString($value)
68
    {
69
        if (strpos($value, '\\') === false) {
70
            return substr($value, 1, -1);
71
        }
72
73
        if ($value[0] === "'") {
74
            return strtr(substr($value, 1, -1), ['\\\\' => '\\', '\\\'' => '\'']);
75
        }
76
77
        $value = substr($value, 1, -1);
78
79
        return preg_replace_callback(
80
            '/\\\(n|r|t|v|e|f|\$|"|\\\|x[0-9A-Fa-f]{1,2}|u{[0-9a-f]{1,6}}|[0-7]{1,3})/',
81
            function ($match) {
82
                switch ($match[1][0]) {
83
                    case 'n':
84
                        return "\n";
85
                    case 'r':
86
                        return "\r";
87
                    case 't':
88
                        return "\t";
89
                    case 'v':
90
                        return "\v";
91
                    case 'e':
92
                        return "\e";
93
                    case 'f':
94
                        return "\f";
95
                    case '$':
96
                        return '$';
97
                    case '"':
98
                        return '"';
99
                    case '\\':
100
                        return '\\';
101
                    case 'x':
102
                        return chr(hexdec(substr($match[0], 1)));
103
                    case 'u':
104
                        return self::unicodeChar(hexdec(substr($match[0], 1)));
105
                    default:
106
                        return chr(octdec($match[0]));
107
                }
108
            },
109
            $value
110
        );
111
    }
112
113
    //http://php.net/manual/en/function.chr.php#118804
114
    private static function unicodeChar($dec)
115
    {
116
        if ($dec < 0x80) {
117
            return chr($dec);
118
        }
119
120
        if ($dec < 0x0800) {
121
            return chr(0xC0 + ($dec >> 6))
122
                .chr(0x80 + ($dec & 0x3f));
123
        }
124
125
        if ($dec < 0x010000) {
126
            return chr(0xE0 + ($dec >> 12))
127
                    .chr(0x80 + (($dec >> 6) & 0x3f))
128
                    .chr(0x80 + ($dec & 0x3f));
129
        }
130
131
        if ($dec < 0x200000) {
132
            return chr(0xF0 + ($dec >> 18))
133
                    .chr(0x80 + (($dec >> 12) & 0x3f))
134
                    .chr(0x80 + (($dec >> 6) & 0x3f))
135
                    .chr(0x80 + ($dec & 0x3f));
136
        }
137
    }
138
}
139