GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

GenerateCommand   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 8
dl 0
loc 164
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 6 1
A execute() 0 22 1
A getCurrentConstants() 0 6 1
A getCurrentMethods() 0 10 1
A emojiToUnicodeHex() 0 6 1
A retrieveRemoteFile() 0 11 2
A parseResponse() 0 12 1
A deprecatedConstants() 0 23 4
A deprecatedMethods() 0 22 4
A writeClass() 0 16 1
1
<?php
2
3
namespace Spatie\Emoji\Generator\Console;
4
5
use GuzzleHttp\Client;
6
use ReflectionClass;
7
use Spatie\Emoji\Emoji;
8
use Spatie\Emoji\Generator\Parser;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Twig\Environment;
13
use Twig\Loader\FilesystemLoader;
14
15
class GenerateCommand extends Command
16
{
17
    /** @var string */
18
    protected const EMOJI_VERSION = '13.1';
19
20
    /** @var int */
21
    protected $now;
22
23
    /** @var string */
24
    protected $deprecationNotice = '# deprecations'.PHP_EOL;
25
26
    /** @var \Spatie\Emoji\Generator\Emoji[] */
27
    protected $emojis;
28
29
    /** @var array[] */
30
    protected $emojisArray;
31
32
    /** @var array[] */
33
    protected $groups;
34
35
    protected function configure()
36
    {
37
        $this
38
            ->setName('generate')
39
            ->setDescription('Generate the package code from the emoji docs');
40
    }
41
42
    protected function execute(InputInterface $input, OutputInterface $output)
43
    {
44
        $this->now = time();
45
        $output->writeln('Generating package code...');
46
47
        $output->writeln('Load file...');
48
        $url = 'https://unicode.org/Public/emoji/'.self::EMOJI_VERSION.'/emoji-test.txt';
49
        $body = $this->retrieveRemoteFile($url);
50
51
        $output->writeln('Parse response...');
52
        $this->parseResponse($body);
53
        $this->deprecatedConstants();
54
        $this->deprecatedMethods();
55
        file_put_contents(__DIR__.'/../temp/'.date('Y_m_d-H_i_s', $this->now).'_deprecations.md', $this->deprecationNotice);
56
57
        $output->writeln('Generate class...');
58
        $this->writeClass($url);
59
60
        $output->writeln('Done!');
61
62
        return 0;
63
    }
64
65
    protected function getCurrentConstants(): array
66
    {
67
        $reflection = new ReflectionClass(Emoji::class);
68
69
        return array_keys($reflection->getConstants());
70
    }
71
72
    protected function getCurrentMethods(): array
73
    {
74
        $reflection = new ReflectionClass(Emoji::class);
75
76
        $docComment = $reflection->getDocComment();
77
78
        preg_match_all('/\@method static string ([\w]+)\(\)/', $docComment, $matches);
79
80
        return $matches[1] ?? [];
81
    }
82
83
    protected function emojiToUnicodeHex(string $emoji)
84
    {
85
        return '\u{'.implode('}\u{', array_map(function ($hex) {
86
            return mb_strtoupper(ltrim($hex, '0'));
87
        }, str_split(bin2hex(mb_convert_encoding($emoji, 'UTF-32', 'UTF-8')), 8))).'}';
88
    }
89
90
    protected function retrieveRemoteFile(string $url)
91
    {
92
        $client = new Client();
93
        $response = $client->get($url);
94
95
        if ($response->getStatusCode() !== 200) {
96
            throw new \RuntimeException('unable to load '.$url);
97
        }
98
99
        return $response->getBody();
100
    }
101
102
    protected function parseResponse(string $body)
103
    {
104
        file_put_contents(__DIR__.'/../temp/'.date('Y_m_d-H_i_s', $this->now).'_response.txt', $body);
105
        $parser = new Parser($body);
106
        $parser->parse();
107
        $this->emojis = $parser->getEmojis();
108
        $this->emojisArray = json_decode(json_encode($this->emojis), true);
109
        $this->groups = $parser->getGroups();
110
        file_put_contents(__DIR__.'/../temp/'.date('Y_m_d-H_i_s', $this->now).'_emojis.json', json_encode($this->emojis));
111
        file_put_contents(__DIR__.'/../../tests/emojis.json', json_encode($this->emojis));
112
        file_put_contents(__DIR__.'/../temp/'.date('Y_m_d-H_i_s', $this->now).'_groups.json', json_encode($this->groups));
113
    }
114
115
    protected function deprecatedConstants()
116
    {
117
        $currentConstants = $this->getCurrentConstants();
118
        $deprecatedConstants = array_values(array_diff($currentConstants, array_column($this->emojisArray, 'const')));
119
120
        if (! empty($deprecatedConstants)) {
121
            $codeToConstant = array_combine(array_column($this->emojisArray, 'code'), array_column($this->emojisArray, 'const'));
122
            $this->deprecationNotice .= PHP_EOL.'## deprecated constants'.PHP_EOL.PHP_EOL;
123
            foreach ($deprecatedConstants as $deprecatedConstant) {
124
                $emoji = constant(Emoji::class.'::'.$deprecatedConstant);
125
                $emojiCode = $this->emojiToUnicodeHex($emoji);
126
                $replacedBy = $codeToConstant[$emojiCode] ?? null;
127
128
                $this->deprecationNotice .= sprintf(
129
                        '* %s *%s* `%s` => `%s`',
130
                        $emoji,
131
                        $emojiCode,
132
                        Emoji::class.'::'.$deprecatedConstant,
133
                        ($replacedBy ? Emoji::class.'::'.$replacedBy : 'N/A')
134
                    ).PHP_EOL;
135
            }
136
        }
137
    }
138
139
    protected function deprecatedMethods()
140
    {
141
        $currentMethods = $this->getCurrentMethods();
142
        $deprecatedMethods = array_values(array_diff($currentMethods, array_column($this->emojisArray, 'method')));
143
        if (! empty($deprecatedMethods)) {
144
            $codeToMethod = array_combine(array_column($this->emojisArray, 'code'), array_column($this->emojisArray, 'method'));
145
            $this->deprecationNotice .= PHP_EOL.'## deprecated methods'.PHP_EOL.PHP_EOL;
146
            foreach ($deprecatedMethods as $deprecatedMethod) {
147
                $emoji = Emoji::{$deprecatedMethod}();
148
                $emojiCode = $this->emojiToUnicodeHex($emoji);
149
                $replacedBy = $codeToMethod[$emojiCode] ?? null;
150
151
                $this->deprecationNotice .= sprintf(
152
                        '* %s *%s* `%s` => `%s`',
153
                        $emoji,
154
                        $emojiCode,
155
                        Emoji::class.'::'.$deprecatedMethod.'()',
156
                        ($replacedBy ? Emoji::class.'::'.$replacedBy.'()' : 'N/A')
157
                    ).PHP_EOL;
158
            }
159
        }
160
    }
161
162
    protected function writeClass(string $url)
163
    {
164
        $loader = new FilesystemLoader(__DIR__.'/../templates');
165
        $twig = new Environment($loader, [
166
            'cache' => false,
167
            'autoescape' => false,
168
        ]);
169
        $class = $twig->load('Emoji.twig')->render([
170
            'url' => $url,
171
            'loaded_at' => $this->now,
172
            'version' => 'v'.self::EMOJI_VERSION,
173
            'groups' => $this->groups,
174
        ]);
175
        file_put_contents(__DIR__.'/../temp/'.date('Y_m_d-H_i_s', $this->now).'.php', $class);
176
        file_put_contents(__DIR__.'/../../src/Emoji.php', $class);
177
    }
178
}
179