]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/OStatus/classes/Ostatus_profile.php
Merge branch '0.9.x' into 1.0.x
[quix0rs-gnu-social.git] / plugins / OStatus / classes / Ostatus_profile.php
index 5595a9d29825cc7350f87f348bedea38d6bc8256..e3b3daa2c56e7d4fa8037119936a4991794a8ff5 100644 (file)
@@ -442,6 +442,18 @@ class Ostatus_profile extends Memcached_DataObject
     {
         $activity = new Activity($entry, $feed);
 
+        // @todo process all activity objects
+        switch ($activity->objects[0]->type) {
+        case ActivityObject::ARTICLE:
+        case ActivityObject::BLOGENTRY:
+        case ActivityObject::NOTE:
+        case ActivityObject::STATUS:
+        case ActivityObject::COMMENT:
+            break;
+        default:
+            throw new ClientException("Can't handle that kind of post.");
+        }
+
         if ($activity->verb == ActivityVerb::POST) {
             $this->processPost($activity, $source);
         } else {
@@ -483,7 +495,7 @@ class Ostatus_profile extends Memcached_DataObject
 
         // It's not always an ActivityObject::NOTE, but... let's just say it is.
 
-        $note = $activity->object;
+        $note = $activity->objects[0];
 
         // The id URI will be used as a unique identifier for for the notice,
         // protecting against duplicate saves. It isn't required to be a URL;
@@ -538,14 +550,22 @@ class Ostatus_profile extends Memcached_DataObject
             }
             $shortSummary = common_shorten_links($summary);
             if (Notice::contentTooLong($shortSummary)) {
-                $url = common_shorten_url(common_local_url('attachment',
-                                                           array('attachment' => $attachment->id)));
+                $url = common_shorten_url($sourceUrl);
                 $shortSummary = substr($shortSummary,
                                        0,
                                        Notice::maxContent() - (mb_strlen($url) + 2));
-                $shortSummary .= '… ' . $url;
-                $content = $shortSummary;
-                $rendered = common_render_text($content);
+                $content = $shortSummary . ' ' . $url;
+
+                // We mark up the attachment link specially for the HTML output
+                // so we can fold-out the full version inline.
+                $attachUrl = common_local_url('attachment',
+                                              array('attachment' => $attachment->id));
+                $rendered = common_render_text($shortSummary) .
+                            '<a href="' . htmlspecialchars($attachUrl) .'"'.
+                            ' class="attachment more"' .
+                            ' title="'. htmlspecialchars(_m('Show more')) . '">' .
+                            '&#8230;' .
+                            '</a>';
             }
         }
 
@@ -706,7 +726,8 @@ class Ostatus_profile extends Memcached_DataObject
      *
      * @param string $profile_url
      * @return Ostatus_profile
-     * @throws Exception
+     * @throws Exception on various error conditions
+     * @throws OStatusShadowException if this reference would obscure a local user/group
      */
 
     public static function ensureProfileURL($profile_url, $hints=array())
@@ -793,7 +814,7 @@ class Ostatus_profile extends Memcached_DataObject
      * remote profiles.
      *
      * @return mixed Ostatus_profile or null
-     * @throws Exception for local profiles
+     * @throws OStatusShadowException for local profiles
      */
     static function getFromProfileURL($profile_url)
     {
@@ -816,7 +837,7 @@ class Ostatus_profile extends Memcached_DataObject
         $user = User::staticGet('id', $profile->id);
 
         if (!empty($user)) {
-            throw new Exception("'$profile_url' is the profile for local user '{$user->nickname}'.");
+            throw new OStatusShadowException($profile, "'$profile_url' is the profile for local user '{$user->nickname}'.");
         }
 
         // Continue discovery; it's a remote profile
@@ -1170,11 +1191,7 @@ class Ostatus_profile extends Memcached_DataObject
     protected static function getActivityObjectProfileURI($object)
     {
         if ($object->id) {
-            // Possibly an upstream bug; tag: URIs are rejected unless you
-            // explicitly ask for them. All other schemes are accepted for
-            // basic URI validation without asking.
-            if (Validate::uri($object->id) ||
-                Validate::uri($object->id, array('allowed_scheme' => array('tag')))) {
+            if (ActivityUtils::validateUri($object->id)) {
                 return $object->id;
             }
         }
@@ -1522,6 +1539,7 @@ class Ostatus_profile extends Memcached_DataObject
      * @param string $addr webfinger address
      * @return Ostatus_profile
      * @throws Exception on error conditions
+     * @throws OStatusShadowException if this reference would obscure a local user/group
      */
     public static function ensureWebfinger($addr)
     {
@@ -1600,9 +1618,18 @@ class Ostatus_profile extends Memcached_DataObject
                 $oprofile = self::ensureProfileURL($hints['profileurl'], $hints);
                 self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
                 return $oprofile;
+            } catch (OStatusShadowException $e) {
+                // We've ended up with a remote reference to a local user or group.
+                // @fixme ideally we should be able to say who it was so we can
+                // go back and refer to it the regular way
+                throw $e;
             } catch (Exception $e) {
                 common_log(LOG_WARNING, "Failed creating profile from profile URL '$profileUrl': " . $e->getMessage());
                 // keep looking
+                //
+                // @fixme this means an error discovering from profile page
+                // may give us a corrupt entry using the webfinger URI, which
+                // will obscure the correct page-keyed profile later on.
             }
         }
 
@@ -1659,10 +1686,22 @@ class Ostatus_profile extends Memcached_DataObject
         throw new Exception("Couldn't find a valid profile for '$addr'");
     }
 
+    /**
+     * Store the full-length scrubbed HTML of a remote notice to an attachment
+     * file on our server. We'll link to this at the end of the cropped version.
+     *
+     * @param string $title plaintext for HTML page's title
+     * @param string $rendered HTML fragment for HTML page's body
+     * @return File
+     */
     function saveHTMLFile($title, $rendered)
     {
-        $final = sprintf("<!DOCTYPE html>\n<html><head><title>%s</title></head>".
-                         '<body><div>%s</div></body></html>',
+        $final = sprintf("<!DOCTYPE html>\n" .
+                         '<html><head>' .
+                         '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' .
+                         '<title>%s</title>' .
+                         '</head>' .
+                         '<body>%s</body></html>',
                          htmlspecialchars($title),
                          $rendered);
 
@@ -1692,3 +1731,24 @@ class Ostatus_profile extends Memcached_DataObject
         return $file;
     }
 }
+
+/**
+ * Exception indicating we've got a remote reference to a local user,
+ * not a remote user!
+ *
+ * If we can ue a local profile after all, it's available as $e->profile.
+ */
+class OStatusShadowException extends Exception
+{
+    public $profile;
+
+    /**
+     * @param Profile $profile
+     * @param string $message
+     */
+    function __construct($profile, $message) {
+        $this->profile = $profile;
+        parent::__construct($message);
+    }
+}
+