FileItem   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 206
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 13
c 4
b 1
f 0
lcom 1
cbo 0
dl 0
loc 206
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getKey() 0 4 1
A get() 0 5 1
A set() 0 19 2
A isHit() 0 4 1
A delete() 0 9 2
A exists() 0 5 1
B fromFile() 0 44 5
1
<?php
2
namespace Perry\Cache\File;
3
4
use \DateTime;
5
use Psr\Cache\ItemInterface;
6
7
class FileItem implements ItemInterface
8
{
9
    /**
10
     * @var string
11
     */
12
    private $key;
13
14
    /**
15
     * @var \Serializable
16
     */
17
    private $value = null;
18
19
    /**
20
     * @var int
21
     */
22
    private $ttl = 0;
0 ignored issues
show
Unused Code introduced by
The property $ttl is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
23
24
    /**
25
     * @var \DateTime
26
     */
27
    private $updated;
0 ignored issues
show
Unused Code introduced by
The property $updated is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
28
29
    /**
30
     * @var bool
31
     */
32
    private $hit = false;
33
34
    /**
35
     * @var string
36
     */
37
    private $filename;
38
39
40
    /**
41
     * Returns the key for the current cache item.
42
     *
43
     * The key is loaded by the Implementing Library, but should be available to
44
     * the higher level callers when needed.
45
     *
46
     * @return string
47
     *   The key string for this cache item.
48
     */
49
    public function getKey()
50
    {
51
        return $this->key;
52
    }
53
54
    /**
55
     * Retrieves the value of the item from the cache associated with this objects key.
56
     *
57
     * The value returned must be identical to the value original stored by set().
58
     *
59
     * if isHit() returns false, this method MUST return null. Note that null
60
     * is a legitimate cached value, so the isHit() method SHOULD be used to
61
     * differentiate between "null value was found" and "no value was found."
62
     *
63
     * @return \Serializable|null
64
     *   The value corresponding to this cache item's key, or null if not found.
65
     */
66
    public function get()
67
    {
68
        // we hit the cache when we get the item.. so we allways return the value
69
        return $this->value;
70
    }
71
72
    /**
73
     * Stores a value into the cache.
74
     *
75
     * The $value argument may be any item that can be serialized by PHP,
76
     * although the method of serialization is left up to the Implementing
77
     * Library.
78
     *
79
     * Implementing Libraries MAY provide a default TTL if one is not specified.
80
     * If no TTL is specified and no default TTL has been set, the TTL MUST
81
     * be set to the maximum possible duration of the underlying storage
82
     * mechanism, or permanent if possible.
83
     *
84
     * @param mixed $value
85
     *   The serializable value to be stored.
86
     * @param int|DateTime $ttl
87
     *   - If an integer is passed, it is interpreted as the number of seconds
88
     *     after which the item MUST be considered expired.
89
     *   - If a DateTime object is passed, it is interpreted as the point in
90
     *     time after which the the item MUST be considered expired.
91
     *   - If no value is passed, a default value MAY be used. If none is set,
92
     *     the value should be stored permanently or for as long as the
93
     *     implementation allows.
94
     * @return bool
95
     *   Returns true if the item was successfully saved, or false if there was
96
     *   an error.
97
     */
98
    public function set($value = null, $ttl = null)
99
    {
100
        $now = new DateTime();
101
102
        // whoever came up with the idea of allowing int AND datetime...
103
        // so lets convert this to an int (its a time to live, not a date to delete ffs)
104
        if ($ttl instanceof DateTime) {
105
            $ttl = $ttl->getTimestamp() - $now->getTimestamp();
106
        }
107
108
        $data = [
109
            "updated" => $now,
110
            "value" => $value,
111
            "key" => $this->key,
112
            "ttl" => $ttl
113
        ];
114
115
        return false !== file_put_contents($this->filename, serialize($data));
116
    }
117
118
    /**
119
     * Confirms if the cache item lookup resulted in a cache hit.
120
     *
121
     * Note: This method MUST NOT have a race condition between calling isHit()
122
     * and calling get().
123
     *
124
     * @return bool
125
     *   True if the request resulted in a cache hit.  False otherwise.
126
     */
127
    public function isHit()
128
    {
129
        return $this->hit;
130
    }
131
132
    /**
133
     * Removes the current key from the cache.
134
     *
135
     * @return \Psr\Cache\ItemInterface
136
     *   The current item.
137
     */
138
    public function delete()
139
    {
140
        if (file_exists($this->filename)) {
141
            unlink($this->filename);
142
        }
143
        $this->hit = false;
144
        $this->value = null;
145
        return $this;
146
    }
147
148
    /**
149
     * Confirms if the cache item exists in the cache.
150
     *
151
     * Note: This method MAY avoid retrieving the cached value for performance
152
     * reasons, which could result in a race condition between exists() and get().
153
     *
154
     * @return bool
155
     *  True if item exists in the cache, false otherwise.
156
     */
157
    public function exists()
158
    {
159
        // for us its the same
160
        return $this->isHit();
161
    }
162
163
    /**
164
     * @param string $filename
165
     * @param string $key
166
     * @return FileItem
167
     */
168
    public static function fromFile($filename, $key)
169
    {
170
        $instance = new self();
171
172
        // those are values we already know
173
        $instance->filename = $filename;
174
        $instance->key = $key;
175
176
        if (file_exists($filename)) {
177
178
            // fopen/fread/fclose since file_get_contents seems to not close the files properly
179
            $fp = fopen($filename, "r");
180
181
            // if we for whatever reason can't open this file,
182
            // we have a cache miss
183
            if (false === $fp) {
184
                $instance->hit =false;
185
                return $instance;
186
            }
187
188
            $contents ="";
189
            while (!feof($fp)) {
190
              $contents .= fread($fp, 8192);
191
            }
192
            fclose($fp);
193
194
            $data = unserialize($contents);
195
196
            $now = new \DateTime();
197
198
            /**
199
             * @var \DateTime $updated
200
             */
201
            $updated = $data['updated'];
202
203
            if ($updated->getTimestamp() + $data['ttl'] >= $now->getTimestamp()) {
204
                $instance->value = $data['value'];
205
                $instance->ttl = $data['ttl'];
206
                $instance->updated = $data['updated'];
207
                $instance->hit = true;
208
            }
209
        }
210
        return $instance;
211
    }
212
}
213