forked from GNUsocial/gnu-social
		
	Fix broken user activitystreams feed due to deleted notices
This commit is contained in:
		| @@ -34,7 +34,9 @@ | ||||
|  * @link      http://status.net/ | ||||
|  */ | ||||
|  | ||||
| if (!defined('GNUSOCIAL')) { exit(1); } | ||||
| if (!defined('GNUSOCIAL')) { | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns the most recent notices (default 20) posted by the authenticating | ||||
| @@ -55,9 +57,64 @@ if (!defined('GNUSOCIAL')) { exit(1); } | ||||
|  */ | ||||
| class ApiTimelineUserAction extends ApiBareAuthAction | ||||
| { | ||||
|     var $notices = null; | ||||
|     public $notices = null; | ||||
|  | ||||
|     var $next_id = null; | ||||
|     public $next_id = null; | ||||
|  | ||||
|     /** | ||||
|      * We expose AtomPub here, so non-GET/HEAD reqs must be read/write. | ||||
|      * | ||||
|      * @param array $args other arguments | ||||
|      * | ||||
|      * @return boolean true | ||||
|      */ | ||||
|  | ||||
|     public function isReadOnly($args) | ||||
|     { | ||||
|         return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * When was this feed last modified? | ||||
|      * | ||||
|      * @return string datestamp of the latest notice in the stream | ||||
|      */ | ||||
|     public function lastModified() | ||||
|     { | ||||
|         if (!empty($this->notices) && (count($this->notices) > 0)) { | ||||
|             return strtotime($this->notices[0]->created); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * An entity tag for this stream | ||||
|      * | ||||
|      * Returns an Etag based on the action name, language, user ID, and | ||||
|      * timestamps of the first and last notice in the timeline | ||||
|      * | ||||
|      * @return string etag | ||||
|      */ | ||||
|     public function etag() | ||||
|     { | ||||
|         if (!empty($this->notices) && (count($this->notices) > 0)) { | ||||
|             $last = count($this->notices) - 1; | ||||
|  | ||||
|             return '"' . implode( | ||||
|                     ':', | ||||
|                     array($this->arg('action'), | ||||
|                         common_user_cache_hash($this->scoped), | ||||
|                         common_language(), | ||||
|                         $this->target->getID(), | ||||
|                         strtotime($this->notices[0]->created), | ||||
|                         strtotime($this->notices[$last]->created)) | ||||
|                 ) | ||||
|                 . '"'; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Take arguments for running | ||||
| @@ -65,8 +122,10 @@ class ApiTimelineUserAction extends ApiBareAuthAction | ||||
|      * @param array $args $_REQUEST args | ||||
|      * | ||||
|      * @return boolean success flag | ||||
|      * @throws AuthorizationException | ||||
|      * @throws ClientException | ||||
|      */ | ||||
|     protected function prepare(array $args=array()) | ||||
|     protected function prepare(array $args = []) | ||||
|     { | ||||
|         parent::prepare($args); | ||||
|  | ||||
| @@ -86,169 +145,22 @@ class ApiTimelineUserAction extends ApiBareAuthAction | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the request | ||||
|      * | ||||
|      * Just show the notices | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function handle() | ||||
|     { | ||||
|         parent::handle(); | ||||
|  | ||||
|         if ($this->isPost()) { | ||||
|             $this->handlePost(); | ||||
|         } else { | ||||
|             $this->showTimeline(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the timeline of notices | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     function showTimeline() | ||||
|     { | ||||
|         // We'll use the shared params from the Atom stub | ||||
|         // for other feed types. | ||||
|         $atom = new AtomUserNoticeFeed($this->target->getUser(), $this->scoped); | ||||
|  | ||||
|         $link = common_local_url( | ||||
|                                  'showstream', | ||||
|                                  array('nickname' => $this->target->getNickname()) | ||||
|                                  ); | ||||
|  | ||||
|         $self = $this->getSelfUri(); | ||||
|  | ||||
|         // FriendFeed's SUP protocol | ||||
|         // Also added RSS and Atom feeds | ||||
|  | ||||
|         $suplink = common_local_url('sup', null, null, $this->target->getID()); | ||||
|         header('X-SUP-ID: ' . $suplink); | ||||
|  | ||||
|  | ||||
|         // paging links | ||||
|         $nextUrl = !empty($this->next_id) | ||||
|                     ? common_local_url('ApiTimelineUser', | ||||
|                                     array('format' => $this->format, | ||||
|                                           'id' => $this->target->getID()), | ||||
|                                     array('max_id' => $this->next_id)) | ||||
|                     : null; | ||||
|  | ||||
|         $prevExtra = array(); | ||||
|         if (!empty($this->notices)) { | ||||
|             assert($this->notices[0] instanceof Notice); | ||||
|             $prevExtra['since_id'] = $this->notices[0]->id; | ||||
|         } | ||||
|  | ||||
|         $prevUrl = common_local_url('ApiTimelineUser', | ||||
|                                     array('format' => $this->format, | ||||
|                                           'id' => $this->target->getID()), | ||||
|                                     $prevExtra); | ||||
|         $firstUrl = common_local_url('ApiTimelineUser', | ||||
|                                     array('format' => $this->format, | ||||
|                                           'id' => $this->target->getID())); | ||||
|  | ||||
|         switch($this->format) { | ||||
|         case 'xml': | ||||
|             $this->showXmlTimeline($this->notices); | ||||
|             break; | ||||
|         case 'rss': | ||||
|             $this->showRssTimeline( | ||||
|                                    $this->notices, | ||||
|                                    $atom->title, | ||||
|                                    $link, | ||||
|                                    $atom->subtitle, | ||||
|                                    $suplink, | ||||
|                                    $atom->logo, | ||||
|                                    $self | ||||
|                                    ); | ||||
|             break; | ||||
|         case 'atom': | ||||
|             header('Content-Type: application/atom+xml; charset=utf-8'); | ||||
|  | ||||
|             $atom->setId($self); | ||||
|             $atom->setSelfLink($self); | ||||
|  | ||||
|             // Add navigation links: next, prev, first | ||||
|             // Note: we use IDs rather than pages for navigation; page boundaries | ||||
|             // change too quickly! | ||||
|  | ||||
|             if (!empty($this->next_id)) { | ||||
|                 $atom->addLink($nextUrl, | ||||
|                                array('rel' => 'next', | ||||
|                                      'type' => 'application/atom+xml')); | ||||
|             } | ||||
|  | ||||
|             if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) { | ||||
|                 $atom->addLink($prevUrl, | ||||
|                                array('rel' => 'prev', | ||||
|                                      'type' => 'application/atom+xml')); | ||||
|             } | ||||
|  | ||||
|             if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) { | ||||
|                 $atom->addLink($firstUrl, | ||||
|                                array('rel' => 'first', | ||||
|                                      'type' => 'application/atom+xml')); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             $atom->addEntryFromNotices($this->notices); | ||||
|             $this->raw($atom->getString()); | ||||
|  | ||||
|             break; | ||||
|         case 'json': | ||||
|             $this->showJsonTimeline($this->notices); | ||||
|             break; | ||||
|         case 'as': | ||||
|             header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE); | ||||
|             $doc = new ActivityStreamJSONDocument($this->scoped); | ||||
|             $doc->setTitle($atom->title); | ||||
|             $doc->addLink($link, 'alternate', 'text/html'); | ||||
|             $doc->addItemsFromNotices($this->notices); | ||||
|  | ||||
|             if (!empty($this->next_id)) { | ||||
|                 $doc->addLink($nextUrl, | ||||
|                                array('rel' => 'next', | ||||
|                                      'type' => ActivityStreamJSONDocument::CONTENT_TYPE)); | ||||
|             } | ||||
|  | ||||
|             if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) { | ||||
|                 $doc->addLink($prevUrl, | ||||
|                                array('rel' => 'prev', | ||||
|                                      'type' => ActivityStreamJSONDocument::CONTENT_TYPE)); | ||||
|             } | ||||
|  | ||||
|             if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) { | ||||
|                 $doc->addLink($firstUrl, | ||||
|                                array('rel' => 'first', | ||||
|                                      'type' => ActivityStreamJSONDocument::CONTENT_TYPE)); | ||||
|             } | ||||
|  | ||||
|             $this->raw($doc->asString()); | ||||
|             break; | ||||
|         default: | ||||
|             // TRANS: Client error displayed when coming across a non-supported API method. | ||||
|             $this->clientError(_('API method not found.'), 404); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get notices | ||||
|      * | ||||
|      * @return array notices | ||||
|      */ | ||||
|     function getNotices() | ||||
|     public function getNotices() | ||||
|     { | ||||
|         $notices = array(); | ||||
|         $notices = []; | ||||
|  | ||||
|         $notice = $this->target->getNotices(($this->page-1) * $this->count, | ||||
|                                           $this->count + 1, | ||||
|                                           $this->since_id, | ||||
|                                           $this->max_id, | ||||
|                                           $this->scoped); | ||||
|         $notice = $this->target->getNotices( | ||||
|             ($this->page - 1) * $this->count, | ||||
|             $this->count + 1, | ||||
|             $this->since_id, | ||||
|             $this->max_id, | ||||
|             $this->scoped | ||||
|         ); | ||||
|  | ||||
|         while ($notice->fetch()) { | ||||
|             if (count($notices) < $this->count) { | ||||
| @@ -263,64 +175,29 @@ class ApiTimelineUserAction extends ApiBareAuthAction | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * We expose AtomPub here, so non-GET/HEAD reqs must be read/write. | ||||
|      * Handle the request | ||||
|      * | ||||
|      * @param array $args other arguments | ||||
|      * Just show the notices | ||||
|      * | ||||
|      * @return boolean true | ||||
|      * @return void | ||||
|      * @throws ClientException | ||||
|      * @throws ServerException | ||||
|      */ | ||||
|  | ||||
|     function isReadOnly($args) | ||||
|     protected function handle() | ||||
|     { | ||||
|         return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD'); | ||||
|     } | ||||
|         parent::handle(); | ||||
|  | ||||
|     /** | ||||
|      * When was this feed last modified? | ||||
|      * | ||||
|      * @return string datestamp of the latest notice in the stream | ||||
|      */ | ||||
|     function lastModified() | ||||
|     { | ||||
|         if (!empty($this->notices) && (count($this->notices) > 0)) { | ||||
|             return strtotime($this->notices[0]->created); | ||||
|         if ($this->isPost()) { | ||||
|             $this->handlePost(); | ||||
|         } else { | ||||
|             $this->showTimeline(); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * An entity tag for this stream | ||||
|      * | ||||
|      * Returns an Etag based on the action name, language, user ID, and | ||||
|      * timestamps of the first and last notice in the timeline | ||||
|      * | ||||
|      * @return string etag | ||||
|      */ | ||||
|     function etag() | ||||
|     { | ||||
|         if (!empty($this->notices) && (count($this->notices) > 0)) { | ||||
|             $last = count($this->notices) - 1; | ||||
|  | ||||
|             return '"' . implode( | ||||
|                                  ':', | ||||
|                                  array($this->arg('action'), | ||||
|                                        common_user_cache_hash($this->scoped), | ||||
|                                        common_language(), | ||||
|                                        $this->target->getID(), | ||||
|                                        strtotime($this->notices[0]->created), | ||||
|                                        strtotime($this->notices[$last]->created)) | ||||
|                                  ) | ||||
|               . '"'; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     function handlePost() | ||||
|     public function handlePost() | ||||
|     { | ||||
|         if (!$this->scoped instanceof Profile || | ||||
|                 !$this->target->sameAs($this->scoped)) { | ||||
|             !$this->target->sameAs($this->scoped)) { | ||||
|             // TRANS: Client error displayed trying to add a notice to another user's timeline. | ||||
|             $this->clientError(_('Only the user can add to their own timeline.'), 403); | ||||
|         } | ||||
| @@ -354,7 +231,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction | ||||
|  | ||||
|         $activity = new Activity($dom->documentElement); | ||||
|  | ||||
|         common_debug('AtomPub: Ignoring right now, but this POST was made to collection: '.$activity->id); | ||||
|         common_debug('AtomPub: Ignoring right now, but this POST was made to collection: ' . $activity->id); | ||||
|  | ||||
|         // Reset activity data so we can handle it in the same functions as with OStatus | ||||
|         // because we don't let clients set their own UUIDs... Not sure what AtomPub thinks | ||||
| @@ -375,7 +252,158 @@ class ApiTimelineUserAction extends ApiBareAuthAction | ||||
|  | ||||
|         header('HTTP/1.1 201 Created'); | ||||
|         header("Location: " . common_local_url('ApiStatusesShow', array('id' => $stored->getID(), | ||||
|                                                                         'format' => 'atom'))); | ||||
|                 'format' => 'atom'))); | ||||
|         $this->showSingleAtomStatus($stored); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the timeline of notices | ||||
|      * | ||||
|      * @return void | ||||
|      * @throws ClientException | ||||
|      * @throws ServerException | ||||
|      * @throws UserNoProfileException | ||||
|      */ | ||||
|     public function showTimeline() | ||||
|     { | ||||
|         // We'll use the shared params from the Atom stub | ||||
|         // for other feed types. | ||||
|         $atom = new AtomUserNoticeFeed($this->target->getUser(), $this->scoped); | ||||
|  | ||||
|         $link = common_local_url( | ||||
|             'showstream', | ||||
|             array('nickname' => $this->target->getNickname()) | ||||
|         ); | ||||
|  | ||||
|         $self = $this->getSelfUri(); | ||||
|  | ||||
|         // FriendFeed's SUP protocol | ||||
|         // Also added RSS and Atom feeds | ||||
|  | ||||
|         $suplink = common_local_url('sup', null, null, $this->target->getID()); | ||||
|         header('X-SUP-ID: ' . $suplink); | ||||
|  | ||||
|  | ||||
|         // paging links | ||||
|         $nextUrl = !empty($this->next_id) | ||||
|             ? common_local_url( | ||||
|                 'ApiTimelineUser', | ||||
|                 array('format' => $this->format, | ||||
|                     'id' => $this->target->getID()), | ||||
|                 array('max_id' => $this->next_id) | ||||
|             ) | ||||
|             : null; | ||||
|  | ||||
|         $prevExtra = []; | ||||
|         if (!empty($this->notices)) { | ||||
|             assert($this->notices[0] instanceof Notice); | ||||
|             $prevExtra['since_id'] = $this->notices[0]->id; | ||||
|         } | ||||
|  | ||||
|         $prevUrl = common_local_url( | ||||
|             'ApiTimelineUser', | ||||
|             array('format' => $this->format, | ||||
|                 'id' => $this->target->getID()), | ||||
|             $prevExtra | ||||
|         ); | ||||
|         $firstUrl = common_local_url( | ||||
|             'ApiTimelineUser', | ||||
|             array('format' => $this->format, | ||||
|                 'id' => $this->target->getID()) | ||||
|         ); | ||||
|  | ||||
|         switch ($this->format) { | ||||
|             case 'xml': | ||||
|                 $this->showXmlTimeline($this->notices); | ||||
|                 break; | ||||
|             case 'rss': | ||||
|                 $this->showRssTimeline( | ||||
|                     $this->notices, | ||||
|                     $atom->title, | ||||
|                     $link, | ||||
|                     $atom->subtitle, | ||||
|                     $suplink, | ||||
|                     $atom->logo, | ||||
|                     $self | ||||
|                 ); | ||||
|                 break; | ||||
|             case 'atom': | ||||
|                 header('Content-Type: application/atom+xml; charset=utf-8'); | ||||
|  | ||||
|                 $atom->setId($self); | ||||
|                 $atom->setSelfLink($self); | ||||
|  | ||||
|                 // Add navigation links: next, prev, first | ||||
|                 // Note: we use IDs rather than pages for navigation; page boundaries | ||||
|                 // change too quickly! | ||||
|  | ||||
|                 if (!empty($this->next_id)) { | ||||
|                     $atom->addLink( | ||||
|                         $nextUrl, | ||||
|                         array('rel' => 'next', | ||||
|                             'type' => 'application/atom+xml') | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) { | ||||
|                     $atom->addLink( | ||||
|                         $prevUrl, | ||||
|                         array('rel' => 'prev', | ||||
|                             'type' => 'application/atom+xml') | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) { | ||||
|                     $atom->addLink( | ||||
|                         $firstUrl, | ||||
|                         array('rel' => 'first', | ||||
|                             'type' => 'application/atom+xml') | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 $atom->addEntryFromNotices($this->notices); | ||||
|                 $this->raw($atom->getString()); | ||||
|  | ||||
|                 break; | ||||
|             case 'json': | ||||
|                 $this->showJsonTimeline($this->notices); | ||||
|                 break; | ||||
|             case 'as': | ||||
|                 header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE); | ||||
|                 $doc = new ActivityStreamJSONDocument($this->scoped); | ||||
|                 $doc->setTitle($atom->title); | ||||
|                 $doc->addLink($link, 'alternate', 'text/html'); | ||||
|                 $doc->addItemsFromNotices($this->notices); | ||||
|  | ||||
|                 if (!empty($this->next_id)) { | ||||
|                     $doc->addLink( | ||||
|                         $nextUrl, | ||||
|                         array('rel' => 'next', | ||||
|                             'type' => ActivityStreamJSONDocument::CONTENT_TYPE) | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) { | ||||
|                     $doc->addLink( | ||||
|                         $prevUrl, | ||||
|                         array('rel' => 'prev', | ||||
|                             'type' => ActivityStreamJSONDocument::CONTENT_TYPE) | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) { | ||||
|                     $doc->addLink( | ||||
|                         $firstUrl, | ||||
|                         array('rel' => 'first', | ||||
|                             'type' => ActivityStreamJSONDocument::CONTENT_TYPE) | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 $this->raw($doc->asString()); | ||||
|                 break; | ||||
|             default: | ||||
|                 // TRANS: Client error displayed when coming across a non-supported API method. | ||||
|                 $this->clientError(_('API method not found.'), 404); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1962,9 +1962,11 @@ class Notice extends Managed_DataObject | ||||
|     /** | ||||
|      * Convert a notice into an activity for export. | ||||
|      * | ||||
|      * @param Profile $scoped   The currently logged in/scoped profile | ||||
|      * @param Profile $scoped The currently logged in/scoped profile | ||||
|      * | ||||
|      * @return Activity activity object representing this Notice. | ||||
|      * @throws ClientException | ||||
|      * @throws ServerException | ||||
|      */ | ||||
|  | ||||
|     function asActivity(Profile $scoped=null) | ||||
|   | ||||
| @@ -27,7 +27,9 @@ | ||||
|  * @link      http://status.net/ | ||||
|  */ | ||||
|  | ||||
| if (!defined('GNUSOCIAL')) { exit(1); } | ||||
| if (!defined('GNUSOCIAL')) { | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * A class for generating JSON documents that represent an Activity Streams | ||||
| @@ -47,7 +49,7 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|     const CONTENT_TYPE = 'application/json; charset=utf-8'; | ||||
|  | ||||
|     /* Top level array representing the document */ | ||||
|     protected $doc = array(); | ||||
|     protected $doc = []; | ||||
|  | ||||
|     /* The current authenticated user */ | ||||
|     protected $cur; | ||||
| @@ -67,9 +69,10 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|      * Constructor | ||||
|      * | ||||
|      * @param User $cur the current authenticated user | ||||
|      * @throws UserNoProfileException | ||||
|      */ | ||||
|  | ||||
|     function __construct($cur = null, $title = null, array $items=[], $links = null, $url = null) | ||||
|     public function __construct($cur = null, $title = null, array $items = [], $links = null, $url = null) | ||||
|     { | ||||
|         parent::__construct($items, $url); | ||||
|  | ||||
| @@ -84,26 +87,26 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|         } | ||||
|  | ||||
|         /* Array of links associated with the document */ | ||||
|         $this->links = empty($links) ? array() : $items; | ||||
|         $this->links = empty($links) ? [] : $items; | ||||
|  | ||||
|         /* URL of a document, this document? containing a list of all the items in the stream */ | ||||
|         if (!empty($this->url)) { | ||||
|             $this->url = $this->url; | ||||
|         if (!empty($url)) { | ||||
|             $this->url = $url; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the title of the document | ||||
|      * | ||||
|      * @param String $title the title | ||||
|      * @param string $title the title | ||||
|      */ | ||||
|  | ||||
|     function setTitle($title) | ||||
|     public function setTitle($title) | ||||
|     { | ||||
|         $this->title = $title; | ||||
|     } | ||||
|  | ||||
|     function setUrl($url) | ||||
|     public function setUrl($url) | ||||
|     { | ||||
|         $this->url = $url; | ||||
|     } | ||||
| @@ -113,10 +116,11 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|      * Add more than one Item to the document | ||||
|      * | ||||
|      * @param mixed $notices an array of Notice objects or handle | ||||
|      * | ||||
|      * @throws ClientException | ||||
|      * @throws ServerException | ||||
|      */ | ||||
|  | ||||
|     function addItemsFromNotices($notices) | ||||
|     public function addItemsFromNotices($notices) | ||||
|     { | ||||
|         if (is_array($notices)) { | ||||
|             foreach ($notices as $notice) { | ||||
| @@ -135,9 +139,17 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|      * @param Notice $notice a Notice to add | ||||
|      */ | ||||
|  | ||||
|     function addItemFromNotice($notice) | ||||
|     public function addItemFromNotice($notice) | ||||
|     { | ||||
|         $act          = $notice->asActivity($this->scoped); | ||||
|         try { | ||||
|             $act = $notice->asActivity($this->scoped); | ||||
|         } catch (Exception $e) { | ||||
|             // We know exceptions like | ||||
|             // "No result found on Fave lookup." | ||||
|             // may happen because of deleted notices etc. | ||||
|             // These are irrelevant for the feed purposes. | ||||
|             return; | ||||
|         } | ||||
|         $act->extra[] = $notice->noticeInfo($this->scoped); | ||||
|         array_push($this->items, $act->asArray()); | ||||
|         $this->count++; | ||||
| @@ -148,8 +160,9 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|      * | ||||
|      * @param string $url the URL for the link | ||||
|      * @param string $rel the link relationship | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     function addLink($url = null, $rel = null, $mediaType = null) | ||||
|     public function addLink($url = null, $rel = null, $mediaType = null) | ||||
|     { | ||||
|         $link = new ActivityStreamsLink($url, $rel, $mediaType); | ||||
|         array_push($this->links, $link->asArray()); | ||||
| @@ -160,15 +173,14 @@ class ActivityStreamJSONDocument extends JSONActivityCollection | ||||
|      * | ||||
|      * @return string encoded JSON output | ||||
|      */ | ||||
|     function asString() | ||||
|     public function asString() | ||||
|     { | ||||
|         $this->doc['generator'] = 'GNU social ' . GNUSOCIAL_VERSION; // extension | ||||
|         $this->doc['title'] = $this->title; | ||||
|         $this->doc['url']   = $this->url; | ||||
|         $this->doc['url'] = $this->url; | ||||
|         $this->doc['totalItems'] = $this->count; | ||||
|         $this->doc['items'] = $this->items; | ||||
|         $this->doc['links'] = $this->links; // extension | ||||
|         return json_encode(array_filter($this->doc)); // filter out empty elements | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user