Completed
Pull Request — develop (#542)
by Mathias
09:01
created

ClearCacheService::log()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
c 0
b 0
f 0
ccs 0
cts 4
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
/*
4
 * This file is part of the Yawik project.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Core\Service;
11
12
use Core\Application;
13
use Interop\Container\ContainerInterface;
14
use Symfony\Component\Console\Input\StringInput;
15
use Symfony\Component\Console\Output\ConsoleOutput;
16
use Symfony\Component\Console\Style\SymfonyStyle;
17
use Symfony\Component\Filesystem\Filesystem;
18
use Symfony\Component\Finder\Finder;
19
use Zend\ModuleManager\Listener\ListenerOptions;
20
use Zend\Stdlib\Glob;
21
22
/**
23
 * Class CacheWarmupService
24
 *
25
 * @package Core\Service
26
 * @author Anthonius Munthi <[email protected]>
27
 * @since 0.32
28
 */
29
class ClearCacheService
30
{
31
    /**
32
     * @var ListenerOptions
33
     */
34
    private $options;
35
36
    /**
37
     * @var Filesystem
38
     */
39
    private $filesystem;
40
41
    /**
42
     * @var SymfonyStyle
43
     */
44
    private $io;
45
46
    /**
47
     * Clear cache constructor.
48
     * @param ListenerOptions $options
49
     * @param Filesystem|null $filesystem
50
     */
51 6
    public function __construct(ListenerOptions $options, Filesystem $filesystem = null)
52
    {
53 6
        if (is_null($filesystem)) {
54 1
            $filesystem = new Filesystem();
55
        }
56 6
        $this->options = $options;
57 6
        $this->filesystem = $filesystem;
58 6
        if (php_sapi_name() === 'cli') {
59 6
            $this->io = new SymfonyStyle(new StringInput(''), new ConsoleOutput());
60
        }
61 6
    }
62
63
    /**
64
     * Creates new ClearCacheService object
65
     * @param ContainerInterface $container
66
     * @return ClearCacheService
67
     */
68 1
    public static function factory(ContainerInterface $container)
69
    {
70
        /* @var \Zend\ModuleManager\ModuleManager $manager */
71 1
        $config = $container->get('ApplicationConfig');
72 1
        $options = new ListenerOptions($config['module_listener_options']);
73 1
        return new static($options);
74
    }
75
76
    /**
77
     * Clear all cache files in cache directory.
78
     * Only cleans cache file in path/to/yawik/var/cache/*.php.
79
     * Files in sub cache directory will not be removed
80
     *
81
     * @throws \Exception when cache directory is null
82
     * @throws \Exception when cache directory is not exists or not writable
83
     */
84 5
    public function clearCache()
85
    {
86
        // do not clear cache when cache directory not exists
87 5
        $cacheDir = $this->options->getCacheDir();
88 5
        if (is_null($cacheDir)) {
89 1
            throw new \Exception(sprintf(
90 1
                'Cache directory is not configured properly.'
91
            ));
92
        }
93 4
        if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
94 1
            throw new \Exception(
95 1
                sprintf(
96 1
                    'Can not clear cache in "%s". Please be sure that directory exists and writable.',
97 1
                    $cacheDir
98
                )
99
            );
100
        }
101 3
        $finder = Finder::create()
102 3
            ->in($cacheDir)
103 3
            ->ignoreDotFiles(false)
104 3
            ->name('*.php')
105 3
            ->name('.checksum')
106 3
            ->depth(0)
107
        ;
108
        try {
109 3
            $this->filesystem->remove($finder);
110 3
            return true;
111
        } catch (\Exception $e) {
112
            // just log the error
113
            $this->log('<error>'.$e->getMessage().'</error>');
114
            return false;
115
        }
116
    }
117
118
    /**
119
     * This function will check cache by creating md5 sum
120
     * from all file modification time in config/autoload/*.php.
121
     * If checksum is invalid it will automatically call clear cache.
122
     */
123 1
    public function checkCache()
124
    {
125 1
        $options = $this->options;
126
127 1
        $configDir = Application::getConfigDir();
128
129 1
        $cacheDir = $options->getCacheDir();
130
131 1
        if (!is_dir($cacheDir)) {
132
            mkdir($cacheDir, 0777, true);
133
        }
134
135 1
        $mtimes = [];
136 1
        $mtimes[] = filemtime($configDir.'/config.php');
137
138 1
        foreach ($options->getConfigGlobPaths() as $path) {
139 1
            foreach (Glob::glob($path, Glob::GLOB_BRACE) as $file) {
140 1
                $mtimes[] = filemtime($file);
141
            }
142
        }
143
144 1
        $checksum = md5(serialize($mtimes));
145
146 1
        $checksumFile = $options->getCacheDir().'/.checksum';
147 1
        if (!file_exists($checksumFile)) {
148 1
            touch($checksumFile);
149
        }
150 1
        if (is_readable($checksumFile)) {
151 1
            $cacheSum = file_get_contents($checksumFile);
152 1
            if ($cacheSum != $checksum) {
153 1
                $this->clearCache();
154 1
                file_put_contents($checksumFile, $checksum, LOCK_EX);
155
            }
156
        } else {
157
            $this->log("Can\'t process cache .checksum file is not readable.");
158
        }
159 1
    }
160
161
    private function log($message)
162
    {
163
        $io = $this->io;
164
        if ($io instanceof SymfonyStyle) {
0 ignored issues
show
introduced by
$io is always a sub-type of Symfony\Component\Console\Style\SymfonyStyle.
Loading history...
165
            $io->writeln($message);
166
        }
167
    }
168
}
169