Completed
Push — master ( 22855a...c4223d )
by Nikita
05:30 queued 03:23
created

RebuildInternalCacheCommand   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 185
Duplicated Lines 43.24 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 7
dl 80
loc 185
rs 8.3999
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 5 1
A execute() 0 8 1
C rebuildComposerSubscribersCache() 28 28 8
C rebuildBundlesCache() 24 24 7
C rebuildCommandsCache() 28 28 8
A extractClassNameFromFile() 0 19 4
B getFileContents() 0 18 5
A putDataToCacheFile() 0 12 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Taisiya\CoreBundle\Command;
4
5
use Symfony\Component\Console\Input\InputInterface;
6
use Symfony\Component\Console\Output\OutputInterface;
7
use Symfony\Component\Finder\Finder;
8
use Taisiya\CoreBundle\Composer\Event\EventSubscriberInterface;
9
use Taisiya\CoreBundle\Console\Style\TaisiyaStyle;
10
use Taisiya\CoreBundle\Exception\InvalidArgumentException;
11
use Taisiya\CoreBundle\Exception\NotReadableException;
12
use Taisiya\CoreBundle\Exception\RuntimeException;
13
use Taisiya\CoreBundle\Provider\ServiceProvider;
14
15
class RebuildInternalCacheCommand extends Command
16
{
17
    /**
18
     * {@inheritdoc}
19
     */
20
    protected function configure()
21
    {
22
        $this->setName('cache:internal-rebuild')
23
            ->setDescription('Rebuild internal application cache');
24
    }
25
26
    /**
27
     * @param InputInterface $input
28
     * @param OutputInterface $output
29
     */
30
    protected function execute(InputInterface $input, OutputInterface $output)
31
    {
32
        $io = new TaisiyaStyle($input, $output);
33
34
        $this->rebuildComposerSubscribersCache($io);
35
        $this->rebuildBundlesCache($io);
36
        $this->rebuildCommandsCache($io);
37
    }
38
39
    /**
40
     * @param TaisiyaStyle $io
41
     */
42 View Code Duplication
    final protected function rebuildComposerSubscribersCache(TaisiyaStyle $io): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
43
    {
44
        $io->isVerbose() && $io->writeln('Rebuild Composer subscribers cache');
45
46
        $subscribers = [];
47
48
        $finder = Finder::create()
49
            ->in(TAISIYA_ROOT)
50
            ->path('/(src|vendor)/')
51
            ->files()
52
            ->name('*Subscriber.php');
53
54
        foreach ($finder as $k => $file) {
55
            $subscriberClass = $this->extractClassNameFromFile($file->getPathname());
56
            try {
57
                $reflectionClass = new \ReflectionClass($subscriberClass);
58
            } catch (\ReflectionException $e) {
59
                continue;
60
            }
61
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(EventSubscriberInterface::class)) {
62
                $io->isVerbose() && $io->writeln('  + '.$subscriberClass);
63
                $subscribers[] = $subscriberClass;
64
            }
65
        }
66
67
        $this->putDataToCacheFile('composer_subscribers.cache.php', $subscribers);
68
        $io->isVerbose() && $io->writeln('  Subscribers saved to <info>composer_subscribers.cache.php</info>');
69
    }
70
71
    /**
72
     * @param TaisiyaStyle $io
73
     */
74 View Code Duplication
    final protected function rebuildBundlesCache(TaisiyaStyle $io): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
75
    {
76
        $io->isVerbose() && $io->writeln('Rebuild bundles cache');
77
78
        $bundles = [];
79
80
        $finder = Finder::create()
81
            ->in(TAISIYA_ROOT)
82
            ->path('/(src|vendor)/')
83
            ->files()
84
            ->name('*ServiceProvider.php');
85
86
        foreach ($finder as $k => $file) {
87
            $bundleServiceProvider = $this->extractClassNameFromFile($file->getPathname());
88
            $reflectionClass = new \ReflectionClass($bundleServiceProvider);
89
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(ServiceProvider::class)) {
90
                $io->isVerbose() && $io->writeln('  + '.$bundleServiceProvider);
91
                $bundles[] = $bundleServiceProvider;
92
            }
93
        }
