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-2016, Ryan Parman, Sam 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 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
37 * @author Ryan Parman
38 * @author Sam Sneddon
39 * @author Ryan McCue
40 * @link http://simplepie.org/ SimplePie
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
42 */
43
44/**
45 * Caches data to memcache
46 *
47 * Registered for URLs with the "memcache" protocol
48 *
49 * For example, `memcache://localhost:11211/?timeout=3600&prefix=sp_` will
50 * connect to memcache on `localhost` on port 11211. All tables will be
51 * prefixed with `sp_` and data will expire after 3600 seconds
52 *
53 * @package SimplePie
54 * @subpackage Caching
55 * @uses Memcache
56 */
57class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
58{
59	/**
60	 * Memcache instance
61	 *
62	 * @var Memcache
63	 */
64	protected $cache;
65
66	/**
67	 * Options
68	 *
69	 * @var array
70	 */
71	protected $options;
72
73	/**
74	 * Cache name
75	 *
76	 * @var string
77	 */
78	protected $name;
79
80	/**
81	 * Create a new cache object
82	 *
83	 * @param string $location Location string (from SimplePie::$cache_location)
84	 * @param string $name Unique ID for the cache
85	 * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
86	 */
87	public function __construct($location, $name, $type)
88	{
89		$this->options = array(
90			'host' => '127.0.0.1',
91			'port' => 11211,
92			'extras' => array(
93				'timeout' => 3600, // one hour
94				'prefix' => 'simplepie_',
95			),
96		);
97		$this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
98
99		$this->name = $this->options['extras']['prefix'] . md5("$name:$type");
100
101		$this->cache = new Memcache();
102		$this->cache->addServer($this->options['host'], (int) $this->options['port']);
103	}
104
105	/**
106	 * Save data to the cache
107	 *
108	 * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
109	 * @return bool Successfulness
110	 */
111	public function save($data)
112	{
113		if ($data instanceof SimplePie)
114		{
115			$data = $data->data;
116		}
117		return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
118	}
119
120	/**
121	 * Retrieve the data saved to the cache
122	 *
123	 * @return array Data for SimplePie::$data
124	 */
125	public function load()
126	{
127		$data = $this->cache->get($this->name);
128
129		if ($data !== false)
130		{
131			return unserialize($data);
132		}
133		return false;
134	}
135
136	/**
137	 * Retrieve the last modified time for the cache
138	 *
139	 * @return int Timestamp
140	 */
141	public function mtime()
142	{
143		$data = $this->cache->get($this->name);
144
145		if ($data !== false)
146		{
147			// essentially ignore the mtime because Memcache expires on its own
148			return time();
149		}
150
151		return false;
152	}
153
154	/**
155	 * Set the last modified time to the current time
156	 *
157	 * @return bool Success status
158	 */
159	public function touch()
160	{
161		$data = $this->cache->get($this->name);
162
163		if ($data !== false)
164		{
165			return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
166		}
167
168		return false;
169	}
170
171	/**
172	 * Remove the cache
173	 *
174	 * @return bool Success status
175	 */
176	public function unlink()
177	{
178		return $this->cache->delete($this->name, 0);
179	}
180}
181