CodeGenerator::setLength()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Firesphere\BootstrapMFA\Generators;
4
5
use SilverStripe\Core\Config\Configurable;
6
use SilverStripe\Core\Injector\Injectable;
7
8
/**
9
 * Class CodeGenerator
10
 * Slightly modified version of a generic generator class
11
 * It's modified to fit the SilverStripe config
12
 *
13
 * @package Firesphere\BootstrapMFA\Generators
14
 */
15
class CodeGenerator
16
{
17
    use Configurable;
18
    use Injectable;
19
20
    const CHARS_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
21
22
    const CHARS_LOWER = 'abcdefghijklmnopqrstuvqxyz';
23
24
    const NUMBERS = '0123456789';
25
26
    const CASE_UPPER = 'upper';
27
28
    const CASE_LOWER = 'lower';
29
30
    const CASE_MIXED = 'mixed';
31
32
    const TYPE_ALPHA = 'alpha';
33
34
    const TYPE_NUMERIC = 'numeric';
35
36
    const TYPE_ALNUM = 'alnum';
37
38
    /**
39
     * @var static
40
     */
41
    protected static $global_inst;
42
43
    /**
44
     * @var string
45
     */
46
    private $case;
47
48
    /**
49
     * @var string
50
     */
51
    private $type;
52
53
    /**
54
     * @var integer
55
     */
56
    private $length;
57
58
    /**
59
     * @var string
60
     */
61
    private $validChars;
62
63
    /**
64
     * @return $this
65
     */
66
    public function uppercase()
67
    {
68
        $this->case = self::CASE_UPPER;
69
70
        return $this;
71
    }
72
73
    /**
74
     * @return $this
75
     */
76
    public function lowercase()
77
    {
78
        $this->case = self::CASE_LOWER;
79
80
        return $this;
81
    }
82
83
    /**
84
     * @return $this
85
     */
86
    public function numbersonly()
87
    {
88
        $this->type = self::TYPE_NUMERIC;
89
90
        return $this;
91
    }
92
93
    /**
94
     * @return $this
95
     */
96
    public function charactersonly()
97
    {
98
        $this->type = self::TYPE_ALPHA;
99
100
        return $this;
101
    }
102
103
    /**
104
     * @param string $chars
105
     * @return $this
106
     */
107
    public function setChars($chars)
108
    {
109
        $this->validChars = $chars;
110
111
        return $this;
112
    }
113
114
    /**
115
     * @return string
116
     */
117
    public function __toString()
118
    {
119
        return $this->generate();
120
    }
121
122
    /**
123
     * Generate a random resulting string
124
     *
125
     * @return string
126
     */
127
    public function generate()
128
    {
129
        $chars = $this->validChars();
130
        $numChars = strlen($chars) - 1;
131
        $length = $this->getLength();
132
        $code = array();
133
        for ($i = 0; $i < $length; ++$i) {
134
            $code[] = $chars[random_int(0, $numChars)];
135
        }
136
137
        return implode('', $code);
138
    }
139
140
    /**
141
     * @return string
142
     */
143
    private function validChars()
144
    {
145
        if ($this->validChars) {
146
            return $this->validChars;
147
        }
148
        $chars = array();
149
        $type = $this->getType();
150
        $case = $this->getCase();
151
        if ($type === self::TYPE_ALNUM || $type === self::TYPE_NUMERIC) {
152
            $chars[] = self::NUMBERS;
153
        }
154
        if ($type === self::TYPE_ALNUM || $type === self::TYPE_ALPHA) {
155
            if ($case === self::CASE_MIXED || $case === self::CASE_LOWER) {
156
                $chars[] = self::CHARS_LOWER;
157
            }
158
            if ($case === self::CASE_MIXED || $case === self::CASE_UPPER) {
159
                $chars[] = self::CHARS_UPPER;
160
            }
161
        }
162
163
        return implode('', $chars);
164
    }
165
166
    /**
167
     * @return string One of the type constants of this class
168
     */
169
    public function getType()
170
    {
171
        return $this->type ?: static::global_inst()->getType();
172
    }
173
174
    /**
175
     * @return mixed
176
     */
177
    public static function global_inst()
178
    {
179
        if (!static::$global_inst) {
180
            static::$global_inst = static::create()
181
                ->alphanumeric()
182
                ->mixedcase()
183
                ->setLength(6);
184
        }
185
186
        return static::$global_inst;
187
    }
188
189
    /**
190
     * @return $this
191
     */
192
    public function mixedcase()
193
    {
194
        $this->case = self::CASE_MIXED;
195
196
        return $this;
197
    }
198
199
    /**
200
     * @return $this
201
     */
202
    public function alphanumeric()
203
    {
204
        $this->type = self::TYPE_ALNUM;
205
206
        return $this;
207
    }
208
209
    /**
210
     * @return mixed
211
     */
212
    public function getCase()
213
    {
214
        return $this->case ?: static::global_inst()->getCase();
215
    }
216
217
    /**
218
     * @return mixed
219
     */
220
    public function getLength()
221
    {
222
        return $this->length ?: static::global_inst()->getLength();
223
    }
224
225
    /**
226
     * @param $length
227
     * @return $this
228
     */
229
    public function setLength($length)
230
    {
231
        $this->length = $length;
232
233
        return $this;
234
    }
235
}
236