| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social 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.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social 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 GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |  * Superclass for plugins that do "real time" updates of timelines using Ajax | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @category  Plugin | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |  * @package   GNUsocial | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:56 -04:00
										 |  |  |  * @author    Evan Prodromou <evan@status.net> | 
					
						
							| 
									
										
										
										
											2014-03-06 13:23:08 +01:00
										 |  |  |  * @author    Mikael Nordfeldth <mmn@hethane.se> | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |  * @copyright 2009-2019 Free Software Foundation, Inc http://www.fsf.org | 
					
						
							|  |  |  |  * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  | defined('GNUSOCIAL') || die(); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |  * Superclass for plugin to do realtime updates | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Based on experience with the Comet and Meteor plugins, | 
					
						
							|  |  |  |  * this superclass extracts out some of the common functionality | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |  * Currently depends on the Favorite module. | 
					
						
							| 
									
										
										
										
											2014-06-27 13:58:35 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |  * @category Plugin | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |  * @package  GNUsocial | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:56 -04:00
										 |  |  |  * @author   Evan Prodromou <evan@status.net> | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |  * @license  https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  | class RealtimePlugin extends Plugin | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 13:29:35 -07:00
										 |  |  |     protected $showurl = null; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * When it's time to initialize the plugin, calculate and | 
					
						
							|  |  |  |      * pass the URLs we need. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onInitializePlugin() | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |         // FIXME: need to find a better way to pass this pattern in
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $this->showurl = common_local_url( | 
					
						
							|  |  |  |             'shownotice', | 
					
						
							|  |  |  |             ['notice' => '0000000000'] | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onCheckSchema() | 
					
						
							| 
									
										
										
										
											2011-07-08 17:52:07 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $schema = Schema::get(); | 
					
						
							|  |  |  |         $schema->ensureTable('realtime_channel', Realtime_channel::schemaDef()); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-13 14:47:40 -04:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Hook for RouterInitialized event. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2014-11-07 15:24:05 +01:00
										 |  |  |      * @param URLMapper $m path-to-action mapper | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |      * @return bool hook return | 
					
						
							|  |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2011-07-13 14:47:40 -04:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2014-11-07 15:24:05 +01:00
										 |  |  |     public function onRouterInitialized(URLMapper $m) | 
					
						
							| 
									
										
										
										
											2011-07-13 14:47:40 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $m->connect( | 
					
						
							|  |  |  |             'main/channel/:channelkey/keepalive', | 
					
						
							|  |  |  |             ['action' => 'keepalivechannel'], | 
					
						
							|  |  |  |             ['channelkey' => '[a-z0-9]{32}'] | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         $m->connect( | 
					
						
							|  |  |  |             'main/channel/:channelkey/close', | 
					
						
							|  |  |  |             ['action' => 'closechannel'], | 
					
						
							|  |  |  |             ['channelkey' => '[a-z0-9]{32}'] | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2011-07-13 14:47:40 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onEndShowScripts(Action $action) | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  |         $channel = $this->_getChannel($action); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($channel)) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $timeline = $this->_pathToChannel([$channel->channel_key]); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |         // If there's not a timeline on this page,
 | 
					
						
							|  |  |  |         // just return true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($timeline)) { | 
					
						
							| 
									
										
										
										
											2009-09-23 11:08:35 -04:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 15:24:12 -04:00
										 |  |  |         $base = $action->selfUrl(); | 
					
						
							| 
									
										
										
										
											2009-09-23 23:04:25 -04:00
										 |  |  |         if (mb_strstr($base, '?')) { | 
					
						
							| 
									
										
										
										
											2009-09-23 15:24:12 -04:00
										 |  |  |             $url = $base . '&realtime=1'; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $url = $base . '?realtime=1'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |         $scripts = $this->_getScripts(); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($scripts as $script) { | 
					
						
							| 
									
										
										
										
											2010-01-27 19:50:08 -08:00
										 |  |  |             $action->script($script); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $user = common_current_user(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($user->id)) { | 
					
						
							|  |  |  |             $user_id = $user->id; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $user_id = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 23:04:25 -04:00
										 |  |  |         if ($action->boolean('realtime')) { | 
					
						
							| 
									
										
										
										
											2009-09-23 22:02:42 +00:00
										 |  |  |             $realtimeUI = ' RealtimeUpdate.initPopupWindow();'; | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2009-11-18 15:41:07 +00:00
										 |  |  |             $pluginPath = common_path('plugins/Realtime/'); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $keepalive = common_local_url('keepalivechannel', ['channelkey' => $channel->channel_key]); | 
					
						
							|  |  |  |             $close = common_local_url('closechannel', ['channelkey' => $channel->channel_key]); | 
					
						
							| 
									
										
										
										
											2011-07-30 08:17:57 -04:00
										 |  |  |             $realtimeUI = ' RealtimeUpdate.initActions('.json_encode($url).', '.json_encode($timeline).', '.json_encode($pluginPath).', '.json_encode($keepalive).', '.json_encode($close).'); '; | 
					
						
							| 
									
										
										
										
											2009-09-23 22:02:42 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-23 21:58:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |         $script = ' $(document).ready(function() { '. | 
					
						
							| 
									
										
										
										
											2009-09-23 22:02:42 +00:00
										 |  |  |           $realtimeUI. | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  |             $this->_updateInitialize($timeline, $user_id). | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |           '}); '; | 
					
						
							| 
									
										
										
										
											2009-12-04 19:41:51 -05:00
										 |  |  |         $action->inlineScript($script); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-18 17:59:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 20:41:54 +02:00
										 |  |  |     public function onEndShowStylesheets(Action $action) | 
					
						
							| 
									
										
										
										
											2009-11-18 17:59:44 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $urlpath = self::staticPath( | 
					
						
							|  |  |  |             str_replace('Plugin', '', __CLASS__), | 
					
						
							|  |  |  |             'css/realtimeupdate.css' | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2014-03-01 11:07:58 +01:00
										 |  |  |         $action->cssLink($urlpath, null, 'screen, projection, tv'); | 
					
						
							| 
									
										
										
										
											2009-11-18 17:59:44 +00:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 13:23:08 +01:00
										 |  |  |     public function onHandleQueuedNotice(Notice $notice) | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $paths = []; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         // Add to the author's timeline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-27 10:58:11 -04:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $profile = $notice->getProfile(); | 
					
						
							|  |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |             $this->log(LOG_ERR, $e->getMessage()); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 13:23:08 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $user = $profile->getUser(); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $paths[] = ['showstream', $user->nickname, null]; | 
					
						
							| 
									
										
										
										
											2014-03-06 13:23:08 +01:00
										 |  |  |         } catch (NoSuchUserException $e) { | 
					
						
							|  |  |  |             // We really should handle the remote profile views too
 | 
					
						
							|  |  |  |             $user = null; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add to the public timeline
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 00:27:51 +02:00
										 |  |  |         $is_local = intval($notice->is_local); | 
					
						
							|  |  |  |         if ($is_local === Notice::LOCAL_PUBLIC || | 
					
						
							|  |  |  |                 ($is_local === Notice::REMOTE && !common_config('public', 'localonly'))) { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $paths[] = ['public', null, null]; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         // Add to the tags timeline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         $tags = $this->getNoticeTags($notice); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($tags)) { | 
					
						
							|  |  |  |             foreach ($tags as $tag) { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |                 $paths[] = ['tag', $tag, null]; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         // Add to inbox timelines
 | 
					
						
							|  |  |  |         // XXX: do a join
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-09 13:56:54 -08:00
										 |  |  |         $ni = $notice->whoGets(); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-09 13:56:54 -08:00
										 |  |  |         foreach (array_keys($ni) as $user_id) { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |             $user = User::getKV('id', $user_id); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $paths[] = ['all', $user->getNickname(), null]; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add to the replies timeline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $reply = new Reply(); | 
					
						
							|  |  |  |         $reply->notice_id = $notice->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($reply->find()) { | 
					
						
							|  |  |  |             while ($reply->fetch()) { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |                 $user = User::getKV('id', $reply->profile_id); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |                 if (!empty($user)) { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |                     $paths[] = ['replies', $user->getNickname(), null]; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add to the group timeline
 | 
					
						
							|  |  |  |         // XXX: join
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $gi = new Group_inbox(); | 
					
						
							|  |  |  |         $gi->notice_id = $notice->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($gi->find()) { | 
					
						
							|  |  |  |             while ($gi->fetch()) { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |                 $ug = User_group::getKV('id', $gi->group_id); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |                 $paths[] = ['showgroup', $ug->getNickname(), null]; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-15 15:30:33 -04:00
										 |  |  |         if (count($paths) > 0) { | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |             $json = $this->noticeAsJson($notice); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |             $this->_connect(); | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-11 11:33:39 -04:00
										 |  |  |             // XXX: We should probably fan-out here and do a
 | 
					
						
							|  |  |  |             // new queue item for each path
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-15 15:30:33 -04:00
										 |  |  |             foreach ($paths as $path) { | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |                 list($action, $arg1, $arg2) = $path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $channels = Realtime_channel::getAllChannels($action, $arg1, $arg2); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |                 $this->log(LOG_INFO, sprintf( | 
					
						
							|  |  |  |                     _("%d candidate channels for notice %d"), | 
					
						
							|  |  |  |                     count($channels), | 
					
						
							|  |  |  |                     $notice->id | 
					
						
							|  |  |  |                 )); | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 foreach ($channels as $channel) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     // XXX: We should probably fan-out here and do a
 | 
					
						
							|  |  |  |                     // new queue item for each user/path combo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (is_null($channel->user_id)) { | 
					
						
							|  |  |  |                         $profile = null; | 
					
						
							|  |  |  |                     } else { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |                         $profile = Profile::getKV('id', $channel->user_id); | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     if ($notice->inScope($profile)) { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |                         $this->log( | 
					
						
							|  |  |  |                             LOG_INFO, | 
					
						
							|  |  |  |                             sprintf( | 
					
						
							|  |  |  |                                 _m("Delivering notice %d to channel (%s, %s, %s) for user '%s'"), | 
					
						
							|  |  |  |                                 $notice->id, | 
					
						
							|  |  |  |                                 $channel->action, | 
					
						
							|  |  |  |                                 $channel->arg1, | 
					
						
							|  |  |  |                                 $channel->arg2, | 
					
						
							|  |  |  |                                 ($profile ? $profile->getNickname() : '<public>') | 
					
						
							|  |  |  |                             ) | 
					
						
							|  |  |  |                         ); | 
					
						
							|  |  |  |                         $timeline = $this->_pathToChannel([$channel->channel_key]); | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |                         $this->_publish($timeline, $json); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |             $this->_disconnect(); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onStartShowBody(Action $action) | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $realtime = $action->boolean('realtime'); | 
					
						
							|  |  |  |         if (!$realtime) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $action->elementStart( | 
					
						
							|  |  |  |             'body', | 
					
						
							|  |  |  |             (common_current_user() ? [ | 
					
						
							|  |  |  |                 'id' => $action->trimmed('action'), | 
					
						
							|  |  |  |                 'class' => 'user_in realtime-popup', | 
					
						
							|  |  |  |             ] : [ | 
					
						
							|  |  |  |                 'id' => $action->trimmed('action'), | 
					
						
							|  |  |  |                 'class'=> 'realtime-popup', | 
					
						
							|  |  |  |             ]) | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2009-09-23 14:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // XXX hack to deal with JS that tries to get the
 | 
					
						
							|  |  |  |         // root url from page output
 | 
					
						
							| 
									
										
										
										
											2009-09-23 23:04:25 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:58:42 -04:00
										 |  |  |         $action->elementStart('address'); | 
					
						
							| 
									
										
										
										
											2011-09-18 13:03:12 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('singleuser', 'enabled')) { | 
					
						
							|  |  |  |             $user = User::singleUser(); | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $url = common_local_url('showstream', ['nickname' => $user->nickname]); | 
					
						
							| 
									
										
										
										
											2011-09-18 13:03:12 -04:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             $url = common_local_url('public'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $action->element( | 
					
						
							|  |  |  |             'a', | 
					
						
							|  |  |  |             ['class' => 'url', | 
					
						
							|  |  |  |              'href'  => $url], | 
					
						
							|  |  |  |             '' | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2011-09-18 13:03:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:58:42 -04:00
										 |  |  |         $action->elementEnd('address'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 22:00:22 +00:00
										 |  |  |         $action->showContentBlock(); | 
					
						
							| 
									
										
										
										
											2009-10-04 04:10:15 -04:00
										 |  |  |         $action->showScripts(); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |         $action->elementEnd('body'); | 
					
						
							|  |  |  |         return false; // No default processing
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function noticeAsJson(Notice $notice) | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         // FIXME: this code should be abstracted to a neutral third
 | 
					
						
							|  |  |  |         // party, like Notice::asJson(). I'm not sure of the ethics
 | 
					
						
							|  |  |  |         // of refactoring from within a plugin, so I'm just abusing
 | 
					
						
							| 
									
										
										
										
											2009-11-09 20:01:46 +01:00
										 |  |  |         // the ApiAction method. Don't do this unless you're me!
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-09 17:21:22 -07:00
										 |  |  |         $act = new ApiAction('/dev/null'); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-09 17:53:35 -07:00
										 |  |  |         $arr = $act->twitterStatusArray($notice, true); | 
					
						
							| 
									
										
										
										
											2015-01-23 12:40:37 +01:00
										 |  |  |         $arr['url'] = $notice->getUrl(true); | 
					
						
							| 
									
										
										
										
											2016-01-06 15:32:00 +01:00
										 |  |  |         $arr['html'] = htmlspecialchars($notice->getRendered()); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         $arr['source'] = htmlspecialchars($arr['source']); | 
					
						
							| 
									
										
										
										
											2014-05-01 15:25:19 +02:00
										 |  |  |         $arr['conversation_url'] = $notice->getConversationUrl(); | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $profile = $notice->getProfile(); | 
					
						
							|  |  |  |         $arr['user']['profile_url'] = $profile->profileurl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:47:37 -05:00
										 |  |  |         // Add needed repeat data
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($notice->repeat_of)) { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |             $original = Notice::getKV('id', $notice->repeat_of); | 
					
						
							| 
									
										
										
										
											2014-04-29 19:46:58 +02:00
										 |  |  |             if ($original instanceof Notice) { | 
					
						
							| 
									
										
										
										
											2015-01-23 12:40:37 +01:00
										 |  |  |                 $arr['retweeted_status']['url'] = $original->getUrl(true); | 
					
						
							| 
									
										
										
										
											2016-01-06 15:32:00 +01:00
										 |  |  |                 $arr['retweeted_status']['html'] = htmlspecialchars($original->getRendered()); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:47:37 -05:00
										 |  |  |                 $arr['retweeted_status']['source'] = htmlspecialchars($original->source); | 
					
						
							|  |  |  |                 $originalProfile = $original->getProfile(); | 
					
						
							|  |  |  |                 $arr['retweeted_status']['user']['profile_url'] = $originalProfile->profileurl; | 
					
						
							| 
									
										
										
										
											2014-05-01 15:25:19 +02:00
										 |  |  |                 $arr['retweeted_status']['conversation_url'] = $original->getConversationUrl(); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:47:37 -05:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-04-29 19:46:58 +02:00
										 |  |  |             unset($original); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:47:37 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |         return $arr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function getNoticeTags(Notice $notice) | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $tags = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $nt = new Notice_tag(); | 
					
						
							|  |  |  |         $nt->notice_id = $notice->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($nt->find()) { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |             $tags = []; | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  |             while ($nt->fetch()) { | 
					
						
							|  |  |  |                 $tags[] = $nt->tag; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $nt->free(); | 
					
						
							|  |  |  |         $nt = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $tags; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _getScripts(): array | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $urlpath = self::staticPath( | 
					
						
							|  |  |  |             str_replace('Plugin', '', __CLASS__), | 
					
						
							|  |  |  |             'js/realtimeupdate.js' | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         return [$urlpath]; | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-02 11:39:38 -07:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:58 -07:00
										 |  |  |      * Export any i18n messages that need to be loaded at runtime... | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Action $action | 
					
						
							|  |  |  |      * @param array $messages | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |      * @return bool hook return value | 
					
						
							|  |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2010-11-02 11:39:38 -07:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onEndScriptMessages(Action $action, array &$messages) | 
					
						
							| 
									
										
										
										
											2010-11-02 11:39:38 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:58 -07:00
										 |  |  |         // TRANS: Text label for realtime view "play" button, usually replaced by an icon.
 | 
					
						
							|  |  |  |         $messages['realtime_play'] = _m('BUTTON', 'Play'); | 
					
						
							|  |  |  |         // TRANS: Tooltip for realtime view "play" button.
 | 
					
						
							|  |  |  |         $messages['realtime_play_tooltip'] = _m('TOOLTIP', 'Play'); | 
					
						
							|  |  |  |         // TRANS: Text label for realtime view "pause" button
 | 
					
						
							|  |  |  |         $messages['realtime_pause'] = _m('BUTTON', 'Pause'); | 
					
						
							|  |  |  |         // TRANS: Tooltip for realtime view "pause" button
 | 
					
						
							|  |  |  |         $messages['realtime_pause_tooltip'] = _m('TOOLTIP', 'Pause'); | 
					
						
							|  |  |  |         // TRANS: Text label for realtime view "popup" button, usually replaced by an icon.
 | 
					
						
							|  |  |  |         $messages['realtime_popup'] = _m('BUTTON', 'Pop up'); | 
					
						
							|  |  |  |         // TRANS: Tooltip for realtime view "popup" button.
 | 
					
						
							|  |  |  |         $messages['realtime_popup_tooltip'] = _m('TOOLTIP', 'Pop up in a window'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2010-11-02 11:39:38 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _updateInitialize($timeline, int $user_id) | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-03-14 13:29:35 -07:00
										 |  |  |         return "RealtimeUpdate.init($user_id, \"$this->showurl\"); ";
 | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _connect() | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _publish($timeline, $json) | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _disconnect() | 
					
						
							| 
									
										
										
										
											2009-07-14 15:26:39 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-15 15:30:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _pathToChannel(array $path): string | 
					
						
							| 
									
										
										
										
											2009-07-15 15:30:33 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         return ''; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _getTimeline(Action $action) | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $channel = $this->_getChannel($action); | 
					
						
							|  |  |  |         if (empty($channel)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         return $this->_pathToChannel([$channel->channel_key]); | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function _getChannel(Action $action) | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $timeline = null; | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |         $arg1     = null; | 
					
						
							|  |  |  |         $arg2     = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         $action_name = $action->trimmed('action'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |         // FIXME: lists
 | 
					
						
							|  |  |  |         // FIXME: search (!)
 | 
					
						
							|  |  |  |         // FIXME: profile + tag
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |         switch ($action_name) { | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |          case 'public': | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |             // no arguments
 | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |             break; | 
					
						
							|  |  |  |          case 'tag': | 
					
						
							|  |  |  |             $tag = $action->trimmed('tag'); | 
					
						
							| 
									
										
										
										
											2011-09-18 12:52:00 -04:00
										 |  |  |             if (!empty($tag)) { | 
					
						
							| 
									
										
										
										
											2011-07-11 09:16:16 -04:00
										 |  |  |                 $arg1 = $tag; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |                 $this->log(LOG_NOTICE, "Unexpected 'tag' action without tag argument"); | 
					
						
							|  |  |  |                 return null; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |          case 'showstream': | 
					
						
							|  |  |  |          case 'all': | 
					
						
							|  |  |  |          case 'replies': | 
					
						
							|  |  |  |          case 'showgroup': | 
					
						
							|  |  |  |             $nickname = common_canonical_nickname($action->trimmed('nickname')); | 
					
						
							|  |  |  |             if (!empty($nickname)) { | 
					
						
							| 
									
										
										
										
											2011-07-11 09:16:16 -04:00
										 |  |  |                 $arg1 = $nickname; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |                 $this->log(LOG_NOTICE, "Unexpected $action_name action without nickname argument."); | 
					
						
							|  |  |  |                 return null; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:28:14 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |          default: | 
					
						
							| 
									
										
										
										
											2011-07-11 09:16:16 -04:00
										 |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |         $user = common_current_user(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $user_id = (!empty($user)) ? $user->id : null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |         $channel = Realtime_channel::getChannel( | 
					
						
							|  |  |  |             $user_id, | 
					
						
							|  |  |  |             $action_name, | 
					
						
							|  |  |  |             $arg1, | 
					
						
							|  |  |  |             $arg2 | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2011-07-13 16:10:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $channel; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:07:20 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-03 15:37:49 +00:00
										 |  |  |     public function onStartReadWriteTables(&$alwaysRW, &$rwdb) | 
					
						
							| 
									
										
										
										
											2011-07-11 15:54:10 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-19 17:06:03 +02:00
										 |  |  |         $alwaysRW[] = 'realtime_channel'; | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2011-07-11 15:54:10 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-13 09:58:52 -04:00
										 |  |  | } |