]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/Realtime/RealtimePlugin.php
Merge branch 'master' into nightly
[quix0rs-gnu-social.git] / plugins / Realtime / RealtimePlugin.php
index 84a1c7e86e84a45edcee5c67d894a7f7cd7f48ad..fbfb0aae306d3460878557e2004e1be6f0b902f5 100644 (file)
  * @category  Plugin
  * @package   StatusNet
  * @author    Evan Prodromou <evan@status.net>
+ * @author    Mikael Nordfeldth <mmn@hethane.se>
  * @copyright 2009 StatusNet, Inc.
+ * @copyright 2014 Free Software Foundation, Inc.
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Superclass for plugin to do realtime updates
@@ -37,6 +37,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  * Based on experience with the Comet and Meteor plugins,
  * this superclass extracts out some of the common functionality
  *
+ * Currently depends on Favorite plugin.
+ *
  * @category Plugin
  * @package  StatusNet
  * @author   Evan Prodromou <evan@status.net>
@@ -51,7 +53,6 @@ class RealtimePlugin extends Plugin
      * When it's time to initialize the plugin, calculate and
      * pass the URLs we need.
      */
-
     function onInitializePlugin()
     {
         // FIXME: need to find a better way to pass this pattern in
@@ -59,39 +60,21 @@ class RealtimePlugin extends Plugin
                                             array('notice' => '0000000000'));
         return true;
     }
-    
+
     function onCheckSchema()
     {
         $schema = Schema::get();
         $schema->ensureTable('realtime_channel', Realtime_channel::schemaDef());
         return true;
     }
-    
-    function onAutoload($cls)
-    {
-        $dir = dirname(__FILE__);
-
-        switch ($cls)
-        {
-        case 'KeepalivechannelAction':
-        case 'ClosechannelAction':
-            include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
-            return false;
-        case 'Realtime_channel':
-            include_once $dir.'/'.$cls.'.php';
-            return false;
-        default:
-            return true;
-        }
-    }
 
     /**
      * Hook for RouterInitialized event.
      *
-     * @param Net_URL_Mapper $m path-to-action mapper
+     * @param URLMapper $m path-to-action mapper
      * @return boolean hook return
      */
-    function onRouterInitialized($m)
+    public function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/channel/:channelkey/keepalive',
                     array('action' => 'keepalivechannel'),
@@ -159,30 +142,40 @@ class RealtimePlugin extends Plugin
         return true;
     }
 
-    function onEndShowStatusNetStyles($action)
+    public function onEndShowStylesheets(Action $action)
     {
-        $action->cssLink(Plugin::staticPath('Realtime', 'realtimeupdate.css'),
-                         null,
-                         'screen, projection, tv');
+        $urlpath = self::staticPath(str_replace('Plugin','',__CLASS__),
+                                    'css/realtimeupdate.css');
+        $action->cssLink($urlpath, null, 'screen, projection, tv');
         return true;
     }
 
