Completed
Push — 6.0 ( b80043...cd08ae )
by liu
02:38
created

Lang::get()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 34
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 15
nc 4
nop 3
dl 0
loc 34
ccs 0
cts 15
cp 0
crap 56
rs 8.8333
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
class Lang
1 ignored issue
show
Coding Style introduced by
Missing doc comment for class Lang
Loading history...
16
{
17
    /**
18
     * 多语言信息
19
     * @var array
20
     */
21
    private $lang = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "lang" must be prefixed with an underscore
Loading history...
22
23
    /**
24
     * 当前语言
25
     * @var string
26
     */
27
    private $range = 'zh-cn';
0 ignored issues
show
Coding Style introduced by
Private member variable "range" must be prefixed with an underscore
Loading history...
28
29
    /**
30
     * 多语言自动侦测变量名
31
     * @var string
32
     */
33
    protected $langDetectVar = 'lang';
34
35
    /**
36
     * 多语言cookie变量
37
     * @var string
38
     */
39
    protected $langCookieVar = 'think_var';
40
41
    /**
42
     * 允许的多语言列表
43
     * @var array
44
     */
45
    protected $allowLangList = [];
46
47
    /**
48
     * Accept-Language转义为对应语言包名称 系统默认配置
49
     * @var array
50
     */
51
    protected $acceptLanguage = [
52
        'zh-hans-cn' => 'zh-cn',
53
    ];
54
55
    // 设定当前的语言
56
    public function setLangSet(string $lang): void
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
57
    {
58
        $this->range = $lang;
59
    }
60
61
    public function getLangSet(): string
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getLangSet()
Loading history...
62
    {
63
        return $this->range;
64
    }
65
66
    /**
67
     * 设置语言定义(不区分大小写)
68
     * @access public
69
     * @param  string|array  $name 语言变量
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
70
     * @param  string        $value 语言值
71
     * @param  string        $range 语言作用域
72
     * @return mixed
73
     */
74
    public function set($name, $value = null, $range = '')
75
    {
76
        $range = $range ?: $this->range;
77
        // 批量定义
78
        if (!isset($this->lang[$range])) {
79
            $this->lang[$range] = [];
80
        }
81
82
        if (is_array($name)) {
83
            return $this->lang[$range] = array_change_key_case($name) + $this->lang[$range];
84
        }
85
86
        return $this->lang[$range][strtolower($name)] = $value;
87
    }
88
89
    /**
90
     * 加载语言定义(不区分大小写)
91
     * @access public
92
     * @param  string|array  $file   语言文件
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 3 found
Loading history...
93
     * @param  string        $range  语言作用域
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
94
     * @return array
95
     */
96
    public function load($file, $range = ''): array
97
    {
98
        $range = $range ?: $this->range;
99
        if (!isset($this->lang[$range])) {
100
            $this->lang[$range] = [];
101
        }
102
103
        // 批量定义
104
        if (is_string($file)) {
105
            $file = [$file];
106
        }
107
108
        $lang = [];
109
110
        foreach ($file as $_file) {
111
            if (is_file($_file)) {
112
                // 记录加载信息
113
                $_lang = include $_file;
114
                if (is_array($_lang)) {
115
                    $lang = array_change_key_case($_lang) + $lang;
116
                }
117
            }
118
        }
119
120
        if (!empty($lang)) {
121
            $this->lang[$range] = $lang + $this->lang[$range];
122
        }
123
124
        return $this->lang[$range];
125
    }
126
127
    /**
128
     * 获取语言定义(不区分大小写)
129
     * @access public
130
     * @param  string|null   $name 语言变量
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
131
     * @param  string        $range 语言作用域
132
     * @return bool
133
     */
134
    public function has(string $name, string $range = ''): bool
135
    {
136
        $range = $range ?: $this->range;
137
138
        return isset($this->lang[$range][strtolower($name)]);
139
    }
140
141
    /**
142
     * 获取语言定义(不区分大小写)
143
     * @access public
144
     * @param  string|null   $name 语言变量
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
145
     * @param  array         $vars 变量替换
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
146
     * @param  string        $range 语言作用域
147
     * @return mixed
148
     */
149
    public function get(string $name = null, array $vars = [], string $range = '')
150
    {
151
        $range = $range ?: $this->range;
152
153
        // 空参数返回所有定义
154
        if (is_null($name)) {
155
            return $this->lang[$range] ?? [];
156
        }
157
158
        $key   = strtolower($name);
159
        $value = $this->lang[$range][$key] ?? $name;
160
161
        // 变量解析
162
        if (!empty($vars) && is_array($vars)) {
163
            /**
164
             * Notes:
165
             * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0
166
             * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数
167
             */
168
            if (key($vars) === 0) {
169
                // 数字索引解析
170
                array_unshift($vars, $value);
171
                $value = call_user_func_array('sprintf', $vars);
172
            } else {
173
                // 关联索引解析
174
                $replace = array_keys($vars);
175
                foreach ($replace as &$v) {
176
                    $v = "{:{$v}}";
177
                }
178
                $value = str_replace($replace, $vars, $value);
179
            }
180
        }
181
182
        return $value;
183
    }
184
185
    /**
186
     * 自动侦测设置获取语言选择
187
     * @access public
188
     * @param  Request $request Request对象
189
     * @return string
190
     */
191
    public function detect(Request $request): string
192
    {
193
        // 自动侦测设置获取语言选择
194
        $langSet = '';
195
196
        if ($request->get($this->langDetectVar)) {
197
            // url中设置了语言变量
198
            $langSet = strtolower($request->get($this->langDetectVar));
0 ignored issues
show
Bug introduced by
It seems like $request->get($this->langDetectVar) can also be of type object; however, parameter $str of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

198
            $langSet = strtolower(/** @scrutinizer ignore-type */ $request->get($this->langDetectVar));
Loading history...
199
        } elseif ($request->cookie($this->langCookieVar)) {
200
            // Cookie中设置了语言变量
201
            $langSet = strtolower($request->cookie($this->langCookieVar));
202
        } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) {
203
            // 自动侦测浏览器语言
204
            preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches);
205
            $langSet = strtolower($matches[1]);
206
            if (isset($this->acceptLanguage[$langSet])) {
207
                $langSet = $this->acceptLanguage[$langSet];
208
            }
209
        }
