Completed
Push — 6.0 ( b4e136...0273cf )
by liu
02:57
created

Lang::defaultLangSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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
/**
16
 * 多语言管理类
17
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
18
class Lang
19
{
20
    /**
21
     * 配置参数
22
     * @var array
23
     */
24
    protected $config = [
25
        // 默认语言
26
        'default_lang'    => 'zh-cn',
27
        // 允许的语言列表
28
        'allow_lang_list' => [],
29
        // 自动侦测和切换
30
        'auto_detect'     => false,
31
        // 是否使用Cookie记录
32
        'use_cookie'      => true,
33
        // 扩展语言包
34
        'extend_list'     => [],
35
        // 多语言cookie变量
36
        'cookie_var'      => 'think_lang',
37
        // 多语言自动侦测变量名
38
        'detect_var'      => 'lang',
39
        // Accept-Language转义为对应语言包名称
40
        'accept_language' => [
41
            'zh-hans-cn' => 'zh-cn',
42
        ],
43
        // 是否支持语言分组
44
        'allow_group'     => false,
45
    ];
46
47
    /**
48
     * 多语言信息
49
     * @var array
50
     */
51
    private $lang = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "lang" must be prefixed with an underscore
Loading history...
52
53
    /**
54
     * 当前语言
55
     * @var string
56
     */
57
    private $range = 'zh-cn';
0 ignored issues
show
Coding Style introduced by
Private member variable "range" must be prefixed with an underscore
Loading history...
58
59
    /**
60
     * Request对象
61
     * @var Request
62
     */
63
    protected $request;
64
65
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $config should have a doc-comment as per coding-style.
Loading history...
66
     * 构造方法
67
     * @access public
68
     */
69 6
    public function __construct(Request $request, array $config = [])
70
    {
71 6
        $this->request = $request;
72 6
        $this->config  = array_merge($this->config, array_change_key_case($config));
73 6
        $this->range   = $this->config['default_lang'];
74
75 6
        if ($this->config['auto_detect']) {
76
            $this->detect();
77
        }
78 6
    }
79
80 6
    public static function __make(Request $request, Config $config)
2 ignored issues
show
Coding Style introduced by
Method name "Lang::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
Coding Style introduced by
Public method name "Lang::__make" must not be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing doc comment for function __make()
Loading history...
81
    {
82 6
        return new static($request, $config->get('lang'));
0 ignored issues
show
Bug introduced by
It seems like $config->get('lang') can also be of type null; however, parameter $config of think\Lang::__construct() does only seem to accept array, 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

82
        return new static($request, /** @scrutinizer ignore-type */ $config->get('lang'));
Loading history...
83
    }
84
85
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $lang should have a doc-comment as per coding-style.
Loading history...
86
     * 设置当前语言
87
     * @access public
88
     * @param  string $name 语言
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $name does not match actual variable name $lang
Loading history...
89
     * @return void
90
     */
91
    public function setLangSet(string $lang): void
92
    {
93
        $this->range = $lang;
94
    }
95
96
    /**
97
     * 获取当前语言
98
     * @access public
99
     * @return string
100
     */
101
    public function getLangSet(): string
102
    {
103
        return $this->range;
104
    }
105
106
    /**
107
     * 获取默认语言
108
     * @access public
109
     * @return string
110
     */
111 6
    public function defaultLangSet()
112
    {
113 6
        return $this->config['default_lang'];
114
    }
115
116
    /**
117
     * 加载语言定义(不区分大小写)
118
     * @access public
119
     * @param  string|array $file   语言文件
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 3 found
Loading history...
120
     * @param  string       $range  语言作用域
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
121
     * @return array
122
     */
123 6
    public function load($file, $range = ''): array
124
    {
125 6
        $range = $range ?: $this->range;
126 6
        if (!isset($this->lang[$range])) {
127 6
            $this->lang[$range] = [];
128
        }
129
130 6
        $lang = [];
131
132 6
        foreach ((array) $file as $_file) {
133 6
            if (is_file($_file)) {
134
                // 记录加载信息
135 1
                $_lang = include $_file;
136 1
                if (is_array($_lang)) {
137 1
                    $lang = array_change_key_case($_lang) + $lang;
138
                }
139
            }
140
        }
141
142 6
        if (!empty($lang)) {
143 1
            $this->lang[$range] = $lang + $this->lang[$range];
144
        }
145
146 6
        return $this->lang[$range];
147
    }
