Completed
Push — feature/code-analysis ( a26fec...c314d5 )
by Jonathan
07:11
created

Cache::clean()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * webtrees-lib: MyArtJaub library for webtrees
4
 *
5
 * @package MyArtJaub\Webtrees
6
 * @author Jonathan Jaubart <[email protected]>
7
 * @copyright Copyright (c) 2012, Jonathan Jaubart
8
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
9
 */
10
11
namespace MyArtJaub\Webtrees; 
12
13
use Fisharebest\Webtrees\Module\AbstractModule;
14
use Psr\Cache\CacheItemInterface;
15
use Psr\Cache\CacheItemPoolInterface;
16
use Stash\Driver\Apc;
17
use Stash\Driver\Ephemeral;
18
use Stash\Driver\FileSystem;
19
20
/**
21
 * Cache component to speed up some potential data retrievals
22
 */
23
class Cache{
24
	
25
    /**
26
     * Underlying Cache object
27
     * @var CacheItemPoolInterface $cache
28
     */
29
	protected $cache=null;
30
	
31
	/**
32
	 * Defines whether the cache has been initialised
33
	 * @var bool $is_init
34
	 */
35
	protected $is_init = false;
36
	
37
	/**
38
	 * *Cache* instance for Singleton pattern
39
	 * @var Cache $instance
40
	 */
41
	protected static $instance = null;
42
	
43
	/**
44
	 * Returns the *Cache* instance of this class.
45
	 *
46
	 * @return Cache The *Singleton* instance.
47
	 */
48
	protected static function getInstance()
49
	{
50
	    if (null === static::$instance) {
51
	        static::$instance = new static();
52
	    }
53
	
54
	    return static::$instance;
55
	}
56
	
57
	/**
58
	 * Initialise the Cache class
59
	 *
60
	 */
61
	protected function init() {		
62
	    if(Apc::isAvailable()) {
63
		    $driver = new Apc();
64
		} else {
65
			if (!is_dir(WT_DATA_DIR.DIRECTORY_SEPARATOR.'cache')) {
66
				// We may not have permission - especially during setup, before we instruct
67
				// the user to "chmod 777 /data"
68
				@mkdir(WT_DATA_DIR.DIRECTORY_SEPARATOR.'cache');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
69
			}
70
			if (is_dir(WT_DATA_DIR.DIRECTORY_SEPARATOR.'cache')) {
71
			    $driver = new FileSystem(array('path' => WT_DATA_DIR.DIRECTORY_SEPARATOR.'cache'));
72
			} else {
73
				// No cache available, let's just use a basic one :-(
74
				$driver = new Ephemeral();
75
			}
76
		}		
77
78
		$this->cache = new \Stash\Pool($driver);		
79
		$this->is_init = true;
80
	}
81
	
82
	/**
83
	 * Initiliase the Cache if not done.
84
	 *
85
	 */
86
	protected function checkInit(){
87
		if(!$this->is_init) $this->init();
88
	}
89
	
90
	/**
91
	 * Returns the name of the cached key, based on the value name and the calling module
92
	 *
93
	 * @param string $value Value name
94
	 * @param AbstractModule $mod Calling module
95
	 * @return string Cached key name
96
	 */
97
	protected function getKeyName($value, AbstractModule $mod = null){
98
	    $this->checkInit();
99
		$mod_name = 'myartjaub';
100
		if($mod !== null) $mod_name = $mod->getName();
101
		return $mod_name.'_'.$value;
102
	}
103
	
104
	/**
105
	 * Returns the cached value, if exists
106
	 * 
107
	 * @param string $value Value name
108
	 * @param AbstractModule $mod Calling module
109
	 * @return \Psr\Cache\CacheItemInterface
110
	 */
111
	public function getI($value, AbstractModule $mod = null){
112
	    $this->checkInit();
113
		return $this->cache->getItem($this->getKeyName($value, $mod));
114
	}
115
	
116
	/**
117
	 * Static invocation of the *get* method.
118
	 *
119
	 * @param string $value Value name
120
	 * @param AbstractModule $mod Calling module
121
	 * @return \Psr\Cache\CacheItemInterface
122
	 */
123
	public static function get($value, AbstractModule $mod = null){
124
	    return self::getInstance()->getI($value, $mod);
125
	}
126
	
127
	/**
128
	 * Cache a value to the specified key
129
	 *
130
	 * @param string|\Psr\Cache\CacheItemInterface $value Value name
131
	 * @param mixed $data Value
132
	 * @param AbstractModule $mod Calling module
133
	 */
134
	public function saveI($value, $data, AbstractModule $mod = null){
135
		$this->checkInit();
136
		
137
		$item = $value;
138
		if(!($value instanceof CacheItemInterface)) {
139
		    $item = new \Stash\Item();
140
    		$item->setKey($this->getKeyName($value, $mod));
0 ignored issues
show
Documentation introduced by
$this->getKeyName($value, $mod) is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
141
		}		
142
		$item->set($data);
143
		$this->cache->save($item);
0 ignored issues
show
Bug introduced by
It seems like $item defined by $value on line 137 can also be of type string; however, Psr\Cache\CacheItemPoolInterface::save() does only seem to accept object<Psr\Cache\CacheItemInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
144
	}
145
	
146
	/**
147
	 * Static invocation of the *save* method.
148
	 *
149
	 * @param string|\Psr\Cache\CacheItemInterface $value Value name
150
	 * @param mixed $data Value
151
	 * @param AbstractModule $mod Calling module
152
	 */
153
	public static function save($value, $data, AbstractModule $mod = null){
154
	    self::getInstance()->saveI($value, $data, $mod);
155
	}
156
	
157
	/**
158
	 * Delete the value associated to the specified key
159
	 *
160
	 * @param string $value Value name
161
	 * @param AbstractModule $mod Calling module
162
	 * @return bool Deletion successful?
163
	 */
164
	public function deleteI($value, AbstractModule $mod = null){
165
	    $this->checkInit();	
166
	    return $this->cache->deleteItem($this->getKeyName($value, $mod));
167
	}
168
	
169
	/**
170
	 * Static invocation of the *delete* method.
171
	 *
172
	 * @param string $value Value name
173
	 * @param AbstractModule $mod Calling module
174
	 * @return bool Deletion successful?
175
	 */
176
	public static function delete($value, AbstractModule $mod = null){
177
	    return self::getInstance()->deleteI($value, $mod);
178
	}
179
	
180
	/**
181
	 * Clean the cache
182
	 *
183
	 */
184
	public function cleanI(){
185
	    $this->checkInit();
186
		$this->cache->clear();
187
	}
188
	
189
	/**
190
	 * Static invocation of the *clean* method.
191
	 */
192
	public static function clean() {
193
	    self::getInstance()->cleanI();
194
	}
195
	
196
}