Completed
Push — develop ( a51f26...2ecf95 )
by Zack
15:32
created
vendor/gettext/gettext/src/Extractors/PhpCode.php 1 patch
Indentation   +156 added lines, -156 removed lines patch added patch discarded remove patch
@@ -11,160 +11,160 @@
 block discarded – undo
11 11
  */
12 12
 class PhpCode extends Extractor implements ExtractorInterface, ExtractorMultiInterface
13 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
-    protected static $functionsScannerClass = 'Gettext\Utils\PhpFunctionsScanner';
46
-
47
-    /**
48
-     * {@inheritdoc}
49
-     * @throws Exception
50
-     */
51
-    public static function fromString($string, Translations $translations, array $options = [])
52
-    {
53
-        static::fromStringMultiple($string, [$translations], $options);
54
-    }
55
-
56
-    /**
57
-     * @inheritDoc
58
-     * @throws Exception
59
-     */
60
-    public static function fromStringMultiple($string, array $translations, array $options = [])
61
-    {
62
-        $options += static::$options;
63
-
64
-        /** @var FunctionsScanner $functions */
65
-        $functions = new static::$functionsScannerClass($string);
66
-
67
-        if ($options['extractComments'] !== false) {
68
-            $functions->enableCommentsExtraction($options['extractComments']);
69
-        }
70
-
71
-        $functions->saveGettextFunctions($translations, $options);
72
-    }
73
-
74
-    /**
75
-     * @inheritDoc
76
-     */
77
-    public static function fromFileMultiple($file, array $translations, array $options = [])
78
-    {
79
-        foreach (static::getFiles($file) as $file) {
80
-            $options['file'] = $file;
81
-            static::fromStringMultiple(static::readFile($file), $translations, $options);
82
-        }
83
-    }
84
-
85
-
86
-    /**
87
-     * Decodes a T_CONSTANT_ENCAPSED_STRING string.
88
-     *
89
-     * @param string $value
90
-     *
91
-     * @return string
92
-     */
93
-    public static function convertString($value)
94
-    {
95
-        if (strpos($value, '\\') === false) {
96
-            return substr($value, 1, -1);
97
-        }
98
-
99
-        if ($value[0] === "'") {
100
-            return strtr(substr($value, 1, -1), ['\\\\' => '\\', '\\\'' => '\'']);
101
-        }
102
-
103
-        $value = substr($value, 1, -1);
104
-
105
-        return preg_replace_callback(
106
-            '/\\\(n|r|t|v|e|f|\$|"|\\\|x[0-9A-Fa-f]{1,2}|u{[0-9a-f]{1,6}}|[0-7]{1,3})/',
107
-            function ($match) {
108
-                switch ($match[1][0]) {
109
-                    case 'n':
110
-                        return "\n";
111
-                    case 'r':
112
-                        return "\r";
113
-                    case 't':
114
-                        return "\t";
115
-                    case 'v':
116
-                        return "\v";
117
-                    case 'e':
118
-                        return "\e";
119
-                    case 'f':
120
-                        return "\f";
121
-                    case '$':
122
-                        return '$';
123
-                    case '"':
124
-                        return '"';
125
-                    case '\\':
126
-                        return '\\';
127
-                    case 'x':
128
-                        return chr(hexdec(substr($match[1], 1)));
129
-                    case 'u':
130
-                        return static::unicodeChar(hexdec(substr($match[1], 1)));
131
-                    default:
132
-                        return chr(octdec($match[1]));
133
-                }
134
-            },
135
-            $value
136
-        );
137
-    }
138
-
139
-    /**
140
-     * @param $dec
141
-     * @return string|null
142
-     * @see http://php.net/manual/en/function.chr.php#118804
143
-     */
144
-    protected static function unicodeChar($dec)
145
-    {
146
-        if ($dec < 0x80) {
147
-            return chr($dec);
148
-        }
149
-
150
-        if ($dec < 0x0800) {
151
-            return chr(0xC0 + ($dec >> 6))
152
-                . chr(0x80 + ($dec & 0x3f));
153
-        }
154
-
155
-        if ($dec < 0x010000) {
156
-            return chr(0xE0 + ($dec >> 12))
157
-                . chr(0x80 + (($dec >> 6) & 0x3f))
158
-                . chr(0x80 + ($dec & 0x3f));
159
-        }
160
-
161
-        if ($dec < 0x200000) {
162
-            return chr(0xF0 + ($dec >> 18))
163
-                . chr(0x80 + (($dec >> 12) & 0x3f))
164
-                . chr(0x80 + (($dec >> 6) & 0x3f))
165
-                . chr(0x80 + ($dec & 0x3f));
166
-        }
167
-
168
-        return null;
169
-    }
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
+	protected static $functionsScannerClass = 'Gettext\Utils\PhpFunctionsScanner';
46
+
47
+	/**
48
+	 * {@inheritdoc}
49
+	 * @throws Exception
50
+	 */
51
+	public static function fromString($string, Translations $translations, array $options = [])
52
+	{
53
+		static::fromStringMultiple($string, [$translations], $options);
54
+	}
55
+
56
+	/**
57
+	 * @inheritDoc
58
+	 * @throws Exception
59
+	 */
60
+	public static function fromStringMultiple($string, array $translations, array $options = [])
61
+	{
62
+		$options += static::$options;
63
+
64
+		/** @var FunctionsScanner $functions */
65
+		$functions = new static::$functionsScannerClass($string);
66
+
67
+		if ($options['extractComments'] !== false) {
68
+			$functions->enableCommentsExtraction($options['extractComments']);
69
+		}
70
+
71
+		$functions->saveGettextFunctions($translations, $options);
72
+	}
73
+
74
+	/**
75
+	 * @inheritDoc
76
+	 */
77
+	public static function fromFileMultiple($file, array $translations, array $options = [])
78
+	{
79
+		foreach (static::getFiles($file) as $file) {
80
+			$options['file'] = $file;
81
+			static::fromStringMultiple(static::readFile($file), $translations, $options);
82
+		}
83
+	}
84
+
85
+
86
+	/**
87
+	 * Decodes a T_CONSTANT_ENCAPSED_STRING string.
88
+	 *
89
+	 * @param string $value
90
+	 *
91
+	 * @return string
92
+	 */
93
+	public static function convertString($value)
94
+	{
95
+		if (strpos($value, '\\') === false) {
96
+			return substr($value, 1, -1);
97
+		}
98
+
99
+		if ($value[0] === "'") {
100
+			return strtr(substr($value, 1, -1), ['\\\\' => '\\', '\\\'' => '\'']);
101
+		}
102
+
103
+		$value = substr($value, 1, -1);
104
+
105
+		return preg_replace_callback(
106
+			'/\\\(n|r|t|v|e|f|\$|"|\\\|x[0-9A-Fa-f]{1,2}|u{[0-9a-f]{1,6}}|[0-7]{1,3})/',
107
+			function ($match) {
108
+				switch ($match[1][0]) {
109
+					case 'n':
110
+						return "\n";
111
+					case 'r':
112
+						return "\r";
113
+					case 't':
114
+						return "\t";
115
+					case 'v':
116
+						return "\v";
117
+					case 'e':
118
+						return "\e";
119
+					case 'f':
120
+						return "\f";
121
+					case '$':
122
+						return '$';
123
+					case '"':
124
+						return '"';
125
+					case '\\':
126
+						return '\\';
127
+					case 'x':
128
+						return chr(hexdec(substr($match[1], 1)));
129
+					case 'u':
130
+						return static::unicodeChar(hexdec(substr($match[1], 1)));
131
+					default:
132
+						return chr(octdec($match[1]));
133
+				}
134
+			},
135
+			$value
136
+		);
137
+	}
138
+
139
+	/**
140
+	 * @param $dec
141
+	 * @return string|null
142
+	 * @see http://php.net/manual/en/function.chr.php#118804
143
+	 */
144
+	protected static function unicodeChar($dec)
145
+	{
146
+		if ($dec < 0x80) {
147
+			return chr($dec);
148
+		}
149
+
150
+		if ($dec < 0x0800) {
151
+			return chr(0xC0 + ($dec >> 6))
152
+				. chr(0x80 + ($dec & 0x3f));
153
+		}
154
+
155
+		if ($dec < 0x010000) {
156
+			return chr(0xE0 + ($dec >> 12))
157
+				. chr(0x80 + (($dec >> 6) & 0x3f))
158
+				. chr(0x80 + ($dec & 0x3f));
159
+		}
160
+
161
+		if ($dec < 0x200000) {
162
+			return chr(0xF0 + ($dec >> 18))
163
+				. chr(0x80 + (($dec >> 12) & 0x3f))
164
+				. chr(0x80 + (($dec >> 6) & 0x3f))
165
+				. chr(0x80 + ($dec & 0x3f));
166
+		}
167
+
168
+		return null;
169
+	}
170 170
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/JsonDictionary.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -10,17 +10,17 @@
 block discarded – undo
