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