]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/activityimporter.php
Merge commit 'refs/merge-requests/165' of git://gitorious.org/statusnet/mainline...
[quix0rs-gnu-social.git] / lib / activityimporter.php
index 07a6b0e77b315ce18c74c1041b63172fa6470411..096eb9ba435c268082312270db195dcd0c75681b 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2010, StatusNet, Inc.
  *
  * class to import activities as part of a user's timeline
- * 
+ *
  * PHP version 5
  *
  * This program is free software: you can redistribute it and/or modify
@@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  * @link      http://status.net/
  */
-
 class ActivityImporter extends QueueHandler
 {
     private $trusted = false;
@@ -56,59 +55,66 @@ class ActivityImporter extends QueueHandler
      *
      * @return
      */
-
     function handle($data)
     {
         list($user, $author, $activity, $trusted) = $data;
 
         $this->trusted = $trusted;
 
+        $done = null;
+
         try {
-            switch ($activity->verb) {
-            case ActivityVerb::FOLLOW:
-                $this->subscribeProfile($user, $author, $activity);
-                break;
-            case ActivityVerb::JOIN:
-                $this->joinGroup($user, $activity);
-                break;
-            case ActivityVerb::POST:
-                $this->postNote($user, $activity);
-                break;
-            default:
-                throw new Exception("Unknown verb: {$activity->verb}");
+            if (Event::handle('StartImportActivity',
+                              array($user, $author, $activity, $trusted, &$done))) {
+                switch ($activity->verb) {
+                case ActivityVerb::FOLLOW:
+                    $this->subscribeProfile($user, $author, $activity);
+                    break;
+                case ActivityVerb::JOIN:
+                    $this->joinGroup($user, $activity);
+                    break;
+                case ActivityVerb::POST:
+                    $this->postNote($user, $author, $activity);
+                    break;
+                default:
+                    // TRANS: Client exception thrown when using an unknown verb for the activity importer.
+                    throw new ClientException(sprintf(_("Unknown verb: \"%s\"."),$activity->verb));
+                }
+                Event::handle('EndImportActivity',
+                              array($user, $author, $activity, $trusted));
+                $done = true;
             }
-        } catch (ClientException $ce) {
-            common_log(LOG_WARNING, $ce->getMessage());
-            return true;
-        } catch (ServerException $se) {
-            common_log(LOG_ERR, $ce->getMessage());
-            return false;
         } catch (Exception $e) {
-            common_log(LOG_ERR, $ce->getMessage());
-            return false;
+            common_log(LOG_ERR, $e->getMessage());
+            $done = true;
         }
-        return true;
+        return $done;
     }
-    
+
     function subscribeProfile($user, $author, $activity)
     {
         $profile = $user->getProfile();
 
         if ($activity->objects[0]->id == $author->id) {
+            if (!$this->trusted) {
+                // TRANS: Client exception thrown when trying to force a subscription for an untrusted user.
+                throw new ClientException(_('Cannot force subscription for untrusted user.'));
+            }
+
             $other = $activity->actor;
             $otherUser = User::staticGet('uri', $other->id);
-            
+
             if (!empty($otherUser)) {
                 $otherProfile = $otherUser->getProfile();
             } else {
-                throw new Exception("Can't force remote user to subscribe.");
+                // TRANS: Client exception thrown when trying to force a remote user to subscribe.
+                throw new Exception(_('Cannot force remote user to subscribe.'));
             }
 
             // XXX: don't do this for untrusted input!
 
             Subscription::start($otherProfile, $profile);
-
-        } else if (empty($activity->actor) 
+        } else if (empty($activity->actor)
                    || $activity->actor->id == $author->id) {
 
             $other = $activity->objects[0];
@@ -116,12 +122,14 @@ class ActivityImporter extends QueueHandler
             $otherProfile = Profile::fromUri($other->id);
 
             if (empty($otherProfile)) {
-                throw new ClientException(_("Unknown profile."));
+                // TRANS: Client exception thrown when trying to subscribe to an unknown profile.
+                throw new ClientException(_('Unknown profile.'));
             }
 
             Subscription::start($profile, $otherProfile);
         } else {
-            throw new Exception("This activity seems unrelated to our user.");
+            // TRANS: Client exception thrown when trying to import an event not related to the importing user.
+            throw new Exception(_('This activity seems unrelated to our user.'));
         }
     }
 
@@ -136,22 +144,25 @@ class ActivityImporter extends QueueHandler
         if (empty($group)) {
             $oprofile = Ostatus_profile::ensureActivityObjectProfile($activity->objects[0]);
             if (!$oprofile->isGroup()) {
-                throw new Exception("Remote profile is not a group!");
+                // TRANS: Client exception thrown when trying to join a remote group that is not a group.
+                throw new ClientException(_('Remote profile is not a group!'));
             }
             $group = $oprofile->localGroup();
         }
 
         assert(!empty($group));
 
-        if (Event::handle('StartJoinGroup', array($group, $user))) {
-            Group_member::join($group->id, $user->id);
-            Event::handle('EndJoinGroup', array($group, $user));
+        if ($user->isMember($group)) {
+            // TRANS: Client exception thrown when trying to join a group the importing user is already a member of.
+            throw new ClientException(_("User is already a member of this group."));
         }
+
+        $user->joinGroup($group);
     }
 
     // XXX: largely cadged from Ostatus_profile::processNote()
 
-    function postNote($user, $activity)
+    function postNote($user, $author, $activity)
     {
         $note = $activity->objects[0];
 
@@ -160,11 +171,32 @@ class ActivityImporter extends QueueHandler
         $notice = Notice::staticGet('uri', $sourceUri);
 
         if (!empty($notice)) {
-            // This is weird.
-            $orig = clone($notice);
-            $notice->profile_id = $user->id;
-            $notice->update($orig);
-            return;
+
+            common_log(LOG_INFO, "Notice {$sourceUri} already exists.");
+
+            if ($this->trusted) {
+
+                $profile = $notice->getProfile();
+
+                $uri = $profile->getUri();
+
+                if ($uri == $author->id) {
+                    common_log(LOG_INFO, "Updating notice author from $author->id to $user->uri");
+                    $orig = clone($notice);
+                    $notice->profile_id = $user->id;
+                    $notice->update($orig);
+                    return;
+                } else {
+                    // TRANS: Client exception thrown when trying to import a notice by another user.
+                    // TRANS: %1$s is the source URI of the notice, %2$s is the URI of the author.
+                    throw new ClientException(sprintf(_('Already know about notice %1$s and '.
+                                                        ' it has a different author %2$s.'),
+                                                      $sourceUri, $uri));
+                }
+            } else {
+                // TRANS: Client exception thrown when trying to overwrite the author information for a non-trusted user during import.
+                throw new ClientException(_('Not overwriting author info for non-trusted user.'));
+            }
         }
 
         // Use summary as fallback for content
@@ -177,8 +209,9 @@ class ActivityImporter extends QueueHandler
             $sourceContent = $note->title;
         } else {
             // @fixme fetch from $sourceUrl?
-            // @todo i18n FIXME: use sprintf and add i18n.
-            throw new ClientException("No content for notice {$sourceUri}.");
+            // TRANS: Client exception thrown when trying to import a notice without content.
+            // TRANS: %s is the notice URI.
+            throw new ClientException(sprintf(_('No content for notice %s.'),$sourceUri));
         }
 
         // Get (safe!) HTML and text versions of the content
@@ -194,7 +227,8 @@ class ActivityImporter extends QueueHandler
                          'replies' => array(),
                          'groups' => array(),
                          'tags' => array(),
-                         'urls' => array());
+                         'urls' => array(),
+                         'distribute' => false);
 
         // Check for optional attributes...
 
@@ -246,6 +280,8 @@ class ActivityImporter extends QueueHandler
             $options['urls'][] = $href;
         }
 
+        common_log(LOG_INFO, "Saving notice {$options['uri']}");
+
         $saved = Notice::saveNew($user->id,
                                  $content,
                                  'restore', // TODO: restore the actual source
@@ -306,12 +342,15 @@ class ActivityImporter extends QueueHandler
 
         return array($groups, $replies);
     }
+
 
     function purify($content)
     {
+        require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
+
         $config = array('safe' => 1,
                         'deny_attribute' => 'id,style,on*');
+
         return htmLawed($content, $config);
     }
 }