Passed
Push — 6.0 ( 1fbc9a...13b6d9 )
by liu
03:06
created

Cookie   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 308
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 89
dl 0
loc 308
rs 8.5599
c 0
b 0
f 0
wmc 48

15 Methods

Rating   Name   Duplication   Size   Complexity  
A jsonFormatProtect() 0 4 4
A setData() 0 3 1
B clear() 0 24 7
A has() 0 8 3
A init() 0 6 3
B get() 0 31 9
A __construct() 0 3 1
A __destruct() 0 6 3
A delete() 0 12 3
A prefix() 0 7 2
A setCookie() 0 3 1
A getCookie() 0 3 1
A set() 0 28 6
A __make() 0 3 1
A forever() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like Cookie often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Cookie, and based on these observations, apply Extract Interface, too.

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 Cookie
1 ignored issue
show
Coding Style introduced by
Missing class doc comment
Loading history...
16
{
17
    /**
18
     * 配置参数
19
     * @var array
20
     */
21
    protected $config = [
22
        // cookie 名称前缀
23
        'prefix'     => '',
24
        // cookie 保存时间
25
        'expire'     => 0,
26
        // cookie 保存路径
27
        'path'       => '/',
28
        // cookie 有效域名
29
        'domain'     => '',
30
        //  cookie 启用安全传输
31
        'secure'     => false,
32
        // httponly设置
33
        'httponly'   => false,
34
        // 是否使用 setcookie
35
        'setcookie'  => true,
36
        // 是否自动写入
37
        'auto_write' => true,
38
    ];
39
40
    /**
41
     * 是否初始化
42
     * @var bool
43
     */
44
    protected $init;
45
46
    /**
47
     * Cookie数据
48
     * @var array
49
     */
50
    protected $data = [];
51
52
    /**
53
     * Cookie写入数据
54
     * @var array
55
     */
56
    protected $cookie = [];
57
58
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $config should have a doc-comment as per coding-style.
Loading history...
59
     * 构造方法
60
     * @access public
61
     */
62
    public function __construct(array $config = [])
63
    {
64
        $this->init($config);
65
    }
66
67
    public static function __make(Config $config)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Method name "Cookie::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
68
    {
69
        return (new static($config->get('cookie')))->setData($_COOKIE);
0 ignored issues
show
Bug introduced by
It seems like $config->get('cookie') can also be of type null; however, parameter $config of think\Cookie::__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

69
        return (new static(/** @scrutinizer ignore-type */ $config->get('cookie')))->setData($_COOKIE);
Loading history...
Bug introduced by
Are you sure the usage of new static($config->get(...e'))->setData($_COOKIE) targeting think\Cookie::setData() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
70
    }
71
72
    /**
73
     * Cookie初始化
74
     * @access public
75
     * @param  array $config
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
76
     * @return void
77
     */
78
    public function init(array $config = []): void
79
    {
80
        $this->config = array_merge($this->config, array_change_key_case($config));
81
82
        if (!empty($this->config['httponly']) && PHP_SESSION_ACTIVE != session_status()) {
83
            ini_set('session.cookie_httponly', '1');
84
        }
85
    }
86
87
    /**
88
     * 设置cookie数据
89
     * @access public
90
     * @param  array $data
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
91
     * @return void
92
     */
93
    public function setData(array $data): void
94
    {
95
        $this->data = $data;
96
    }
97
98
    /**
99
     * 获取cookie保存数据
100
     * @access public
101
     * @return array
102
     */
103
    public function getCookie(): array
104
    {
105
        return $this->cookie;
106
    }
107
108
    /**
109
     * 设置或者获取cookie作用域(前缀)
110
     * @access public
111
     * @param  string $prefix
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
112
     * @return string|void
113
     */
114
    public function prefix(string $prefix = '')
115
    {
116
        if (empty($prefix)) {
117
            return $this->config['prefix'];
118
        }
119
120
        $this->config['prefix'] = $prefix;
121
    }
122
123
    /**
124
     * Cookie 设置
125
     *
126
     * @access public
127
     * @param  string               $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
128
     * @param  mixed                $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
129
     * @param  null|integer|array   $option 可选参数 可能会是
130
     * @return void
131
     */
132
    public function set(string $name, $value = '', $option = null): void
133
    {
134
        !isset($this->init) && $this->init();
135
136
        // 参数设置(会覆盖黙认设置)
137
        if (!is_null($option)) {
138
            if (is_numeric($option)) {
139
                $option = ['expire' => $option];
140
            }
141
142
            $config = array_merge($this->config, array_change_key_case($option));
143
        } else {
144
            $config = $this->config;
145
        }
146
147
        $name = $config['prefix'] . $name;
148
149
        // 设置cookie
150
        if (is_array($value)) {
151
            array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'encode');
152
            $value = 'think:' . json_encode($value);
153
        }
154
155
        $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;
156
157
        $this->data[$name] = $value;
158
159
        $this->setCookie($name, (string) $value, $expire, $config);
160
    }
161
162
    /**
163
     * Cookie 保存
164
     *
165
     * @access public
166
     * @param  string $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
167
     * @param  mixed  $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
168
     * @param  int    $expire 有效期
169
     * @param  array  $option 可选参数
170
     * @return void
171
     */
172
    protected function setCookie(string $name, string $value, int $expire, array $option = []): void
173
    {
174
        $this->cookie[$name] = [$value, $expire, $option];
175
    }
176
177
    /**
178
     * 永久保存Cookie数据
179
     * @access public
180
     * @param  string $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
181
     * @param  mixed  $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
182
     * @param  mixed  $option 可选参数 可能会是 null|integer|string
183
     * @return void
184
     */
185
    public function forever(string $name, $value = '', $option = null): void
186
    {
187
        if (is_null($option) || is_numeric($option)) {
188
            $option = [];
189
        }
190
191
        $option['expire'] = 315360000;
192
193
        $this->set($name, $value, $option);
194
    }
195
196
    /**
197
     * 判断Cookie数据
198
     * @access public
199
     * @param  string        $name cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
200
     * @param  string|null   $prefix cookie前缀
201
     * @return bool
202
     */
203
    public function has(string $name, string $prefix = null): bool
204
    {
205
        !isset($this->init) && $this->init();
206
207
        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
208
        $name   = $prefix . $name;
209
210
        return isset($this->data[$name]);
211
    }
212
213
    /**
214
     * Cookie获取
215
     * @access public
216
     * @param  string        $name cookie名称 留空获取全部
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
217
     * @param  string|null   $prefix cookie前缀
218
     * @return mixed
219
     */
220
    public function get(string $name = '', string $prefix = null)
221
    {
222
        !isset($this->init) && $this->init();
223
224
        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
225
        $key    = $prefix . $name;
226
227
        if ('' == $name) {
228
            if ($prefix) {
229
                $value = [];
230
                foreach ($this->data as $k => $val) {
231
                    if (0 === strpos($k, $prefix)) {
232
                        $value[$k] = $val;
233
                    }
234
                }
235
            } else {
236
                $value = $this->data;
237
            }
238
        } elseif (isset($this->data[$key])) {
239
            $value = $this->data[$key];
240
241
            if (0 === strpos($value, 'think:')) {
242
                $value = substr($value, 6);
243
                $value = json_decode($value, true);
244
                array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'decode');
245
            }
246
        } else {
247
            $value = null;
248
        }
249
250
        return $value;
251
    }
252
253
    /**
254
     * Cookie删除
255
     * @access public
256
     * @param  string        $name cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
257
     * @param  string|null   $prefix cookie前缀
258
     * @return void
259
     */
260
    public function delete(string $name, string $prefix = null): void
261
    {
262
        !isset($this->init) && $this->init();
263
264
        $config = $this->config;
265
        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
266
        $name   = $prefix . $name;
267
268
        $this->setCookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config);
269
270
        // 删除指定cookie
271
        unset($this->data[$name]);
272
    }
