]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/MemcachedPlugin.php
Fix for ticket 2756 - Calls to OAuth endpoints are redirected to the
[quix0rs-gnu-social.git] / plugins / MemcachedPlugin.php
1 <?php
2 /**
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2009, StatusNet, Inc.
5  *
6  * Plugin to implement cache interface for memcached
7  *
8  * PHP version 5
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Affero General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * @category  Cache
24  * @package   StatusNet
25  * @author    Evan Prodromou <evan@status.net>
26  * @author    Craig Andrews <candrews@integralblue.com>
27  * @copyright 2009 StatusNet, Inc.
28  * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
29  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
30  * @link      http://status.net/
31  */
32
33 if (!defined('STATUSNET')) {
34     // This check helps protect against security problems;
35     // your code file can't be executed directly from the web.
36     exit(1);
37 }
38
39 /**
40  * A plugin to use memcached for the cache interface
41  *
42  * This used to be encoded as config-variable options in the core code;
43  * it's now broken out to a separate plugin. The same interface can be
44  * implemented by other plugins.
45  *
46  * @category  Cache
47  * @package   StatusNet
48  * @author    Evan Prodromou <evan@status.net>
49  * @author    Craig Andrews <candrews@integralblue.com>
50  * @copyright 2009 StatusNet, Inc.
51  * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
52  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
53  * @link      http://status.net/
54  */
55
56 class MemcachedPlugin extends Plugin
57 {
58     static $cacheInitialized = false;
59
60     private $_conn  = null;
61     public $servers = array('127.0.0.1;11211');
62
63     public $defaultExpiry = 86400; // 24h
64
65     /**
66      * Initialize the plugin
67      *
68      * Note that onStartCacheGet() may have been called before this!
69      *
70      * @return boolean flag value
71      */
72
73     function onInitializePlugin()
74     {
75         $this->_ensureConn();
76         self::$cacheInitialized = true;
77         return true;
78     }
79
80     /**
81      * Get a value associated with a key
82      *
83      * The value should have been set previously.
84      *
85      * @param string &$key   in; Lookup key
86      * @param mixed  &$value out; value associated with key
87      *
88      * @return boolean hook success
89      */
90
91     function onStartCacheGet(&$key, &$value)
92     {
93         $this->_ensureConn();
94         $value = $this->_conn->get($key);
95         Event::handle('EndCacheGet', array($key, &$value));
96         return false;
97     }
98
99     /**
100      * Associate a value with a key
101      *
102      * @param string  &$key     in; Key to use for lookups
103      * @param mixed   &$value   in; Value to associate
104      * @param integer &$flag    in; Flag empty or Cache::COMPRESSED
105      * @param integer &$expiry  in; Expiry (passed through to Memcache)
106      * @param boolean &$success out; Whether the set was successful
107      *
108      * @return boolean hook success
109      */
110
111     function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
112     {
113         $this->_ensureConn();
114         if ($expiry === null) {
115             $expiry = $this->defaultExpiry;
116         }
117         $success = $this->_conn->set($key, $value, $expiry);
118         Event::handle('EndCacheSet', array($key, $value, $flag,
119                                            $expiry));
120         return false;
121     }
122
123     /**
124      * Atomically increment an existing numeric key value.
125      * Existing expiration time will not be changed.
126      *
127      * @param string &$key    in; Key to use for lookups
128      * @param int    &$step   in; Amount to increment (default 1)
129      * @param mixed  &$value  out; Incremented value, or false if key not set.
130      *
131      * @return boolean hook success
132      */
133     function onStartCacheIncrement(&$key, &$step, &$value)
134     {
135         $this->_ensureConn();
136         $value = $this->_conn->increment($key, $step);
137         Event::handle('EndCacheIncrement', array($key, $step, $value));
138         return false;
139     }
140
141     /**
142      * Delete a value associated with a key
143      *
144      * @param string  &$key     in; Key to lookup
145      * @param boolean &$success out; whether it worked
146      *
147      * @return boolean hook success
148      */
149
150     function onStartCacheDelete(&$key, &$success)
151     {
152         $this->_ensureConn();
153         $success = $this->_conn->delete($key);
154         Event::handle('EndCacheDelete', array($key));
155         return false;
156     }
157
158     function onStartCacheReconnect(&$success)
159     {
160         // nothing to do
161         return true;
162     }
163
164     /**
165      * Ensure that a connection exists
166      *
167      * Checks the instance $_conn variable and connects
168      * if it is empty.
169      *
170      * @return void
171      */
172
173     private function _ensureConn()
174     {
175         if (empty($this->_conn)) {
176             $this->_conn = new Memcached(common_config('site', 'nickname'));
177
178             if (!count($this->_conn->getServerList())) {
179             if (is_array($this->servers)) {
180                 $servers = $this->servers;
181             } else {
182                 $servers = array($this->servers);
183             }
184             foreach ($servers as $server) {
185                 if (strpos($server, ';') !== false) {
186                     list($host, $port) = explode(';', $server);
187                 } else {
188                     $host = $server;
189                     $port = 11211;
190                 }
191
192                 $this->_conn->addServer($host, $port);
193             }
194
195             // Compress items stored in the cache.
196
197             // Allows the cache to store objects larger than 1MB (if they
198             // compress to less than 1MB), and improves cache memory efficiency.
199
200             $this->_conn->setOption(Memcached::OPT_COMPRESSION, true);
201             }
202         }
203     }
204
205     /**
206      * Translate general flags to Memcached-specific flags
207      * @param int $flag
208      * @return int
209      */
210     protected function flag($flag)
211     {
212         //no flags are presently supported
213         return $flag;
214     }
215
216     function onPluginVersion(&$versions)
217     {
218         $versions[] = array('name' => 'Memcached',
219                             'version' => STATUSNET_VERSION,
220                             'author' => 'Evan Prodromou, Craig Andrews',
221                             'homepage' => 'http://status.net/wiki/Plugin:Memcached',
222                             'rawdescription' =>
223                             _m('Use <a href="http://memcached.org/">Memcached</a> to cache query results.'));
224         return true;
225     }
226 }
227