Completed
Branch master (6f5719)
by Ryuichi
03:47 queued 02:31
created

TemporaryFile::get()   C

Complexity

Conditions 8
Paths 83

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 9.1365

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 17
cts 23
cp 0.7391
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 25
nc 83
nop 1
crap 9.1365
1
<?php
2
namespace WebStream\Cache\Driver;
3
4
use WebStream\DI\Injector;
0 ignored issues
show
Bug introduced by
The type WebStream\DI\Injector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
5
use WebStream\Container\Container;
0 ignored issues
show
Bug introduced by
The type WebStream\Container\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use WebStream\IO\File;
0 ignored issues
show
Bug introduced by
The type WebStream\IO\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use WebStream\Exception\Extend\IOException;
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Extend\IOException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
9
/**
10
 * TemporaryFile
11
 * @author Ryuichi Tanaka
12
 * @since 2015/07/12
13
 * @version 0.7
14
 */
15
class TemporaryFile implements ICache
16
{
17
    use injector;
18
19
    /**
20
     * @var Container キャッシュ依存コンテナ
21
     */
22
    private $cacheContainer;
23
24
    /**
25
     * @var string キャッシュ接頭辞
26
     */
27
    private $cachePrefix;
28
29
    /**
30
     * {@inheritdoc}
31
     */
32
    public function __construct(Container $cacheContainer)
33
    {
34
        $this->cacheContainer = $cacheContainer;
35
        $this->cachePrefix = $this->cacheContainer->cachePrefix . '.' . $this->cacheContainer->classPrefix . '.';
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 4
    public function add($key, $data, $ttl = 0, $overwrite = false): bool
42
    {
43 4
        if (!$this->isAvailableCacheLibrary()) {
44
            return false;
45
        }
46 4
        $key = $this->cachePrefix . $key;
47 4
        $writer = null;
48 4
        $isAppend = !$overwrite;
49
50 4
        $value = base64_encode(serialize([
51 4
            "time" => time(),
52 4
            "ttl" => intval($ttl),
53 4
            "data" => $data
54
        ]));
55
56
        try {
57 4
            $file = new File($this->cacheContainer->cacheDir . '/' . $key . '.cache');
58 4
            $writer = $this->cacheContainer->ioContainer->fileWriter->getWriter($file, $isAppend);
59 4
            $writer->write($value);
60 4
            $this->logger->info("Execute cache save: " . $key);
61 4
            return true;
62
        } catch (IOException $e) {
63
            $this->logger->warn($e->getMessage());
64
            return false;
65
        } finally {
66 4
            if ($writer !== null) {
67
                try {
68 4
                    $writer->close();
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
69 4
                } catch (IOException $ignore) {
70
                    // Nothing to do
71
                }
72
            }
73
        }
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79 4
    public function get($key)
80
    {
81 4
        if (!$this->isAvailableCacheLibrary()) {
82
            return null;
83
        }
84 4
        $key = $this->cachePrefix . $key;
85 4
        $value = null;
86 4
        $reader = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $reader is dead and can be removed.
Loading history...
87 4
        $file = new File($this->cacheContainer->cacheDir . '/' . $key . '.cache');
88
89 4
        if ($file->isReadable()) {
90
            try {
91 2
                $reader = $this->cacheContainer->ioContainer->fileReader->getReader($file);
92 2
                $data = unserialize(base64_decode($reader->read()));
93 2
                if ($data['ttl'] > 0) {
94
                    if (time() > $data['time'] + $data['ttl']) {
95
                        $this->logger->info("Expired cache: " . $key);
96
                        $file->delete();
97
                    }
98
                } else {
99 2
                    $value = $data['data'];
100 2
                    $this->logger->info("Execute cache read: " . $key);
101
                }
102
            } catch (IOException $e) {
103
                $this->logger->warn($e->getMessage());
104 2
            } finally {
105 2
                if ($reader !== null) {
106
                    try {
107 2
                        $reader->close();
108 2
                    } catch (IOException $ignore) {
109
                        // Nothing to do
110
                    }
111
                }
112
            }
113
        }
114
115 4
        return $value;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121 1
    public function delete($key): bool
122
    {
123 1
        if (!$this->isAvailableCacheLibrary()) {
124
            return false;
125
        }
126 1
        $key = $this->cachePrefix . $key;
127 1
        $result = false;
128
129 1
        $file = new File($this->cacheContainer->cacheDir . '/' . $key . '.cache');
130 1
        if ($file->isWritable()) {
131 1
            $result = $file->delete();
132 1
            if ($result) {
133 1
                $this->logger->info("Execute cache cleared: " . $key);
134
            } else {
135
                $this->logger->warn("Failed to clear cache: " . $key);
136
            }
137
        } else {
138
            $this->logger->warn("Failed to clear cache: " . $key);
139
        }
140
141 1
        return $result;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147 1
    public function clear(): bool
148
    {
149 1
        if (!$this->isAvailableCacheLibrary()) {
150
            return false;
151
        }
152 1
        $dir = new File($this->cacheContainer->cacheDir);
153 1
        $result = true;
154
155 1
        if ($dir->isReadable()) {
156 1
            $iterator = $this->cacheContainer->ioContainer->fileIterator->getIterator($dir->getFilePath());
157 1
            foreach ($iterator as $filepath => $fileObject) {
158 1
                if (strpos($filepath, $this->cachePrefix, 0) !== false) {
159
                    try {
160 1
                        $file = new File($filepath);
161 1
                        if ($file->isWritable()) {
162 1
                            if ($file->delete()) {
163 1
                                $this->logger->info("Execute cache cleared: " . $this->cachePrefix . "*");
164
                            } else {
165
                                $this->logger->warn("Failed to clear cache: " . $this->cachePrefix . "*");
166
                                $result = false;
167
                            }
168
                        } else {
169
                            $result = false;
170
                        }
171
                    } catch (IOException $e) {
172
                        $this->logger->warn($e->getMessage());
173 1
                        $result = false;
174
                    }
175
                }
176
            }
177
        } else {
178
            $this->logger->warn("Can't read directory:" . $dir->getFilePath());
179
            $result = false;
180
        }
181
182 1
        return $result;
183
    }
184
185
    /**
186
     * キャッシュライブラリが使用可能か検査する
187
     * @return bool 使用可能でtrue
188
     */
189 4
    private function isAvailableCacheLibrary(): bool
190
    {
191 4
        if ($this->cacheContainer->available) {
192 4
            return true;
193
        }
194
195
        $this->logger->warn("TemporaryFile cache library is unavailable.");
196
197
        return false;
198
    }
199
}
200