This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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; |
||
14 | |||
15 | /** |
||
16 | * Mongo cache wrapper. |
||
17 | * |
||
18 | * @author Franck Cassedanne <franck at ouarz.net> |
||
19 | */ |
||
20 | class Mongo extends AbstractCache |
||
21 | { |
||
22 | |||
23 | /** |
||
24 | * Holds the array of TTLs. |
||
25 | * @var array |
||
26 | */ |
||
27 | protected $ttls = array(); |
||
28 | |||
29 | /** |
||
30 | * Holds the MongoDB object |
||
31 | * @var \MongoDB|Mongo\DatabaseAdapter |
||
32 | */ |
||
33 | public $db; |
||
34 | |||
35 | /** |
||
36 | * Holds the MongoCollection object |
||
37 | * @var \MongoCollection|Mongo\CollectionAdapter |
||
38 | */ |
||
39 | public $collection; |
||
40 | |||
41 | /** |
||
42 | * Indicates the use of the legacy \MongoClient. |
||
43 | * @var bool |
||
44 | */ |
||
45 | private $is_legacy = false; |
||
46 | |||
47 | 57 | /** |
|
48 | * Constructor. Sets the Mongo DB adapter. |
||
49 | * |
||
50 | 57 | * @param \MongoClient|\MongoDB\Client $Mongo A Mongo client instance. |
|
51 | 57 | * @param array $options Array of options. |
|
52 | 57 | */ |
|
53 | public function __construct($Mongo, array $options=null) |
||
54 | { |
||
55 | 57 | if (!is_a($Mongo, '\MongoDB\Client') && !is_a($Mongo, '\MongoClient')) { |
|
56 | throw new \InvalidArgumentException( |
||
57 | 57 | 'Expected instance of "\MongoDB\Client" or "\MongoClient"' |
|
58 | 57 | ); |
|
59 | 57 | } |
|
60 | |||
61 | 57 | // default options |
|
62 | $this->options['db_name'] = 'apix'; |
||
63 | 57 | $this->options['collection_name'] = 'cache'; |
|
64 | 57 | $this->options['object_serializer'] = 'php'; // null, php, json, igBinary. |
|
65 | |||
66 | 57 | // Set the adapter and merge the user+default options |
|
67 | 57 | parent::__construct($Mongo, $options); |
|
68 | |||
69 | if (is_a($Mongo, '\MongoDB\Client')) { |
||
70 | 57 | $this->is_legacy = false; |
|
71 | $this->db = new Mongo\DatabaseAdapter( |
||
72 | $this->adapter->{$this->options['db_name']} |
||
73 | 57 | ); |
|
74 | 57 | } else { |
|
75 | 57 | $this->is_legacy = true; |
|
76 | 57 | $this->db = $this->adapter->selectDB($this->options['db_name']); |
|
77 | } |
||
78 | 57 | ||
79 | 57 | $this->collection = $this->db->createCollection( |
|
80 | $this->options['collection_name'], |
||
81 | array() |
||
82 | ); |
||
83 | |||
84 | 36 | $this->collection->ensureIndex( |
|
85 | array('key' => 1), |
||
86 | 36 | array( |
|
87 | 36 | 'unique' => true, |
|
88 | 'dropDups' => true, |
||
89 | // 'sparse' => true |
||
90 | ) |
||
91 | 36 | ); |
|
92 | 36 | ||
93 | 36 | // Using MongoDB TTL collections (MongoDB 2.2+) |
|
94 | 24 | $this->collection->ensureIndex( |
|
95 | array('expire' => 1), |
||
96 | 24 | array('expireAfterSeconds' => 1) |
|
97 | ); |
||
98 | |||
99 | 18 | $this->setSerializer($this->options['object_serializer']); |
|
100 | 18 | } |
|
101 | 18 | ||
102 | 18 | /** |
|
103 | * {@inheritdoc} |
||
104 | */ |
||
105 | public function loadKey($key) |
||
106 | { |
||
107 | $mKey = $this->mapKey($key); |
||
108 | $cache = $this->get($mKey); |
||
109 | |||
110 | // check expiration |
||
111 | 39 | if ( null === $cache or ( |
|
0 ignored issues
–
show
|
|||
112 | isset($cache['expire']) && (string) $cache['expire']->sec < time() |
||
113 | 39 | )) { |
|
114 | 39 | unset($this->ttls[$mKey]); |
|
115 | 39 | ||
116 | 39 | return null; |
|
117 | } |
||
118 | 39 | ||
119 | 21 | return $cache['serialized'] |
|
120 | 21 | ? $this->serializer->unserialize( |
|
121 | 21 | $this->is_legacy |
|
122 | 21 | ? $cache['serialized']->bin |
|
123 | : $cache['serialized']->getData()) |
||
124 | 39 | : $cache['data']; |
|
125 | } |
||
126 | |||
127 | /** |
||
128 | * Retrieves the cache item for the given id. |
||
129 | * |
||
130 | 27 | * @param string $key The cache key to retrieve. |
|
131 | * @return mixed|null Returns the cached data or null. |
||
132 | 27 | */ |
|
133 | 27 | public function get($key) |
|
134 | 27 | { |
|
135 | 27 | $cache = $this->collection->findOne( |
|
136 | array('key' => $key), |
||
137 | 27 | array('data', 'expire', 'serialized') |
|
138 | 27 | ); |
|
139 | 27 | ||
140 | 27 | if ($cache !== null) { |
|
141 | $this->ttls[$key] = isset($cache['expire']) |
||
142 | 27 | ? $cache['expire']->sec - time() |
|
143 | : 0; |
||
144 | } |
||
145 | |||
146 | return $cache; |
||
147 | } |
||
148 | 48 | ||
149 | /** |
||
150 | 48 | * {@inheritdoc} |
|
151 | */ |
||
152 | 48 | public function loadTag($tag) |
|
153 | 3 | { |
|
154 | 3 | $cache = $this->collection->find( |
|
155 | array('tags' => $this->mapTag($tag)), |
||
156 | 48 | array('key') |
|
157 | ); |
||
158 | 48 | ||
159 | 24 | $keys = array_map( |
|
160 | 24 | function ($v) { return $v['key']; }, |
|
161 | 24 | array_values(iterator_to_array($cache)) |
|
162 | 24 | ); |
|
163 | 24 | ||
164 | return empty($keys) ? null : $keys; |
||
165 | 48 | } |
|
166 | 9 | ||
167 | 9 | /** |
|
168 | 9 | * {@inheritdoc} |
|
169 | */ |
||
170 | 48 | public function save($data, $key, array $tags=null, $ttl=null) |
|
171 | 48 | { |
|
172 | 48 | $key = $this->mapKey($key); |
|
173 | |||
174 | 48 | $cache = array('key' => $key, 'data' => null, 'serialized' => null); |
|
175 | 48 | ||
176 | 48 | if (null !== $this->serializer && (is_object($data) || is_array($data))) { |
|
177 | $cache['serialized'] = |
||
178 | 48 | $this->is_legacy |
|
179 | ? new \MongoBinData($this->serializer->serialize($data), \MongoBinData::BYTE_ARRAY) |
||
180 | : new \MongoDB\BSON\Binary($this->serializer->serialize($data), \MongoDB\BSON\Binary::TYPE_GENERIC); |
||
181 | } else { |
||
182 | $cache['data'] = $data; |
||
183 | } |
||
184 | 3 | ||
185 | if ($this->options['tag_enable'] && null !== $tags) { |
||
186 | 3 | $cache['tags'] = array(); |
|
187 | 3 | foreach ($tags as $tag) { |
|
188 | 3 | $cache['tags'][] = $this->mapTag($tag); |
|
189 | 3 | } |
|
190 | 3 | } |
|
191 | 3 | ||
192 | 3 | $this->ttls[$key] = 0; |
|
193 | |||
194 | 3 | if (null !== $ttl && 0 !== $ttl) { |
|
195 | $expire = time()+$ttl; |
||
196 | |||
197 | $cache['expire'] = $this->is_legacy |
||
198 | ? new \MongoDate($expire) |
||
199 | : new \MongoDB\BSON\UTCDateTime($expire * 1000); |
||
200 | 9 | ||
201 | $this->ttls[$key] = $ttl; |
||
202 | 9 | } |
|
203 | 9 | ||
204 | 9 | $res = $this->collection->update( |
|
205 | array('key' => $key), $cache, array('upsert' => true) |
||
206 | 9 | ); |
|
207 | |||
208 | return (boolean) $res['ok']; |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | 57 | * {@inheritdoc} |
|
213 | */ |
||
214 | 57 | public function clean(array $tags) |
|
215 | 3 | { |
|
216 | $items = array(); |
||
217 | 3 | foreach ($tags as $tag) { |
|
218 | $items += (array) $this->loadTag($tag); |
||
219 | } |
||
220 | 57 | $res = $this->collection->remove( |
|
221 | 57 | array('key'=>array('$in'=>$items)) |
|
222 | ); |
||
223 | 57 | ||
224 | return (boolean) $res['n']; |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * {@inheritdoc} |
||
229 | */ |
||
230 | public function delete($key) |
||
231 | 3 | { |
|
232 | $res = $this->collection->remove( |
||
233 | 3 | array('key' => $this->mapKey($key)) |
|
234 | ); |
||
235 | |||
236 | return (boolean) $res['n']; |
||
237 | } |
||
238 | |||
239 | 6 | /** |
|
240 | * {@inheritdoc} |
||
241 | 6 | */ |
|
242 | public function flush($all=false) |
||
243 | 6 | { |
|
244 | 6 | if (true === $all) { |
|
245 | 6 | $res = $this->collection->drop(); |
|
246 | return (boolean) $res['ok']; |
||
247 | } |
||
248 | |||
249 | 3 | $regex = $this->is_legacy |
|
250 | ? new \MongoRegex('/^' . $this->mapKey('') . '/') |
||
251 | : array('$regex' => '^' . $this->mapKey('')); |
||
252 | |||
253 | $res = $this->collection->remove( array('key' => $regex) ); |
||
254 | |||
255 | return (boolean) $res['ok']; |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * Counts the number of cached items. |
||
260 | * |
||
261 | * @return integer Returns the number of items in the cache. |
||
262 | */ |
||
263 | public function count() |
||
264 | { |
||
265 | return (integer) $this->collection->count(); |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * {@inheritdoc} |
||
270 | */ |
||
271 | View Code Duplication | public function getTtl($key) |
|
272 | { |
||
273 | $mKey = $this->mapKey($key); |
||
274 | |||
275 | return !isset($this->ttls[$mKey]) && null === $this->get($mKey) |
||
276 | ? false |
||
277 | : $this->ttls[$mKey]; |
||
278 | } |
||
279 | |||
280 | } |
||
281 |
PHP has two types of connecting operators (logical operators, and boolean operators):
and
&&
or
||
The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like
&&
, or||
.Let’s take a look at a few examples:
Logical Operators are used for Control-Flow
One case where you explicitly want to use logical operators is for control-flow such as this:
Since
die
introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined withthrow
at this point:These limitations lead to logical operators rarely being of use in current PHP code.