1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* |
5
|
|
|
* This file is part of the Apix Project. |
6
|
|
|
* |
7
|
|
|
* (c) Franck Cassedanne <franck at ouarz.net> |
8
|
|
|
* |
9
|
|
|
* @license http://opensource.org/licenses/BSD-3-Clause New BSD License |
10
|
|
|
* |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace Apix\Cache\PsrCache; |
14
|
|
|
|
15
|
|
|
use Psr\Cache\CacheItemInterface as ItemInterface; |
16
|
|
|
use Psr\Cache\CacheItemPoolInterface as ItemPoolInterface; |
17
|
|
|
|
18
|
|
|
class Item implements ItemInterface |
19
|
|
|
{ |
20
|
|
|
const DEFAULT_EXPIRATION = 'now +1 year'; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* The pool that the item belongs to. |
24
|
|
|
* @var ItemPoolInterface |
25
|
|
|
*/ |
26
|
|
|
// protected $pool; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* The cache key for the item. |
30
|
|
|
* @var string |
31
|
|
|
*/ |
32
|
|
|
protected $key; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The raw (unserialized) cached value. |
36
|
|
|
* @var mixed |
37
|
|
|
*/ |
38
|
|
|
protected $value; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Wether the item has been saved to the cache yet. |
42
|
|
|
* @var bool |
43
|
|
|
*/ |
44
|
|
|
protected $hit = false; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* The expiration date. |
48
|
|
|
* @var \DateTime |
49
|
|
|
*/ |
50
|
|
|
protected $expiration; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Constructs a new Item. |
54
|
|
|
* You should never use this directly. It is used internally to create items |
55
|
|
|
* from the pool. |
56
|
|
|
* @param string $key The item key |
57
|
|
|
* @param mixed $value The item value (unserialized) |
58
|
|
|
* @param \DateTime|integer|null $ttl |
59
|
|
|
* @param bool $hit Was this item retrived from cache? |
60
|
|
|
*/ |
61
|
799 |
|
public function __construct($key, $value = null, $ttl = null, $hit = false) |
62
|
|
|
{ |
63
|
799 |
|
if (strpbrk($key, '{}()/\@:')) { |
64
|
34 |
|
throw new InvalidArgumentException( |
65
|
|
|
'Item key contains an invalide character.' . $key |
66
|
34 |
|
); |
67
|
|
|
} |
68
|
799 |
|
$this->key = $key; |
69
|
799 |
|
$this->value = $value; |
70
|
799 |
|
$this->hit = $hit; |
71
|
799 |
|
$this->setExpiration($ttl); |
72
|
799 |
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* {@inheritdoc} |
76
|
|
|
*/ |
77
|
391 |
|
public function getKey() |
78
|
|
|
{ |
79
|
391 |
|
return $this->key; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* {@inheritdoc} |
84
|
|
|
*/ |
85
|
425 |
|
public function get() |
86
|
|
|
{ |
87
|
425 |
|
return $this->hit ? $this->value : null; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* {@inheritdoc} |
92
|
|
|
*/ |
93
|
357 |
|
public function set($value = null) |
94
|
|
|
{ |
95
|
357 |
|
$this->value = $value; |
96
|
357 |
|
$this->hit = false; // TODO: check wether we should we do this? |
97
|
|
|
|
98
|
357 |
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* {@inheritdoc} |
103
|
|
|
*/ |
104
|
425 |
|
public function isHit() |
105
|
|
|
{ |
106
|
425 |
|
return $this->hit; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* {@inheritdoc} |
111
|
|
|
*/ |
112
|
136 |
|
public function exists() |
113
|
|
|
{ |
114
|
|
|
// TODO: review! |
115
|
136 |
|
return $this->hit; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* {@inheritdoc} |
120
|
|
|
*/ |
121
|
34 |
|
public function isRegenerating() |
122
|
|
|
{ |
123
|
34 |
|
return false; // TODO |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* {@inheritdoc} |
128
|
|
|
*/ |
129
|
799 |
View Code Duplication |
public function setExpiration($ttl = null) |
|
|
|
|
130
|
|
|
{ |
131
|
799 |
|
if ($ttl instanceof \DateTime) { |
132
|
68 |
|
$this->expiration = $ttl; |
133
|
799 |
|
} elseif (is_numeric($ttl)) { |
134
|
221 |
|
$this->expiration = new \DateTime('now +' . $ttl . ' seconds'); |
135
|
799 |
|
} elseif (is_null($ttl)) { |
136
|
|
|
// stored permanently or for as long as the default value. |
137
|
799 |
|
$this->expiration = new \DateTime(self::DEFAULT_EXPIRATION); |
138
|
799 |
|
} else { |
139
|
34 |
|
throw new InvalidArgumentException( |
140
|
|
|
'Integer or \DateTime object expected.' |
141
|
34 |
|
); |
142
|
|
|
} |
143
|
|
|
|
144
|
799 |
|
return $this; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* {@inheritdoc} |
149
|
|
|
*/ |
150
|
136 |
|
public function getExpiration() |
151
|
|
|
{ |
152
|
136 |
|
return $this->expiration; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Returns the time to live in second. |
157
|
|
|
* |
158
|
|
|
* @return integer |
159
|
|
|
*/ |
160
|
425 |
|
public function getTtlInSecond() |
161
|
|
|
{ |
162
|
425 |
|
return $this->expiration->format('U') - time(); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Sets the cache hit for this item. |
167
|
|
|
* |
168
|
|
|
* @param boolean $hit |
169
|
|
|
* @return static |
170
|
|
|
* The invoked object. |
171
|
|
|
*/ |
172
|
357 |
|
public function setHit($hit) |
173
|
|
|
{ |
174
|
357 |
|
$this->hit = (bool) $hit; |
175
|
|
|
|
176
|
357 |
|
return $this; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* {@inheritdoc} |
181
|
|
|
*/ |
182
|
|
|
public function expiresAt($expiration) |
183
|
|
|
{ |
184
|
|
|
return $this->setExpiration($expiration); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* {@inheritdoc} |
189
|
|
|
*/ |
190
|
|
View Code Duplication |
public function expiresAfter($time) |
|
|
|
|
191
|
|
|
{ |
192
|
|
|
if ($time instanceof \DateInterval) { |
193
|
|
|
$this->expiration = new \DateTime(); |
194
|
|
|
$this->expiration->add($time); |
195
|
|
|
|
196
|
|
|
} elseif (is_numeric($time)) { |
197
|
|
|
$this->expiration = new \DateTime('now +' . $time . ' seconds'); |
198
|
|
|
|
199
|
|
|
} elseif (null === $time) { |
200
|
|
|
// stored permanently or for as long as the default value. |
201
|
|
|
$this->expiration = new \DateTime(self::DEFAULT_EXPIRATION); |
202
|
|
|
} else { |
203
|
|
|
throw new InvalidArgumentException( |
204
|
|
|
'Integer or \DateInterval object expected.' |
205
|
|
|
); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
return $this; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
} |
212
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.