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 cache key for the item. |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
protected $key; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* The raw (unserialized) cached value. |
30
|
|
|
* @var mixed |
31
|
|
|
*/ |
32
|
|
|
protected $value; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Wether the item has been saved to the cache yet. |
36
|
|
|
* @var bool |
37
|
|
|
*/ |
38
|
|
|
protected $hit = false; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* The expiration date. |
42
|
|
|
* @var \DateTime |
43
|
|
|
*/ |
44
|
|
|
protected $expiration; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Constructs a new Item. |
48
|
|
|
* You should never use this directly. It is used internally to create items |
49
|
|
|
* from the pool. |
50
|
|
|
* @param string $key The item key |
51
|
|
|
* @param mixed $value The item value (unserialized) |
52
|
|
|
* @param \DateTime|integer|null $ttl |
53
|
|
|
* @param bool $hit Was this item retrived from cache? |
54
|
|
|
*/ |
55
|
|
|
public function __construct($key, $value = null, $ttl = null, $hit = false) |
56
|
|
|
{ |
57
|
|
|
$this->key = self::normalizedKey($key); |
58
|
|
|
$this->value = $value; |
59
|
|
|
$this->hit = $hit; |
60
|
|
|
$this->expiresAt($ttl); |
|
|
|
|
61
|
1037 |
|
} |
62
|
|
|
|
63
|
1037 |
|
/** |
64
|
34 |
|
* Returns a normalised key. |
65
|
|
|
* |
66
|
34 |
|
* @return string |
67
|
|
|
*/ |
68
|
1037 |
|
public static function normalizedKey($key) |
69
|
1037 |
|
{ |
70
|
1037 |
|
if (!is_string($key) || empty($key) || strpbrk($key, '{}()/\@:') ) { |
71
|
1037 |
|
throw new InvalidArgumentException( |
72
|
1037 |
|
'Item key (' . var_export($key, true) . ') is invalid.' |
73
|
|
|
); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
return $key; |
77
|
459 |
|
} |
78
|
|
|
|
79
|
459 |
|
/** |
80
|
|
|
* {@inheritdoc} |
81
|
|
|
*/ |
82
|
|
|
public function getKey() |
83
|
|
|
{ |
84
|
|
|
return $this->key; |
85
|
493 |
|
} |
86
|
|
|
|
87
|
493 |
|
/** |
88
|
|
|
* {@inheritdoc} |
89
|
|
|
*/ |
90
|
|
|
public function get() |
91
|
|
|
{ |
92
|
|
|
return $this->hit ? $this->value : null; |
93
|
425 |
|
} |
94
|
|
|
|
95
|
425 |
|
/** |
96
|
425 |
|
* {@inheritdoc} |
97
|
|
|
*/ |
98
|
425 |
|
public function set($value = null) |
99
|
|
|
{ |
100
|
|
|
$this->value = $value; |
101
|
|
|
$this->hit = false; |
102
|
|
|
|
103
|
|
|
return $this; |
104
|
493 |
|
} |
105
|
|
|
|
106
|
493 |
|
/** |
107
|
|
|
* {@inheritdoc} |
108
|
|
|
*/ |
109
|
|
|
public function isHit() |
110
|
|
|
{ |
111
|
|
|
return $this->hit && $this->getTtlInSecond() > 0; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* {@inheritdoc} |
116
|
|
|
*/ |
117
|
|
|
public function getExpiration() |
118
|
|
|
{ |
119
|
|
|
return $this->expiration; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Returns the time to live in second. |
124
|
|
|
* |
125
|
|
|
* @return integer |
126
|
|
|
*/ |
127
|
|
|
public function getTtlInSecond() |
128
|
|
|
{ |
129
|
|
|
return $this->expiration->format('U') - time(); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Sets the cache hit for this item. |
134
|
|
|
* |
135
|
|
|
* @param boolean $hit |
136
|
|
|
* @return static The invoked object. |
137
|
|
|
*/ |
138
|
|
|
public function setHit($hit) |
139
|
|
|
{ |
140
|
|
|
$this->hit = (bool) $hit; |
141
|
|
|
|
142
|
|
|
return $this; |
143
|
|
|
} |
144
|
272 |
|
|
145
|
|
|
/** |
146
|
272 |
|
* {@inheritdoc} |
147
|
|
|
*/ |
148
|
|
View Code Duplication |
public function expiresAt($expiration = null) |
|
|
|
|
149
|
|
|
{ |
150
|
|
|
if ($expiration instanceof \DateTime) { |
151
|
|
|
$this->expiration = $expiration; |
152
|
|
|
|
153
|
|
|
} elseif (is_int($expiration)) { |
154
|
493 |
|
$this->expiration = new \DateTime( |
155
|
|
|
'now +' . $expiration . ' seconds' |
156
|
493 |
|
); |
157
|
|
|
|
158
|
|
|
} elseif (null === $expiration) { |
159
|
|
|
$this->expiration = new \DateTime(self::DEFAULT_EXPIRATION); |
160
|
|
|
|
161
|
|
|
} else { |
162
|
|
|
|
163
|
|
|
throw new InvalidArgumentException( |
164
|
|
|
'Integer or \DateTime object expected.' |
165
|
|
|
); |
166
|
425 |
|
} |
167
|
|
|
|
168
|
425 |
|
return $this; |
169
|
|
|
} |
170
|
425 |
|
|
171
|
|
|
/** |
172
|
|
|
* {@inheritdoc} |
173
|
|
|
*/ |
174
|
|
View Code Duplication |
public function expiresAfter($time) |
|
|
|
|
175
|
|
|
{ |
176
|
1037 |
|
if ($time instanceof \DateInterval) { |
177
|
|
|
$this->expiration = new \DateTime(); |
178
|
1037 |
|
$this->expiration->add($time); |
179
|
68 |
|
|
180
|
|
|
} elseif (is_int($time)) { |
181
|
1037 |
|
$this->expiration = new \DateTime('now +' . $time . ' seconds'); |
182
|
221 |
|
|
183
|
221 |
|
} elseif (null === $time) { |
184
|
221 |
|
$this->expiration = new \DateTime(self::DEFAULT_EXPIRATION); |
185
|
|
|
|
186
|
1037 |
|
} else { |
187
|
1037 |
|
|
188
|
|
|
throw new InvalidArgumentException( |
189
|
1037 |
|
'Integer or \DateInterval object expected.' |
190
|
|
|
); |
191
|
34 |
|
} |
192
|
|
|
|
193
|
34 |
|
return $this; |
194
|
|
|
} |
195
|
|
|
|
196
|
1037 |
|
/** |
197
|
|
|
* Returns the item value. |
198
|
|
|
* |
199
|
|
|
* @return string |
200
|
|
|
*/ |
201
|
|
|
public function __toString() |
202
|
170 |
|
{ |
203
|
|
|
return $this->value; |
204
|
170 |
|
} |
205
|
34 |
|
|
206
|
|
|
} |
207
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.