Completed
Push — v4.0-dev ( 627b53 )
by Oscar
03:24
created

Translation   C

Complexity

Total Complexity 69

Size/Duplication

Total Lines 509
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 6
Bugs 1 Features 0
Metric Value
wmc 69
c 6
b 1
f 0
lcom 2
cbo 1
dl 0
loc 509
rs 5.6445

41 Methods

Rating   Name   Duplication   Size   Complexity  
A generateId() 0 4 1
A getId() 0 4 1
A getOriginal() 0 4 1
A hasOriginal() 0 4 2
A __construct() 0 7 1
A getClone() 0 14 3
A is() 0 4 3
A setTranslation() 0 6 1
A getTranslation() 0 4 1
A hasTranslation() 0 4 2
A setPlural() 0 8 1
A getPlural() 0 4 1
A hasPlural() 0 4 2
A setPluralTranslations() 0 7 1
A setPluralTranslation() 0 7 1
A getPluralTranslation() 0 4 2
A getPluralTranslations() 0 4 1
A hasPluralTranslation() 0 4 1
A deletePluralTranslation() 0 6 1
A setTranslationCount() 0 8 2
A getTranslationCount() 0 4 2
B normalizeTranslationCount() 0 19 5
A getContext() 0 4 1
A hasContext() 0 4 3
A addReference() 0 5 1
A hasReferences() 0 4 1
A getReferences() 0 4 1
A deleteReferences() 0 4 1
A addComment() 0 4 1
A hasComments() 0 4 1
A getComments() 0 4 1
A deleteComments() 0 4 1
A addExtractedComment() 0 4 1
A hasExtractedComments() 0 4 1
A getExtractedComments() 0 4 1
A deleteExtractedComments() 0 4 1
A addFlag() 0 4 1
A hasFlags() 0 4 1
A getFlags() 0 4 1
A deleteFlags() 0 4 1
C mergeWith() 0 30 13

How to fix   Complexity   

Complex Class

Complex classes like Translation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Translation, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Gettext;
4
5
/**
6
 * Class to manage a translation string.
7
 */
8
class Translation
9
{
10
    protected $context;
11
    protected $original;
12
    protected $translation = '';
13
    protected $plural;
14
    protected $pluralTranslation = array();
15
    protected $references = array();
16
    protected $comments = array();
17
    protected $extractedComments = array();
18
    protected $flags = array();
19
    protected $translationCount;
20
21
    /**
22
     * Generates the id of a translation (context + glue + original).
23
     *
24
     * @param string $context
25
     * @param string $original
26
     *
27
     * @return string
28
     */
29
    public static function generateId($context, $original)
30
    {
31
        return "{$context}\004{$original}";
32
    }
33
34
    /**
35
     * Construct.
36
     *
37
     * @param string $context  The context of the translation
38
     * @param string $original The original string
39
     * @param string $plural   The original plural string
40
     */
41
    public function __construct($context, $original, $plural = '')
42
    {
43
        $this->context = (string) $context;
44
        $this->original = (string) $original;
45
46
        $this->setPlural($plural);
47
    }
48
49
    /**
50
     * Clones this translation.
51
     *
52
     * @param null|string $context  Optional new context
53
     * @param null|string $original Optional new original
54
     */
55
    public function getClone($context = null, $original = null)
56
    {
57
        $new = clone $this;
58
59
        if ($context !== null) {
60
            $new->context = (string) $context;
61
        }
62
63
        if ($original !== null) {
64
            $new->original = (string) $original;
65
        }
66
67
        return $new;
68
    }
69
70
    /**
71
     * Returns the id of this translation.
72
     *
73
     * @return string
74
     */
75
    public function getId()
76
    {
77
        return static::generateId($this->context, $this->original);
78
    }
79
80
    /**
81
     * Checks whether the translation matches with the arguments.
82
     *
83
     * @param string $context
84
     * @param string $original
85
     *
86
     * @return bool
87
     */
88
    public function is($context, $original = '')
89
    {
90
        return (($this->context === $context) && ($this->original === $original)) ? true : false;
91
    }
92
93
    /**
94
     * Gets the original string.
95
     *
96
     * @return string
97
     */
98
    public function getOriginal()
99
    {
100
        return $this->original;
101
    }
102
103
    /**
104
     * Checks if the original string is empty or not.
105
     *
106
     * @return bool
107
     */
108
    public function hasOriginal()
109
    {
110
        return ($this->original !== '') ? true : false;
111
    }
112
113
    /**
114
     * Sets the translation string.
115
     *
116
     * @param string $translation
117
     * 
118
     * @return self
119
     */
120
    public function setTranslation($translation)
121
    {
122
        $this->translation = (string) $translation;
123
124
        return $this;
125
    }
126
127
    /**
128
     * Gets the translation string.
129
     *
130
     * @return string
131
     */
132
    public function getTranslation()
133
    {
134
        return $this->translation;
135
    }
136
137
    /**
138
     * Checks if the translation string is empty or not.
139
     *
140
     * @return bool
141
     */
142
    public function hasTranslation()
143
    {
144
        return ($this->translation !== '') ? true : false;
145
    }
146
147
    /**
148
     * Sets the plural translation string.
149
     *
150
     * @param string $plural
151
     * 
152
     * @return self
153
     */
154
    public function setPlural($plural)
155
    {
156
        $this->plural = (string) $plural;
157
158
        $this->normalizeTranslationCount();
159
160
        return $this;
161
    }
162
163
    /**
164
     * Gets the plural translation string.
165
     *
166
     * @return string
167
     */
168
    public function getPlural()
169
    {
170
        return $this->plural;
171
    }
172
173
    /**
174
     * Checks if the plural translation string is empty or not.
175
     *
176
     * @return bool
177
     */
178
    public function hasPlural()
179
    {
180
        return ($this->plural !== '') ? true : false;
181
    }
182
183
    /**
184
     * Set a new plural translation.
185
     *
186
     * @param array $plural
187
     * 
188
     * @return self
189
     */
190
    public function setPluralTranslations(array $plural)
191
    {
192
        $this->pluralTranslation = $plural;
193
        $this->normalizeTranslationCount();
194
195
        return $this;
196
    }
197
198
    /**
199
     * Set a new plural translation.
200
     *
201
     * @param string $plural The plural string to add
202
     * @param int    $key    The key of the plural translation.
203
     * 
204
     * @return self
205
     */
206
    public function setPluralTranslation($plural, $key = 0)
207
    {
208
        $this->pluralTranslation[$key] = $plural;
209
        $this->normalizeTranslationCount();
210
211
        return $this;
212
    }
213
214
    /**
215
     * Gets one or all plural translations.
216
     *
217
     * @param int|null $key The key to return. If is null, return all translations
218
     *
219
     * @return string|array
220
     */
221
    public function getPluralTranslation($key = 0)
222
    {
223
        return isset($this->pluralTranslation[$key]) ? (string) $this->pluralTranslation[$key] : '';
224
    }
225
226
    /**
227
     * Gets all plural translations.
228
     *
229
     * @return array
230
     */
231
    public function getPluralTranslations()
232
    {
233
        return $this->pluralTranslation;
234
    }
235
236
    /**
237
     * Checks if there are any plural translation.
238
     *
239
     * @return bool
240
     */
241
    public function hasPluralTranslation()
242
    {
243
        return implode('', $this->pluralTranslation) !== '';
244
    }
245
246
    /**
247
     * Removes all plural translations.
248
     */
249
    public function deletePluralTranslation()
250
    {
251
        $this->pluralTranslation = array();
252
253
        $this->normalizeTranslationCount();
254
    }
255
256
    /**
257
     * Set the number of singular + plural translations allowed.
258
     *
259
     * @param int $count
260
     * 
261
     * @return self
262
     */
263
    public function setTranslationCount($count)
264
    {
265
        $this->translationCount = is_null($count) ? null : intval($count);
266
267
        $this->normalizeTranslationCount();
268
269
        return $this;
270
    }
271
272
    /**
273
     * Returns the number of singular + plural translations
274
     * Returns null if this Translation is not a plural one.
275
     *
276
     * @return int|null
277
     */
278
    public function getTranslationCount()
279
    {
280
        return $this->hasPlural() ? $this->translationCount : null;
281
    }
282
283
    /**
284
     * Normalizes the translation count.
285
     */
286
    protected function normalizeTranslationCount()
287
    {
288
        if ($this->translationCount === null) {
289
            return;
290
        }
291
292
        if ($this->hasPlural()) {
293
            $allowed = $this->translationCount - 1;
294
            $current = count($this->pluralTranslation);
295
296
            if ($allowed > $current) {
297
                $this->pluralTranslation = $this->pluralTranslation + array_fill(0, $allowed, '');
298
            } elseif ($current > $allowed) {
299
                $this->pluralTranslation = array_slice($this->pluralTranslation, 0, $allowed);
300
            }
301
        } else {
302
            $this->pluralTranslation = array();
303
        }
304
    }
305
306
    /**
307
     * Gets the context of this translation.
308
     *
309
     * @return string
310
     */
311
    public function getContext()
312
    {
313
        return $this->context;
314
    }
315
316
    /**
317
     * Checks if the context is empty or not.
318
     *
319
     * @return bool
320
     */
321
    public function hasContext()
322
    {
323
        return (isset($this->context) && ($this->context !== '')) ? true : false;
324
    }
325
326
    /**
327
     * Adds a new reference for this translation.
328
     *
329
     * @param string   $filename The file path where the translation has been found
330
     * @param null|int $line     The line number where the translation has been found
331
     */
332
    public function addReference($filename, $line = null)
333
    {
334
        $key = "{$filename}:{$line}";
335
        $this->references[$key] = array($filename, $line);
336
    }
337
338
    /**
339
     * Checks if the translation has any reference.
340
     *
341
     * @return bool
342
     */
343
    public function hasReferences()
344
    {
345
        return !empty($this->references);
346
    }
347
348
    /**
349
     * Return all references for this translation.
350
     *
351
     * @return array
352
     */
353
    public function getReferences()
354
    {
355
        return array_values($this->references);
356
    }
357
358
    /**
359
     * Removes all references.
360
     */
361
    public function deleteReferences()
362
    {
363
        $this->references = array();
364
    }
365
366
    /**
367
     * Adds a new comment for this translation.
368
     *
369
     * @param string $comment
370
     */
371
    public function addComment($comment)
372
    {
373
        $this->comments[] = $comment;
374
    }
375
376
    /**
377
     * Checks if the translation has any comment.
378
     *
379
     * @return bool
380
     */
381
    public function hasComments()
382
    {
383
        return isset($this->comments[0]);
384
    }
385
386
    /**
387
     * Returns all comments for this translation.
388
     *
389
     * @return array
390
     */
391
    public function getComments()
392
    {
393
        return $this->comments;
394
    }
395
396
    /**
397
     * Removes all comments.
398
     */
399
    public function deleteComments()
400
    {
401
        $this->comments = array();
402
    }
403
404
    /**
405
     * Adds a new extracted comment for this translation.
406
     *
407
     * @param string $comment
408
     */
409
    public function addExtractedComment($comment)
410
    {
411
        $this->extractedComments[] = $comment;
412
    }
413
414
    /**
415
     * Checks if the translation has any extracted comment.
416
     *
417
     * @return bool
418
     */
419
    public function hasExtractedComments()
420
    {
421
        return isset($this->extractedComments[0]);
422
    }
423
424
    /**
425
     * Returns all extracted comments for this translation.
426
     *
427
     * @return array
428
     */
429
    public function getExtractedComments()
430
    {
431
        return $this->extractedComments;
432
    }
433
434
    /**
435
     * Removes all extracted comments.
436
     */
437
    public function deleteExtractedComments()
438
    {
439
        $this->extractedComments = array();
440
    }
441
442
    /**
443
     * Adds a new flat for this translation.
444
     *
445
     * @param string $flag
446
     */
447
    public function addFlag($flag)
448
    {
449
        $this->flags[] = $flag;
450
    }
451
452
    /**
453
     * Checks if the translation has any flag.
454
     *
455
     * @return bool
456
     */
457
    public function hasFlags()
458
    {
459
        return isset($this->flags[0]);
460
    }
461
462
    /**
463
     * Returns all extracted flags for this translation.
464
     *
465
     * @return array
466
     */
467
    public function getFlags()
468
    {
469
        return $this->flags;
470
    }
471
472
    /**
473
     * Removes all flags.
474
     */
475
    public function deleteFlags()
476
    {
477
        $this->flags = array();
478
    }
479
480
    /**
481
     * Merges this translation with other translation.
482
     *
483
     * @param Translation $translation The translation to merge with
484
     * @param int|null    $method      One or various Translations::MERGE_* constants to define how to merge the translations
485
     */
486
    public function mergeWith(Translation $translation, $method = null)
487
    {
488
        if ($method === null) {
489
            $method = Translations::$mergeDefault;
490
        }
491
492
        if (!$this->hasTranslation() || ($translation->hasTranslation() && ($method & Translations::MERGE_OVERRIDE))) {
493
            $this->setTranslation($translation->getTranslation());
494
        }
495
496
        if (($method & Translations::MERGE_PLURAL) && !$this->hasPlural()) {
497
            $this->setPlural($translation->getPlural());
498
        }
499
500
        if ($this->hasPlural() && !$this->hasPluralTranslation() && $translation->hasPluralTranslation()) {
501
            $this->pluralTranslation = $translation->getPluralTranslation();
0 ignored issues
show
Documentation Bug introduced by
It seems like $translation->getPluralTranslation() of type string is incompatible with the declared type array of property $pluralTranslation.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
502
        }
503
504
        if ($method & Translations::MERGE_REFERENCES) {
505
            foreach ($translation->getReferences() as $reference) {
506
                $this->addReference($reference[0], $reference[1]);
507
            }
508
        }
509
510
        if ($method & Translations::MERGE_COMMENTS) {
511
            $this->comments = array_values(array_unique(array_merge($translation->getComments(), $this->comments)));
512
            $this->extractedComments = array_values(array_unique(array_merge($translation->getExtractedComments(), $this->extractedComments)));
513
            $this->flags = array_values(array_unique(array_merge($translation->getFlags(), $this->flags)));
514
        }
515
    }
516
}
517