Completed
Pull Request — develop (#509)
by ANTHONIUS
21:03
created

ClearCacheService::checkCache()   B

Complexity

Conditions 7
Paths 36

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 8.3946
c 0
b 0
f 0
cc 7
nc 36
nop 0
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
    public function __construct(ListenerOptions $options, Filesystem $filesystem = null)
52
    {
53
        if (is_null($filesystem)) {
54
            $filesystem = new Filesystem();
55
        }
56
        $this->options = $options;
57
        $this->filesystem = $filesystem;
58
        if (php_sapi_name() === 'cli') {
59
            $this->io = new SymfonyStyle(new StringInput(''), new ConsoleOutput());
60
        }
61
    }
62
63
    /**
64
     * Creates new ClearCacheService object
65
     * @param ContainerInterface $container
66
     * @return ClearCacheService
67
     */
68
    public static function factory(ContainerInterface $container)
69
    {
70
        /* @var \Zend\ModuleManager\ModuleManager $manager */
71
        $config = $container->get('ApplicationConfig');
72
        $options = new ListenerOptions($config['module_listener_options']);
73
        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
    public function clearCache()
85
    {
86
        // do not clear cache when cache directory not exists
87
        $cacheDir = $this->options->getCacheDir();
88
        if (is_null($cacheDir)) {
89
            throw new \Exception(sprintf(
90
                'Cache directory is not configured properly.'
91
            ));
92
        }
93
        if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
94
            throw new \Exception(
95
                sprintf(
96
                    'Can not clear cache in "%s". Please be sure that directory exists and writable.',
97
                    $cacheDir
98
                )
99
            );
100
        }
101
        $finder = Finder::create()
102
            ->in($cacheDir)
103
            ->ignoreDotFiles(false)
104
            ->name('*.php')
105
            ->name('.checksum')
106
            ->depth(0)
107
        ;
108
        try {
109
            $this->filesystem->remove($finder);
0 ignored issues
show
Documentation introduced by
$finder is of type object<Symfony\Component\Finder\Finder>, but the function expects a string|object<Symfony\Co...nt\Filesystem\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
110
        } catch (\Exception $e) {
111
            // just log the error
112
            $this->log('<error>'.$e->getMessage().'</error>');
113
        }
114
    }
115
116
    /**
117
     * This function will check cache by creating md5 sum
118
     * from all file modification time in config/autoload/*.php.
119
     * If checksum is invalid it will automatically call clear cache.
120
     */
121
    public function checkCache()
122
    {
123
        $options = $this->options;
124
125
        $configDir = Application::getConfigDir();
126
127
        $cacheDir = $options->getCacheDir();
128
129
        if (!is_dir($cacheDir)) {
130
            mkdir($cacheDir, 0777, true);
131
        }
132
133
        $mtimes = [];
134
        $mtimes[] = filemtime($configDir.'/config.php');
135
136
        foreach ($options->getConfigGlobPaths() as $path) {
137
            foreach (Glob::glob($path, Glob::GLOB_BRACE) as $file) {
138
                $mtimes[] = filemtime($file);
139
            }
140
        }
141
142
        $checksum = md5(serialize($mtimes));
143
144
        $checksumFile = $options->getCacheDir().'/.checksum';
145
        if (!file_exists($checksumFile)) {
146
            touch($checksumFile);
147
        }
148
        if (is_readable($checksumFile)) {
149
            $cacheSum = file_get_contents($checksumFile);
150
            if ($cacheSum != $checksum) {
151
                $this->clearCache();
152
                file_put_contents($checksumFile, $checksum, LOCK_EX);
153
            }
154
        } else {
155
            $this->log("Can\'t process cache .checksum file is not readable.");
156
        }
157
    }
158
159
    private function log($message)
160
    {
161
        $io = $this->io;
162
        if ($io instanceof SymfonyStyle) {
163
            $io->writeln($message);
164
        }
165
    }
166
}
167