Completed
Push — master ( dd4d74...24ba14 )
by Da Phuture
10:51 queued 05:05
created

FileStorage::clear()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 4
nop 1
1
<?php
2
3
namespace Kemist\Cache\Storage;
4
5
/**
6
 * FileStorage object for file based cache
7
 * 
8
 * @package Kemist\Cache
9
 * 
10
 * @version 1.1.4
11
 */
12
class FileStorage extends AbstractStorage implements StorageInterface {
13
14
  /**
15
   * Cache file extension
16
   * @var int
17
   */
18
  protected $extension = 'kcf';
19
20
  /**
21
   * Cache file locking
22
   * @var bool
23
   */
24
  protected $fileLocking = true;
25
26
  /**
27
   * Cache directory
28
   * @var type 
29
   */
30
  protected $cacheDir;
31
32
  /**
33
   * Constructor
34
   * 
35
   * @param array $options
36
   */
37
  public function __construct(array $options = array()) {
38
    if (!isset($options['cache_dir'])) {
39
      $options['cache_dir'] = sys_get_temp_dir() . '/kemist_cache/';
40
      if (!is_dir($options['cache_dir'])) {
41
        mkdir($options['cache_dir']);
42
      }
43
    }
44
    if (substr($options['cache_dir'], -1, 1) != '/') {
45
      $options['cache_dir'].='/';
46
    }
47
    $this->cacheDir = $options['cache_dir'];
48
    $this->extension = (isset($options['extension']) ? $options['extension'] : 'kcf');
49
    $this->fileLocking = (isset($options['file_locking']) ? $options['file_locking'] : true);
50
  }
51
52
  /**
53
   * Initialise Cache storage
54
   * 
55
   * @return boolean
56
   * 
57
   * @throws \Kemist\Cache\Exception
58
   */
59
  public function init() {
60
    if (!is_writable($this->cacheDir)) {
61
      throw new \Kemist\Cache\Exception("Cache directory is not writable!");
62
    }
63
    return true;
64
  }
65
66
  /**
67
   * Checks if the specified name in cache exists
68
   * 	 
69
   * @param string $name cache name
70
   *
71
   * @return bool
72
   */
73
  public function has($name) {
74
    return file_exists($this->cacheDir . '.' . $name . '.' . $this->extension);
75
  }
76
77
  /**
78
   * Deletes the specified cache or each one if '' given
79
   * 	 
80
   * @param string $name cache name
81
   *
82
   * @return bool
83
   */
84
  public function delete($name = '') {
85
    if ($name == '') {
86
      foreach ($this->getAllCacheFiles() as $file) {
87
        unlink($this->cacheDir . $file);
88
      }
89
      return true;
90
    } elseif (file_exists($this->cacheDir . '.' . $name . '.' . $this->extension)) {
91
      unlink($this->cacheDir . '.' . $name . '.' . $this->extension);
92
      return true;
93
    }
94
95
    return false;
96
  }
97
98
  /**
99
   * Saves the variable to the $name cache
100
   * 	 
101
   * @param string $name cache name
102
   * @param mixed $val variable to be stored
103
   * @param bool $compressed Compress value with gz
104
   *
105
   * @return bool
106
   */
107
  public function store($name, $val, $compressed = false) {
108
    $success = false;
109
110
    if (false !== $handle = fopen($this->cacheDir . '.' . $name . '.' . $this->extension, 'wb')) {
111
      if ($this->lockFile($handle, true)) {
112
        $success = fputs($handle, ($compressed ? gzcompress($val) : $val));
113
        $this->unlockFile($handle);
114
      }
115
116
      fclose($handle);
117
      $success ? $this->storeName($name) : null;
118
    }
119
120
    return $success;
121
  }
122
123
  /**
124
   * Retrieves the content of $name cache
125
   * 	 
126
   * @param string $name cache name
127
   * @param bool $compressed
128
   *
129
   * @return mixed
130
   */
131
  public function get($name, $compressed = false) {
132
    $fileName = $this->cacheDir . '.' . $name . '.' . $this->extension;
133
    if (!file_exists($fileName)) {
134
      $this->miss();
135
      return false;
136
    }
137
138
    $success = false;
139
    if (false !== $handle = fopen($fileName, "rb")) {
140
      if ($this->lockFile($handle)) {
141
        $temp = '';
142
        while (!feof($handle)) {
143
          $temp .= fread($handle, 8192);
144
        }
145
        $this->unlockFile($handle);
146
        $this->hit();
147
        $success = ($compressed ? gzuncompress($temp) : $temp);
148
      }
149
      fclose($handle);
150
      $success ? $this->storeName($name) : null;
151
    }
152
153
    return $success;
154
  }
155
156
  /**
157
   * Locks file
158
   * 
159
   * @param resource $handle
160
   * @param bool $write
161
   * 
162
   * @return bool
163
   */
164
  protected function lockFile($handle, $write = false) {
165
    if (!$this->fileLocking) {
166
      return true;
167
    }
168
    return ($write ? flock($handle, LOCK_EX) : flock($handle, LOCK_SH));
169
  }
170
171
  /**
172
   * Unlocks file
173
   * 
174
   * @param resource $handle
175
   * 
176
   * @return bool
177
   */
178
  protected function unlockFile($handle) {
179
    if (!$this->fileLocking) {
180
      return true;
181
    }
182
    return flock($handle, LOCK_UN);
183
  }
184
185
  /**
186
   * Retrieves information of Cache state
187
   * 
188
   * @param bool $getFields
189
   * 	 
190
   * @return array
191
   */
192
  public function info($getFields = false) {
193
    $info = array();
194
    $info['CACHE_TYPE'] = 'File';
195
    $info['CACHE_HITS'] = $this->hits;
196
    $info['CACHE_MISSES'] = $this->misses;
197
    $fields = array();
198
199
    foreach ($this->getAllCacheFiles() as $file) {
200
      $name = basename($file, '.' . $this->extension);
201
      $info[$name]['size'] = filesize(($this->cacheDir . $file));
202
      $info[$name]['last_modified'] = date('Y.m.d. H:i:s', filemtime($this->cacheDir . $file));
203
      $info[$name]['last_accessed'] = date('Y.m.d. H:i:s', fileatime($this->cacheDir . $file));
204
      $fields[] = $name;
205
    }
206
207
    if ($getFields) {
208
      foreach ($fields as $field) {
209
        $field = substr($field, 1);
210
        $info['field_content'][$field] = $this->get($field);
211
      }
212
    }
213
214
    return $info;
215
  }
216
217
  /**
218
   * Gets all cache files
219
   * 
220
   * @return array
221
   */
222
  protected function getAllCacheFiles() {
223
    $files = array();
224
    foreach (scandir($this->cacheDir) as $file) {
225
      $temp = explode('.', $file);
226
      if (array_pop($temp) == $this->extension) {
227
        $files[] = $file;
228
      }
229
    }
230
    return $files;
231
  }
232
233
}
234