148
149
    /**
150
     * 判断是否存在语言定义(不区分大小写)
151
     * @access public
152
     * @param  string|null $name 语言变量
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
153
     * @param  string      $range 语言作用域
154
     * @return bool
155
     */
156
    public function has(string $name, string $range = ''): bool
157
    {
158
        $range = $range ?: $this->range;
159
160
        if ($this->config['allow_group'] && strpos($name, '.')) {
161
            list($name1, $name2) = explode('.', $name, 2);
162
            return isset($this->lang[$range][strtolower($name1)][$name2]);
163
        }
164
165
        return isset($this->lang[$range][strtolower($name)]);
166
    }
167
168
    /**
169
     * 获取语言定义(不区分大小写)
170
     * @access public
171
     * @param  string|null $name 语言变量
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
172
     * @param  array       $vars 变量替换
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
173
     * @param  string      $range 语言作用域
174
     * @return mixed
175
     */
176
    public function get(string $name = null, array $vars = [], string $range = '')
177
    {
178
        $range = $range ?: $this->range;
179
180
        // 空参数返回所有定义
181
        if (is_null($name)) {
182
            return $this->lang[$range] ?? [];
183
        }
184
185
        if ($this->config['allow_group'] && strpos($name, '.')) {
186
            list($name1, $name2) = explode('.', $name, 2);
187
188
            $value = $this->lang[$range][strtolower($name1)][$name2] ?? $name;
189
        } else {
190
            $value = $this->lang[$range][strtolower($name)] ?? $name;
191
        }
192
193
        // 变量解析
194
        if (!empty($vars) && is_array($vars)) {
195
            /**
196
             * Notes:
197
             * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0
198
             * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数
199
             */
200
            if (key($vars) === 0) {
201
                // 数字索引解析
202
                array_unshift($vars, $value);
203
                $value = call_user_func_array('sprintf', $vars);
204
            } else {
205
                // 关联索引解析
206
                $replace = array_keys($vars);
207
                foreach ($replace as &$v) {
208
                    $v = "{:{$v}}";
209
                }
210
                $value = str_replace($replace, $vars, $value);
211
            }
212
        }
213
214
        return $value;
215
    }
216
217
    /**
218
     * 自动侦测设置获取语言选择
219
     * @access protected
220
     * @return void
221
     */
222
    protected function detect(): void
223
    {
224
        // 自动侦测设置获取语言选择
225
        $langSet = '';
226
227
        if ($this->request->get($this->config['detect_var'])) {
228
            // url中设置了语言变量
229
            $langSet = strtolower($this->request->get($this->config['detect_var']));
230
        } elseif ($this->request->cookie($this->config['cookie_var'])) {
231
            // Cookie中设置了语言变量
232
            $langSet = strtolower($this->request->cookie($this->config['cookie_var']));
233
        } elseif ($this->request->server('HTTP_ACCEPT_LANGUAGE')) {
234
            // 自动侦测浏览器语言
235
            preg_match('/^([a-z\d\-]+)/i', $this->request->server('HTTP_ACCEPT_LANGUAGE'), $matches);
236
            $langSet = strtolower($matches[1]);
237
238
            if (isset($this->config['accept_language'][$langSet])) {
239
                $langSet = $this->config['accept_language'][$langSet];
240
            }
241
        }
242
243
        if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) {
244
            // 合法的语言
245
            $this->range = $langSet;
246
        }
247
    }
248
249
    /**
250
     * 保存当前语言到Cookie
251
     * @access public
252
     * @param  Cookie $cookie Cookie对象
253
     * @return void
254
     */
255
    public function saveToCookie(Cookie $cookie)
256
    {
257
        if ($this->config['use_cookie']) {
258
            $cookie->set($this->config['cookie_var'], $this->range);
259
        }
260
    }
261
262
}
263