-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathCacheableBehavior.php
More file actions
157 lines (143 loc) · 4.37 KB
/
CacheableBehavior.php
File metadata and controls
157 lines (143 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
/**
* Cacheable Model Behavior
*
* Stores model queries in cache
*
* @package Cacheable
* @author Dean Sofer
* @version $Id$
* @copyright
* @dependencies Clear_Cache Plugin by Ceeram https://github.com/ceeram/clear_cache
**/
App::uses('Security', 'Utility');
class CacheableBehavior extends ModelBehavior {
/**
* Contains configuration settings for use with individual model objects.
* Individual model settings should be stored as an associative array,
* keyed off of the model name.
*
* @var array
* @access public
* @see Model::$alias
*/
var $_settings = array();
/**
* Initiate Cacheable Behavior
*
* @param object $model
* @param array $config
* @return void
* @access public
*/
function setup(Model $model, $config = array()) {
$defaults = array(
'engine' => 'File',
'duration' => '+1 hour',
'configured' => false,
'prefix' => '',
'folder' => 'cacheable',
);
$this->_settings[$model->alias] = array_merge($defaults, $config);
}
/**
* Sets up the cache configurations for cacheable and checks directory existence.
* Runs a maximum of 1 time per model per request to reduce overhead!
*
* @param string $model
* @param string $type
* @param string $duration
* @return void
* @author Dean
*/
protected function _configure($model, $duration = null) {
if (!$this->_settings[$model->alias]['configured']) {
if ($this->_settings[$model->alias]['engine'] == 'File') {
if (!is_dir(CACHE . $this->_settings[$model->alias]['folder'])) {
mkdir(CACHE . $this->_settings[$model->alias]['folder']);
}
if (!is_dir(CACHE . $this->_settings[$model->alias]['folder'] . DS . $model->alias)) {
mkdir(CACHE . $this->_settings[$model->alias]['folder'] . DS . $model->alias);
}
}
if (!$duration) {
$duration = $this->_settings[$model->alias]['duration'];
}
Cache::config('cacheable' . $model->alias, array(
'engine' => $this->_settings[$model->alias]['engine'],
'path' => CACHE . $this->_settings[$model->alias]['folder'] . DS . $model->alias . DS,
'duration' => $duration,
'prefix' => $this->_settings[$model->alias]['prefix'],
));
$this->_settings[$model->alias]['configured'] = true;
}
}
/**
* Checks the cache for query results, if none are found a new query is made
* and the results are stored to a unique key for the query. Also works with
* complex operations by using Model methods called cache<QueryName>($options)
*
* @param string $model
* @param string $type
* @param string $query
* @param string $options
* @return void
* @author Dean Sofer
*/
public function cache($model, $type, $queryOptions = array(), $options = array()) {
$options = array_merge(array(
'duration' => null,
'update' => false,
), $options);
$key = $this->generateCacheKey($model, $type, $queryOptions);
if ($options['update']) {
$this->deleteCache($model, $key);
}
$data = $this->getCache($model, $key);
if ($data === false) {
$data = $model->find($type, $queryOptions);
$this->setCache($model, $key, $data);
}
return $data;
}
/**
* Generates a unique key based on the find type and query parameters
*
* @param string $type
* @param string $queryOptions
* @return void
* @author Dean
*/
public function generateCacheKey($model, $type, $queryOptions = array()) {
// Just in case the model gets imported too early
if (isset($model->locale)) {
return $model->locale . '_' . $type . '_' . Security::hash(serialize($queryOptions));
} else {
return $type . '_' . Security::hash(serialize($queryOptions));
}
}
public function deleteCache($model, $key = null) {
$this->_configure($model);
App::uses('ClearCache', 'ClearCache.Lib');
$ClearCache = new ClearCache();
if ($key) {
return Cache::delete($key, 'cacheable' . $model->alias);
} else {
return $ClearCache->files($this->_settings[$model->alias]['folder'] . DS . $model->alias);
}
}
public function getCache($model, $key) {
$this->_configure($model);
return Cache::read($key, 'cacheable' . $model->alias);
}
public function setCache($model, $key, $data) {
$this->_configure($model);
return Cache::write($key, $data, 'cacheable' . $model->alias);
}
public function afterSave(Model $model, $created, $options = array()) {
$this->deleteCache($model);
}
public function afterDelete(Model $model) {
$this->deleteCache($model);
}
}