Test Failed
Push — trunk ( db071f...8d464a )
by SuperNova.WS
06:33
created

classCache::isInitialized()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * @package supernova
5
 * @version #43a0.11#
6
 * @copyright (c) 2009-2017 Gorlum for http://supernova.ws
7
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
 *
9
 */
10
11
/**
12
 *
13
 * Basic cacher class that handles different cache engines
14
 * It's pretty smart to handle one cache instance for all application instances (if there is PHP-cacher installed)
15
 * Currently supported only XCache and no-cache (array)
16
 * With no-cache some advanced features would be unaccessible
17
 * Cacher works not only with single values. It's also support multidimensional arrays
18
 * Currently support is a bit limited - for example there is no "walk" function. However basic array abilities supported
19
 * You should NEVER operate with arrays inside of cacher and should ALWAYS use wrap-up functions
20
 *
21
 * @property bool  _INITIALIZED
22
 * @property array lng_stat_usage - Array for locale strings usage statistics
23
 * @property array tables
24
 *
25
 * @package supernova
26
 */
27
class classCache implements ArrayAccess {
28
  const CACHER_NOT_INIT = -1;
29
  const CACHER_NO_CACHE = 0;
30
  const CACHER_XCACHE = 1;
31
32
  // CACHER_NOT_INIT - not initialized
33
  // CACHER_NO_CACHE - no cache - array() used
34
  // CACHER_XCACHE   - xCache
35
  protected static $mode = self::CACHER_NOT_INIT;
36
  protected static $data;
37
  protected $prefix;
38
39
  protected static $cacheObject;
40
41
  public function __construct($prefIn = 'CACHE_', $init_mode = false) {
42
    if (!($init_mode === false || $init_mode === self::CACHER_NO_CACHE || ($init_mode === self::CACHER_XCACHE && extension_loaded('xcache')))) {
43
      throw new UnexpectedValueException('Wrong work mode or current mode does not supported on your server');
44
    }
45
46
    $this->prefix = $prefIn;
47
    if (extension_loaded('xcache') && ($init_mode === self::CACHER_XCACHE || $init_mode === false)) {
48
      if (self::$mode === self::CACHER_NOT_INIT) {
49
        self::$mode = self::CACHER_XCACHE;
50
      }
51
    } else {
52
      if (self::$mode === self::CACHER_NOT_INIT) {
53
        self::$mode = self::CACHER_NO_CACHE;
54
        if (!self::$data) {
55
          self::$data = array();
56
        }
57
      }
58
    }
59
  }
60
61
  public static function getInstance($prefIn = 'CACHE_', $table_name = '') {
62
    if (!isset(self::$cacheObject)) {
63
      $className = get_class();
64
      self::$cacheObject = new $className($prefIn);
65
    }
66
67
    return self::$cacheObject;
68
  }
69
70
  public final function __clone() {
71
    // You NEVER need to copy cacher object or siblings
72
    throw new BadMethodCallException('Clone is not allowed');
73
  }
74
75
  /**
76
   * @return int
77
   */
78
  public function getMode() {
79
    return self::$mode;
80
  }
81
82
  /**
83
   * @return string
84
   */
85
  public function getPrefix() {
86
    return $this->prefix;
87
  }
88
89
  /**
90
   * @param $prefix
91
   */
92
  public function setPrefix($prefix) {
93
    $this->prefix = $prefix;
94
  }
95
96
  // -------------------------------------------------------------------------
97
  // Here comes low-level functions - those that directly works with cacher engines
98
  // -------------------------------------------------------------------------
99
  public function __set($name, $value) {
100
    switch (self::$mode) {
101
      case self::CACHER_NO_CACHE:
102
        self::$data[$this->prefix . $name] = $value;
103
      break;
104
105
      case self::CACHER_XCACHE:
106
        xcache_set($this->prefix . $name, $value);
107
      break;
108
    }
109
  }
110
111
  public function __get($name) {
112
    switch (self::$mode) {
113
      case self::CACHER_NO_CACHE:
114
        return self::$data[$this->prefix . $name];
115
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
116
117
      case self::CACHER_XCACHE:
118
        return xcache_get($this->prefix . $name);
119
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
120
    }
121
122
    return null;
123
  }
124
125
  public function __isset($name) {
126
    switch (self::$mode) {
127
      case self::CACHER_NO_CACHE:
128
        return isset(self::$data[$this->prefix . $name]);
129
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
130
131
      case self::CACHER_XCACHE:
132
        return xcache_isset($this->prefix . $name) && ($this->__get($name) !== null);
133
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
134
    }
135
136
    return false;
137
  }
138
139
  public function __unset($name) {
140
    switch (self::$mode) {
141
      case self::CACHER_NO_CACHE:
142
        unset(self::$data[$this->prefix . $name]);
143
      break;
144
145
      case self::CACHER_XCACHE:
146
        xcache_unset($this->prefix . $name);
147
      break;
148
    }
149
  }
150
151
  public function unset_by_prefix($prefix_unset = '') {
152
    static $array_clear;
153
    !$array_clear ? $array_clear = function (&$v, $k, $p) {
154
      strpos($k, $p) === 0 ? $v = null : false;
155
    } : false;
156
157
    switch (self::$mode) {
158
      case self::CACHER_NO_CACHE:
159
//        array_walk(self::$data, create_function('&$v,$k,$p', 'if(strpos($k, $p) === 0)$v = NULL;'), $this->prefix.$prefix_unset);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
160
        array_walk(self::$data, $array_clear, $this->prefix . $prefix_unset);
161
162
        return true;
163
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
164
165
      case self::CACHER_XCACHE:
166
        if (!function_exists('xcache_unset_by_prefix')) {
167
          return false;
168
        }
169
170
        return xcache_unset_by_prefix($this->prefix . $prefix_unset);
171
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
172
    }
173
174
    return true;
175
  }
176
  // -------------------------------------------------------------------------
177
  // End of low-level functions
178
  // -------------------------------------------------------------------------
179
180
  protected function make_element_name($args, $diff = 0) {
181
    $num_args = count($args);
182
183
    if ($num_args < 1) {
184
      return false;
185
    }
186
187
    $name = '';
188
    $aName = array();
189
    for ($i = 0; $i <= $num_args - 1 - $diff; $i++) {
190
      $name .= "[{$args[$i]}]";
191
      array_unshift($aName, $name);
192
    }
193
194
    return $aName;
195
  }
196
197
  public function array_set() {
198
    $args = func_get_args();
199
    $name = $this->make_element_name($args, 1);
200
201
    if (!$name) {
202
      return null;
203
    }
204
205
    if ($this->$name[0] === null) {
206
      for ($i = count($name) - 1; $i > 0; $i--) {
207
        $cName = "{$name[$i]}_COUNT";
208
        $cName1 = "{$name[$i-1]}_COUNT";
209
        if ($this->$cName1 == null || $i == 1) {
210
          $this->$cName++;
211
        }
212
      }
213
    }
214
215
    $this->$name[0] = $args[count($args) - 1];
216
217
    return true;
218
  }
219
220
  public function array_get() {
221
    $name = $this->make_element_name(func_get_args());
222
    if (!$name) {
223
      return null;
224
    }
225
226
    return $this->$name[0];
227
  }
228
229
  public function array_count() {
230
    $name = $this->make_element_name(func_get_args());
231
    if (!$name) {
232
      return 0;
233
    }
234
    $cName = "{$name[0]}_COUNT";
235
    $retVal = $this->$cName;
236
    if (!$retVal) {
237
      $retVal = null;
238
    }
239
240
    return $retVal;
241
  }
242
243
  public function array_unset() {
244
    $name = $this->make_element_name(func_get_args());
245
246
    if (!$name) {
247
      return false;
248
    }
249
    $this->unset_by_prefix($name[0]);
250
251
    for ($i = 1; $i < count($name); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
252
      $cName = "{$name[$i]}_COUNT";
253
      $cName1 = "{$name[$i-1]}_COUNT";
254
255
      if ($i == 1 || $this->$cName1 === null) {
256
        $this->$cName--;
257
        if ($this->$cName <= 0) {
258
          unset($this->$cName);
259
        }
260
      }
261
    }
262
263
    return true;
264
  }
265
266
  public function dumpData() {
267
    switch (self::$mode) {
268
      case self::CACHER_NO_CACHE:
269
        return dump(self::$data, $this->prefix);
270
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
271
272
      default:
273
        return false;
274
      break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
275
    }
276
  }
277
278
  public function reset() {
279
    $this->unset_by_prefix();
280
281
    $this->_INITIALIZED = false;
282
  }
283
284
  public function init($reInit = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $reInit is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
285
    $this->_INITIALIZED = true;
286
  }
287
288
  public function isInitialized() {
289
    return $this->_INITIALIZED;
290
  }
291
292
  /**
293
   * Whether a offset exists
294
   * @link http://php.net/manual/en/arrayaccess.offsetexists.php
295
   *
296
   * @param mixed $offset <p>
297
   * An offset to check for.
298
   * </p>
299
   *
300
   * @return boolean true on success or false on failure.
301
   * </p>
302
   * <p>
303
   * The return value will be casted to boolean if non-boolean was returned.
304
   * @since 5.0.0
305
   */
306
  public function offsetExists($offset) {
307
    return $this->__isset($offset);
308
  }
309
310
  /**
311
   * Offset to retrieve
312
   * @link http://php.net/manual/en/arrayaccess.offsetget.php
313
   *
314
   * @param mixed $offset <p>
315
   * The offset to retrieve.
316
   * </p>
317
   *
318
   * @return mixed Can return all value types.
319
   * @since 5.0.0
320
   */
321
  public function offsetGet($offset) {
322
    return $this->__get($offset);
323
  }
324
325
  /**
326
   * Offset to set
327
   * @link http://php.net/manual/en/arrayaccess.offsetset.php
328
   *
329
   * @param mixed $offset <p>
330
   * The offset to assign the value to.
331
   * </p>
332
   * @param mixed $value <p>
333
   * The value to set.
334
   * </p>
335
   *
336
   * @return void
337
   * @since 5.0.0
338
   */
339
  public function offsetSet($offset, $value) {
340
    $this->__set($offset, $value);
341
  }
342
343
  /**
344
   * Offset to unset
345
   * @link http://php.net/manual/en/arrayaccess.offsetunset.php
346
   *
347
   * @param mixed $offset <p>
348
   * The offset to unset.
349
   * </p>
350
   *
351
   * @return void
352
   * @since 5.0.0
353
   */
354
  public function offsetUnset($offset) {
355
    $this->__unset($offset);
356
  }
357
358
}
359