Completed
Push — master ( 3f9378...6e7ea1 )
by Alexander
10:30
created

MessageSource::translate()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 10
cc 3
nc 2
nop 3
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace Yii\I18n\Resource;
9
10
use Psr\EventDispatcher\EventDispatcherInterface;
11
use yii\base\Component;
12
use yii\i18n\event\OnMissingTranslation;
13
14
/**
15
 * MessageSource is the base class for message translation repository classes.
16
 *
17
 * A message source stores message translations in some persistent storage.
18
 *
19
 * Child classes should override [[loadMessages()]] to provide translated messages.
20
 *
21
 * @author Qiang Xue <[email protected]>
22
 * @since 2.0
23
 */
24
abstract class MessageSource extends Component
25
{
26
    private $eventDispatcher;
27
28
    /**
29
     * @var bool whether to force message translation when the source and target languages are the same.
30
     * Defaults to false, meaning translation is only performed when source and target languages are different.
31
     */
32
    public $forceTranslation = false;
33
    /**
34
     * @var string the language that the original messages are in. If not set, it will use the value of
35
     * [[\yii\base\Application::sourceLanguage]].
36
     */
37
    public $sourceLanguage = 'en-US';
38
39
    private $messages = [];
40
41
    public function __construct(EventDispatcherInterface $eventDispatcher)
42
    {
43
        $this->eventDispatcher = $eventDispatcher;
44
    }
45
46
47
    /**
48
     * Loads the message translation for the specified language and category.
49
     * If translation for specific locale code such as `en-US` isn't found it
50
     * tries more generic `en`.
51
     *
52
     * @param string $category the message category
53
     * @param string $language the target language
54
     * @return array the loaded messages. The keys are original messages, and the values
55
     * are translated messages.
56
     */
57
    abstract protected function loadMessages($category, $language): array;
58
59
    /**
60
     * Returns all messages for a given category in a given language.
61
     * Returned value is a result of {@see loadMessages()}
62
     *
63
     * @param string $category
64
     * @param string $language
65
     *
66
     * @return array
67
     */
68
    public function getMessages($category, $language)
69
    {
70
        $key = $language . '/' . $category;
71
        if (!isset($this->messages[$key])) {
72
            $this->messages[$key] = $this->loadMessages($category, $language);
73
        }
74
75
        return $this->messages[$key];
76
    }
77
78
    /**
79
     * Translates a message to the specified language.
80
     *
81
     * Note that unless [[forceTranslation]] is true, if the target language
82
     * is the same as the [[sourceLanguage|source language]], the message
83
     * will NOT be translated.
84
     *
85
     * If a translation is not found, a [[TranslationEvent::MISSING|missingTranslation]] event will be triggered.
86
     *
87
     * @param string $category the message category
88
     * @param string $message the message to be translated
89
     * @param string $language the target language
90
     * @return string|null the translated message or false if translation wasn't found or isn't required
91
     */
92
    public function translate($category, $message, $language): ?string
93
    {
94
        if ($this->forceTranslation || $language !== $this->sourceLanguage) {
95
            return $this->translateMessage($category, $message, $language);
96
        }
97
98
        return null;
99
    }
100
101
    /**
102
     * Translates the specified message.
103
     * If the message is not found, a [[TranslationEvent::MISSING|missingTranslation]] event will be triggered.
104
     * If there is an event handler, it may provide a [[MissingTranslationEvent::$translatedMessage|fallback translation]].
105
     * If no fallback translation is provided this method will return `false`.
106
     * @param string $category the category that the message belongs to.
107
     * @param string $message the message to be translated.
108
     * @param string $language the target language.
109
     * @return string|null the translated message or null if translation wasn't found.
110
     */
111
    protected function translateMessage($category, $message, $language): ?string
112
    {
113
        $messages = $this->getMessages($category, $language);
114
        if (isset($messages[$message]) && $messages[$message] !== '') {
115
            return $messages[$message];
116
        }
117
118
        $missingTranslation = new OnMissingTranslation($category, $language, $message);
119
        $this->eventDispatcher->dispatch($missingTranslation);
120
121
122
        if ($missingTranslation->hasFallback()) {
123
            return $messages[$message] = $missingTranslation->fallback();
124
        }
125
126
127
        return $messages[$message] = null;
128
    }
129
}
130