Completed
Push — master ( 3a3730...3061b5 )
by Nikita
04:26
created

RebuildCacheCommand::extractClassNameFromFile()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
cc 4
eloc 12
nc 4
nop 1
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
        $io->section('Search bundles');
27
28
        $bundles = [];
29
30
        $finder = Finder::create()
31
            ->in(TAISIYA_ROOT)
32
            ->path('/(src|vendor)/')
33
            ->files()
34
            ->name('*ServiceProvider.php');
35
36
        foreach ($finder as $k => $file) {
37
            $bundleServiceProvider = $this->extractClassNameFromFile($file->getPathname());
38
            $reflectionClass = new \ReflectionClass($bundleServiceProvider);
39
            if (!$reflectionClass->isAbstract() && $reflectionClass->isSubclassOf(ServiceProvider::class)) {
40
                $output->isVerbose() && $output->write('  + '.$bundleServiceProvider);
41
                $bundles[] = $bundleServiceProvider;
42
            }
43
        }
44
45
        $this->putDataToCacheFile('bundles_providers.cached.php', $bundles);
46
    }
47
48
    final protected function extractClassNameFromFile(string $filepath): string
49
    {
50
        $contents = $this->getFileContents($filepath);
51
52
        preg_match('/namespace\s+(.+?)\;/', $contents, $namespace);
53
        if (!is_array($namespace) || !array_key_exists(1, $namespace)) {
54
            $namespace = null;
55
        } else {
56
            $namespace = $namespace[1];
57
        }
58
59
        preg_match('/class\s+(\w+)/', $contents, $class);
60
        if (!array_key_exists(1, $class)) {
61
            throw new RuntimeException('Couldn\'t extract class from file '.$filepath);
62
        }
63
        $class = $class[1];
64
65
        return preg_replace('/\\+/', '\\', implode('\\', ['', $namespace, $class]));
66
    }
67
68
    /**
69
     * @param string $filepath
70
     * @throws InvalidArgumentException
71
     * @throws NotReadableException
72
     * @throws RuntimeException
73
     * @return string
74
     */
75
    final protected function getFileContents(string $filepath): string
76
    {
77
        if (!file_exists($filepath)) {
78
            throw new InvalidArgumentException('File '.$filepath.' not exists');
79
        } elseif (!is_file($filepath)) {
80
            throw new InvalidArgumentException('The '.$filepath.' is not a regular file');
81
        } elseif (!is_readable($filepath)) {
82
            throw new NotReadableException('File '.$filepath.' not readable');
83
        }
84
85
        $contents = file_get_contents($filepath);
86
87
        if ($contents === false) {
88
            throw new RuntimeException('Couldn\'t get contents from file '.$filepath);
89
        }
90
91
        return $contents;
92
    }
93
94
    /**
95
     * @param string $filename
96
     * @param array $data
97
     * @throws RuntimeException
98
     */
99
    final protected function putDataToCacheFile(string $filename, array $data): void
100
    {
101
        $cacheDir = TAISIYA_ROOT.'/var/cache';
102
        if (!file_exists($cacheDir)) {
103
            if (!mkdir($cacheDir, 0777, true)) {
104
                throw new RuntimeException('Couldn\'t create directory '.$cacheDir);
105
            }
106
        }
107
        if (!file_put_contents($cacheDir.'/'.$filename, "<?php\n\nreturn ".var_export($data, true).";\n")) {
108
            throw new RuntimeException('Couldn\'t write contents to file '.$cacheDir.'/'.$filename);
109
        }
110
    }
111
}
112