Issues (23)

src/IdentityService.php (13 issues)

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: zhanglingyu
5
 * Date: 2019-03-06
6
 * Time: 10:57
7
 */
8
9
namespace ArcherZdip\Identity;
10
11
class IdentityService
12
{
13
    /** @var array $attributes */
14
    protected $attributes = [];
15
16
    /** @var array $citys 中国城市列表 */
17
    protected $citys = [];
18
19
    /** @var array $provinces 中国省份列表 */
20
    protected $provinces = [];
21
22
    /** @var array $fillable set param */
23
    protected $fillable = ['province', 'birth', 'sex']; //'city', 'region',
24
25
    /** @var $limit */
0 ignored issues
show
Documentation Bug introduced by
The doc comment $limit at position 0 could not be parsed: Unknown type name '$limit' at position 0 in $limit.
Loading history...
26
    protected $limit;
27
28
    /** @var int 男 */
29
    const MALE = 0;
30
31
    /** @var int 女 */
32
    const FEMALE = 1;
33
34
    /** @var int max limit */
35
    const MAXCOUNT = 100;
36
37
    /**
38
     * Get one chinese id number
39
     *
40
     * @return mixed
41
     * @throws \Exception
42
     */
43
    public function one()
44
    {
45
        return collect($this->generate())->first();
46
    }
47
48
    /**
49
     * Get multiterm chinese id number.
50
     *
51
     * @return \Illuminate\Support\Collection
52
     * @throws \Exception
53
     */
54
    public function get()
55
    {
56
        $ids = [];
57
        for ($i = 0; $i < $this->getLimit(); $i++) {
58
            $ids[] = $this->generate();
59
        }
60
61
        return collect($ids);
62
    }
63
64
    /**
65
     * @param $limit
66
     * @return $this
67
     */
68
    public function limit($limit)
69
    {
70
        $limit = (int)$limit ?: 1;
71
        $limit = ($limit >= self::MAXCOUNT) ? self::MAXCOUNT : $limit;
72
        $this->limit = $limit;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @return string
79
     * @throws \Exception
80
     */
81
    protected function generate()
82
    {
83
        $cityId = $this->calcCityId();
84
        $birth = $this->calcBirth();
85
        $sex = $this->calcSex();
86
87
        // random number
88
        $suffix_a = mt_rand(0, 9);
89
        $suffix_b = mt_rand(0, 9);
90
91
        $base = $cityId . $birth . $suffix_a . $suffix_b . $sex;
92
93
        $idNumber = $base . $this->calcSuffixD($base);
94
        return $idNumber;
95
    }
96
97
    /**
98
     * calc province
99
     *
100
     * @return mixed
101
     */
102
    protected function calcProvince()
103
    {
104
        $province = $this->getProvinces();
105
        // set province
106
        if (!isset($this->attributes['province']) || !in_array($this->attributes['province'], $province->toArray(), true)) {
107
            return $province->random();
108
        }
109
110
        return $this->attributes['province'];
111
    }
112
113
    /**
114
     * @return mixed
115
     * @throws \Exception
116
     */
117
    protected function calcCityId()
118
    {
119
        $province = $this->getProvince();
120
        $list = $this->getCitys()[$province];
121
        if (collect(['澳门特别行政区', '香港特别行政区', '台湾省'])->contains($province)) {
122
            return $list[0]['cityid'];
123
        }
124
125
        $randomId = random_int(1, count($list) - 1);
126
127
        $cityIdList = array_values($list[$randomId])[0];
128
129
        $randomCid = random_int(0, count($cityIdList) - 1);
130
131
        return $cityIdList[$randomCid]['cityid'];
132
    }
133
134
    /**
135
     * Calc sex
136
     * @return $this
137
     * @throws \Exception
138
     */
139
    protected function calcSex()
140
    {
141
        $sex = $this->getSex();
142
        // sex is null , random 1 - 8
143
        if ($sex === false) {
144
            $sex = random_int(1, 8);
145
        } // sex is male
146
        elseif ($sex == self::MALE) {
147
            $sex = 2 * random_int(1, 4) - 1;
148
        } // sex is female
149
        else {
150
            $sex = 2 * random_int(1, 4);
151
        }
152
153
        return $sex;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $sex returns the type integer which is incompatible with the documented return type ArcherZdip\Identity\IdentityService.
Loading history...
154
    }
155
156
    /**
157
     * Get timedate
158
     * param datetime format xxxx-xx-xx
159
     * @return false|string $datetime
160
     */
161
    protected function calcBirth()
162
    {
163
        $birth = $this->getBirth();
164
        //random Datatime
165
        if ($birth === false) {
166
            $startDate = mktime(0, 0, 0, 1, 1, 1950);
167
            $year = date('Y');
168
            $month = date('m');
169
            $day = date('d');
170
            $endDate = mktime(0, 0, 0, $month, $day, $year);
0 ignored issues
show
$day of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
            $endDate = mktime(0, 0, 0, $month, /** @scrutinizer ignore-type */ $day, $year);
Loading history...
$year of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
            $endDate = mktime(0, 0, 0, $month, $day, /** @scrutinizer ignore-type */ $year);
Loading history...
$month of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
            $endDate = mktime(0, 0, 0, /** @scrutinizer ignore-type */ $month, $day, $year);
Loading history...
171
            $birth = mt_rand($startDate, $endDate);
172
            $datetime = date('Ymd', $birth);
173
        } else {
174
            list($year, $month, $day) = explode('-', $birth);
175
            if (!checkdate($month, $day, $year)) {
0 ignored issues
show
$year of type string is incompatible with the type integer expected by parameter $year of checkdate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
            if (!checkdate($month, $day, /** @scrutinizer ignore-type */ $year)) {
Loading history...
$month of type string is incompatible with the type integer expected by parameter $month of checkdate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
            if (!checkdate(/** @scrutinizer ignore-type */ $month, $day, $year)) {
Loading history...
$day of type string is incompatible with the type integer expected by parameter $day of checkdate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
            if (!checkdate($month, /** @scrutinizer ignore-type */ $day, $year)) {
Loading history...
176
                die('Invalided datetime');
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
177
            }
178
            $datetime = $year . $month . $day;
179
        }
180
181
        return $datetime;
182
    }
183
184
    /**
185
     * @param $key
186
     * @param $value
187
     * @return $this
188
     */
189
    protected function setAttributes($key, $value)
190
    {
191
        if ($this->isFillable($key)) {
192
            $this->attributes[$key] = $value;
193
        }
194
195
        return $this;
196
    }
197
198
    /**
199
     * @param $key
200
     * @return bool
201
     */
202
    protected function isFillable($key)
203
    {
204
        if (in_array($key, $this->getFillable())) {
205
            return true;
206
        }
207
208
        return false;
209
    }
210
211
    /**
212
     * @return array
213
     */
214
    protected function getFillable()
215
    {
216
        return $this->fillable;
217
    }
218
219
    /**
220
     * @return mixed
221
     */
222
    protected function getProvince()
223
    {
224
        return $this->calcProvince();
225
    }
226
227
    /**
228
     * @return mixed
229
     */
230
    protected function getSex()
231
    {
232
        return isset($this->attributes['sex']) ? $this->attributes['sex'] : false;
233
    }
234
235
    /**
236
     * @return mixed
237
     */
238
    protected function getBirth()
239
    {
240
        return isset($this->attributes['birth']) ? $this->attributes['birth']: false;
241
    }
242
243
    /**
244
     * @return mixed
245
     */
246
    protected function getLimit()
247
    {
248
        return $this->limit;
249
    }
250
251
    /**
252
     * @param $name
253
     * @param $arguments
254
     * @return IdentityService
255
     */
256
    public function __call($name, $arguments)
257
    {
258
        if (!is_null($arguments) && isset($arguments[0]) ) {
259
            $this->setAttributes($name, $arguments[0]);
260
        }
261
        return $this;
262
    }
263
264
    /**
265
     * @return array
266
     */
267
    protected function getCitys()
268
    {
269
        $this->loadCitys();
270
271
        return $this->citys;
272
    }
273
274
    /**
275
     * @return array
276
     */
277
    protected function getProvinces()
278
    {
279
        $this->loadProvinces();
280
281
        return $this->provinces;
282
    }
283
284
    /**
285
     * Get the provinces from json file
286
     * @return $this
287
     */
288
    protected function loadProvinces()
289
    {
290
        //Get the provinces from json file
291
        if (sizeof($this->provinces) == 0) {
292
            $this->provinces = collect(json_decode(file_get_contents(__DIR__ . '/data/provinces.json'), true));
0 ignored issues
show
Documentation Bug introduced by
It seems like collect(json_decode(file...rovinces.json'), true)) of type Illuminate\Support\Collection is incompatible with the declared type array of property $provinces.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
293
        }
294
        return $this;
295
    }
296
297
    /**
298
     * Get citys from Json file
299
     * @return $this
300
     */
301
    protected function loadCitys()
302
    {
303
        //Get the citys from the JSON file
304
        if (sizeof($this->citys) == 0) {
305
            $this->citys = collect(json_decode(file_get_contents(__DIR__ . '/data/citys.json'), true));
0 ignored issues
show
Documentation Bug introduced by
It seems like collect(json_decode(file...ta/citys.json'), true)) of type Illuminate\Support\Collection is incompatible with the declared type array of property $citys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
306
        }
307
308
        //Return the citys
309
        return $this;
310
    }
311
312
    /**
313
     * calc chinese id number last word
314
     * @param $base
315
     * @return string
316
     */
317
    protected function calcSuffixD($base)
318
    {
319
        if (strlen($base) <> 17) {
320
            die('Invalid Length');
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
321
        }
322
        // 权重
323
        $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
324
        $sums = 0;
325
        for ($i = 0; $i < 17; $i++) {
326
            $sums += substr($base, $i, 1) * $factor[$i];
327
        }
328
329
        $mods = $sums % 11; //10X98765432
330
331
        switch ($mods) {
332
            case 0:
333
                return '1';
334
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
335
            case 1:
336
                return '0';
337
                break;
338
            case 2:
339
                return 'X';
340
                break;
341
            case 3:
342
                return '9';
343
                break;
344
            case 4:
345
                return '8';
346
                break;
347
            case 5:
348
                return '7';
349
                break;
350
            case 6:
351
                return '6';
352
                break;
353
            case 7:
354
                return '5';
355
                break;
356
            case 8:
357
                return '4';
358
                break;
359
            case 9:
360
                return '3';
361
                break;
362
            case 10:
363
                return '2';
364
                break;
365
        }
366
    }
367
}