frqnck /
apix-cache
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
dieintroduces 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 withthrowat this point:These limitations lead to logical operators rarely being of use in current PHP code.