1: | <?php
|
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: | class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom
|
31: | {
|
32: | |
33: | |
34: |
|
35: | protected $fetchStatements = array('default' => 'SELECT %2$s
|
36: | FROM %1$s
|
37: | WHERE 1
|
38: | AND id = :id
|
39: | AND cache_id IS NULL
|
40: | AND compile_id IS NULL',
|
41: | 'withCacheId' => 'SELECT %2$s
|
42: | FROM %1$s
|
43: | WHERE 1
|
44: | AND id = :id
|
45: | AND cache_id = :cache_id
|
46: | AND compile_id IS NULL',
|
47: | 'withCompileId' => 'SELECT %2$s
|
48: | FROM %1$s
|
49: | WHERE 1
|
50: | AND id = :id
|
51: | AND compile_id = :compile_id
|
52: | AND cache_id IS NULL',
|
53: | 'withCacheIdAndCompileId' => 'SELECT %2$s
|
54: | FROM %1$s
|
55: | WHERE 1
|
56: | AND id = :id
|
57: | AND cache_id = :cache_id
|
58: | AND compile_id = :compile_id');
|
59: |
|
60: | |
61: | |
62: |
|
63: | protected $insertStatement = 'INSERT INTO %s
|
64: |
|
65: | SET id = :id,
|
66: | name = :name,
|
67: | cache_id = :cache_id,
|
68: | compile_id = :compile_id,
|
69: | modified = CURRENT_TIMESTAMP,
|
70: | expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
|
71: | content = :content
|
72: |
|
73: | ON DUPLICATE KEY UPDATE
|
74: | name = :name,
|
75: | cache_id = :cache_id,
|
76: | compile_id = :compile_id,
|
77: | modified = CURRENT_TIMESTAMP,
|
78: | expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
|
79: | content = :content';
|
80: |
|
81: | |
82: | |
83: |
|
84: | protected $deleteStatement = 'DELETE FROM %1$s WHERE %2$s';
|
85: |
|
86: | |
87: | |
88: |
|
89: | protected $truncateStatement = 'TRUNCATE TABLE %s';
|
90: |
|
91: | |
92: | |
93: |
|
94: | protected $fetchColumns = 'modified, content';
|
95: |
|
96: | |
97: | |
98: |
|
99: | protected $fetchTimestampColumns = 'modified';
|
100: |
|
101: | |
102: | |
103: |
|
104: | protected $pdo;
|
105: |
|
106: | |
107: | |
108: |
|
109: | protected $table;
|
110: |
|
111: | |
112: | |
113: |
|
114: | protected $database;
|
115: |
|
116: | |
117: | |
118: | |
119: | |
120: | |
121: | |
122: | |
123: | |
124: |
|
125: | public function __construct(PDO $pdo, $table, $database = null)
|
126: | {
|
127: | if (is_null($table)) {
|
128: | throw new SmartyException("Table name for caching can't be null");
|
129: | }
|
130: | $this->pdo = $pdo;
|
131: | $this->table = $table;
|
132: | $this->database = $database;
|
133: | $this->fillStatementsWithTableName();
|
134: | }
|
135: |
|
136: | |
137: | |
138: | |
139: | |
140: | |
141: |
|
142: | protected function fillStatementsWithTableName()
|
143: | {
|
144: | foreach ($this->fetchStatements as &$statement) {
|
145: | $statement = sprintf($statement, $this->getTableName(), '%s');
|
146: | }
|
147: | $this->insertStatement = sprintf($this->insertStatement, $this->getTableName());
|
148: | $this->deleteStatement = sprintf($this->deleteStatement, $this->getTableName(), '%s');
|
149: | $this->truncateStatement = sprintf($this->truncateStatement, $this->getTableName());
|
150: | return $this;
|
151: | }
|
152: |
|
153: | |
154: | |
155: | |
156: | |
157: | |
158: | |
159: | |
160: | |
161: | |
162: | |
163: |
|
164: | protected function getFetchStatement($columns, $id, $cache_id = null, $compile_id = null)
|
165: | {
|
166: | $args = array();
|
167: | if (!is_null($cache_id) && !is_null($compile_id)) {
|
168: | $query = $this->fetchStatements[ 'withCacheIdAndCompileId' ] and
|
169: | $args = array('id' => $id, 'cache_id' => $cache_id, 'compile_id' => $compile_id);
|
170: | } elseif (is_null($cache_id) && !is_null($compile_id)) {
|
171: | $query = $this->fetchStatements[ 'withCompileId' ] and
|
172: | $args = array('id' => $id, 'compile_id' => $compile_id);
|
173: | } elseif (!is_null($cache_id) && is_null($compile_id)) {
|
174: | $query = $this->fetchStatements[ 'withCacheId' ] and $args = array('id' => $id, 'cache_id' => $cache_id);
|
175: | } else {
|
176: | $query = $this->fetchStatements[ 'default' ] and $args = array('id' => $id);
|
177: | }
|
178: | $query = sprintf($query, $columns);
|
179: | $stmt = $this->pdo->prepare($query);
|
180: | foreach ($args as $key => $value) {
|
181: | $stmt->bindValue($key, $value);
|
182: | }
|
183: | return $stmt;
|
184: | }
|
185: |
|
186: | |
187: | |
188: | |
189: | |
190: | |
191: | |
192: | |
193: | |
194: | |
195: | |
196: | |
197: | |
198: |
|
199: | protected function fetch($id, $name, $cache_id = null, $compile_id = null, &$content, &$mtime)
|
200: | {
|
201: | $stmt = $this->getFetchStatement($this->fetchColumns, $id, $cache_id, $compile_id);
|
202: | $stmt->execute();
|
203: | $row = $stmt->fetch();
|
204: | $stmt->closeCursor();
|
205: | if ($row) {
|
206: | $content = $this->outputContent($row[ 'content' ]);
|
207: | $mtime = strtotime($row[ 'modified' ]);
|
208: | } else {
|
209: | $content = null;
|
210: | $mtime = null;
|
211: | }
|
212: | }
|
213: |
|
214: | |
215: | |
216: | |
217: | |
218: | |
219: | |
220: | |
221: | |
222: | |
223: | |
224: | |
225: | |
226: |
|
227: |
|
228: |
|
229: |
|
230: |
|
231: |
|
232: |
|
233: |
|
234: | |
235: | |
236: | |
237: | |
238: | |
239: | |
240: | |
241: | |
242: | |
243: | |
244: | |
245: | |
246: |
|
247: | protected function save($id, $name, $cache_id = null, $compile_id = null, $exp_time, $content)
|
248: | {
|
249: | $stmt = $this->pdo->prepare($this->insertStatement);
|
250: | $stmt->bindValue('id', $id);
|
251: | $stmt->bindValue('name', $name);
|
252: | $stmt->bindValue('cache_id', $cache_id, (is_null($cache_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
|
253: | $stmt->bindValue('compile_id', $compile_id, (is_null($compile_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
|
254: | $stmt->bindValue('expire', (int)$exp_time, PDO::PARAM_INT);
|
255: | $stmt->bindValue('content', $this->inputContent($content));
|
256: | $stmt->execute();
|
257: | return !!$stmt->rowCount();
|
258: | }
|
259: |
|
260: | |
261: | |
262: | |
263: | |
264: | |
265: | |
266: | |
267: |
|
268: | protected function inputContent($content)
|
269: | {
|
270: | return $content;
|
271: | }
|
272: |
|
273: | |
274: | |
275: | |
276: | |
277: | |
278: | |
279: | |
280: |
|
281: | protected function outputContent($content)
|
282: | {
|
283: | return $content;
|
284: | }
|
285: |
|
286: | |
287: | |
288: | |
289: | |
290: | |
291: | |
292: | |
293: | |
294: | |
295: | |
296: |
|
297: | protected function delete($name = null, $cache_id = null, $compile_id = null, $exp_time = null)
|
298: | {
|
299: |
|
300: | if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
|
301: |
|
302: | $this->pdo->query($this->truncateStatement);
|
303: | return -1;
|
304: | }
|
305: |
|
306: | $where = array();
|
307: |
|
308: | if ($name !== null) {
|
309: | $where[] = 'name = ' . $this->pdo->quote($name);
|
310: | }
|
311: |
|
312: | if ($cache_id !== null) {
|
313: | $where[] =
|
314: | '(cache_id = ' .
|
315: | $this->pdo->quote($cache_id) .
|
316: | ' OR cache_id LIKE ' .
|
317: | $this->pdo->quote($cache_id . '|%') .
|
318: | ')';
|
319: | }
|
320: |
|
321: | if ($compile_id !== null) {
|
322: | $where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
|
323: | }
|
324: |
|
325: | if ($exp_time === Smarty::CLEAR_EXPIRED) {
|
326: | $where[] = 'expire < CURRENT_TIMESTAMP';
|
327: | }
|
328: | elseif ($exp_time !== null) {
|
329: | $where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
|
330: | }
|
331: |
|
332: | $query = $this->pdo->query(sprintf($this->deleteStatement, join(' AND ', $where)));
|
333: | return $query->rowCount();
|
334: | }
|
335: |
|
336: | |
337: | |
338: | |
339: | |
340: | |
341: |
|
342: | protected function getTableName()
|
343: | {
|
344: | return (is_null($this->database)) ? "`{$this->table}`" : "`{$this->database}`.`{$this->table}`";
|
345: | }
|
346: | }
|
347: | |