210
211
        if (empty($this->allowLangList) || in_array($langSet, $this->allowLangList)) {
212
            // 合法的语言
213
            $this->range = $langSet ?: $this->range;
214
        }
215
216
        return $this->range;
217
    }
218
219
    /**
220
     * 设置语言自动侦测的变量
221
     * @access public
222
     * @param  string $var 变量名称
223
     * @return void
224
     */
225
    public function setLangDetectVar(string $var): void
226
    {
227
        $this->langDetectVar = $var;
228
    }
229
230
    /**
231
     * 获取语言自动侦测的变量
232
     * @access public
233
     * @return string
234
     */
235
    public function getLangDetectVar(): string
236
    {
237
        return $this->langDetectVar;
238
    }
239
240
    /**
241
     * 设置语言的cookie保存变量
242
     * @access public
243
     * @param  string $var 变量名称
244
     * @return void
245
     */
246
    public function setLangCookieVar(string $var): void
247
    {
248
        $this->langCookieVar = $var;
249
    }
250
251
    /**
252
     * 获取语言的cookie保存变量
253
     * @access public
254
     * @return string
255
     */
256
    public function getLangCookieVar(): string
257
    {
258
        return $this->langCookieVar;
259
    }
260
261
    /**
262
     * 设置允许的语言列表
263
     * @access public
264
     * @param  array $list 语言列表
265
     * @return void
266
     */
267
    public function setAllowLangList(array $list): void
268
    {
269
        $this->allowLangList = $list;
270
    }
271
272
    /**
273
     * 设置转义的语言列表
274
     * @access public
275
     * @param  array $list 语言列表
276
     * @return void
277
     */
278
    public function setAcceptLanguage(array $list): void
279
    {
280
        $this->acceptLanguage = array_merge($this->acceptLanguage, $list);
281
    }
282
}
283