-    function onHandleQueuedNotice($notice)
+    public function onHandleQueuedNotice(Notice $notice)
     {
         $paths = array();
 
         // Add to the author's timeline
 
-        $user = User::staticGet('id', $notice->profile_id);
+        try {
+            $profile = $notice->getProfile();
+        } catch (Exception $e) {
+            $this->log(LOG_ERR, $e->getMessage());
+            return true;
+        }
 
-        if (!empty($user)) {
+        try {
+            $user = $profile->getUser();
             $paths[] = array('showstream', $user->nickname, null);
+        } catch (NoSuchUserException $e) {
+            // We really should handle the remote profile views too
+            $user = null;
         }
 
         // Add to the public timeline
 
-        if ($notice->is_local == Notice::LOCAL_PUBLIC ||
-            ($notice->is_local == Notice::REMOTE_OMB && !common_config('public', 'localonly'))) {
+        $is_local = intval($notice->is_local);
+        if ($is_local === Notice::LOCAL_PUBLIC ||
+                ($is_local === Notice::REMOTE && !common_config('public', 'localonly'))) {
             $paths[] = array('public', null, null);
         }
 
@@ -202,7 +195,7 @@ class RealtimePlugin extends Plugin
         $ni = $notice->whoGets();
 
         foreach (array_keys($ni) as $user_id) {
-            $user = User::staticGet('id', $user_id);
+            $user = User::getKV('id', $user_id);
             $paths[] = array('all', $user->nickname, null);
         }
 
@@ -213,7 +206,7 @@ class RealtimePlugin extends Plugin
 
         if ($reply->find()) {
             while ($reply->fetch()) {
-                $user = User::staticGet('id', $reply->profile_id);
+                $user = User::getKV('id', $reply->profile_id);
                 if (!empty($user)) {
                     $paths[] = array('replies', $user->nickname, null);
                 }
@@ -228,7 +221,7 @@ class RealtimePlugin extends Plugin
 
         if ($gi->find()) {
             while ($gi->fetch()) {
-                $ug = User_group::staticGet('id', $gi->group_id);
+                $ug = User_group::getKV('id', $gi->group_id);
                 $paths[] = array('showgroup', $ug->nickname, null);
             }
         }
@@ -238,31 +231,41 @@ class RealtimePlugin extends Plugin
             $json = $this->noticeAsJson($notice);
 
             $this->_connect();
-            
+
             // XXX: We should probably fan-out here and do a
             // new queue item for each path
 
             foreach ($paths as $path) {
-               
-               list($action, $arg1, $arg2) = $path;
-               
-               $channels = Realtime_channel::getAllChannels($action, $arg1, $arg2);
-               
-               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 {
-                               $profile = Profile::staticGet('id', $channel->user_id);
-                       }
-                       if ($notice->inScope($profile)) {
-                               $timeline = $this->_pathToChannel(array($channel->channel_key));                
-                               $this->_publish($timeline, $json);
-                       }
-               }
+
+                list($action, $arg1, $arg2) = $path;
+
+                $channels = Realtime_channel::getAllChannels($action, $arg1, $arg2);
+                $this->log(LOG_INFO, sprintf(_("%d candidate channels for notice %d"),
+                                             count($channels), 
+                                             $notice->id));
+
+                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 {
+                        $profile = Profile::getKV('id', $channel->user_id);
+                    }
+                    if ($notice->inScope($profile)) {
+                        $this->log(LOG_INFO, 
+                                   sprintf(_("Delivering notice %d to channel (%s, %s, %s) for user '%s'"),
+                                           $notice->id,
+                                           $channel->action,
+                                           $channel->arg1,
+                                           $channel->arg2,
+                                           ($profile) ? ($profile->nickname) : "<public>"));
+                        $timeline = $this->_pathToChannel(array($channel->channel_key));
+                        $this->_publish($timeline, $json);
+                    }
+                }
             }
 
             $this->_disconnect();
@@ -288,9 +291,18 @@ class RealtimePlugin extends Plugin
         // root url from page output
 
         $action->elementStart('address');
+
+        if (common_config('singleuser', 'enabled')) {
+            $user = User::singleUser();
+            $url = common_local_url('showstream', array('nickname' => $user->nickname));
+        } else {
+            $url = common_local_url('public');
+        }
+
         $action->element('a', array('class' => 'url',
-                                  'href' => common_local_url('public')),
+                                    'href' => $url),
                          '');
+
         $action->elementEnd('address');
 
         $action->showContentBlock();
@@ -309,10 +321,10 @@ class RealtimePlugin extends Plugin
         $act = new ApiAction('/dev/null');
 
         $arr = $act->twitterStatusArray($notice, true);
-        $arr['url'] = $notice->bestUrl();
+        $arr['url'] = $notice->getUrl(true);
         $arr['html'] = htmlspecialchars($notice->rendered);
         $arr['source'] = htmlspecialchars($arr['source']);
-        $arr['conversation_url'] = $this->getConversationUrl($notice);
+        $arr['conversation_url'] = $notice->getConversationUrl();
 
         $profile = $notice->getProfile();
         $arr['user']['profile_url'] = $profile->profileurl;
@@ -320,16 +332,16 @@ class RealtimePlugin extends Plugin
         // Add needed repeat data
 
         if (!empty($notice->repeat_of)) {
-            $original = Notice::staticGet('id', $notice->repeat_of);
-            if (!empty($original)) {
-                $arr['retweeted_status']['url'] = $original->bestUrl();
+            $original = Notice::getKV('id', $notice->repeat_of);
+            if ($original instanceof Notice) {
+                $arr['retweeted_status']['url'] = $original->getUrl(true);
                 $arr['retweeted_status']['html'] = htmlspecialchars($original->rendered);
                 $arr['retweeted_status']['source'] = htmlspecialchars($original->source);
                 $originalProfile = $original->getProfile();
                 $arr['retweeted_status']['user']['profile_url'] = $originalProfile->profileurl;
-                $arr['retweeted_status']['conversation_url'] = $this->getConversationUrl($original);
+                $arr['retweeted_status']['conversation_url'] = $original->getConversationUrl();
             }
-            $original = null;
+            unset($original);
         }
 
         return $arr;
@@ -355,42 +367,11 @@ class RealtimePlugin extends Plugin
         return $tags;
     }
 
-    function getConversationUrl($notice)
-    {
-        $convurl = null;
-
-        if ($notice->hasConversation()) {
-            $conv = Conversation::staticGet(
-                'id',
-                $notice->conversation
-            );
-            $convurl = $conv->uri;
-
-            if(empty($convurl)) {
-                $msg = sprintf(
-                    "Couldn't find Conversation ID %d to make 'in context'"
-                    . "link for Notice ID %d",
-                    $notice->conversation,
-                    $notice->id
-                );
-
-                common_log(LOG_WARNING, $msg);
-            } else {
-                $convurl .= '#notice-' . $notice->id;
-            }
-        }
-
-        return $convurl;
-    }
-
     function _getScripts()
     {
-        if (common_config('site', 'minify')) {
-            $js = 'realtimeupdate.min.js';
-        } else {
-            $js = 'realtimeupdate.js';
-        }
-        return array(Plugin::staticPath('Realtime', $js));
+        $urlpath = self::staticPath(str_replace('Plugin','',__CLASS__),
+                                    'js/realtimeupdate.js');
+        return array($urlpath);
     }
 
     /**
@@ -455,26 +436,26 @@ class RealtimePlugin extends Plugin
     function _getChannel($action)
     {
         $timeline = null;
-               $arg1     = null;
-               $arg2     = null;
-               
+        $arg1     = null;
+        $arg2     = null;
+
         $action_name = $action->trimmed('action');
 
-               // FIXME: lists
-               // FIXME: search (!)
-               // FIXME: profile + tag
-               
+        // FIXME: lists
+        // FIXME: search (!)
+        // FIXME: profile + tag
+
         switch ($action_name) {
          case 'public':
-               // no arguments
+            // no arguments
             break;
          case 'tag':
             $tag = $action->trimmed('tag');
-            if (empty($tag)) {
+            if (!empty($tag)) {
                 $arg1 = $tag;
             } else {
-               $this->log(LOG_NOTICE, "Unexpected 'tag' action without tag argument");
-               return null;
+                $this->log(LOG_NOTICE, "Unexpected 'tag' action without tag argument");
+                return null;
             }
             break;
          case 'showstream':
@@ -485,29 +466,29 @@ class RealtimePlugin extends Plugin
             if (!empty($nickname)) {
                 $arg1 = $nickname;
             } else {
-               $this->log(LOG_NOTICE, "Unexpected $action_name action without nickname argument.");
-               return null;
+                $this->log(LOG_NOTICE, "Unexpected $action_name action without nickname argument.");
+                return null;
             }
             break;
          default:
             return null;
         }
 
-               $user = common_current_user();
-               
-               $user_id = (!empty($user)) ? $user->id : null;
-               
-               $channel = Realtime_channel::getChannel($user_id,
-                                                                                               $action_name,
-                                                                                               $arg1,
-                                                                                               $arg2);
+        $user = common_current_user();
+
+        $user_id = (!empty($user)) ? $user->id : null;
+
+        $channel = Realtime_channel::getChannel($user_id,
+                                                $action_name,
+                                                $arg1,
+                                                $arg2);
 
         return $channel;
     }
-    
+
     function onStartReadWriteTables(&$alwaysRW, &$rwdb)
     {
-       $alwaysRW[] = 'realtime_channel';
-       return true;
+        $alwaysRW[] = 'realtime_channel';
+        return true;
     }
 }