Po   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 200
Duplicated Lines 7 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 37
lcom 1
cbo 4
dl 14
loc 200
rs 9.44
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A fixMultiLines() 0 16 5
A convertString() 0 25 3
F fromString() 14 131 29

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Gettext\Extractors;
4
5
use Gettext\Translations;
6
use Gettext\Translation;
7
use Gettext\Utils\HeadersExtractorTrait;
8
9
/**
10
 * Class to get gettext strings from php files returning arrays.
11
 */
12
class Po extends Extractor implements ExtractorInterface
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 View Code Duplication
                    if (strpos($key, 'msgstr[') === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
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 View Code Duplication
                        if ($append === 'PluralTranslation') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
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) == '"'
166
                && isset($lines[$j + 1])
167
                && substr(trim($lines[$j + 1]), 0, 1) == '"'
168
            ) {
169
                $line = substr($line, 0, -1).substr(trim($lines[$j + 1]), 1);
170
            } else {
171
                $i = $j;
172
                break;
173
            }
174
        }
175
176
        return $line;
177
    }
178
179
    /**
180
     * Convert a string from its PO representation.
181
     *
182
     * @param string $value
183
     *
184
     * @return string
185
     */
186
    public static function convertString($value)
187
    {
188
        if (!$value) {
189
            return '';
190
        }
191
192
        if ($value[0] === '"') {
193
            $value = substr($value, 1, -1);
194
        }
195
196
        return strtr(
197
            $value,
198
            [
199
                '\\\\' => '\\',
200
                '\\a' => "\x07",
201
                '\\b' => "\x08",
202
                '\\t' => "\t",
203
                '\\n' => "\n",
204
                '\\v' => "\x0b",
205
                '\\f' => "\x0c",
206
                '\\r' => "\r",
207
                '\\"' => '"',
208
            ]
209
        );
210
    }
211
}
212