Nickname::getFile()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
namespace SimpleCMS\Nickname\Packages;
4
5
use Exception;
6
use function mt_rand;
7
use function shuffle;
8
use function finfo_file;
9
use function finfo_open;
10
use function file_exists;
11
use function finfo_close;
12
use function array_filter;
13
use function array_values;
14
use function array_key_exists;
15
16
class Nickname
17
{
18
    protected string $mode;
19
    protected int $append_length;
20
    protected array $paths = [];
21
    protected array $dicts = [];
22
    protected array $adjectiveDicts = [];
23
24
    public function __construct()
25
    {
26
        $this->mode = config('cms_nickname.mode', 'name');
27
        $this->append_length = (int) config('cms_nickname.append_length', 4);
28
        $this->paths = (array) config('cms_nickname.dicts', []);
29
    }
30
31
    private function loadDict(): void
32
    {
33
        $dictPath = $this->getFile($this->mode);
34
        $this->dicts = [];
35
        if ($this->isJsonFile($dictPath)) {
36
            $this->dicts = array_merge($this->dicts, json_decode(file_get_contents($dictPath), true));
37
        }
38
        $this->loadAdjective();
39
    }
40
41
    private function loadAdjective(): void
42
    {
43
        if ($this->mode == 'noun') {
44
            $dictPath = $this->getFile('adjective');
45
            $this->adjectiveDicts = [];
46
            if ($this->isJsonFile($dictPath)) {
47
                $this->adjectiveDicts = array_merge($this->adjectiveDicts, json_decode(file_get_contents($dictPath), true));
48
            }
49
        }
50
    }
51
52
    private function getPath(string $name): string
53
    {
54
        return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $name . '.json';
55
    }
56
57
    private function getFile(string $name): string
58
    {
59
        $defaultPath = $this->getPath($name);
60
        if (array_key_exists($name, $this->paths) && $this->paths[$name]) {
61
            $defaultPath = $this->paths[$name];
62
        }
63
        return $defaultPath;
64
    }
65
66
    private function isJsonFile(string $path): bool
67
    {
68
        if (!file_exists($path)) {
69
            throw new Exception("The file does not exist.");
70
        }
71
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
72
        $mimeType = finfo_file($finfo, $path);
73
        finfo_close($finfo);
74
        return $mimeType == 'application/json';
75
    }
76
77
    /**
78
     * @param int $num
79
     * @return array|string
80
     */
81
    public function generate(int $num = 1): array|string
82
    {
83
        $this->loadDict();
84
        $num = $num < 1 ? 1 : $num;
85
        $nicknames = [];
86
        for ($i = 0; $i < $num; $i++) {
87
            $nickname = $this->generateNickname();
88
            $nicknames[] = $nickname;
89
        }
90
        $this->clearDict();
91
        return $num == 1 ? head($nicknames) : $nicknames;
92
    }
93
94
    private function clearDict(): void
95
    {
96
        $this->dicts = [];
97
        $this->adjectiveDicts = [];
98
    }
99
100
    private function generateNickname(): string
101
    {
102
        return match ($this->mode) {
103
            'name' => $this->generateNameNickname(),
104
            'noun' => $this->generateNounNickname(),
105
            'nickname' => $this->generateSingleNickname(),
106
            default => $this->generateSingleNickname()
107
        };
108
    }
109
110
    private function generateNameNickname(): string
111
    {
112
        $nameDicts = array_values(array_filter($this->dicts));
113
        shuffle($nameDicts);
114
        return $nameDicts[0] . $nameDicts[1] . $this->generateRandomNumbers($this->append_length);
115
    }
116
117
    private function generateNounNickname(): string
118
    {
119
        $adjectiveDicts = array_values(array_filter($this->adjectiveDicts));
120
        shuffle($adjectiveDicts);
121
        $nameDicts = array_values(array_filter($this->dicts));
122
        shuffle($nameDicts);
123
        return $adjectiveDicts[0] . $nameDicts[0] . $this->generateRandomNumbers($this->append_length);
124
    }
125
126
    private function generateSingleNickname(): string
127
    {
128
        $nameDicts = array_values(array_filter($this->dicts));
129
        shuffle($nameDicts);
130
        return $nameDicts[0] . $this->generateRandomNumbers($this->append_length);
131
    }
132
133
    private function generateRandomNumbers(int $length): string
134
    {
135
        $randomNumbers = '';
136
        for ($i = 0; $i < $length; $i++) {
137
            $randomNumbers .= mt_rand(0, 9);
138
        }
139
        return $randomNumbers;
140
    }
141
}