Completed
Push — master ( 3061b5...033afb )
by Nikita
02:31
created

RebuildCacheCommand::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
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\Console\Style\TaisiyaStyle;
9
use Taisiya\CoreBundle\Exception\InvalidArgumentException;
10
use Taisiya\CoreBundle\Exception\NotReadableException;
11
use Taisiya\CoreBundle\Exception\RuntimeException;
12
use Taisiya\CoreBundle\Provider\ServiceProvider;
13
14
class RebuildCacheCommand extends Command
15
{
16
    protected function configure()
17
    {
18
        $this->setName('cache:rebuild')
19
            ->setDescription('Rebuild internal application cache');
20
    }
21
22
    protected function execute(InputInterface $input, OutputInterface $output)
23
    {
24
        $io = new TaisiyaStyle($input, $output);
25
26
        $this->rebuildBundlesCache($io);
27
        $this->rebuildCommandsCache($io);
28
    }
29
30 View Code Duplication
    final protected function rebuildBundlesCache(TaisiyaStyle $io)
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...
31
    {
32
        $io->isVerbose() && $io->writeln('Rebuild bundles cache');
33
34
        $bundles = [];
35
36
        $finder = Finder::create()
37
            ->in(TAISIYA_ROOT)
38
            ->path('/(src|vendor)/')
39
            ->files()
40
            ->name('*ServiceProvider.php');
41
42
        foreach ($finder as $k => $file) {
43
            $bundleServiceProvider = $this->extractClassNameFromFile($file->getPathname());
44
            $reflectionClass = new \ReflectionClass($bundleServiceProvider);
45
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(ServiceProvider::class)) {
46
                $io->isVerbose() && $io->writeln('  + '.$bundleServiceProvider);
47
                $bundles[] = $bundleServiceProvider;
48
            }
49
        }
50
51
        $this->putDataToCacheFile('bundles.cache.php', $bundles);
52
        $io->isVerbose() && $io->writeln('  Bundles saved to <info>bundles.cache.php</info>');
53
    }
54
55 View Code Duplication
    final protected function rebuildCommandsCache(TaisiyaStyle $io)
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...
56
    {
57
        $io->isVerbose() && $io->writeln('Rebuild commands cache');
58
59
        $commands = [];
60
61
        $finder = Finder::create()
62
            ->in(TAISIYA_ROOT)
63
            ->path('/(src|vendor)/')
64
            ->files()
65
            ->name('*Command.php');
66
67
        foreach ($finder as $k => $file) {
68
            $commandClass = $this->extractClassNameFromFile($file->getPathname());
69
            try {
70
                $reflectionClass = new \ReflectionClass($commandClass);
71
            } catch (\ReflectionException $e) {
72
                continue;
73
            }
74
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(Command::class)) {
75
                $io->isVerbose() && $io->writeln('  + '.$commandClass);
76
                $commands[] = $commandClass;
77
            }
78
        }
79
80
        $this->putDataToCacheFile('commands.cache.php', $commands);
81
        $io->isVerbose() && $io->writeln('  Commands saved to <info>commands.cache.php</info>');
82
    }
83
84
    final protected function extractClassNameFromFile(string $filepath): string
85
    {
86
        $contents = $this->getFileContents($filepath);
87
88
        preg_match('/namespace\s+(.+?)\;/', $contents, $namespace);
89
        if (!is_array($namespace) || !array_key_exists(1, $namespace)) {
90
            $namespace = null;
91
        } else {
92
            $namespace = $namespace[1];
93
        }
94
95
        preg_match('/class\s+(\w+)/', $contents, $class);
96
        if (!array_key_exists(1, $class)) {
97
            throw new RuntimeException('Couldn\'t extract class from file '.$filepath);
98
        }
99
        $class = $class[1];
100
101
        return preg_replace('/\\+/', '\\', implode('\\', ['', $namespace, $class]));
102
    }
103
104
    /**
105
     * @param string $filepath
106
     * @throws InvalidArgumentException
107
     * @throws NotReadableException
108
     * @throws RuntimeException
109
     * @return string
110
     */
111
    final protected function getFileContents(string $filepath): string
112
    {
113
        if (!file_exists($filepath)) {
114
            throw new InvalidArgumentException('File '.$filepath.' not exists');
115
        } elseif (!is_file($filepath)) {
116
            throw new InvalidArgumentException('The '.$filepath.' is not a regular file');
117
        } elseif (!is_readable($filepath)) {
118
            throw new NotReadableException('File '.$filepath.' not readable');
119
        }
120
121
        $contents = file_get_contents($filepath);
122
123
        if ($contents === false) {
124
            throw new RuntimeException('Couldn\'t get contents from file '.$filepath);
125
        }
126
127
        return $contents;
128
    }
129
130
    /**
131
     * @param string $filename
132
     * @param array $data
133
     * @throws RuntimeException
134
     */
135
    final protected function putDataToCacheFile(string $filename, array $data): void
136
    {
137
        $cacheDir = TAISIYA_ROOT.'/var/cache';
138
        if (!file_exists($cacheDir)) {
139
            if (!mkdir($cacheDir, 0777, true)) {
140
                throw new RuntimeException('Couldn\'t create directory '.$cacheDir);
141
            }
142
        }
143
        if (!file_put_contents($cacheDir.'/'.$filename, "<?php\n\nreturn ".var_export($data, true).";\n")) {
144
            throw new RuntimeException('Couldn\'t write contents to file '.$cacheDir.'/'.$filename);
145
        }
146
    }
147
}
148