]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/activityutils.php
Merge branch 'nightly' into 'nightly'
[quix0rs-gnu-social.git] / lib / activityutils.php
index 07d8a86141a9456458bc73043cd753af40dd056b..b83bc0a238045e2acc6959127fba521e199d4fcd 100644 (file)
@@ -65,11 +65,16 @@ class ActivityUtils
      *
      * @return string related link, if any
      */
-    static function getPermalink($element)
+    static function getPermalink(DOMNode $element)
     {
         return self::getLink($element, 'alternate', 'text/html');
     }
 
+    static function getSelfLink(DOMNode $element)
+    {
+        return self::getLink($element, 'self', 'application/atom+xml');
+    }
+
     /**
      * Get the permalink for an Activity object
      *
@@ -90,8 +95,9 @@ class ActivityUtils
                 $linkRel = $link->getAttribute(self::REL);
                 $linkType = $link->getAttribute(self::TYPE);
 
+                // XXX: Am I allowed to do this according to specs? (matching using common_bare_mime)
                 if ($linkRel == $rel &&
-                    (is_null($type) || $linkType == $type)) {
+                    (is_null($type) || common_bare_mime($linkType) == common_bare_mime($type))) {
                     return $link->getAttribute(self::HREF);
                 }
             }
@@ -281,26 +287,27 @@ class ActivityUtils
     static function validateUri($uri)
     {
         // Check mailto: URIs first
+        $validate = new Validate();
 
         if (preg_match('/^mailto:(.*)$/', $uri, $match)) {
-            return Validate::email($match[1], common_config('email', 'check_domain'));
+            return $validate->email($match[1], common_config('email', 'check_domain'));
         }
 
-        if (Validate::uri($uri)) {
+        if ($validate->uri($uri)) {
             return true;
         }
 
         // Possibly an upstream bug; tag: URIs aren't validated properly
         // unless you explicitly ask for them. All other schemes are accepted
         // for basic URI validation without asking.
-        if (Validate::uri($uri, array('allowed_scheme' => array('tag')))) {
+        if ($validate->uri($uri, array('allowed_schemes' => array('tag')))) {
             return true;
         }
 
         return false;
     }
 
-    static function getFeedAuthor($feedEl)
+    static function getFeedAuthor(DOMElement $feedEl)
     {
         // Try old and deprecated activity:subject
 
@@ -347,9 +354,9 @@ class ActivityUtils
         return null;
     }
 
-    static function compareTypes($type, $objects)    // this does verbs too!
+    static function compareTypes($type, $objects)
     {
-        $type = self::resolveUri($type);
+        $type = self::resolveUri($type, false);
         foreach ((array)$objects as $object) {
             if ($type === self::resolveUri($object)) {
                 return true;
@@ -358,6 +365,11 @@ class ActivityUtils
         return false;
     }
 
+    static function compareVerbs($type, $objects)
+    {
+        return self::compareTypes($type, $objects);
+    }
+
     static function resolveUri($uri, $make_relative=false)
     {
         if (empty($uri)) {
@@ -374,32 +386,74 @@ class ActivityUtils
     }
 
     static function findLocalObject(array $uris, $type=ActivityObject::NOTE) {
-        $object = null;
-        // TODO: Extend this in plugins etc.
-        if (Event::handle('StartFindLocalActivityObject', array($uris, $type, &$object))) {
+        $obj_class = null;
+        // TODO: Extend this in plugins etc. and describe in EVENTS.txt
+        if (Event::handle('StartFindLocalActivityObject', array($uris, $type, &$obj_class))) {
             switch (self::resolveUri($type)) {
             case ActivityObject::PERSON:
                 // GROUP will also be here in due time...
-                $object = new Profile();
+                $obj_class = 'Profile';
                 break;
             default:
-                $object = new Notice();
+                $obj_class = 'Notice';
             }
         }
-        foreach (array_unique($uris) as $uri) {
+        $object = null;
+        $uris = array_unique($uris);
+        foreach ($uris as $uri) {
             try {
                 // the exception thrown will cancel before reaching $object
-                $object = call_user_func(array($object, 'fromUri'), $uri);
+                $object = call_user_func("{$obj_class}::fromUri", $uri);
                 break;
-            } catch (Exception $e) {
-                common_debug('Could not find local activity object from uri: '.$uri);
+            } catch (UnknownUriException $e) {
+                common_debug('Could not find local activity object from uri: '.$e->object_uri);
             }
         }
-        if (!empty($object)) {
-            Event::handle('EndFindLocalActivityObject', array($object->getUri(), $type, $object));
-        } else {
-            throw new Exception('Could not find any activityobject stored locally with given URI');
+        if (!$object instanceof Managed_DataObject) {
+            throw new ServerException('Could not find any activityobject stored locally with given URIs: '.var_export($uris,true));
         }
+        Event::handle('EndFindLocalActivityObject', array($object->getUri(), $object->getObjectType(), $object));
         return $object;
     }
+
+    // Check authorship by supplying a Profile as a default and letting plugins
+    // set it to something else if the activity's author is actually someone
+    // else (like with a group or peopletag feed as handled in OStatus).
+    //
+    // NOTE: Returned is not necessarily the supplied profile! For example,
+    // the "feed author" may be a group, but the "activity author" is a person!
+    static function checkAuthorship(Activity $activity, Profile $profile)
+    {
+        if (Event::handle('CheckActivityAuthorship', array($activity, &$profile))) {
+            // if (empty($activity->actor)), then we generated this Activity ourselves and can trust $profile
+
+            $actor_uri = $profile->getUri();
+
+            if (!in_array($actor_uri, array($activity->actor->id, $activity->actor->link))) {
+                // A mismatch between our locally stored URI and the supplied author?
+                // Probably not more than a blog feed or something (with multiple authors or so)
+                // but log it for future inspection.
+                common_log(LOG_WARNING, "Got an actor '{$activity->actor->title}' ({$activity->actor->id}) on single-user feed for " . $actor_uri);
+            } elseif (empty($activity->actor->id)) {
+                // Plain <author> without ActivityStreams actor info.
+                // We'll just ignore this info for now and save the update under the feed's identity.
+            }
+        }
+
+        if (!$profile instanceof Profile) {
+            throw new ServerException('Could not get an author Profile for activity');
+        }
+
+        return $profile;
+    }
+
+    static public function typeToTitle($type)
+    {
+        return ucfirst(self::resolveUri($type, true));
+    }
+
+    static public function verbToTitle($verb)
+    {
+        return ucfirst(self::resolveUri($verb, true));
+    }
 }