| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * GNU social - a federating social network | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Plguin inplementing Redis based caching | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * LICENCE: This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  Files | 
					
						
							|  |  |  |  * @package   GNUsocial | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |  * @author    Stéphane Bérubé <chimo@chromic.org> | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |  * @author    Miguel Dantas <biodantas@gmail.com> | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |  * @copyright 2018, 2019 Free Software Foundation http://fsf.org | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | 
					
						
							|  |  |  |  * @link      https://www.gnu.org/software/social/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | defined('GNUSOCIAL') || die(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  | use Predis\Client; | 
					
						
							|  |  |  | use Predis\PredisException; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | class RedisCachePlugin extends Plugin | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |     const PLUGIN_VERSION = '0.0.1'; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |     // settings which can be set in config.php with addPlugin('Embed', ['param'=>'value', ...]);
 | 
					
						
							|  |  |  |     public $server = null; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     public $defaultExpiry = 86400; // 24h
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected $client = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     function onInitializePlugin() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->_ensureConn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function _ensureConn() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->client === null) { | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |             $this->client = new Client($this->server); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheGet(&$key, &$value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  |             $ret = $this->client->get($key); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Hit, overwrite "value" and return false
 | 
					
						
							|  |  |  |         // to indicate we took care of this
 | 
					
						
							|  |  |  |         if ($ret !== null) { | 
					
						
							|  |  |  |             $value = unserialize($ret); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Miss, let GS do its thing
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($expiry === null) { | 
					
						
							|  |  |  |             $expiry = $this->defaultExpiry; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $ret = $this->client->setex($key, $expiry, serialize($value)); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-02 16:49:46 +01:00
										 |  |  |         if (is_int($ret) || $ret->getPayload() === "OK") { | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             $success = true; | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheDelete($key) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         if ($key === null) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |             $ret = $this->client->del($key); | 
					
						
							|  |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         // Let other caches delete stuff if we didn't succeed
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:53:57 +01:00
										 |  |  |         return isset($ret) && $ret === 1; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheIncrement(&$key, &$step, &$value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  |             $this->client->incrby($key, $step); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 15:03:30 +01:00
										 |  |  |     public function onPluginVersion(array &$versions): bool | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         $versions[] = array('name' => 'RedisCache', | 
					
						
							|  |  |  |                             'version' => self::VERSION, | 
					
						
							|  |  |  |                             'author' => 'chimo', | 
					
						
							|  |  |  |                             'homepage' => 'https://github.com/chimo/gs-rediscache', | 
					
						
							|  |  |  |                             'description' => | 
					
						
							|  |  |  |                             // TRANS: Plugin description.
 | 
					
						
							| 
									
										
										
										
											2019-08-21 20:03:02 +01:00
										 |  |  |                             _m('Plugin implementing Redis as a backend for GNU social caching')); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |