Completed
Push — master ( c246ca...b4afa9 )
by Oscar
02:35
created

Translation::mergeExtractedComments()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 12
rs 9.2
1
<?php
2
3
namespace Gettext;
4
5
/**
6
 * Class to manage a translation string.
7
 */
8
class Translation
9
{
10
    const MERGE_TRANSLATION_OVERRIDE = 64;
11
    const MERGE_PLURAL_OVERRIDE = 128;
12
    const MERGE_COMMENTS_MINES = 256;
13
    const MERGE_COMMENTS_THEIRS = 512;
14
    const MERGE_EXTRACTED_COMMENTS_MINES = 1024;
15
    const MERGE_EXTRACTED_COMMENTS_THEIRS = 2048;
16
    const MERGE_FLAGS_MINES = 4096;
17
    const MERGE_FLAGS_THEIRS = 8192;
18
    const MERGE_REFERENCES_MINES = 16384;
19
    const MERGE_REFERENCES_THEIRS = 32768;
20
21
    protected $context;
22
    protected $original;
23
    protected $translation = '';
24
    protected $plural;
25
    protected $pluralTranslation = [];
26
    protected $references = [];
27
    protected $comments = [];
28
    protected $extractedComments = [];
29
    protected $flags = [];
30
31
    /**
32
     * Generates the id of a translation (context + glue + original).
33
     *
34
     * @param string $context
35
     * @param string $original
36
     *
37
     * @return string
38
     */
39
    public static function generateId($context, $original)
40
    {
41
        return "{$context}\004{$original}";
42
    }
43
44
    /**
45
     * Construct.
46
     *
47
     * @param string $context  The context of the translation
48
     * @param string $original The original string
49
     * @param string $plural   The original plural string
50
     */
51
    public function __construct($context, $original, $plural = '')
52
    {
53
        $this->context = (string) $context;
54
        $this->original = (string) $original;
55
56
        $this->setPlural($plural);
57
    }
58
59
    /**
60
     * Clones this translation.
61
     *
62
     * @param null|string $context  Optional new context
63
     * @param null|string $original Optional new original
64
     * 
65
     * @return Translation
66
     */
67
    public function getClone($context = null, $original = null)
68
    {
69
        $new = clone $this;
70
71
        if ($context !== null) {
72
            $new->context = (string) $context;
73
        }
74
75
        if ($original !== null) {
76
            $new->original = (string) $original;
77
        }
78
79
        return $new;
80
    }
81
82
    /**
83
     * Returns the id of this translation.
84
     *
85
     * @return string
86
     */
87
    public function getId()
88
    {
89
        return static::generateId($this->context, $this->original);
90
    }
91
92
    /**
93
     * Checks whether the translation matches with the arguments.
94
     *
95
     * @param string $context
96
     * @param string $original
97
     *
98
     * @return bool
99
     */
100
    public function is($context, $original = '')
101
    {
102
        return (($this->context === $context) && ($this->original === $original)) ? true : false;
103
    }
104
105
    /**
106
     * Gets the original string.
107
     *
108
     * @return string
109
     */
110
    public function getOriginal()
111
    {
112
        return $this->original;
113
    }
114
115
    /**
116
     * Checks if the original string is empty or not.
117
     *
118
     * @return bool
119
     */
120
    public function hasOriginal()
121
    {
122
        return ($this->original !== '') ? true : false;
123
    }
124
125
    /**
126
     * Sets the translation string.
127
     *
128
     * @param string $translation
129
     * 
130
     * @return self
131
     */
132
    public function setTranslation($translation)
133
    {
134
        $this->translation = (string) $translation;
135
136
        return $this;
137
    }
138
139
    /**
140
     * Gets the translation string.
141
     *
142
     * @return string
143
     */
144
    public function getTranslation()
145
    {
146
        return $this->translation;
147
    }
148
149
    /**
150
     * Checks if the translation string is empty or not.
151
     *
152
     * @return bool
153
     */
154
    public function hasTranslation()
155
    {
156
        return ($this->translation !== '') ? true : false;
157
    }
158
159
    /**
160
     * Sets the plural translation string.
161
     *
162
     * @param string $plural
163
     * 
164
     * @return self
165
     */
166
    public function setPlural($plural)
167
    {
168
        $this->plural = (string) $plural;
169
170
        return $this;
171
    }
172
173
    /**
174
     * Gets the plural translation string.
175
     *
176
     * @return string
177
     */
178
    public function getPlural()
179
    {
180
        return $this->plural;
181
    }
182
183
    /**
184
     * Checks if the plural translation string is empty or not.
185
     *
186
     * @return bool
187
     */
188
    public function hasPlural()
189
    {
190
        return ($this->plural !== '') ? true : false;
191
    }
192
193
    /**
194
     * Set a new plural translation.
195
     *
196
     * @param array $plural
197
     * 
198
     * @return self
199
     */
200
    public function setPluralTranslations(array $plural)
201
    {
202
        $this->pluralTranslation = $plural;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Gets all plural translations.
209
     * 
210
     * @param int $limit
211
     *
212
     * @return array
213
     */
214
    public function getPluralTranslations($limit = null)
215
    {
216
        if ($limit === null) {
217
            return $this->pluralTranslation;
218
        }
219
220
        $current = count($this->pluralTranslation);
221
222
        if ($limit > $current) {
223
            return $this->pluralTranslation + array_fill(0, $limit, '');
224
        }
225
226
        if ($limit < $current) {
227
            return array_slice($this->pluralTranslation, 0, $limit);
228
        }
229
230
        return $this->pluralTranslation;
231
    }
232
233
    /**
234
     * Checks if there are any plural translation.
235
     * 
236
     * @param bool $checkContent
237
     *
238
     * @return bool
239
     */
240
    public function hasPluralTranslations($checkContent = false)
241
    {
242
        if ($checkContent) {
243
            return implode('', $this->pluralTranslation) !== '';
244
        }
245
246
        return !empty($this->pluralTranslation);
247
    }
248
249
    /**
250
     * Removes all plural translations.
251
     * 
252
     * @return self
253
     */
254
    public function deletePluralTranslation()
255
    {
256
        $this->pluralTranslation = [];
257
258
        return $this;
259
    }
260
261
    /**
262
     * Gets the context of this translation.
263
     *
264
     * @return string
265
     */
266
    public function getContext()
267
    {
268
        return $this->context;
269
    }
270
271
    /**
272
     * Checks if the context is empty or not.
273
     *
274
     * @return bool
275
     */
276
    public function hasContext()
277
    {
278
        return (isset($this->context) && ($this->context !== '')) ? true : false;
279
    }
280
281
    /**
282
     * Adds a new reference for this translation.
283
     *
284
     * @param string   $filename The file path where the translation has been found
285
     * @param null|int $line     The line number where the translation has been found
286
     * 
287
     * @return self
288
     */
289
    public function addReference($filename, $line = null)
290
    {
291
        $key = "{$filename}:{$line}";
292
        $this->references[$key] = [$filename, $line];
293
294
        return $this;
295
    }
296
297
    /**
298
     * Checks if the translation has any reference.
299
     *
300
     * @return bool
301
     */
302
    public function hasReferences()
303
    {
304
        return !empty($this->references);
305
    }
306
307
    /**
308
     * Return all references for this translation.
309
     *
310
     * @return array
311
     */
312
    public function getReferences()
313
    {
314
        return array_values($this->references);
315
    }
316
317
    /**
318
     * Removes all references.
319
     * 
320
     * @return self
321
     */
322
    public function deleteReferences()
323
    {
324
        $this->references = [];
325
326
        return $this;
327
    }
328
329
    /**
330
     * Adds a new comment for this translation.
331
     *
332
     * @param string $comment
333
     * 
334
     * @return self
335
     */
336
    public function addComment($comment)
337
    {
338
        if (!in_array($comment, $this->comments, true)) {
339
            $this->comments[] = $comment;
340
        }
341
342
        return $this;
343
    }
344
345
    /**
346
     * Checks if the translation has any comment.
347
     *
348
     * @return bool
349
     */
350
    public function hasComments()
351
    {
352
        return isset($this->comments[0]);
353
    }
354
355
    /**
356
     * Returns all comments for this translation.
357
     *
358
     * @return array
359
     */
360
    public function getComments()
361
    {
362
        return $this->comments;
363
    }
364
365
    /**
366
     * Removes all comments.
367
     * 
368
     * @return self
369
     */
370
    public function deleteComments()
371
    {
372
        $this->comments = [];
373
374
        return $this;
375
    }
376
377
    /**
378
     * Adds a new extracted comment for this translation.
379
     *
380
     * @param string $comment
381
     * 
382
     * @return self
383
     */
384
    public function addExtractedComment($comment)
385
    {
386
        if (!in_array($comment, $this->extractedComments, true)) {
387
            $this->extractedComments[] = $comment;
388
        }
389
390
        return $this;
391
    }
392
393
    /**
394
     * Checks if the translation has any extracted comment.
395
     *
396
     * @return bool
397
     */
398
    public function hasExtractedComments()
399
    {
400
        return isset($this->extractedComments[0]);
401
    }
402
403
    /**
404
     * Returns all extracted comments for this translation.
405
     *
406
     * @return array
407
     */
408
    public function getExtractedComments()
409
    {
410
        return $this->extractedComments;
411
    }
412
413
    /**
414
     * Removes all extracted comments.
415
     * 
416
     * @return self
417
     */
418
    public function deleteExtractedComments()
419
    {
420
        $this->extractedComments = [];
421
422
        return $this;
423
    }
424
425
    /**
426
     * Adds a new flag for this translation.
427
     *
428
     * @param string $flag
429
     * 
430
     * @return self
431
     */
432
    public function addFlag($flag)
433
    {
434
        if (!in_array($flag, $this->flags, true)) {
435
            $this->flags[] = $flag;
436
        }
437
438
        return $this;
439
    }
440
441
    /**
442
     * Checks if the translation has any flag.
443
     *
444
     * @return bool
445
     */
446
    public function hasFlags()
447
    {
448
        return isset($this->flags[0]);
449
    }
450
451
    /**
452
     * Returns all extracted flags for this translation.
453
     *
454
     * @return array
455
     */
456
    public function getFlags()
457
    {
458
        return $this->flags;
459
    }
460
461
    /**
462
     * Removes all flags.
463
     * 
464
     * @return self
465
     */
466
    public function deleteFlags()
467
    {
468
        $this->flags = [];
469
470
        return $this;
471
    }
472
473
    /**
474
     * Merges this translation with other translation.
475
     *
476
     * @param Translation $translation The translation to merge with
477
     * @param int         $options     The merging options
478
     * 
479
     * @return self
480
     */
481
    public function mergeWith(Translation $translation, $options = self::MERGE_TRANSLATION_OVERRIDE)
482
    {
483
        $this->mergeTranslation($translation, $options);
484
        $this->mergeReferences($translation, $options);
485
        $this->mergeComments($translation, $options);
486
        $this->mergeExtractedComments($translation, $options);
487
        $this->mergeFlags($translation, $options);
488
489
        return $this;
490
    }
491
492
    /**
493
     * Merge the translations of two translations
494
     * 
495
     * @param Translation $translation
496
     * @param int         $options
497
     */
498
    private function mergeTranslation(Translation $translation, $options)
499
    {
500
        $override = (boolean) ($options & self::MERGE_TRANSLATION_OVERRIDE);
501
502
        if (!$this->hasTranslation() || ($translation->hasTranslation() && $override)) {
503
            $this->setTranslation($translation->getTranslation());
504
        }
505
506
        if (!$this->hasPlural() || ($translation->hasPlural() && ($options & self::MERGE_PLURAL_OVERRIDE))) {
507
            $this->setPlural($translation->getPlural());
508
        }
509
510
        if (!$this->hasPluralTranslations() || ($translation->hasPluralTranslations() && $override)) {
511
            $this->setPluralTranslations($translation->getPluralTranslations());
512
        }
513
    }
514
515
    /**
516
     * Merge the references of two translations
517
     * 
518
     * @param Translation $translation
519
     * @param int         $options
520
     */
521
    private function mergeReferences(Translation $translation, $options)
522
    {
523
        if ($options & self::MERGE_REFERENCES_THEIRS) {
524
            $this->deleteReferences();
525
        }
526
527
        if (!($options & self::MERGE_REFERENCES_MINES)) {
528
            foreach ($translation->getReferences() as $reference) {
529
                $this->addReference($reference[0], $reference[1]);
530
            }
531
        }
532
    }
533
534
    /**
535
     * Merge the comments of two translations
536
     * 
537
     * @param Translation $translation
538
     * @param int         $options
539
     */
540
    private function mergeComments(Translation $translation, $options)
541
    {
542
        if ($options & self::MERGE_COMMENTS_THEIRS) {
543
            $this->deleteComments();
544
        }
545
546
        if (!($options & self::MERGE_COMMENTS_MINES)) {
547
            foreach ($translation->getComments() as $comment) {
548
                $this->addComment($comment);
549
            }
550
        }
551
    }
552
553
    /**
554
     * Merge the extracted comments of two translations
555
     * 
556
     * @param Translation $translation
557
     * @param int         $options
558
     */
559
    private function mergeExtractedComments(Translation $translation, $options)
560
    {
561
        if ($options & self::MERGE_EXTRACTED_COMMENTS_THEIRS) {
562
            $this->deleteExtractedComments();
563
        }
564
565
        if (!($options & self::MERGE_EXTRACTED_COMMENTS_MINES)) {
566
            foreach ($translation->getExtractedComments() as $comment) {
567
                $this->addExtractedComment($comment);
568
            }
569
        }
570
    }
571
572
    /**
573
     * Merge the flags of two translations
574
     * 
575
     * @param Translation $translation
576
     * @param int         $options
577
     */
578
    private function mergeFlags(Translation $translation, $options)
579
    {
580
        if ($options & self::MERGE_FLAGS_THEIRS) {
581
            $this->deleteFlags();
582
        }
583
584
        if (!($options & self::MERGE_FLAGS_MINES)) {
585
            foreach ($translation->getFlags() as $flag) {
586
                $this->addFlag($flag);
587
            }
588
        }
589
    }
590
}
591