| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ActivityPub implementation for GNU social | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package   GNUsocial | 
					
						
							|  |  |  |  * @author    Diogo Cordeiro <diogo@fc.up.pt> | 
					
						
							|  |  |  |  * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org | 
					
						
							|  |  |  |  * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							|  |  |  |  * @link      http://www.gnu.org/software/social/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | defined('GNUSOCIAL') || die(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ActivityPub notice representation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  Plugin | 
					
						
							|  |  |  |  * @package   GNUsocial | 
					
						
							|  |  |  |  * @author    Diogo Cordeiro <diogo@fc.up.pt> | 
					
						
							|  |  |  |  * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-13 02:54:38 +01:00
										 |  |  | class Activitypub_notice | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Generates a pretty notice from a Notice object | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Notice $notice | 
					
						
							|  |  |  |      * @return array array to be used in a response | 
					
						
							|  |  |  |      * @throws EmptyPkeyValueException | 
					
						
							|  |  |  |      * @throws InvalidUrlException | 
					
						
							|  |  |  |      * @throws ServerException | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |      * @author Diogo Cordeiro <diogo@fc.up.pt> | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function notice_to_array($notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $profile = $notice->getProfile(); | 
					
						
							|  |  |  |         $attachments = []; | 
					
						
							|  |  |  |         foreach ($notice->attachments() as $attachment) { | 
					
						
							|  |  |  |             $attachments[] = Activitypub_attachment::attachment_to_array($attachment); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $tags = []; | 
					
						
							|  |  |  |         foreach ($notice->getTags() as $tag) { | 
					
						
							|  |  |  |             if ($tag != "") {       // Hacky workaround to avoid stupid outputs
 | 
					
						
							|  |  |  |                 $tags[] = Activitypub_tag::tag_to_array($tag); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 00:05:51 +01:00
										 |  |  |         if ($notice->isPublic()) { | 
					
						
							|  |  |  |             $to = ['https://www.w3.org/ns/activitystreams#Public']; | 
					
						
							|  |  |  |             $cc = [common_local_url('apActorFollowers', ['id' => $profile->getID()])]; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // Since we currently don't support sending unlisted/followers-only
 | 
					
						
							|  |  |  |             // notices, arriving here means we're instead answering to that type
 | 
					
						
							|  |  |  |             // of posts. Not having subscription policy working, its safer to
 | 
					
						
							|  |  |  |             // always send answers of type unlisted.
 | 
					
						
							|  |  |  |             $to = []; | 
					
						
							|  |  |  |             $cc = ['https://www.w3.org/ns/activitystreams#Public']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         foreach ($notice->getAttentionProfiles() as $to_profile) { | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |             $to[] = $href = $to_profile->getUri(); | 
					
						
							|  |  |  |             $tags[] = Activitypub_mention_tag::mention_tag_to_array_from_values($href, $to_profile->getNickname() . '@' . parse_url($href, PHP_URL_HOST)); | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $item = [ | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |             '@context' => 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'id' => self::getUrl($notice), | 
					
						
							|  |  |  |             'type' => 'Note', | 
					
						
							|  |  |  |             'published' => str_replace(' ', 'T', $notice->getCreated()) . 'Z', | 
					
						
							|  |  |  |             'url' => self::getUrl($notice), | 
					
						
							| 
									
										
										
										
											2019-12-10 22:27:32 +00:00
										 |  |  |             'attributedTo' => $profile->getUri(), | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |             'to' => $to, | 
					
						
							|  |  |  |             'cc' => $cc, | 
					
						
							|  |  |  |             'conversation' => $notice->getConversationUrl(), | 
					
						
							|  |  |  |             'content' => $notice->getRendered(), | 
					
						
							|  |  |  |             'isLocal' => $notice->isLocal(), | 
					
						
							|  |  |  |             'attachment' => $attachments, | 
					
						
							|  |  |  |             'tag' => $tags | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Is this a reply?
 | 
					
						
							|  |  |  |         if (!empty($notice->reply_to)) { | 
					
						
							| 
									
										
										
										
											2019-07-17 16:25:24 +01:00
										 |  |  |             $item['inReplyTo'] = self::getUrl(Notice::getById($notice->reply_to)); | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Do we have a location for this notice?
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $location = Notice_location::locFromStored($notice); | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |             $item['latitude'] = $location->lat; | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |             $item['longitude'] = $location->lon; | 
					
						
							|  |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |             // Apparently no.
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $item; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Create a Notice via ActivityPub Note Object. | 
					
						
							|  |  |  |      * Returns created Notice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $object | 
					
						
							| 
									
										
										
										
											2019-08-13 00:05:51 +01:00
										 |  |  |      * @param Profile $actor_profile | 
					
						
							| 
									
										
										
										
											2019-08-19 23:33:18 +01:00
										 |  |  |      * @param bool $directMessage | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |      * @return Notice | 
					
						
							|  |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |      * @author Diogo Cordeiro <diogo@fc.up.pt> | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-07-05 01:58:22 +01:00
										 |  |  |     public static function create_notice(array $object, Profile $actor_profile, bool $directMessage = false): Notice | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-07-07 17:57:48 +01:00
										 |  |  |         $id = $object['id'];                                 // int
 | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |         $url = isset($object['url']) ? $object['url'] : $id; // string
 | 
					
						
							| 
									
										
										
										
											2020-07-07 17:57:48 +01:00
										 |  |  |         $content = $object['content'];                       // string
 | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // possible keys: ['inReplyTo', 'latitude', 'longitude']
 | 
					
						
							|  |  |  |         $settings = []; | 
					
						
							|  |  |  |         if (isset($object['inReplyTo'])) { | 
					
						
							|  |  |  |             $settings['inReplyTo'] = $object['inReplyTo']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (isset($object['latitude'])) { | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |             $settings['latitude'] = $object['latitude']; | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (isset($object['longitude'])) { | 
					
						
							|  |  |  |             $settings['longitude'] = $object['longitude']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $act = new Activity(); | 
					
						
							|  |  |  |         $act->verb = ActivityVerb::POST; | 
					
						
							|  |  |  |         $act->time = time(); | 
					
						
							|  |  |  |         $act->actor = $actor_profile->asActivityObject(); | 
					
						
							|  |  |  |         $act->context = new ActivityContext(); | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |         $options = ['source' => 'ActivityPub', | 
					
						
							|  |  |  |             'uri' => $id, | 
					
						
							|  |  |  |             'url' => $url, | 
					
						
							|  |  |  |             'is_local' => self::getNotePolicyType($object, $actor_profile)]; | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 23:33:18 +01:00
										 |  |  |         if ($directMessage) { | 
					
						
							|  |  |  |             $options['scope'] = Notice::MESSAGE_SCOPE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         // Is this a reply?
 | 
					
						
							|  |  |  |         if (isset($settings['inReplyTo'])) { | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 $inReplyTo = ActivityPubPlugin::grab_notice_from_url($settings['inReplyTo']); | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |                 $act->context->replyToID = $inReplyTo->getUri(); | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |                 $act->context->replyToUrl = $inReplyTo->getUrl(); | 
					
						
							|  |  |  |             } catch (Exception $e) { | 
					
						
							|  |  |  |                 // It failed to grab, maybe we got this note from another source
 | 
					
						
							|  |  |  |                 // (e.g.: OStatus) that handles this differently or we really
 | 
					
						
							|  |  |  |                 // failed to get it...
 | 
					
						
							|  |  |  |                 // Welp, nothing that we can do about, let's
 | 
					
						
							|  |  |  |                 // just fake we don't have such notice.
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $inReplyTo = null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Mentions
 | 
					
						
							|  |  |  |         $mentions = []; | 
					
						
							|  |  |  |         if (isset($object['tag']) && is_array($object['tag'])) { | 
					
						
							|  |  |  |             foreach ($object['tag'] as $tag) { | 
					
						
							| 
									
										
										
										
											2020-02-14 17:25:26 +00:00
										 |  |  |                 if (array_key_exists('type', $tag) && $tag['type'] == 'Mention') { | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |                     $mentions[] = $tag['href']; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $mentions_profiles = []; | 
					
						
							|  |  |  |         $discovery = new Activitypub_explorer; | 
					
						
							|  |  |  |         foreach ($mentions as $mention) { | 
					
						
							|  |  |  |             try { | 
					
						
							| 
									
										
										
										
											2020-08-04 20:00:55 +01:00
										 |  |  |                 $actor_profile = $discovery->lookup($mention); | 
					
						
							|  |  |  |                 if (!empty($actor_profile)) { | 
					
						
							|  |  |  |                     $mentions_profiles[] = $actor_profile[0]; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |             } catch (Exception $e) { | 
					
						
							| 
									
										
										
										
											2020-08-04 20:00:55 +01:00
										 |  |  |                 // Invalid actor found, just let it go, it will eventually be handled by some other federation plugin like OStatus.
 | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         unset($discovery); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($mentions_profiles as $mp) { | 
					
						
							| 
									
										
										
										
											2019-08-19 23:33:18 +01:00
										 |  |  |             if (!$mp->hasBlocked($actor_profile)) { | 
					
						
							| 
									
										
										
										
											2019-12-10 22:27:32 +00:00
										 |  |  |                 $act->context->attention[$mp->getUri()] = 'http://activitystrea.ms/schema/1.0/person'; | 
					
						
							| 
									
										
										
										
											2019-08-19 23:33:18 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add location if that is set
 | 
					
						
							|  |  |  |         if (isset($settings['latitude'], $settings['longitude'])) { | 
					
						
							|  |  |  |             $act->context->location = Location::fromLatLon($settings['latitude'], $settings['longitude']); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Reject notice if it is too long (without the HTML) | 
					
						
							| 
									
										
										
										
											2019-07-17 16:25:24 +01:00
										 |  |  |            if (Notice::contentTooLong($content)) { | 
					
						
							|  |  |  |            throw new Exception('That\'s too long. Maximum notice size is %d character.'); | 
					
						
							|  |  |  |            }*/ | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $actobj = new ActivityObject(); | 
					
						
							|  |  |  |         $actobj->type = ActivityObject::NOTE; | 
					
						
							|  |  |  |         $actobj->content = strip_tags($content, '<p><b><i><u><a><ul><ol><li>'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Finally add the activity object to our activity
 | 
					
						
							|  |  |  |         $act->objects[] = $actobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $note = Notice::saveActivity($act, $actor_profile, $options); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $note; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Validates a note. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $object | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |      * @return bool false if unacceptable for GS but valid ActivityPub object | 
					
						
							|  |  |  |      * @throws Exception if invalid ActivityPub object | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |      * @author Diogo Cordeiro <diogo@fc.up.pt> | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function validate_note($object) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!isset($object['id'])) { | 
					
						
							|  |  |  |             common_debug('ActivityPub Notice Validator: Rejected because Object ID was not specified.'); | 
					
						
							|  |  |  |             throw new Exception('Object ID not specified.'); | 
					
						
							|  |  |  |         } elseif (!filter_var($object['id'], FILTER_VALIDATE_URL)) { | 
					
						
							|  |  |  |             common_debug('ActivityPub Notice Validator: Rejected because Object ID is invalid.'); | 
					
						
							|  |  |  |             throw new Exception('Invalid Object ID.'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!isset($object['type']) || $object['type'] !== 'Note') { | 
					
						
							|  |  |  |             common_debug('ActivityPub Notice Validator: Rejected because of Type.'); | 
					
						
							|  |  |  |             throw new Exception('Invalid Object type.'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-05 23:22:32 +01:00
										 |  |  |         if (isset($object['url']) && !filter_var($object['url'], FILTER_VALIDATE_URL)) { | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |             common_debug('ActivityPub Notice Validator: Rejected because Object URL is invalid.'); | 
					
						
							|  |  |  |             throw new Exception('Invalid Object URL.'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-13 00:05:51 +01:00
										 |  |  |         if (!(isset($object['to']) && isset($object['cc']))) { | 
					
						
							|  |  |  |             common_debug('ActivityPub Notice Validator: Rejected because either Object CC or TO wasn\'t specified.'); | 
					
						
							|  |  |  |             throw new Exception('Either Object CC or TO wasn\'t specified.'); | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |         if (!isset($object['content'])) { | 
					
						
							|  |  |  |             common_debug('ActivityPub Notice Validator: Rejected because Content was not specified (GNU social requires content in notes).'); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-17 16:25:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the original representation URL of a given notice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Notice $notice notice from which to retrieve the URL | 
					
						
							|  |  |  |      * @return string URL | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |      * @throws InvalidUrlException | 
					
						
							|  |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-07-17 16:25:24 +01:00
										 |  |  |      * @author Bruno Casteleiro <brunoccast@fc.up.pt> | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |     public static function getUrl(Notice $notice): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($notice->isLocal()) { | 
					
						
							|  |  |  |             return common_local_url('apNotice', ['id' => $notice->getID()]); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return $notice->getUrl(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-13 00:05:51 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Extract note policy type from note targets. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $note received Note | 
					
						
							|  |  |  |      * @param Profile $actor_profile Note author | 
					
						
							|  |  |  |      * @return int Notice policy type | 
					
						
							|  |  |  |      * @author Bruno Casteleiro <brunoccast@fc.up.pt> | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-10-11 19:09:08 +01:00
										 |  |  |     public static function getNotePolicyType(array $note, Profile $actor_profile): int | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-13 00:05:51 +01:00
										 |  |  |         if (in_array('https://www.w3.org/ns/activitystreams#Public', $note['to'])) { | 
					
						
							|  |  |  |             return $actor_profile->isLocal() ? Notice::LOCAL_PUBLIC : Notice::REMOTE; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // either an unlisted or followers-only note, we'll handle
 | 
					
						
							|  |  |  |             // both as a GATEWAY notice since this type is not visible
 | 
					
						
							|  |  |  |             // from the public timelines, hence partially enough while
 | 
					
						
							|  |  |  |             // we don't have subscription_policy working.
 | 
					
						
							|  |  |  |             return Notice::GATEWAY; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-11 12:27:21 +01:00
										 |  |  | } |