10 10
  */
11 11
 class JsonDictionary extends Extractor implements ExtractorInterface
12 12
 {
13
-    use DictionaryTrait;
13
+	use DictionaryTrait;
14 14
 
15
-    /**
16
-     * {@inheritdoc}
17
-     */
18
-    public static function fromString($string, Translations $translations, array $options = [])
19
-    {
20
-        $messages = json_decode($string, true);
15
+	/**
16
+	 * {@inheritdoc}
17
+	 */
18
+	public static function fromString($string, Translations $translations, array $options = [])
19
+	{
20
+		$messages = json_decode($string, true);
21 21
 
22
-        if (is_array($messages)) {
23
-            static::fromArray($messages, $translations);
24
-        }
25
-    }
22
+		if (is_array($messages)) {
23
+			static::fromArray($messages, $translations);
24
+		}
25
+	}
26 26
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Mo.php 1 patch
Indentation   +117 added lines, -117 removed lines patch added patch discarded remove patch
@@ -11,121 +11,121 @@
 block discarded – undo
11 11
  */
12 12
 class Mo extends Extractor implements ExtractorInterface
13 13
 {
14
-    const MAGIC1 = -1794895138;
15
-    const MAGIC2 = -569244523;
16
-    const MAGIC3 = 2500072158;
17
-
18
-    protected static $stringReaderClass = 'Gettext\Utils\StringReader';
19
-
20
-    /**
21
-     * {@inheritdoc}
22
-     */
23
-    public static function fromString($string, Translations $translations, array $options = [])
24
-    {
25
-        /** @var StringReader $stream */
26
-        $stream = new static::$stringReaderClass($string);
27
-        $magic = static::readInt($stream, 'V');
28
-
29
-        if (($magic === static::MAGIC1) || ($magic === static::MAGIC3)) { //to make sure it works for 64-bit platforms
30
-            $byteOrder = 'V'; //low endian
31
-        } elseif ($magic === (static::MAGIC2 & 0xFFFFFFFF)) {
32
-            $byteOrder = 'N'; //big endian
33
-        } else {
34
-            throw new Exception('Not MO file');
35
-        }
36
-
37
-        static::readInt($stream, $byteOrder);
38
-
39
-        $total = static::readInt($stream, $byteOrder); //total string count
40
-        $originals = static::readInt($stream, $byteOrder); //offset of original table
41
-        $tran = static::readInt($stream, $byteOrder); //offset of translation table
42
-
43
-        $stream->seekto($originals);
44
-        $table_originals = static::readIntArray($stream, $byteOrder, $total * 2);
45
-
46
-        $stream->seekto($tran);
47
-        $table_translations = static::readIntArray($stream, $byteOrder, $total * 2);
48
-
49
-        for ($i = 0; $i < $total; ++$i) {
50
-            $next = $i * 2;
51
-
52
-            $stream->seekto($table_originals[$next + 2]);
53
-            $original = $stream->read($table_originals[$next + 1]);
54
-
55
-            $stream->seekto($table_translations[$next + 2]);
56
-            $translated = $stream->read($table_translations[$next + 1]);
57
-
58
-            if ($original === '') {
59
-                // Headers
60
-                foreach (explode("\n", $translated) as $headerLine) {
61
-                    if ($headerLine === '') {
62
-                        continue;
63
-                    }
64
-
65
-                    $headerChunks = preg_split('/:\s*/', $headerLine, 2);
66
-                    $translations->setHeader($headerChunks[0], isset($headerChunks[1]) ? $headerChunks[1] : '');
67
-                }
68
-
69
-                continue;
70
-            }
71
-
72
-            $chunks = explode("\x04", $original, 2);
73
-
74
-            if (isset($chunks[1])) {
75
-                $context = $chunks[0];
76
-                $original = $chunks[1];
77
-            } else {
78
-                $context = '';
79
-            }
80
-
81
-            $chunks = explode("\x00", $original, 2);
82
-
83
-            if (isset($chunks[1])) {
84
-                $original = $chunks[0];
85
-                $plural = $chunks[1];
86
-            } else {
87
-                $plural = '';
88
-            }
89
-
90
-            $translation = $translations->insert($context, $original, $plural);
91
-
92
-            if ($translated === '') {
93
-                continue;
94
-            }
95
-
96
-            if ($plural === '') {
97
-                $translation->setTranslation($translated);
98
-                continue;
99
-            }
100
-
101
-            $v = explode("\x00", $translated);
102
-            $translation->setTranslation(array_shift($v));
103
-            $translation->setPluralTranslations($v);
104
-        }
105
-    }
106
-
107
-    /**
108
-     * @param StringReader $stream
109
-     * @param string       $byteOrder
110
-     */
111
-    protected static function readInt(StringReader $stream, $byteOrder)
112
-    {
113
-        if (($read = $stream->read(4)) === false) {
114
-            return false;
115
-        }
116
-
117
-        $read = unpack($byteOrder, $read);
118
-
119
-        return array_shift($read);
120
-    }
121
-
122
-    /**
123
-     * @param StringReader $stream
124
-     * @param string       $byteOrder
125
-     * @param int          $count
126
-     */
127
-    protected static function readIntArray(StringReader $stream, $byteOrder, $count)
128
-    {
129
-        return unpack($byteOrder.$count, $stream->read(4 * $count));
130
-    }
14
+	const MAGIC1 = -1794895138;
15
+	const MAGIC2 = -569244523;
16
+	const MAGIC3 = 2500072158;
17
+
18
+	protected static $stringReaderClass = 'Gettext\Utils\StringReader';
19
+
20
+	/**
21
+	 * {@inheritdoc}
22
+	 */
23
+	public static function fromString($string, Translations $translations, array $options = [])
24
+	{
25
+		/** @var StringReader $stream */
26
+		$stream = new static::$stringReaderClass($string);
27
+		$magic = static::readInt($stream, 'V');
28
+
29
+		if (($magic === static::MAGIC1) || ($magic === static::MAGIC3)) { //to make sure it works for 64-bit platforms
30
+			$byteOrder = 'V'; //low endian
31
+		} elseif ($magic === (static::MAGIC2 & 0xFFFFFFFF)) {
32
+			$byteOrder = 'N'; //big endian
33
+		} else {
34
+			throw new Exception('Not MO file');
35
+		}
36
+
37
+		static::readInt($stream, $byteOrder);
38
+
39
+		$total = static::readInt($stream, $byteOrder); //total string count
40
+		$originals = static::readInt($stream, $byteOrder); //offset of original table
41
+		$tran = static::readInt($stream, $byteOrder); //offset of translation table
42
+
43
+		$stream->seekto($originals);
44
+		$table_originals = static::readIntArray($stream, $byteOrder, $total * 2);
45
+
46
+		$stream->seekto($tran);
47
+		$table_translations = static::readIntArray($stream, $byteOrder, $total * 2);
48
+
49
+		for ($i = 0; $i < $total; ++$i) {
50
+			$next = $i * 2;
51
+
52
+			$stream->seekto($table_originals[$next + 2]);
53
+			$original = $stream->read($table_originals[$next + 1]);
54
+
55
+			$stream->seekto($table_translations[$next + 2]);
56
+			$translated = $stream->read($table_translations[$next + 1]);
57
+
58
+			if ($original === '') {
59
+				// Headers
60
+				foreach (explode("\n", $translated) as $headerLine) {
61
+					if ($headerLine === '') {
62
+						continue;
63
+					}
64
+
65
+					$headerChunks = preg_split('/:\s*/', $headerLine, 2);
66
+					$translations->setHeader($headerChunks[0], isset($headerChunks[1]) ? $headerChunks[1] : '');
67
+				}
68
+
69
+				continue;
70
+			}
71
+
72
+			$chunks = explode("\x04", $original, 2);
73
+
74
+			if (isset($chunks[1])) {
75
+				$context = $chunks[0];
76
+				$original = $chunks[1];
77
+			} else {
78
+				$context = '';
79
+			}
80
+
81
+			$chunks = explode("\x00", $original, 2);
82
+
83
+			if (isset($chunks[1])) {
84
+				$original = $chunks[0];
85
+				$plural = $chunks[1];
86
+			} else {
87
+				$plural = '';
88
+			}
89
+
90
+			$translation = $translations->insert($context, $original, $plural);
91
+
92
+			if ($translated === '') {
93
+				continue;
94
+			}
95
+
96
+			if ($plural === '') {
97
+				$translation->setTranslation($translated);
98
+				continue;
99
+			}
100
+
101
+			$v = explode("\x00", $translated);
102
+			$translation->setTranslation(array_shift($v));
103
+			$translation->setPluralTranslations($v);
104
+		}
105
+	}
106
+
107
+	/**
108
+	 * @param StringReader $stream
109
+	 * @param string       $byteOrder
110
+	 */
111
+	protected static function readInt(StringReader $stream, $byteOrder)
112
+	{
113
+		if (($read = $stream->read(4)) === false) {
114
+			return false;
115
+		}
116
+
117
+		$read = unpack($byteOrder, $read);
118
+
119
+		return array_shift($read);
120
+	}
121
+
122
+	/**
123
+	 * @param StringReader $stream
124
+	 * @param string       $byteOrder
125
+	 * @param int          $count
126
+	 */
127
+	protected static function readIntArray(StringReader $stream, $byteOrder, $count)
128
+	{
129
+		return unpack($byteOrder.$count, $stream->read(4 * $count));
130
+	}
131 131
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Jed.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -9,47 +9,47 @@
 block discarded – undo
9 9
  */
10 10
 class Jed extends Extractor implements ExtractorInterface
11 11
 {
12
-    /**
13
-     * {@inheritdoc}
14
-     */
15
-    public static function fromString($string, Translations $translations, array $options = [])
16
-    {
17
-        static::extract(json_decode($string, true), $translations);
18
-    }
19
-
20
-    /**
21
-     * Handle an array of translations and append to the Translations instance.
22
-     *
23
-     * @param array        $content
24
-     * @param Translations $translations
25
-     */
26
-    public static function extract(array $content, Translations $translations)
27
-    {
28
-        $messages = current($content);
29
-        $headers = isset($messages['']) ? $messages[''] : null;
30
-        unset($messages['']);
31
-
32
-        if (!empty($headers['domain'])) {
33
-            $translations->setDomain($headers['domain']);
34
-        }
35
-
36
-        if (!empty($headers['lang'])) {
37
-            $translations->setLanguage($headers['lang']);
38
-        }
39
-
40
-        if (!empty($headers['plural-forms'])) {
41
-            $translations->setHeader(Translations::HEADER_PLURAL, $headers['plural-forms']);
42
-        }
43
-
44
-        $context_glue = '\u0004';
45
-
46
-        foreach ($messages as $key => $translation) {
47
-            $key = explode($context_glue, $key);
48
-            $context = isset($key[1]) ? array_shift($key) : '';
49
-
50
-            $translations->insert($context, array_shift($key))
51
-                ->setTranslation(array_shift($translation))
52
-                ->setPluralTranslations($translation);
53
-        }
54
-    }
12
+	/**
13
+	 * {@inheritdoc}
14
+	 */
15
+	public static function fromString($string, Translations $translations, array $options = [])
16
+	{
17
+		static::extract(json_decode($string, true), $translations);
18
+	}
19
+
20
+	/**
21
+	 * Handle an array of translations and append to the Translations instance.
22
+	 *
23
+	 * @param array        $content
24
+	 * @param Translations $translations
25
+	 */
26
+	public static function extract(array $content, Translations $translations)
27
+	{
28
+		$messages = current($content);
29
+		$headers = isset($messages['']) ? $messages[''] : null;
30
+		unset($messages['']);
31
+
32
+		if (!empty($headers['domain'])) {
33
+			$translations->setDomain($headers['domain']);
34
+		}
35
+
36
+		if (!empty($headers['lang'])) {
37
+			$translations->setLanguage($headers['lang']);
38
+		}
39
+
40
+		if (!empty($headers['plural-forms'])) {
41
+			$translations->setHeader(Translations::HEADER_PLURAL, $headers['plural-forms']);
42
+		}
43
+
44
+		$context_glue = '\u0004';
45
+
46
+		foreach ($messages as $key => $translation) {
47
+			$key = explode($context_glue, $key);
48
+			$context = isset($key[1]) ? array_shift($key) : '';
49
+
50
+			$translations->insert($context, array_shift($key))
51
+				->setTranslation(array_shift($translation))
52
+				->setPluralTranslations($translation);
53
+		}
54
+	}
55 55
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Po.php 1 patch
Indentation   +201 added lines, -201 removed lines patch added patch discarded remove patch
@@ -11,205 +11,205 @@
 block discarded – undo
11 11
  */
12 12
 class Po extends Extractor implements ExtractorInterface
13 13
 {
14
-    use HeadersExtractorTrait;
15
-
16
-    /**
17
-     * Parses a .po file and append the translations found in the Translations instance.
18
-     *
19
-     * {@inheritdoc}
20
-     */
21
-    public static function fromString($string, Translations $translations, array $options = [])
22
-    {
23
-        $lines = explode("\n", $string);
24
-        $i = 0;
25
-
26
-        $translation = $translations->createNewTranslation('', '');
27
-
28
-        for ($n = count($lines); $i < $n; ++$i) {
29
-            $line = trim($lines[$i]);
30
-            $line = static::fixMultiLines($line, $lines, $i);
31
-
32
-            if ($line === '') {
33
-                if ($translation->is('', '')) {
34
-                    static::extractHeaders($translation->getTranslation(), $translations);
35
-                } elseif ($translation->hasOriginal()) {
36
-                    $translations[] = $translation;
37
-                }
38
-
39
-                $translation = $translations->createNewTranslation('', '');
40
-                continue;
41
-            }
42
-
43
-            $splitLine = preg_split('/\s+/', $line, 2);
44
-            $key = $splitLine[0];
45
-            $data = isset($splitLine[1]) ? $splitLine[1] : '';
46
-
47
-            if ($key === '#~') {
48
-                $translation->setDisabled(true);
49
-
50
-                $splitLine = preg_split('/\s+/', $data, 2);
51
-                $key = $splitLine[0];
52
-                $data = isset($splitLine[1]) ? $splitLine[1] : '';
53
-            }
54
-
55
-            switch ($key) {
56
-                case '#':
57
-                    $translation->addComment($data);
58
-                    $append = null;
59
-                    break;
60
-
61
-                case '#.':
62
-                    $translation->addExtractedComment($data);
63
-                    $append = null;
64
-                    break;
65
-
66
-                case '#,':
67
-                    foreach (array_map('trim', explode(',', trim($data))) as $value) {
68
-                        $translation->addFlag($value);
69
-                    }
70
-                    $append = null;
71
-                    break;
72
-
73
-                case '#:':
74
-                    foreach (preg_split('/\s+/', trim($data)) as $value) {
75
-                        if (preg_match('/^(.+)(:(\d*))?$/U', $value, $matches)) {
76
-                            $translation->addReference($matches[1], isset($matches[3]) ? $matches[3] : null);
77
-                        }
78
-                    }
79
-                    $append = null;
80
-                    break;
81
-
82
-                case 'msgctxt':
83
-                    $translation = $translation->getClone(static::convertString($data));
84
-                    $append = 'Context';
85
-                    break;
86
-
87
-                case 'msgid':
88
-                    $translation = $translation->getClone(null, static::convertString($data));
89
-                    $append = 'Original';
90
-                    break;
91
-
92
-                case 'msgid_plural':
93
-                    $translation->setPlural(static::convertString($data));
94
-                    $append = 'Plural';
95
-                    break;
96
-
97
-                case 'msgstr':
98
-                case 'msgstr[0]':
99
-                    $translation->setTranslation(static::convertString($data));
100
-                    $append = 'Translation';
101
-                    break;
102
-
103
-                case 'msgstr[1]':
104
-                    $translation->setPluralTranslations([static::convertString($data)]);
105
-                    $append = 'PluralTranslation';
106
-                    break;
107
-
108
-                default:
109
-                    if (strpos($key, 'msgstr[') === 0) {
110
-                        $p = $translation->getPluralTranslations();
111
-                        $p[] = static::convertString($data);
112
-
113
-                        $translation->setPluralTranslations($p);
114
-                        $append = 'PluralTranslation';
115
-                        break;
116
-                    }
117
-
118
-                    if (isset($append)) {
119
-                        if ($append === 'Context') {
120
-                            $translation = $translation->getClone($translation->getContext()
121
-                                ."\n"
122
-                                .static::convertString($data));
123
-                            break;
124
-                        }
125
-
126
-                        if ($append === 'Original') {
127
-                            $translation = $translation->getClone(null, $translation->getOriginal()
128
-                                ."\n"
129
-                                .static::convertString($data));
130
-                            break;
131
-                        }
132
-
133
-                        if ($append === 'PluralTranslation') {
134
-                            $p = $translation->getPluralTranslations();
135
-                            $p[] = array_pop($p)."\n".static::convertString($data);
136
-                            $translation->setPluralTranslations($p);
137
-                            break;
138
-                        }
139
-
140
-                        $getMethod = 'get'.$append;
141
-                        $setMethod = 'set'.$append;
142
-                        $translation->$setMethod($translation->$getMethod()."\n".static::convertString($data));
143
-                    }
144
-                    break;
145
-            }
146
-        }
147
-
148
-        if ($translation->hasOriginal() && !in_array($translation, iterator_to_array($translations))) {
149
-            $translations[] = $translation;
150
-        }
151
-    }
152
-
153
-    /**
154
-     * Gets one string from multiline strings.
155
-     *
156
-     * @param string $line
157
-     * @param array  $lines
158
-     * @param int    &$i
159
-     *
160
-     * @return string
161
-     */
162
-    protected static function fixMultiLines($line, array $lines, &$i)
163
-    {
164
-        for ($j = $i, $t = count($lines); $j < $t; ++$j) {
165
-            if (substr($line, -1, 1) == '"' && isset($lines[$j + 1])) {
166
-                $nextLine = trim($lines[$j + 1]);
167
-                if (substr($nextLine, 0, 1) == '"') {
168
-                    $line = substr($line, 0, -1).substr($nextLine, 1);
169
-                    continue;
170
-                }
171
-                if (substr($nextLine, 0, 4) == '#~ "') {
172
-                    $line = substr($line, 0, -1).substr($nextLine, 4);
173
-                    continue;
174
-                }
175
-            }
176
-            $i = $j;
177
-            break;
178
-        }
179
-
180
-        return $line;
181
-    }
182
-
183
-    /**
184
-     * Convert a string from its PO representation.
185
-     *
186
-     * @param string $value
187
-     *
188
-     * @return string
189
-     */
190
-    public static function convertString($value)
191
-    {
192
-        if (!$value) {
193
-            return '';
194
-        }
195
-
196
-        if ($value[0] === '"') {
197
-            $value = substr($value, 1, -1);
198
-        }
199
-
200
-        return strtr(
201
-            $value,
202
-            [
203
-                '\\\\' => '\\',
204
-                '\\a' => "\x07",
205
-                '\\b' => "\x08",
206
-                '\\t' => "\t",
207
-                '\\n' => "\n",
208
-                '\\v' => "\x0b",
209
-                '\\f' => "\x0c",
210
-                '\\r' => "\r",
211
-                '\\"' => '"',
212
-            ]
213
-        );
214
-    }
14
+	use HeadersExtractorTrait;
15
+
16
+	/**
17
+	 * Parses a .po file and append the translations found in the Translations instance.
18
+	 *
19
+	 * {@inheritdoc}
20
+	 */
21
+	public static function fromString($string, Translations $translations, array $options = [])
22
+	{
23
+		$lines = explode("\n", $string);
24
+		$i = 0;
25
+
26
+		$translation = $translations->createNewTranslation('', '');
27
+
28
+		for ($n = count($lines); $i < $n; ++$i) {
29
+			$line = trim($lines[$i]);
30
+			$line = static::fixMultiLines($line, $lines, $i);
31
+
32
+			if ($line === '') {
33
+				if ($translation->is('', '')) {
34
+					static::extractHeaders($translation->getTranslation(), $translations);
35
+				} elseif ($translation->hasOriginal()) {
36
+					$translations[] = $translation;
37
+				}
38
+
39
+				$translation = $translations->createNewTranslation('', '');
40
+				continue;
41
+			}
42
+
43
+			$splitLine = preg_split('/\s+/', $line, 2);
44
+			$key = $splitLine[0];
45
+			$data = isset($splitLine[1]) ? $splitLine[1] : '';
46
+
47
+			if ($key === '#~') {
48
+				$translation->setDisabled(true);
49
+
50
+				$splitLine = preg_split('/\s+/', $data, 2);
51
+				$key = $splitLine[0];
52
+				$data = isset($splitLine[1]) ? $splitLine[1] : '';
53
+			}
54
+
55
+			switch ($key) {
56
+				case '#':
57
+					$translation->addComment($data);
58
+					$append = null;
59
+					break;
60
+
61
+				case '#.':
62
+					$translation->addExtractedComment($data);
63
+					$append = null;
64
+					break;
65
+
66
+				case '#,':
67
+					foreach (array_map('trim', explode(',', trim($data))) as $value) {
68
+						$translation->addFlag($value);
69
+					}
70
+					$append = null;
71
+					break;
72
+
73
+				case '#:':
74
+					foreach (preg_split('/\s+/', trim($data)) as $value) {
75
+						if (preg_match('/^(.+)(:(\d*))?$/U', $value, $matches)) {
76
+							$translation->addReference($matches[1], isset($matches[3]) ? $matches[3] : null);
77
+						}
78
+					}
79
+					$append = null;
80
+					break;
81
+
82
+				case 'msgctxt':
83
+					$translation = $translation->getClone(static::convertString($data));
84
+					$append = 'Context';
85
+					break;
86
+
87
+				case 'msgid':
88
+					$translation = $translation->getClone(null, static::convertString($data));
89
+					$append = 'Original';
90
+					break;
91
+
92
+				case 'msgid_plural':
93
+					$translation->setPlural(static::convertString($data));
94
+					$append = 'Plural';
95
+					break;
96
+
97
+				case 'msgstr':
98
+				case 'msgstr[0]':
99
+					$translation->setTranslation(static::convertString($data));
100
+					$append = 'Translation';
101
+					break;
102
+
103
+				case 'msgstr[1]':
104
+					$translation->setPluralTranslations([static::convertString($data)]);
105
+					$append = 'PluralTranslation';
106
+					break;
107
+
108
+				default:
109
+					if (strpos($key, 'msgstr[') === 0) {
110
+						$p = $translation->getPluralTranslations();
111
+						$p[] = static::convertString($data);
112
+
113
+						$translation->setPluralTranslations($p);
114
+						$append = 'PluralTranslation';
115
+						break;
116
+					}
117
+
118
+					if (isset($append)) {
119
+						if ($append === 'Context') {
120
+							$translation = $translation->getClone($translation->getContext()
121
+								."\n"
122
+								.static::convertString($data));
123
+							break;
124
+						}
125
+
126
+						if ($append === 'Original') {
127
+							$translation = $translation->getClone(null, $translation->getOriginal()
128
+								."\n"
129
+								.static::convertString($data));
130
+							break;
131
+						}
132
+
133
+						if ($append === 'PluralTranslation') {
134
+							$p = $translation->getPluralTranslations();
135
+							$p[] = array_pop($p)."\n".static::convertString($data);
136
+							$translation->setPluralTranslations($p);
137
+							break;
138
+						}
139
+
140
+						$getMethod = 'get'.$append;
141
+						$setMethod = 'set'.$append;
142
+						$translation->$setMethod($translation->$getMethod()."\n".static::convertString($data));
143
+					}
144
+					break;
145
+			}
146
+		}
147
+
148
+		if ($translation->hasOriginal() && !in_array($translation, iterator_to_array($translations))) {
149
+			$translations[] = $translation;
150
+		}
151
+	}
152
+
153
+	/**
154
+	 * Gets one string from multiline strings.
155
+	 *
156
+	 * @param string $line
157
+	 * @param array  $lines
158
+	 * @param int    &$i
159
+	 *
160
+	 * @return string
161
+	 */
162
+	protected static function fixMultiLines($line, array $lines, &$i)
163
+	{
164
+		for ($j = $i, $t = count($lines); $j < $t; ++$j) {
165
+			if (substr($line, -1, 1) == '"' && isset($lines[$j + 1])) {
166
+				$nextLine = trim($lines[$j + 1]);
167
+				if (substr($nextLine, 0, 1) == '"') {
168
+					$line = substr($line, 0, -1).substr($nextLine, 1);
169
+					continue;
170
+				}
171
+				if (substr($nextLine, 0, 4) == '#~ "') {
172
+					$line = substr($line, 0, -1).substr($nextLine, 4);
173
+					continue;
174
+				}
175
+			}
176
+			$i = $j;
177
+			break;
178
+		}
179
+
180
+		return $line;
181
+	}
182
+
183
+	/**
184
+	 * Convert a string from its PO representation.
185
+	 *
186
+	 * @param string $value
187
+	 *
188
+	 * @return string
189
+	 */
190
+	public static function convertString($value)
191
+	{
192
+		if (!$value) {
193
+			return '';
194
+		}
195
+
196
+		if ($value[0] === '"') {
197
+			$value = substr($value, 1, -1);
198
+		}
199
+
200
+		return strtr(
201
+			$value,
202
+			[
203
+				'\\\\' => '\\',
204
+				'\\a' => "\x07",
205
+				'\\b' => "\x08",
206
+				'\\t' => "\t",
207
+				'\\n' => "\n",
208
+				'\\v' => "\x0b",
209
+				'\\f' => "\x0c",
210
+				'\\r' => "\r",
211
+				'\\"' => '"',
212
+			]
213
+		);
214
+	}
215 215
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/VueJs.php 1 patch
Indentation   +404 added lines, -404 removed lines patch added patch discarded remove patch
@@ -16,408 +16,408 @@
 block discarded – undo
16 16
  */
17 17
 class VueJs extends Extractor implements ExtractorInterface, ExtractorMultiInterface
18 18
 {
19
-    public static $options = [
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
-    protected static $functionsScannerClass = 'Gettext\Utils\JsFunctionsScanner';
45
-
46
-    /**
47
-     * @inheritDoc
48
-     * @throws Exception
49
-     */
50
-    public static function fromFileMultiple($file, array $translations, array $options = [])
51
-    {
52
-        foreach (static::getFiles($file) as $file) {
53
-            $options['file'] = $file;
54
-            static::fromStringMultiple(static::readFile($file), $translations, $options);
55
-        }
56
-    }
57
-
58
-    /**
59
-     * @inheritdoc
60
-     * @throws Exception
61
-     */
62
-    public static function fromString($string, Translations $translations, array $options = [])
63
-    {
64
-        static::fromStringMultiple($string, [$translations], $options);
65
-    }
66
-
67
-    /**
68
-     * @inheritDoc
69
-     * @throws Exception
70
-     */
71
-    public static function fromStringMultiple($string, array $translations, array $options = [])
72
-    {
73
-        $options += static::$options;
74
-        $options += [
75
-            // HTML attribute prefixes we parse as JS which could contain translations (are JS expressions)
76
-            'attributePrefixes' => [
77
-                ':',
78
-                'v-bind:',
79
-                'v-on:',
80
-                'v-text',
81
-            ],
82
-            // HTML Tags to parse
83
-            'tagNames' => [
84
-                'translate',
85
-            ],
86
-            // HTML tags to parse when attribute exists
87
-            'tagAttributes' => [
88
-                'v-translate',
89
-            ],
90
-            // Comments
91
-            'commentAttributes' => [
92
-                'translate-comment',
93
-            ],
94
-            'contextAttributes' => [
95
-                'translate-context',
96
-            ],
97
-            // Attribute with plural content
98
-            'pluralAttributes' => [
99
-                'translate-plural',
100
-            ],
101
-        ];
102
-
103
-        // Ok, this is the weirdest hack, but let me explain:
104
-        // On Linux (Mac is fine), when converting HTML to DOM, new lines get trimmed after the first tag.
105
-        // So if there are new lines between <template> and next element, they are lost
106
-        // So we insert a "." which is a text node, and it will prevent that newlines are stripped between elements.
107
-        // Same thing happens between template and script tag.
108
-        $string = str_replace('<template>', '<template>.', $string);
109
-        $string = str_replace('</template>', '</template>.', $string);
110
-
111
-        // Normalize newlines
112
-        $string = str_replace(["\r\n", "\n\r", "\r"], "\n", $string);
113
-
114
-        // VueJS files are valid HTML files, we will operate with the DOM here
115
-        $dom = static::convertHtmlToDom($string);
116
-
117
-        $script = static::extractScriptTag($string);
118
-
119
-        // Parse the script part as a regular JS code
120
-        if ($script) {
121
-            $scriptLineNumber = $dom->getElementsByTagName('script')->item(0)->getLineNo();
122
-            static::getScriptTranslationsFromString(
123
-                $script,
124
-                $translations,
125
-                $options,
126
-                $scriptLineNumber - 1
127
-            );
128
-        }
129
-
130
-        // Template part is parsed separately, all variables will be extracted
131
-        // and handled as a regular JS code
132
-        $template = $dom->getElementsByTagName('template')->item(0);
133
-        if ($template) {
134
-            static::getTemplateTranslations(
135
-                $template,
136
-                $translations,
137
-                $options,
138
-                $template->getLineNo() - 1
139
-            );
140
-        }
141
-    }
142
-
143
-    /**
144
-     * Extracts script tag contents using regex instead of DOM operations.
145
-     * If we parse using DOM, some contents may change, for example, tags within strings will be stripped
146
-     *
147
-     * @param $string
148
-     * @return bool|string
149
-     */
150
-    protected static function extractScriptTag($string)
151
-    {
152
-        if (preg_match('#<\s*?script\b[^>]*>(.*?)</script\b[^>]*>#s', $string, $matches)) {
153
-            return $matches[1];
154
-        }
155
-
156
-        return '';
157
-    }
158
-
159
-    /**
160
-     * @param string $html
161
-     * @return DOMDocument
162
-     */
163
-    protected static function convertHtmlToDom($html)
164
-    {
165
-        $dom = new DOMDocument;
166
-
167
-        libxml_use_internal_errors(true);
168
-
169
-        // Prepend xml encoding so DOMDocument document handles UTF8 correctly.
170
-        // Assuming that vue template files will not have any xml encoding tags, because duplicate tags may be ignored.
171
-        $dom->loadHTML('<?xml encoding="utf-8"?>' . $html);
172
-
173
-        libxml_clear_errors();
174
-
175
-        return $dom;
176
-    }
177
-
178
-    /**
179
-     * Extract translations from script part
180
-     *
181
-     * @param string $scriptContents Only script tag contents, not the whole template
182
-     * @param Translations|Translations[] $translations One or multiple domain Translation objects
183
-     * @param array $options
184
-     * @param int $lineOffset Number of lines the script is offset in the vue template file
185
-     * @throws Exception
186
-     */
187
-    protected static function getScriptTranslationsFromString(
188
-        $scriptContents,
189
-        $translations,
190
-        array $options = [],
191
-        $lineOffset = 0
192
-    ) {
193
-        /** @var FunctionsScanner $functions */
194
-        $functions = new static::$functionsScannerClass($scriptContents);
195
-        $options['lineOffset'] = $lineOffset;
196
-        $functions->saveGettextFunctions($translations, $options);
197
-    }
198
-
199
-    /**
200
-     * Parse template to extract all translations (element content and dynamic element attributes)
201
-     *
202
-     * @param DOMNode $dom
203
-     * @param Translations|Translations[] $translations One or multiple domain Translation objects
204
-     * @param array $options
205
-     * @param int $lineOffset Line number where the template part starts in the vue file
206
-     * @throws Exception
207
-     */
208
-    protected static function getTemplateTranslations(
209
-        DOMNode $dom,
210
-        $translations,
211
-        array $options,
212
-        $lineOffset = 0
213
-    ) {
214
-        // Build a JS string from all template attribute expressions
215
-        $fakeAttributeJs = static::getTemplateAttributeFakeJs($options, $dom);
216
-
217
-        // 1 line offset is necessary because parent template element was ignored when converting to DOM
218
-        static::getScriptTranslationsFromString($fakeAttributeJs, $translations, $options, $lineOffset);
219
-
220
-        // Build a JS string from template element content expressions
221
-        $fakeTemplateJs = static::getTemplateFakeJs($dom);
222
-        static::getScriptTranslationsFromString($fakeTemplateJs, $translations, $options, $lineOffset);
223
-
224
-        static::getTagTranslations($options, $dom, $translations);
225
-    }
226
-
227
-    /**
228
-     * @param array $options
229
-     * @param DOMNode $dom
230
-     * @param Translations|Translations[] $translations
231
-     */
232
-    protected static function getTagTranslations(array $options, DOMNode $dom, $translations)
233
-    {
234
-        // Since tag scanning does not support domains, we always use the first translation given
235
-        $translations = is_array($translations) ? reset($translations) : $translations;
236
-
237
-        $children = $dom->childNodes;
238
-        for ($i = 0; $i < $children->length; $i++) {
239
-            $node = $children->item($i);
240
-
241
-            if (!($node instanceof DOMElement)) {
242
-                continue;
243
-            }
244
-
245
-            $translatable = false;
246
-
247
-            if (in_array($node->tagName, $options['tagNames'], true)) {
248
-                $translatable = true;
249
-            }
250
-
251
-            $attrList = $node->attributes;
252
-            $context = null;
253
-            $plural = "";
254
-            $comment = null;
255
-
256
-            for ($j = 0; $j < $attrList->length; $j++) {
257
-                /** @var DOMAttr $domAttr */
258
-                $domAttr = $attrList->item($j);
259
-                // Check if this is a dynamic vue attribute
260
-                if (in_array($domAttr->name, $options['tagAttributes'])) {
261
-                    $translatable = true;
262
-                }
263
-                if (in_array($domAttr->name, $options['contextAttributes'])) {
264
-                    $context = $domAttr->value;
265
-                }
266
-                if (in_array($domAttr->name, $options['pluralAttributes'])) {
267
-                    $plural = $domAttr->value;
268
-                }
269
-                if (in_array($domAttr->name, $options['commentAttributes'])) {
270
-                    $comment = $domAttr->value;
271
-                }
272
-            }
273
-
274
-            if ($translatable) {
275
-                $translation = $translations->insert($context, trim($node->textContent), $plural);
276
-                $translation->addReference($options['file'], $node->getLineNo());
277
-                if ($comment) {
278
-                    $translation->addExtractedComment($comment);
279
-                }
280
-            }
281
-
282
-            if ($node->hasChildNodes()) {
283
-                static::getTagTranslations($options, $node, $translations);
284
-            }
285
-        }
286
-    }
287
-
288
-    /**
289
-     * Extract JS expressions from element attribute bindings (excluding text within elements)
290
-     * For example: <span :title="__('extract this')"> skip element content </span>
291
-     *
292
-     * @param array $options
293
-     * @param DOMNode $dom
294
-     * @return string JS code
295
-     */
296
-    protected static function getTemplateAttributeFakeJs(array $options, DOMNode $dom)
297
-    {
298
-        $expressionsByLine = static::getVueAttributeExpressions($options['attributePrefixes'], $dom);
299
-
300
-        if (empty($expressionsByLine)) {
301
-            return '';
302
-        }
303
-
304
-        $maxLines = max(array_keys($expressionsByLine));
305
-        $fakeJs = '';
306
-
307
-        for ($line = 1; $line <= $maxLines; $line++) {
308
-            if (isset($expressionsByLine[$line])) {
309
-                $fakeJs .= implode("; ", $expressionsByLine[$line]);
310
-            }
311
-            $fakeJs .= "\n";
312
-        }
313
-
314
-        return $fakeJs;
315
-    }
316
-
317
-    /**
318
-     * Loop DOM element recursively and parse out all dynamic vue attributes which are basically JS expressions
319
-     *
320
-     * @param array $attributePrefixes List of attribute prefixes we parse as JS (may contain translations)
321
-     * @param DOMNode $dom
322
-     * @param array $expressionByLine [lineNumber => [jsExpression, ..], ..]
323
-     * @return array [lineNumber => [jsExpression, ..], ..]
324
-     */
325
-    protected static function getVueAttributeExpressions(
326
-        array $attributePrefixes,
327
-        DOMNode $dom,
328
-        array &$expressionByLine = []
329
-    ) {
330
-        $children = $dom->childNodes;
331
-
332
-        for ($i = 0; $i < $children->length; $i++) {
333
-            $node = $children->item($i);
334
-
335
-            if (!($node instanceof DOMElement)) {
336
-                continue;
337
-            }
338
-            $attrList = $node->attributes;
339
-
340
-            for ($j = 0; $j < $attrList->length; $j++) {
341
-                /** @var DOMAttr $domAttr */
342
-                $domAttr = $attrList->item($j);
343
-
344
-                // Check if this is a dynamic vue attribute
345
-                if (static::isAttributeMatching($domAttr->name, $attributePrefixes)) {
346
-                    $line = $domAttr->getLineNo();
347
-                    $expressionByLine += [$line => []];
348
-                    $expressionByLine[$line][] = $domAttr->value;
349
-                }
350
-            }
351
-
352
-            if ($node->hasChildNodes()) {
353
-                $expressionByLine = static::getVueAttributeExpressions($attributePrefixes, $node, $expressionByLine);
354
-            }
355
-        }
356
-
357
-        return $expressionByLine;
358
-    }
359
-
360
-    /**
361
-     * Check if this attribute name should be parsed for translations
362
-     *
363
-     * @param string $attributeName
364
-     * @param string[] $attributePrefixes
365
-     * @return bool
366
-     */
367
-    protected static function isAttributeMatching($attributeName, $attributePrefixes)
368
-    {
369
-        foreach ($attributePrefixes as $prefix) {
370
-            if (strpos($attributeName, $prefix) === 0) {
371
-                return true;
372
-            }
373
-        }
374
-        return false;
375
-    }
376
-
377
-    /**
378
-     * Extract JS expressions from within template elements (excluding attributes)
379
-     * For example: <span :title="skip attributes"> {{__("extract element content")}} </span>
380
-     *
381
-     * @param DOMNode $dom
382
-     * @return string JS code
383
-     */
384
-    protected static function getTemplateFakeJs(DOMNode $dom)
385
-    {
386
-        $fakeJs = '';
387
-        $lines = explode("\n", $dom->textContent);
388
-
389
-        // Build a fake JS file from template by extracting JS expressions within each template line
390
-        foreach ($lines as $line) {
391
-            $expressionMatched = static::parseOneTemplateLine($line);
392
-
393
-            $fakeJs .= implode("; ", $expressionMatched) . "\n";
394
-        }
395
-
396
-        return $fakeJs;
397
-    }
398
-
399
-    /**
400
-     * Match JS expressions in a template line
401
-     *
402
-     * @param string $line
403
-     * @return string[]
404
-     */
405
-    protected static function parseOneTemplateLine($line)
406
-    {
407
-        $line = trim($line);
408
-
409
-        if (!$line) {
410
-            return [];
411
-        }
412
-
413
-        $regex = '#\{\{(.*?)\}\}#';
414
-
415
-        preg_match_all($regex, $line, $matches);
416
-
417
-        $matched = array_map(function ($v) {
418
-            return trim($v, '\'"{}');
419
-        }, $matches[1]);
420
-
421
-        return $matched;
422
-    }
19
+	public static $options = [
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
+	protected static $functionsScannerClass = 'Gettext\Utils\JsFunctionsScanner';
45
+
46
+	/**
47
+	 * @inheritDoc
48
+	 * @throws Exception
49
+	 */
50
+	public static function fromFileMultiple($file, array $translations, array $options = [])
51
+	{
52
+		foreach (static::getFiles($file) as $file) {
53
+			$options['file'] = $file;
54
+			static::fromStringMultiple(static::readFile($file), $translations, $options);
55
+		}
56
+	}
57
+
58
+	/**
59
+	 * @inheritdoc
60
+	 * @throws Exception
61
+	 */
62
+	public static function fromString($string, Translations $translations, array $options = [])
63
+	{
64
+		static::fromStringMultiple($string, [$translations], $options);
65
+	}
66
+
67
+	/**
68
+	 * @inheritDoc
69
+	 * @throws Exception
70
+	 */
71
+	public static function fromStringMultiple($string, array $translations, array $options = [])
72
+	{
73
+		$options += static::$options;
74
+		$options += [
75
+			// HTML attribute prefixes we parse as JS which could contain translations (are JS expressions)
76
+			'attributePrefixes' => [
77
+				':',
78
+				'v-bind:',
79
+				'v-on:',
80
+				'v-text',
81
+			],
82
+			// HTML Tags to parse
83
+			'tagNames' => [
84
+				'translate',
85
+			],
86
+			// HTML tags to parse when attribute exists
87
+			'tagAttributes' => [
88
+				'v-translate',
89
+			],
90
+			// Comments
91
+			'commentAttributes' => [
92
+				'translate-comment',
93
+			],
94
+			'contextAttributes' => [
95
+				'translate-context',
96
+			],
97
+			// Attribute with plural content
98
+			'pluralAttributes' => [
99
+				'translate-plural',
100
+			],
101
+		];
102
+
103
+		// Ok, this is the weirdest hack, but let me explain:
104
+		// On Linux (Mac is fine), when converting HTML to DOM, new lines get trimmed after the first tag.
105
+		// So if there are new lines between <template> and next element, they are lost
106
+		// So we insert a "." which is a text node, and it will prevent that newlines are stripped between elements.
107
+		// Same thing happens between template and script tag.
108
+		$string = str_replace('<template>', '<template>.', $string);
109
+		$string = str_replace('</template>', '</template>.', $string);
110
+
111
+		// Normalize newlines
112
+		$string = str_replace(["\r\n", "\n\r", "\r"], "\n", $string);
113
+
114
+		// VueJS files are valid HTML files, we will operate with the DOM here
115
+		$dom = static::convertHtmlToDom($string);
116
+
117
+		$script = static::extractScriptTag($string);
118
+
119
+		// Parse the script part as a regular JS code
120
+		if ($script) {
121
+			$scriptLineNumber = $dom->getElementsByTagName('script')->item(0)->getLineNo();
122
+			static::getScriptTranslationsFromString(
123
+				$script,
124
+				$translations,
125
+				$options,
126
+				$scriptLineNumber - 1
127
+			);
128
+		}
129
+
130
+		// Template part is parsed separately, all variables will be extracted
131
+		// and handled as a regular JS code
132
+		$template = $dom->getElementsByTagName('template')->item(0);
133
+		if ($template) {
134
+			static::getTemplateTranslations(
135
+				$template,
136
+				$translations,
137
+				$options,
138
+				$template->getLineNo() - 1
139
+			);
140
+		}
141
+	}
142
+
143
+	/**
144
+	 * Extracts script tag contents using regex instead of DOM operations.
145
+	 * If we parse using DOM, some contents may change, for example, tags within strings will be stripped
146
+	 *
147
+	 * @param $string
148
+	 * @return bool|string
149
+	 */
150
+	protected static function extractScriptTag($string)
151
+	{
152
+		if (preg_match('#<\s*?script\b[^>]*>(.*?)</script\b[^>]*>#s', $string, $matches)) {
153
+			return $matches[1];
154
+		}
155
+
156
+		return '';
157
+	}
158
+
159
+	/**
160
+	 * @param string $html
161
+	 * @return DOMDocument
162
+	 */
163
+	protected static function convertHtmlToDom($html)
164
+	{
165
+		$dom = new DOMDocument;
166
+
167
+		libxml_use_internal_errors(true);
168
+
169
+		// Prepend xml encoding so DOMDocument document handles UTF8 correctly.
170
+		// Assuming that vue template files will not have any xml encoding tags, because duplicate tags may be ignored.
171
+		$dom->loadHTML('<?xml encoding="utf-8"?>' . $html);
172
+
173
+		libxml_clear_errors();
174
+
175
+		return $dom;
176
+	}
177
+
178
+	/**
179
+	 * Extract translations from script part
180
+	 *
181
+	 * @param string $scriptContents Only script tag contents, not the whole template
182
+	 * @param Translations|Translations[] $translations One or multiple domain Translation objects
183
+	 * @param array $options
184
+	 * @param int $lineOffset Number of lines the script is offset in the vue template file
185
+	 * @throws Exception
186
+	 */
187
+	protected static function getScriptTranslationsFromString(
188
+		$scriptContents,
189
+		$translations,
190
+		array $options = [],
191
+		$lineOffset = 0
192
+	) {
193
+		/** @var FunctionsScanner $functions */
194
+		$functions = new static::$functionsScannerClass($scriptContents);
195
+		$options['lineOffset'] = $lineOffset;
196
+		$functions->saveGettextFunctions($translations, $options);
197
+	}
198
+
199
+	/**
200
+	 * Parse template to extract all translations (element content and dynamic element attributes)
201
+	 *
202
+	 * @param DOMNode $dom
203
+	 * @param Translations|Translations[] $translations One or multiple domain Translation objects
204
+	 * @param array $options
205
+	 * @param int $lineOffset Line number where the template part starts in the vue file
206
+	 * @throws Exception
207
+	 */
208
+	protected static function getTemplateTranslations(
209
+		DOMNode $dom,
210
+		$translations,
211
+		array $options,
212
+		$lineOffset = 0
213
+	) {
214
+		// Build a JS string from all template attribute expressions
215
+		$fakeAttributeJs = static::getTemplateAttributeFakeJs($options, $dom);
216
+
217
+		// 1 line offset is necessary because parent template element was ignored when converting to DOM
218
+		static::getScriptTranslationsFromString($fakeAttributeJs, $translations, $options, $lineOffset);
219
+
220
+		// Build a JS string from template element content expressions
221
+		$fakeTemplateJs = static::getTemplateFakeJs($dom);
222
+		static::getScriptTranslationsFromString($fakeTemplateJs, $translations, $options, $lineOffset);
223
+
224
+		static::getTagTranslations($options, $dom, $translations);
225
+	}
226
+
227
+	/**
228
+	 * @param array $options
229
+	 * @param DOMNode $dom
230
+	 * @param Translations|Translations[] $translations
231
+	 */
232
+	protected static function getTagTranslations(array $options, DOMNode $dom, $translations)
233
+	{
234
+		// Since tag scanning does not support domains, we always use the first translation given
235
+		$translations = is_array($translations) ? reset($translations) : $translations;
236
+
237
+		$children = $dom->childNodes;
238
+		for ($i = 0; $i < $children->length; $i++) {
239
+			$node = $children->item($i);
240
+
241
+			if (!($node instanceof DOMElement)) {
242
+				continue;
243
+			}
244
+
245
+			$translatable = false;
246
+
247
+			if (in_array($node->tagName, $options['tagNames'], true)) {
248
+				$translatable = true;
249
+			}
250
+
251
+			$attrList = $node->attributes;
252
+			$context = null;
253
+			$plural = "";
254
+			$comment = null;
255
+
256
+			for ($j = 0; $j < $attrList->length; $j++) {
257
+				/** @var DOMAttr $domAttr */
258
+				$domAttr = $attrList->item($j);
259
+				// Check if this is a dynamic vue attribute
260
+				if (in_array($domAttr->name, $options['tagAttributes'])) {
261
+					$translatable = true;
262
+				}
263
+				if (in_array($domAttr->name, $options['contextAttributes'])) {
264
+					$context = $domAttr->value;
265
+				}
266
+				if (in_array($domAttr->name, $options['pluralAttributes'])) {
267
+					$plural = $domAttr->value;
268
+				}
269
+				if (in_array($domAttr->name, $options['commentAttributes'])) {
270
+					$comment = $domAttr->value;
271
+				}
272
+			}
273
+
274
+			if ($translatable) {
275
+				$translation = $translations->insert($context, trim($node->textContent), $plural);
276
+				$translation->addReference($options['file'], $node->getLineNo());
277
+				if ($comment) {
278
+					$translation->addExtractedComment($comment);
279
+				}
280
+			}
281
+
282
+			if ($node->hasChildNodes()) {
283
+				static::getTagTranslations($options, $node, $translations);
284
+			}
285
+		}
286
+	}
287
+
288
+	/**
289
+	 * Extract JS expressions from element attribute bindings (excluding text within elements)
290
+	 * For example: <span :title="__('extract this')"> skip element content </span>
291
+	 *
292
+	 * @param array $options
293
+	 * @param DOMNode $dom
294
+	 * @return string JS code
295
+	 */
296
+	protected static function getTemplateAttributeFakeJs(array $options, DOMNode $dom)
297
+	{
298
+		$expressionsByLine = static::getVueAttributeExpressions($options['attributePrefixes'], $dom);
299
+
300
+		if (empty($expressionsByLine)) {
301
+			return '';
302
+		}
303
+
304
+		$maxLines = max(array_keys($expressionsByLine));
305
+		$fakeJs = '';
306
+
307
+		for ($line = 1; $line <= $maxLines; $line++) {
308
+			if (isset($expressionsByLine[$line])) {
309
+				$fakeJs .= implode("; ", $expressionsByLine[$line]);
310
+			}
311
+			$fakeJs .= "\n";
312
+		}
313
+
314
+		return $fakeJs;
315
+	}
316
+
317
+	/**
318
+	 * Loop DOM element recursively and parse out all dynamic vue attributes which are basically JS expressions
319
+	 *
320
+	 * @param array $attributePrefixes List of attribute prefixes we parse as JS (may contain translations)
321
+	 * @param DOMNode $dom
322
+	 * @param array $expressionByLine [lineNumber => [jsExpression, ..], ..]
323
+	 * @return array [lineNumber => [jsExpression, ..], ..]
324
+	 */
325
+	protected static function getVueAttributeExpressions(
326
+		array $attributePrefixes,
327
+		DOMNode $dom,
328
+		array &$expressionByLine = []
329
+	) {
330
+		$children = $dom->childNodes;
331
+
332
+		for ($i = 0; $i < $children->length; $i++) {
333
+			$node = $children->item($i);
334
+
335
+			if (!($node instanceof DOMElement)) {
336
+				continue;
337
+			}
338
+			$attrList = $node->attributes;
339
+
340
+			for ($j = 0; $j < $attrList->length; $j++) {
341
+				/** @var DOMAttr $domAttr */
342
+				$domAttr = $attrList->item($j);
343
+
344
+				// Check if this is a dynamic vue attribute
345
+				if (static::isAttributeMatching($domAttr->name, $attributePrefixes)) {
346
+					$line = $domAttr->getLineNo();
347
+					$expressionByLine += [$line => []];
348
+					$expressionByLine[$line][] = $domAttr->value;
349
+				}
350
+			}
351
+
352
+			if ($node->hasChildNodes()) {
353
+				$expressionByLine = static::getVueAttributeExpressions($attributePrefixes, $node, $expressionByLine);
354
+			}
355
+		}
356
+
357
+		return $expressionByLine;
358
+	}
359
+
360
+	/**
361
+	 * Check if this attribute name should be parsed for translations
362
+	 *
363
+	 * @param string $attributeName
364
+	 * @param string[] $attributePrefixes
365
+	 * @return bool
366
+	 */
367
+	protected static function isAttributeMatching($attributeName, $attributePrefixes)
368
+	{
369
+		foreach ($attributePrefixes as $prefix) {
370
+			if (strpos($attributeName, $prefix) === 0) {
371
+				return true;
372
+			}
373
+		}
374
+		return false;
375
+	}
376
+
377
+	/**
378
+	 * Extract JS expressions from within template elements (excluding attributes)
379
+	 * For example: <span :title="skip attributes"> {{__("extract element content")}} </span>
380
+	 *
381
+	 * @param DOMNode $dom
382
+	 * @return string JS code
383
+	 */
384
+	protected static function getTemplateFakeJs(DOMNode $dom)
385
+	{
386
+		$fakeJs = '';
387
+		$lines = explode("\n", $dom->textContent);
388
+
389
+		// Build a fake JS file from template by extracting JS expressions within each template line
390
+		foreach ($lines as $line) {
391
+			$expressionMatched = static::parseOneTemplateLine($line);
392
+
393
+			$fakeJs .= implode("; ", $expressionMatched) . "\n";
394
+		}
395
+
396
+		return $fakeJs;
397
+	}
398
+
399
+	/**
400
+	 * Match JS expressions in a template line
401
+	 *
402
+	 * @param string $line
403
+	 * @return string[]
404
+	 */
405
+	protected static function parseOneTemplateLine($line)
406
+	{
407
+		$line = trim($line);
408
+
409
+		if (!$line) {
410
+			return [];
411
+		}
412
+
413
+		$regex = '#\{\{(.*?)\}\}#';
414
+
415
+		preg_match_all($regex, $line, $matches);
416
+
417
+		$matched = array_map(function ($v) {
418
+			return trim($v, '\'"{}');
419
+		}, $matches[1]);
420
+
421
+		return $matched;
422
+	}
423 423
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Extractor.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -8,73 +8,73 @@
 block discarded – undo
8 8
 
9 9
 abstract class Extractor implements ExtractorInterface
10 10
 {
11
-    /**
12
-     * {@inheritdoc}
13
-     */
14
-    public static function fromFile($file, Translations $translations, array $options = [])
15
-    {
16
-        foreach (static::getFiles($file) as $file) {
17
-            $options['file'] = $file;
18
-            static::fromString(static::readFile($file), $translations, $options);
19
-        }
20
-    }
11
+	/**
12
+	 * {@inheritdoc}
13
+	 */
14
+	public static function fromFile($file, Translations $translations, array $options = [])
15
+	{
16
+		foreach (static::getFiles($file) as $file) {
17
+			$options['file'] = $file;
18
+			static::fromString(static::readFile($file), $translations, $options);
19
+		}
20
+	}
21 21
 
22
-    /**
23
-     * Checks and returns all files.
24
-     *
25
-     * @param string|array $file The file/s
26
-     *
27
-     * @return array The file paths
28
-     */
29
-    protected static function getFiles($file)
30
-    {
31
-        if (empty($file)) {
32
-            throw new InvalidArgumentException('There is not any file defined');
33
-        }
22
+	/**
23
+	 * Checks and returns all files.
24
+	 *
25
+	 * @param string|array $file The file/s
26
+	 *
27
+	 * @return array The file paths
28
+	 */
29
+	protected static function getFiles($file)
30
+	{
31
+		if (empty($file)) {
32
+			throw new InvalidArgumentException('There is not any file defined');
33
+		}
34 34
 
35
-        if (is_string($file)) {
36
-            if (!is_file($file)) {
37
-                throw new InvalidArgumentException("'$file' is not a valid file");
38
-            }
35
+		if (is_string($file)) {
36
+			if (!is_file($file)) {
37
+				throw new InvalidArgumentException("'$file' is not a valid file");
38
+			}
39 39
 
40
-            if (!is_readable($file)) {
41
-                throw new InvalidArgumentException("'$file' is not a readable file");
42
-            }
40
+			if (!is_readable($file)) {
41
+				throw new InvalidArgumentException("'$file' is not a readable file");
42
+			}
43 43
 
44
-            return [$file];
45
-        }
44
+			return [$file];
45
+		}
46 46
 
47
-        if (is_array($file)) {
48
-            $files = [];
47
+		if (is_array($file)) {
48
+			$files = [];
49 49
 
50
-            foreach ($file as $f) {
51
-                $files = array_merge($files, static::getFiles($f));
52
-            }
50
+			foreach ($file as $f) {
51
+				$files = array_merge($files, static::getFiles($f));
52
+			}
53 53
 
54
-            return $files;
55
-        }
54
+			return $files;
55
+		}
56 56
 
57
-        throw new InvalidArgumentException('The first argument must be string or array');
58
-    }
57
+		throw new InvalidArgumentException('The first argument must be string or array');
58
+	}
59 59
 
60
-    /**
61
-     * Reads and returns the content of a file.
62
-     *
63
-     * @param string $file
64
-     *
65
-     * @return string
66
-     */
67
-    protected static function readFile($file)
68
-    {
69
-        $length = filesize($file);
60
+	/**
61
+	 * Reads and returns the content of a file.
62
+	 *
63
+	 * @param string $file
64
+	 *
65
+	 * @return string
66
+	 */
67
+	protected static function readFile($file)
68
+	{
69
+		$length = filesize($file);
70 70
 
71
-        if (!($fd = fopen($file, 'rb'))) {
72
-            throw new Exception("Cannot read the file '$file', probably permissions");
73
-        }
71
+		if (!($fd = fopen($file, 'rb'))) {
72
+			throw new Exception("Cannot read the file '$file', probably permissions");
73
+		}
74 74
 
75
-        $content = $length ? fread($fd, $length) : '';
76
-        fclose($fd);
75
+		$content = $length ? fread($fd, $length) : '';
76
+		fclose($fd);
77 77
 
78
-        return $content;
79
-    }
78
+		return $content;
79
+	}
80 80
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Json.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -10,17 +10,17 @@
 block discarded – undo
10 10
  */
11 11
 class Json extends Extractor implements ExtractorInterface
12 12
 {
13
-    use MultidimensionalArrayTrait;
13
+	use MultidimensionalArrayTrait;
14 14
 
15
-    /**
16
-     * {@inheritdoc}
17
-     */
18
-    public static function fromString($string, Translations $translations, array $options = [])
19
-    {
20
-        $messages = json_decode($string, true);
15
+	/**
16
+	 * {@inheritdoc}
17
+	 */
18
+	public static function fromString($string, Translations $translations, array $options = [])
19
+	{
20
+		$messages = json_decode($string, true);
21 21
 
22
-        if (is_array($messages)) {
23
-            static::fromArray($messages, $translations);
24
-        }
25
-    }
22
+		if (is_array($messages)) {
23
+			static::fromArray($messages, $translations);
24
+		}
25
+	}
26 26
 }
Please login to merge, or discard this patch.
vendor/gettext/gettext/src/Extractors/Yaml.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -11,17 +11,17 @@
 block discarded – undo
11 11
  */
12 12
 class Yaml extends Extractor implements ExtractorInterface
13 13
 {
14
-    use MultidimensionalArrayTrait;
14
+	use MultidimensionalArrayTrait;
15 15
 
16
-    /**
17
-     * {@inheritdoc}
18
-     */
19
-    public static function fromString($string, Translations $translations, array $options = [])
20
-    {
21
-        $messages = YamlParser::parse($string);
16
+	/**
17
+	 * {@inheritdoc}
18
+	 */
19
+	public static function fromString($string, Translations $translations, array $options = [])
20
+	{
21
+		$messages = YamlParser::parse($string);
22 22
 
23
-        if (is_array($messages)) {
24
-            static::fromArray($messages, $translations);
25
-        }
26
-    }
23
+		if (is_array($messages)) {
24
+			static::fromArray($messages, $translations);
25
+		}
26
+	}
27 27
 }
Please login to merge, or discard this patch.