Passed
Push — master ( 47fbf0...a2ba4c )
by Vicens
06:47
created

Captcha::setConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 5
Ratio 55.56 %

Importance

Changes 0
Metric Value
dl 5
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
/**
3
 * @desc 验证码类
4
 * @author vicens<[email protected]>
5
 */
6
7
8
9
namespace Vicens\Captcha;
10
11
use Symfony\Component\HttpFoundation\Session\Session;
12
13
class Captcha
14
{
15
    const DEFAULT_NAME = 'default';
16
17
    protected $config = [
18
        /**
19
         * 默认验证码长度
20
         * @var int
21
         */
22
        'length' => 4,
23
        /**
24
         * 验证码内容
25
         * @var string
26
         */
27
        'charset' => 'abcdefghijklmnpqrstuvwxyz123456789'
28
    ];
29
30
    /**
31
     * 存储驱动
32
     * @var Session
33
     */
34
    protected $store;
35
36
37
    public function __construct(Session $session, array $config = [])
38
    {
39
        $this->store = $session;
40
41
        $this->setConfig($config);
42
    }
43
44
    /**
45
     * 设置验证码配置
46
     * @param array $config
47
     * @return $this
48
     */
49
    public function setConfig(array $config)
50
    {
51 View Code Duplication
        foreach ($config as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
52
            if (array_key_exists($key, $this->config)) {
53
                $this->config[$key] = $value;
54
            }
55
        }
56
        return $this;
57
    }
58
59
    /**
60
     * 获取配置
61
     * @return array
62
     */
63
    public function getConfig()
64
    {
65
        return $this->config;
66
    }
67
68
    /**
69
     * 生成验证码
70
     * @param string $name
71
     * @param array $config
72
     * @return Image
73
     */
74
    public function make($name = null, array $config = [])
75
    {
76
77
        $config = array_merge($config, $this->config);
78
79
        $code = $this->generate($config['charset'], $config['length']);
80
81
        $this->store($name, $code);
82
83
        return new Image($code, $config);
84
    }
85
86
    /**
87
     * 仅测试正确性, 不删除验证码
88
     * @param $input
89
     * @param string $name
90
     * @return bool
91
     */
92
    public function test($input, $name = null)
93
    {
94
95
        if (!($this->has($name) && $input)) {
96
            return false;
97
        }
98
99
        //返回验证结果
100
        return strtolower($input) == $this->get($name);//password_verify(strtolower($input), $this->get($name));
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
101
    }
102
103
    /**
104
     * 检测正确性,并删除验证码
105
     * @param $input
106
     * @param string $name
107
     * @return bool
108
     */
109
    public function check($input, $name = null)
110
    {
111
        $result = $this->test($input, $name);
112
113
        $this->remove($name);
114
115
        return $result;
116
    }
117
118
    /**
119
     * 生成验证码
120
     * @param array|string $charset
121
     * @param int $length
122
     * @return string
123
     */
124
    protected function generate($charset, $length = 4)
125
    {
126
        $characters = str_split($charset);
127
128
        $code = '';
129
        for ($i = 0; $i < $length; $i++) {
130
            $code .= $characters[rand(0, count($characters) - 1)];
131
        }
132
133
        return $code;
134
    }
135
136
137
    /**
138
     * 加密字符串
139
     * @param $value
140
     * @return bool|string
141
     */
142
    protected function hash($value)
143
    {
144
        $hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => 10));
145
146
        if ($hash === false) {
147
            throw new \RuntimeException('Bcrypt hashing not supported.');
148
        }
149
150
        return $value;
151
    }
152
153
    /**
154
     * 返回存储到session中的键全名
155
     * @param string $name
156
     * @return string
157
     */
158
    protected function getFullName($name)
159
    {
160
        return 'captcha.' . $name ?: self::DEFAULT_NAME;
161
    }
162
163
    /**
164
     * @param $name
165
     * @return bool
166
     */
167
    protected function has($name)
168
    {
169
        return $this->store->has($this->getFullName($name));
170
    }
171
172
    /**
173
     * 存储验证码
174
     * @param $name
175
     * @param $code
176
     */
177
    protected function store($name, $code)
178
    {
179
        $this->store->set($this->getFullName($name), $this->hash(strtolower($code)));
180
    }
181
182
    /**
183
     * 从存储中获取验证码
184
     * @param $name
185
     * @return mixed
186
     */
187
    protected function get($name)
188
    {
189
        return $this->store->get($this->getFullName($name));
190
    }
191
192
    /**
193
     * 从存储中删除验证码
194
     * @param $name
195
     * @return mixed
196
     */
197
    protected function remove($name)
198
    {
199
        return $this->store->remove($this->getFullName($name));
200
    }
201
}