94
95
        $this->putDataToCacheFile('bundles.cache.php', $bundles);
96
        $io->isVerbose() && $io->writeln('  Bundles saved to <info>bundles.cache.php</info>');
97
    }
98
99
    /**
100
     * @param TaisiyaStyle $io
101
     */
102 View Code Duplication
    final protected function rebuildCommandsCache(TaisiyaStyle $io): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
103
    {
104
        $io->isVerbose() && $io->writeln('Rebuild commands cache');
105
106
        $commands = [];
107
108
        $finder = Finder::create()
109
            ->in(TAISIYA_ROOT)
110
            ->path('/(src|vendor)/')
111
            ->files()
112
            ->name('*Command.php');
113
114
        foreach ($finder as $k => $file) {
115
            $commandClass = $this->extractClassNameFromFile($file->getPathname());
116
            try {
117
                $reflectionClass = new \ReflectionClass($commandClass);
118
            } catch (\ReflectionException $e) {
119
                continue;
120
            }
121
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(Command::class)) {
122
                $io->isVerbose() && $io->writeln('  + '.$commandClass);
123
                $commands[] = $commandClass;
124
            }
125
        }
126
127
        $this->putDataToCacheFile('commands.cache.php', $commands);
128
        $io->isVerbose() && $io->writeln('  Commands saved to <info>commands.cache.php</info>');
129
    }
130
131
    /**
132
     * @param string $filepath
133
     * @throws RuntimeException
134
     * @return string
135
     */
136
    final protected function extractClassNameFromFile(string $filepath): string
137
    {
138
        $contents = $this->getFileContents($filepath);
139
140
        preg_match('/namespace\s+(.+?)\;/', $contents, $namespace);
141
        if (!is_array($namespace) || !array_key_exists(1, $namespace)) {
142
            $namespace = null;
143
        } else {
144
            $namespace = $namespace[1];
145
        }
146
147
        preg_match('/class\s+(\w+)/', $contents, $class);
148
        if (!array_key_exists(1, $class)) {
149
            throw new RuntimeException('Couldn\'t extract class from file '.$filepath);
150
        }
151
        $class = $class[1];
152
153
        return preg_replace('/\\+/', '\\', implode('\\', ['', $namespace, $class]));
154
    }
155
156
    /**
157
     * @param string $filepath
158
     * @throws InvalidArgumentException
159
     * @throws NotReadableException
160
     * @throws RuntimeException
161
     * @return string
162
     */
163
    final protected function getFileContents(string $filepath): string
164
    {
165
        if (!file_exists($filepath)) {
166
            throw new InvalidArgumentException('File '.$filepath.' not exists');
167
        } elseif (!is_file($filepath)) {
168
            throw new InvalidArgumentException('The '.$filepath.' is not a regular file');
169
        } elseif (!is_readable($filepath)) {
170
            throw new NotReadableException('File '.$filepath.' not readable');
171
        }
172
173
        $contents = file_get_contents($filepath);
174
175
        if ($contents === false) {
176
            throw new RuntimeException('Couldn\'t get contents from file '.$filepath);
177
        }
178
179
        return $contents;
180
    }
181
182
    /**
183
     * @param string $filename
184
     * @param array $data
185
     * @throws RuntimeException
186
     */
187
    final protected function putDataToCacheFile(string $filename, array $data): void
188
    {
189
        $cacheDir = TAISIYA_ROOT.'/var/cache';
190
        if (!file_exists($cacheDir)) {
191
            if (!mkdir($cacheDir, 0777, true)) {
192
                throw new RuntimeException('Couldn\'t create directory '.$cacheDir);
193
            }
194
        }
195
        if (!file_put_contents($cacheDir.'/'.$filename, "<?php\n\nreturn ".var_export($data, true).";\n")) {
196
            throw new RuntimeException('Couldn\'t write contents to file '.$cacheDir.'/'.$filename);
197
        }
198
    }
199
}
200