Passed
Push — assets ( d7f7f9...9e9406 )
by Arnaud
09:23 queued 06:30
created

Cache   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 168
rs 10
c 0
b 0
f 0
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getRelativePathname() 0 5 1
A getHash() 0 3 1
A removesOldHashFiles() 0 9 2
A isExists() 0 12 4
A getHashFilePathname() 0 10 2
A preparesHashFile() 0 3 1
A getCachePathname() 0 6 1
A save() 0 12 2
A __construct() 0 15 4
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Assets;
12
13
use Cecil\Builder;
14
use Cecil\Config;
15
use Cecil\Util;
16
17
class Cache
18
{
19
    /** @var Builder */
20
    protected $builder;
21
    /** @var Config */
22
    protected $config;
23
    /** @var string */
24
    protected $scope;
25
    /** @var string */
26
    protected $rootPath;
27
28
    /**
29
     * @param Builder $builder
30
     * @param string  $scope
31
     * @param string  $rootPath
32
     */
33
    public function __construct(Builder $builder, string $scope, string $rootPath)
34
    {
35
        $this->builder = $builder;
36
        $this->config = $builder->getConfig();
37
38
        $this->scope = $scope;
39
        $this->rootPath = $rootPath;
40
41
        if ($this->config->get('cache.enabled') === false) {
42
            $cacheDir = Util::joinFile($this->config->getCachePath(), $this->scope);
43
            if (!empty($cacheDir) && is_dir($cacheDir)) {
44
                Util::getFS()->remove($cacheDir);
45
            }
46
47
            return;
48
        }
49
    }
50
51
    /**
52
     * Returns true if cache entry already exists.
53
     *
54
     * @param string $file
55
     *
56
     * @return bool
57
     */
58
    public function isExists(string $file): bool
59
    {
60
        if ($this->config->get('cache.enabled') === false) {
61
            return false;
62
        }
63
64
        if (!Util::getFS()->exists($this->getCachePathname($file))
65
        || !Util::getFS()->exists($this->getHashFilePathname($file))) {
66
            return false;
67
        }
68
69
        return true;
70
    }
71
72
    /**
73
     * Returns MD5 hash of $file.
74
     *
75
     * @param string $file
76
     *
77
     * @return string
78
     */
79
    public function getHash(string $file): string
80
    {
81
        return hash_file('md5', $file);
82
    }
83
84
    /**
85
     * Copying cached file and creates hash file.
86
     *
87
     * @param string      $file
88
     * @param string|null $hash
89
     *
90
     * @return void
91
     */
92
    public function save(string $file, string $hash = null): void
93
    {
94
        if ($this->config->get('cache.enabled') === false) {
95
            return;
96
        }
97
98
        $this->removesOldHashFiles($this->getRelativePathname($file));
99
        // copy file
100
        Util::getFS()->copy($file, $this->getCachePathname($file), true);
101
        // creates hash file
102
        Util::getFS()->mkdir(Util::joinFile($this->config->getCachePath(), Util::joinFile($this->scope, 'hash')));
103
        Util::getFS()->touch($this->getHashFilePathname($file, $hash));
104
    }
105
106
    /**
107
     * Returns path to the from from the $rootPath.
108
     *
109
     * @param string $file
110
     *
111
     * @return string
112
     */
113
    private function getRelativePathname(string $file): string
114
    {
115
        $this->relativePath = trim(Util::getFS()->makePathRelative(dirname($file), $this->rootPath), './');
0 ignored issues
show
Bug Best Practice introduced by
The property relativePath does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
116
117
        return Util::joinFile($this->relativePath, basename($file));
118
    }
119
120
    /**
121
     * Creates cached file path.
122
     *
123
     * @param string $file
124
     *
125
     * @return string
126
     */
127
    private function getCachePathname($file): string
128
    {
129
        return Util::joinFile(
130
            $this->config->getCachePath(),
131
            Util::joinFile($this->scope, 'files'),
132
            $this->getRelativePathname($file)
133
        );
134
    }
135
136
    /**
137
     * Creates file hash.
138
     *
139
     * @param string      $file
140
     * @param string|null $hash
141
     *
142
     * @return string
143
     */
144
    private function getHashFilePathname(string $file, string $hash = null): string
145
    {
146
        if ($hash === null) {
147
            $hash = $this->getHash($file);
148
        }
149
150
        return Util::joinFile(
151
            $this->config->getCachePath(),
152
            Util::joinFile($this->scope, 'hash'),
153
            $this->preparesHashFile($this->getRelativePathname($file)).$hash
154
        );
155
    }
156
157
    /**
158
     * Prepares hash file path.
159
     *
160
     * @param string $path
161
     *
162
     * @return string
163
     */
164
    private function preparesHashFile(string $path): string
165
    {
166
        return str_replace(DIRECTORY_SEPARATOR, '-', $path).'_';
167
    }
168
169
    /**
170
     * Removes previous hash files.
171
     *
172
     * @param string $path
173
     *
174
     * @return void
175
     */
176
    private function removesOldHashFiles(string $path): void
177
    {
178
        $pattern = Util::joinFile(
179
            $this->config->getCachePath(),
180
            Util::joinFile($this->scope, 'hash'),
181
            $this->preparesHashFile($path)
182
        ).'*';
183
        foreach (glob($pattern) as $filename) {
184
            Util::getFS()->remove($filename);
185
        }
186
    }
187
}
188