273
274
    /**
275
     * Cookie清空
276
     * @access public
277
     * @param  string|null $prefix cookie前缀
278
     * @return void
279
     */
280
    public function clear(string $prefix = null): void
281
    {
282
        // 清除指定前缀的所有cookie
283
        if (empty($this->data)) {
284
            return;
285
        }
286
287
        !isset($this->init) && $this->init();
288
289
        // 要删除的cookie前缀,不指定则删除config设置的指定前缀
290
        $config = $this->config;
291
        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
292
293
        if ($prefix) {
294
            // 如果前缀为空字符串将不作处理直接返回
295
            foreach ($this->data as $key => $val) {
296
                if (0 === strpos($key, $prefix)) {
297
                    $this->setCookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config);
298
                    unset($this->data[$key]);
299
                }
300
            }
301
        }
302
303
        return;
304
    }
305
306
    private function jsonFormatProtect(&$val, $key, $type = 'encode')
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Private method name "Cookie::jsonFormatProtect" must be prefixed with an underscore
Loading history...
307
    {
308
        if (!empty($val) && true !== $val) {
309
            $val = 'decode' == $type ? urldecode($val) : urlencode((string) $val);
310
        }
311
    }
312
313
    /**
314
     * 析构方法
315
     * @access public
316
     */
317
    public function __destruct()
318
    {
319
        if ($this->config['auto_write']) {
320
            foreach ($this->cookie as $name => $val) {
321
                list($value, $expire, $option) = $val;
322
                setCookie($name, $value, $option['path'], $option['domain'], $option['secure'], $option['httponly']);
323
            }
324
        }
325
    }
326
}
327