Completed
Pull Request — master (#380)
by Anton
05:26
created

Translator::translate()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 5
nop 2
dl 0
loc 16
ccs 8
cts 8
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link https://github.com/bluzphp/framework
7
 */
8
9
/**
10
 * @namespace
11
 */
12
namespace Bluz\Translator;
13
14
use Bluz\Common\Exception\ConfigurationException;
15
use Bluz\Common\Options;
16
17
/**
18
 * Translator based on gettext library
19
 *
20
 * @package  Bluz\Translator
21
 * @author   Anton Shevchuk
22
 * @link     https://github.com/bluzphp/framework/wiki/Translator
23
 */
24
class Translator
25
{
26
    use Options;
27
28
    /**
29
     * Locale
30
     *
31
     * @var string
32
     * @link http://www.loc.gov/standards/iso639-2/php/code_list.php
33
     */
34
    protected $locale = 'en_US';
35
36
    /**
37
     * @var string text domain
38
     */
39
    protected $domain = 'messages';
40
41
    /**
42
     * @var string path to text domain files
43
     */
44
    protected $path;
45
46
    /**
47
     * Set domain
48
     *
49
     * @param  string $domain
50
     * @return self
51
     */
52 3
    public function setDomain($domain)
53
    {
54 3
        $this->domain = $domain;
55 3
        return $this;
56
    }
57
58
    /**
59
     * Set locale
60
     *
61
     * @param  string $locale
62
     * @return self
63
     */
64 3
    public function setLocale($locale)
65
    {
66 3
        $this->locale = $locale;
67 3
        return $this;
68
    }
69
70
    /**
71
     * Set path to l10n
72
     *
73
     * @param  string $path
74
     * @return self
75
     */
76 3
    public function setPath($path)
77
    {
78 3
        $this->path = $path;
79 3
        return $this;
80
    }
81
82
    /**
83
     * Initialization
84
     *
85
     * @return void
86
     * @throw  \Bluz\Config\ConfigException
87
     */
88
    protected function initOptions()
89
    {
90
        // Setup locale
91
        putenv('LC_ALL=' . $this->locale);
92
        putenv('LANG=' . $this->locale);
93
        putenv('LANGUAGE=' . $this->locale);
94
95
        // Windows workaround
96
        defined('LC_MESSAGES') ? : define('LC_MESSAGES', 6);
97
98
        setlocale(LC_MESSAGES, $this->locale);
99
100
        // For gettext only
101
        if (function_exists('gettext')) {
102
            // Setup domain path
103
            $this->addTextDomain($this->domain, $this->path);
104
105
            // Setup default domain
106
            textdomain($this->domain);
107
        }
108
    }
109
110
    /**
111
     * Add text domain for gettext
112
     *
113
     * @param  string $domain of text for gettext setup
114
     * @param  string $path on filesystem
115
     * @return self
116
     * @throws ConfigurationException
117
     */
118 1
    public function addTextDomain($domain, $path)
119
    {
120
        // check path
121 1
        if (!is_dir($path)) {
122 1
            throw new ConfigurationException("Translator configuration path `$path` not found");
123
        }
124
125
        bindtextdomain($domain, $path);
126
127
        // @todo: hardcoded codeset
128
        bind_textdomain_codeset($domain, 'UTF-8');
129
130
        return $this;
131
    }
132
133
    /**
134
     * Translate message
135
     *
136
     * Simple example of usage
137
     * equal to gettext('Message')
138
     *     Translator::translate('Message');
139
     *
140
     * Simple replace of one or more argument(s)
141
     * equal to sprintf(gettext('Message to %s'), 'Username')
142
     *     Translator::translate('Message to %s', 'Username');
143
     *
144
     * @param  string $message
145
     * @param  string[] ...$text
146
     * @return string
147
     */
148 82
    public static function translate($message, ...$text)
149
    {
150 82
        if (empty($message)) {
151 1
            return $message;
152
        }
153
154 82
        if (function_exists('gettext')) {
155 82
            $message = gettext($message);
156
        }
157
158 82
        if (func_num_args() > 1) {
159 67
            $message = vsprintf($message, $text);
160
        }
161
162 82
        return $message;
163
    }
164
165
    /**
166
     * Translate plural form
167
     *
168
     * Example of usage plural form + sprintf
169
     * equal to sprintf(ngettext('%d comment', '%d comments', 4), 4)
170
     *     Translator::translatePlural('%d comment', '%d comments', 4, 4)
171
     *
172
     * Example of usage plural form + sprintf
173
     * equal to sprintf(ngettext('%d comment', '%d comments', 4), 4, 'Topic')
174
     *     Translator::translatePlural('%d comment to %s', '%d comments to %s', 4, 'Topic')
175
     *
176
     * @param  string  $singular
177
     * @param  string  $plural
178
     * @param  integer $number
179
     * @param  string[]  ...$text
180
     * @return string
181
     * @link   http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html
182
     */
183 2
    public static function translatePlural($singular, $plural, $number, ...$text)
184
    {
185 2
        if (function_exists('ngettext')) {
186 2
            $message = ngettext($singular, $plural, $number);
187
        } else {
188
            $message = $singular;
189
        }
190
191 2
        if (func_num_args() > 3) {
192
            // first element is number
193 1
            array_unshift($text, $number);
194 1
            $message = vsprintf($message, $text);
195
        }
196
197 2
        return $message;
198
    }
199
}
200