]> git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/simplepie/SimplePie/Cache/MySQL.php
poche now uses Full Text RSS to fetch content
[github/wallabag/wallabag.git] / inc / 3rdparty / simplepie / SimplePie / Cache / MySQL.php
1 <?php
2 /**
3 * SimplePie
4 *
5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
7 *
8 * Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
13 *
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
16 *
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
20 *
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * @package SimplePie
36 * @version 1.3-dev
37 * @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
38 * @author Ryan Parman
39 * @author Geoffrey Sneddon
40 * @author Ryan McCue
41 * @link http://simplepie.org/ SimplePie
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
44 */
45
46
47 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
48 {
49 protected $mysql;
50 protected $options;
51 protected $id;
52
53 public function __construct($url, $name, $extension)
54 {
55 $this->options = array(
56 'user' => null,
57 'pass' => null,
58 'host' => '127.0.0.1',
59 'port' => '3306',
60 'path' => '',
61 'extras' => array(
62 'prefix' => '',
63 ),
64 );
65 $this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($url));
66
67 // Path is prefixed with a "/"
68 $this->options['dbname'] = substr($this->options['path'], 1);
69
70 try
71 {
72 $this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
73 }
74 catch (PDOException $e)
75 {
76 $this->mysql = null;
77 return;
78 }
79
80 $this->id = $name . $extension;
81
82 if (!$query = $this->mysql->query('SHOW TABLES'))
83 {
84 $this->mysql = null;
85 return;
86 }
87
88 $db = array();
89 while ($row = $query->fetchColumn())
90 {
91 $db[] = $row;
92 }
93
94 if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
95 {
96 $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
97 if ($query === false)
98 {
99 $this->mysql = null;
100 }
101 }
102
103 if (!in_array($this->options['extras']['prefix'] . 'items', $db))
104 {
105 $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
106 if ($query === false)
107 {
108 $this->mysql = null;
109 }
110 }
111 }
112
113 public function save($data)
114 {
115 if ($this->mysql === null)
116 {
117 return false;
118 }
119
120 if (is_a($data, 'SimplePie'))
121 {
122 $data = clone $data;
123
124 $prepared = self::prepare_simplepie_object_for_cache($data);
125
126 $query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
127 $query->bindValue(':feed', $this->id);
128 if ($query->execute())
129 {
130 if ($query->fetchColumn() > 0)
131 {
132 $items = count($prepared[1]);
133 if ($items)
134 {
135 $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
136 $query = $this->mysql->prepare($sql);
137 $query->bindValue(':items', $items);
138 }
139 else
140 {
141 $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
142 $query = $this->mysql->prepare($sql);
143 }
144
145 $query->bindValue(':data', $prepared[0]);
146 $query->bindValue(':time', time());
147 $query->bindValue(':feed', $this->id);
148 if (!$query->execute())
149 {
150 return false;
151 }
152 }
153 else
154 {
155 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
156 $query->bindValue(':feed', $this->id);
157 $query->bindValue(':count', count($prepared[1]));
158 $query->bindValue(':data', $prepared[0]);
159 $query->bindValue(':time', time());
160 if (!$query->execute())
161 {
162 return false;
163 }
164 }
165
166 $ids = array_keys($prepared[1]);
167 if (!empty($ids))
168 {
169 foreach ($ids as $id)
170 {
171 $database_ids[] = $this->mysql->quote($id);
172 }
173
174 $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
175 $query->bindValue(':feed', $this->id);
176
177 if ($query->execute())
178 {
179 $existing_ids = array();
180 while ($row = $query->fetchColumn())
181 {
182 $existing_ids[] = $row;
183 }
184
185 $new_ids = array_diff($ids, $existing_ids);
186
187 foreach ($new_ids as $new_id)
188 {
189 if (!($date = $prepared[1][$new_id]->get_date('U')))
190 {
191 $date = time();
192 }
193
194 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
195 $query->bindValue(':feed', $this->id);
196 $query->bindValue(':id', $new_id);
197 $query->bindValue(':data', serialize($prepared[1][$new_id]->data));
198 $query->bindValue(':date', $date);
199 if (!$query->execute())
200 {
201 return false;
202 }
203 }
204 return true;
205 }
206 }
207 else
208 {
209 return true;
210 }
211 }
212 }
213 else
214 {
215 $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
216 $query->bindValue(':feed', $this->id);
217 if ($query->execute())
218 {
219 if ($query->rowCount() > 0)
220 {
221 $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
222 $query->bindValue(':data', serialize($data));
223 $query->bindValue(':time', time());
224 $query->bindValue(':feed', $this->id);
225 if ($this->execute())
226 {
227 return true;
228 }
229 }
230 else
231 {
232 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
233 $query->bindValue(':id', $this->id);
234 $query->bindValue(':data', serialize($data));
235 $query->bindValue(':time', time());
236 if ($query->execute())
237 {
238 return true;
239 }
240 }
241 }
242 }
243 return false;
244 }
245
246 public function load()
247 {
248 if ($this->mysql === null)
249 {
250 return false;
251 }
252
253 $query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
254 $query->bindValue(':id', $this->id);
255 if ($query->execute() && ($row = $query->fetch()))
256 {
257 $data = unserialize($row[1]);
258
259 if (isset($this->options['items'][0]))
260 {
261 $items = (int) $this->options['items'][0];
262 }
263 else
264 {
265 $items = (int) $row[0];
266 }
267
268 if ($items !== 0)
269 {
270 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
271 {
272 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
273 }
274 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
275 {
276 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
277 }
278 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
279 {
280 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
281 }
282 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
283 {
284 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
285 }
286 else
287 {
288 $feed = null;
289 }
290
291 if ($feed !== null)
292 {
293 $sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
294 if ($items > 0)
295 {
296 $sql .= ' LIMIT ' . $items;
297 }
298
299 $query = $this->mysql->prepare($sql);
300 $query->bindValue(':feed', $this->id);
301 if ($query->execute())
302 {
303 while ($row = $query->fetchColumn())
304 {
305 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
306 }
307 }
308 else
309 {
310 return false;
311 }
312 }
313 }
314 return $data;
315 }
316 return false;
317 }
318
319 public function mtime()
320 {
321 if ($this->mysql === null)
322 {
323 return false;
324 }
325
326 $query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
327 $query->bindValue(':id', $this->id);
328 if ($query->execute() && ($time = $query->fetchColumn()))
329 {
330 return $time;
331 }
332 else
333 {
334 return false;
335 }
336 }
337
338 public function touch()
339 {
340 if ($this->mysql === null)
341 {
342 return false;
343 }
344
345 $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
346 $query->bindValue(':time', time());
347 $query->bindValue(':id', $this->id);
348 if ($query->execute() && $query->rowCount() > 0)
349 {
350 return true;
351 }
352 else
353 {
354 return false;
355 }
356 }
357
358 public function unlink()
359 {
360 if ($this->mysql === null)
361 {
362 return false;
363 }
364
365 $query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
366 $query->bindValue(':id', $this->id);
367 $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
368 $query2->bindValue(':id', $this->id);
369 if ($query->execute() && $query2->execute())
370 {
371 return true;
372 }
373 else
374 {
375 return false;
376 }
377 }
378 }