Completed
Push — 6.0 ( 0362ee...eb7ea2 )
by liu
02:40
created

Lang::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 6
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
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
    protected $config = [
22
        // 默认语言
23
        'default_lang'    => 'zh-cn',
24
        // 允许的语言列表
25
        'allow_lang_list' => [],
26
        // 自动侦测和切换
27
        'auto_detect'     => false,
28
        // 是否使用Cookie记录
29
        'use_cookie'      => true,
30
        // 扩展语言包
31
        'extend_list'     => [],
32
        // 多语言cookie变量
33
        'cookie_var'      => 'think_lang',
34
        // 多语言自动侦测变量名
35
        'detect_var'      => 'lang',
36
        // Accept-Language转义为对应语言包名称
37
        'accept_language' => [
38
            'zh-hans-cn' => 'zh-cn',
39
        ],
40
    ];
41
42
    /**
43
     * 多语言信息
44
     * @var array
45
     */
46
    private $lang = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "lang" must be prefixed with an underscore
Loading history...
47
48
    /**
49
     * 当前语言
50
     * @var string
51
     */
52
    private $range = 'zh-cn';
0 ignored issues
show
Coding Style introduced by
Private member variable "range" must be prefixed with an underscore
Loading history...
53
54
    /**
55
     * Request对象
56
     * @var Request
57
     */
58
    protected $request;
59
60
    /**
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...
61
     * 构造方法
62
     * @access public
63
     */
64
    public function __construct(Request $request, array $config = [])
65
    {
66
        $this->request = $request;
67
        $this->config  = array_merge($this->config, array_change_key_case($config));
68
        $this->range   = $this->config['default_lang'];
69
70
        if ($this->config['auto_detect']) {
71
            $this->detect();
72
        }
73
    }
74
75
    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...
76
    {
77
        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

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