Driver_File   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 181
rs 10
c 0
b 0
f 0
wmc 18
lcom 1
cbo 2

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A clear() 0 13 2
A delete() 0 11 3
A info() 0 15 1
A keys() 0 19 2
B load() 0 15 5
A save() 0 23 3
1
<?php
2
3
/**
4
 * Provides caching functionality on the filesystem
5
 *
6
 * PHP Version 5
7
 *
8
 * @category  Core
9
 * @package   Cache
10
 * @author    Hans-Joachim Piepereit <[email protected]>
11
 * @copyright 2013 cSphere Team
12
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
13
 * @link      http://www.csphere.eu
14
 **/
15
16
namespace csphere\core\cache;
17
18
/**
19
 * Provides caching functionality on the filesystem
20
 *
21
 * @category  Core
22
 * @package   Cache
23
 * @author    Hans-Joachim Piepereit <[email protected]>
24
 * @copyright 2013 cSphere Team
25
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
26
 * @link      http://www.csphere.eu
27
 **/
28
29
class Driver_File extends Base
30
{
31
    /**
32
     * Stores the cache directory
33
     **/
34
    private $_dir = '';
35
36
    /**
37
     * Files to exclude for stats
38
     **/
39
    private $_exclude = ['info.txt'];
40
41
    /**
42
     * Creates the cache handler object
43
     *
44
     * @param array $config Configuration details as an array
45
     *
46
     * @throws \Exception
47
     *
48
     * @return \csphere\core\cache\Driver_File
49
     **/
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
50
51
    public function __construct(array $config)
52
    {
53
        parent::__construct($config);
54
55
        $this->_dir = \csphere\core\init\path() . 'csphere/storage/cache/';
56
57
        if (!is_writeable($this->_dir)) {
58
59
            throw new \Exception('Directory "' . $this->_dir . '" is not writeable');
60
        }
61
    }
62
63
    /**
64
     * Clears the cache content
65
     *
66
     * @return boolean
67
     **/
68
    public function clear()
69
    {
70
        $content = \csphere\core\files\File::search(
71
            $this->_dir, false, $this->_exclude
72
        );
73
74
        foreach ($content AS $file) {
75
76
            unlink($this->_dir . $file);
77
        }
78
79
        return true;
80
    }
81
82
    /**
83
     * Removes a cached key
84
     *
85
     * @param string $key Name of the key
86
     * @param int    $ttl Time to life used for the key
87
     *
88
     * @return boolean
89
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
90
91
    public function delete($key, $ttl = 0)
92
    {
93
        $token = empty($ttl) ? $key : 'ttl_' . $key;
94
95
        if (file_exists($this->_dir . $token . '.tmp')) {
96
97
            unlink($this->_dir . $token . '.tmp');
98
        }
99
100
        return true;
101
    }
102
103
    /**
104
     * Returns a formatted array with statistics
105
     *
106
     * @return array
107
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
108
109
    public function info()
110
    {
111
        $info = parent::info();
112
113
        $files = \csphere\core\files\File::search(
114
            $this->_dir, false, $this->_exclude
115
        );
116
117
        $info['version'] = '';
118
        $info['client']  = '';
119
        $info['server']  = '';
120
        $info['keys']    = count($files);
121
122
        return $info;
123
    }
124
125
    /**
126
     * Returns a formatted array with all keys and additional information
127
     *
128
     * @return array
129
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
130
131
    public function keys()
132
    {
133
        $info = \csphere\core\files\File::search(
134
            $this->_dir, false, $this->_exclude
135
        );
136
137
        $form = [];
138
139
        foreach ($info AS $filename) {
140
141
            $form[$filename] = ['name' => $filename,
142
                                'time' => filemtime($this->_dir . $filename),
143
                                'size' => filesize($this->_dir . $filename)];
144
        }
145
146
        $form = array_values($form);
147
148
        return $form;
149
    }
150
151
    /**
152
     * Fetches the desired key
153
     *
154
     * @param string $key Name of the key
155
     * @param int    $ttl Time to life used for the key
156
     *
157
     * @return array
158
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
159
160
    public function load($key, $ttl = 0)
161
    {
162
        $token = empty($ttl) ? $key : 'ttl_' . $key;
163
164
        if (file_exists($this->_dir . $token . '.tmp')
165
            && (empty($ttl)
166
            || filemtime($this->_dir . $token . '.tmp') >= (time() - $ttl))
167
        ) {
168
            $string = file_get_contents($this->_dir . $token . '.tmp');
169
170
            return unserialize($string);
171
        }
172
173
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type declared by the abstract method csphere\core\cache\Base::load of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
174
    }
175
176
    /**
177
     * Stores the key with its value in the cache
178
     *
179
     * @param string $key   Name of the key
180
     * @param array  $value Content to be stored
181
     * @param int    $ttl   Time to life used for the key
182
     *
183
     * @return boolean
184
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
185
186
    public function save($key, $value, $ttl = 0)
187
    {
188
        $token = empty($ttl) ? $key : 'ttl_' . $key;
189
190
        $store = serialize($value);
191
192
        $save_cache = fopen($this->_dir . $token . '.tmp', 'w');
193
194
        // Set stream encoding if possible to avoid converting issues
195
        if (function_exists('stream_encoding')) {
196
197
            stream_encoding($save_cache, 'UTF-8');
198
        }
199
200
        fwrite($save_cache, $store);
201
        fclose($save_cache);
202
203
        chmod($this->_dir . $token . '.tmp', 0755);
204
205
        $this->log($key);
206
207
        return true;
208
    }
209
}
210