2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								< ? php  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								declare ( strict_types  =  1 );  
						 
					
						
							
								
									
										
										
										
											2021-10-10 09:26:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// {{{ License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ category   ActivityPub 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ author     Diogo  Peralta  Cordeiro  <@ diogo . site > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ copyright  2018 - 2019 ,  2021  Free  Software  Foundation ,  Inc  http :// www . fsf . org 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ license    https :// www . gnu . org / licenses / agpl . html  GNU  AGPL  v3  or  later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								namespace  Plugin\ActivityPub ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 11:39:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  ActivityPhp\Type ;  
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  ActivityPhp\Type\AbstractObject ;  
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Core\DB\DB ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  App\Core\Event ;  
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Core\HTTPClient ;  
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  function  App\Core\I18n\_m ;  
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Core\Log ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  App\Core\Modules\Plugin ;  
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Core\Queue\Queue ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  App\Core\Router\RouteLoader ;  
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Core\Router\Router ;  
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Entity\Activity ;  
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Entity\Actor ;  
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Entity\Note ;  
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Util\Common ;  
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  App\Util\Exception\BugFoundException ;  
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Component\Collection\Util\Controller\OrderedCollection ;  
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Component\FreeNetwork\Entity\FreeNetworkActorProtocol ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Component\FreeNetwork\Util\Discovery ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  Exception ;  
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  InvalidArgumentException ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Controller\Inbox ;  
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Controller\Outbox ;  
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Entity\ActivitypubActivity ;  
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Entity\ActivitypubActor ;  
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Entity\ActivitypubObject ;  
						 
					
						
							
								
									
										
										
										
											2022-02-25 01:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Explorer ;  
						 
					
						
							
								
									
										
										
										
											2021-11-30 16:47:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\HTTPSignature ;  
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Model ;  
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\OrderedCollectionController ;  
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Response\ActivityResponse ;  
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Response\ActorResponse ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Response\NoteResponse ;  
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\TypeResponse ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Validator\contentLangModelValidator ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Plugin\ActivityPub\Util\Validator\manuallyApprovesFollowersModelValidator ;  
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Symfony\Component\HttpFoundation\JsonResponse ;  
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface ;  
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  Symfony\Contracts\HttpClient\ResponseInterface ;  
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								use  XML_XRD ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  XML_XRD_Element_Link ;  
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Adds  ActivityPub  support  to  GNU  social  when  enabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ copyright  2018 - 2019 ,  2021  Free  Software  Foundation ,  Inc  http :// www . fsf . org 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ license    https :// www . gnu . org / licenses / agpl . html  GNU  AGPL  v3  or  later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								class  ActivityPub  extends  Plugin  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ActivityStreams 2.0 Accept Headers
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  static  array  $accept_headers  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'application/activity+json' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'application/json' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'application/ld+json' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // So that this isn't hardcoded everywhere
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  const  PUBLIC_TO  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'https://www.w3.org/ns/activitystreams#Public' , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        'Public' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'as:Public' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  const  HTTP_CLIENT_HEADERS  =  [ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        'Accept'      =>  'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        'User-Agent'  =>  'GNUsocialBot '  .  GNUSOCIAL_VERSION  .  ' - '  .  GNUSOCIAL_PROJECT_URL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    public  function  version () :  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  '3.0.0' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  static  array  $activity_streams_two_context  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'https://www.w3.org/ns/activitystreams' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        'https://w3id.org/security/v1' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ 'gs'           =>  'https://www.gnu.org/software/social/ns#' ], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ 'litepub'      =>  'http://litepub.social/ns#' ], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ 'chatMessage'  =>  'litepub:chatMessage' ], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'inConversation'  =>  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                '@id'    =>  'gs:inConversation' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                '@type'  =>  '@id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ], 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  onInitializePlugin () :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Event :: handle ( 'ActivityStreamsTwoContext' ,  [ & self :: $activity_streams_two_context ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self :: $activity_streams_two_context  =  array_unique ( self :: $activity_streams_two_context ,  \SORT_REGULAR ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onQueueActivitypubInbox ( ActivitypubActor  $ap_actor ,  Actor  $actor ,  string | AbstractObject  $type ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // TODO: Check if Actor has authority over payload
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Store Activity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $ap_act  =  Model\Activity :: fromJson ( $type ,  [ 'source'  =>  'ActivityPub' ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        FreeNetworkActorProtocol :: protocolSucceeded ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            'activitypub' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $ap_actor -> getActorId (), 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Discovery :: normalize ( $actor -> getNickname ()  .  '@'  .  parse_url ( $ap_actor -> getInboxUri (),  \PHP_URL_HOST )), 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        DB :: flush (); 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 13:18:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  (( $att_targets  =  $ap_act -> getAttentionTargets ())  !==  [])  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( Event :: handle ( 'ActivityPubNewNotification' ,  [ $actor ,  ( $act  =  $ap_act -> getActivity ()),  $att_targets ,  _m ( '{actor_id} triggered a notification via ActivityPub.' ,  [ '{actor_id}'  =>  $actor -> getId ()])])  ===  Event :: next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Event :: handle ( 'NewNotification' ,  [ $actor ,  $act ,  $att_targets ,  _m ( '{actor_id} triggered a notification via ActivityPub.' ,  [ '{nickname}'  =>  $actor -> getId ()])]); 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  This  code  executes  when  GNU  social  creates  the  page  routing ,  and  we  hook 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  on  this  event  to  add  our  Inbox  and  Outbox  handler  for  ActivityPub . 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-10 09:26:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  @ param  RouteLoader  $r  the  router  that  was  initialized 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  onAddRoute ( RouteLoader  $r ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 17:04:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $r -> connect ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 23:46:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            'activitypub_inbox' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            '/inbox.json' , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-20 05:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Inbox :: class , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            options :  [ 'format'  =>  self :: $accept_headers [ 0 ]], 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 17:04:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $r -> connect ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 23:46:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            'activitypub_actor_inbox' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            '/actor/{gsactor_id<\d+>}/inbox.json' , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 17:04:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ Inbox :: class ,  'handle' ], 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            options :  [ 'format'  =>  self :: $accept_headers [ 0 ]], 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 17:04:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $r -> connect ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 23:46:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            'activitypub_actor_outbox' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            '/actor/{gsactor_id<\d+>}/outbox.json' , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ Outbox :: class ,  'viewOutboxByActorId' ], 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            options :  [ 'accept'  =>  self :: $accept_headers ,  'format'  =>  self :: $accept_headers [ 0 ]], 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 20:29:26 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Fill  Actor -> getUrl ()  calls  with  correct  URL  coming  from  ActivityPub 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onStartGetActorUri ( Actor  $actor ,  int  $type ,  ? string  & $url ) :  bool 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Is remote?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ! $actor -> getIsLocal () 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Is in ActivityPub?
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            &&  ! \is_null ( $ap_actor  =  DB :: findOneBy ( ActivitypubActor :: class ,  [ 'actor_id'  =>  $actor -> getId ()],  return_null :  true )) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // We can only provide a full URL (anything else wouldn't make sense)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            &&  $type  ===  Router :: ABSOLUTE_URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $url  =  $ap_actor -> getUri (); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 15:02:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Fill  Actor -> canAdmin ()  for  Actors  that  came  from  ActivityPub 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  onFreeNetworkActorCanAdmin ( Actor  $actor ,  Actor  $other ,  bool  & $canAdmin ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Are both in AP?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ! \is_null ( $ap_actor  =  DB :: findOneBy ( ActivitypubActor :: class ,  [ 'actor_id'  =>  $actor -> getId ()],  return_null :  true )) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            &&  ! \is_null ( $ap_other  =  DB :: findOneBy ( ActivitypubActor :: class ,  [ 'actor_id'  =>  $other -> getId ()],  return_null :  true )) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 15:02:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Are they both in the same server?
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 01:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $canAdmin  =  parse_url ( $ap_actor -> getUri (),  \PHP_URL_HOST )  ===  parse_url ( $ap_other -> getUri (),  \PHP_URL_HOST ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 15:02:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Overload  core  endpoints  to  make  resources  available  in  ActivityStreams  2.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  Exception 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  onControllerResponseInFormat ( string  $route ,  array  $accept_header ,  array  $vars ,  ? TypeResponse  & $response  =  null ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( \count ( array_intersect ( self :: $accept_headers ,  $accept_header ))  ===  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( $route )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 18:45:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  'actor_view_id' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-10 16:02:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  'person_actor_view_id' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'person_actor_view_nickname' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'group_actor_view_id' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'group_actor_view_nickname' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'bot_actor_view_id' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'bot_actor_view_nickname' : 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $response  =  ActorResponse :: handle ( $vars [ 'actor' ]); 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 00:22:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  'activity_view' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $response  =  ActivityResponse :: handle ( $vars [ 'activity' ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  'note_view' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $response  =  NoteResponse :: handle ( $vars [ 'note' ]); 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'activitypub_actor_outbox' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $response  =  new  TypeResponse ( $vars [ 'type' ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( Event :: handle ( 'ActivityPubActivityStreamsTwoResponse' ,  [ $route ,  $vars ,  & $response ])  !==  Event :: stop )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( is_subclass_of ( $vars [ 'controller' ][ 0 ],  OrderedCollection :: class ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $response  =  new  TypeResponse ( OrderedCollectionController :: fromControllerVars ( $vars )[ 'type' ]); 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 00:22:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $response  =  new  JsonResponse ([ 'error'  =>  'Unknown Object cannot be represented.' ]); 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 20:28:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Event :: stop ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Add  ActivityStreams  2  Extensions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  onActivityPubValidateActivityStreamsTwoData ( string  $type_name ,  array  & $validators ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( $type_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'Person' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $validators [ 'manuallyApprovesFollowers' ]  =  manuallyApprovesFollowersModelValidator :: class ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  'Note' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $validators [ 'contentLang' ]  =  contentLangModelValidator :: class ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FreeNetworkComponent Events
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Let  FreeNetwork  Component  know  we  exist  and  which  class  to  use  to  call  the  freeNetworkDistribute  method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 20:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onAddFreeNetworkProtocol ( array  & $protocols ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $protocols []  =  '\Plugin\ActivityPub\ActivityPub' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 04:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  The  FreeNetwork  component  will  call  this  function  to  pull  ActivityPub  objects  by  URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ param  string  $uri  Query 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 04:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  @ return  bool  true  if  imported ,  false  otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  static  function  freeNetworkGrabRemote ( string  $uri ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( Common :: isValidHttpUrl ( $uri ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $object  =  self :: getObjectByUri ( $uri ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! \is_null ( $object ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( $object  instanceof  Type\AbstractObject )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        if  ( \in_array ( $object -> get ( 'type' ),  array_keys ( Model\Actor :: $_as2_actor_type_to_gs_actor_type )))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            DB :: wrapInTransaction ( fn  ()  =>  Model\Actor :: fromJson ( $object )); 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 04:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            DB :: wrapInTransaction ( fn  ()  =>  Model\Activity :: fromJson ( $object )); 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 04:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  catch  ( Exception | Throwable )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-21 04:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // May be invalid input, we can safely ignore in this case
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onQueueActivitypubPostman ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Actor  $sender , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Activity  $activity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        string  $inbox , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        array  $to_actors , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        array  & $retry_args , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ) :  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $data  =  Model :: toJson ( $activity ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( $sender -> isGroup ())  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // When the sender is a group, we have to wrap it in an Announce activity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $data  =  Type :: create ( 'Announce' ,  [ 'object'  =>  $data ]) -> toJson (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $res  =  self :: postman ( $sender ,  $data ,  $inbox ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // accumulate errors for later use, if needed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $status_code  =  $res -> getStatusCode (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! ( $status_code  ===  200  ||  $status_code  ===  202  ||  $status_code  ===  409 ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $res_body  =  json_decode ( $res -> getContent (),  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $retry_args [ 'reason' ]  ? ? =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $retry_args [ 'reason' ][]  =  $res_body [ 'error' ]  ? ?  'An unknown error occurred.' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                foreach  ( $to_actors  as  $actor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( $actor -> isPerson ())  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        FreeNetworkActorProtocol :: protocolSucceeded ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            'activitypub' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            $actor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            Discovery :: normalize ( $actor -> getNickname ()  .  '@'  .  parse_url ( $inbox ,  \PHP_URL_HOST )), 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( Exception  $e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Log :: error ( 'ActivityPub @ freeNetworkDistribute: '  .  $e -> getMessage (),  [ $e ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $retry_args [ 'reason' ]  ? ? =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $retry_args [ 'reason' ][]  =  " Got an exception:  { $e -> getMessage () } " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $retry_args [ 'exception' ]  ? ? =  []; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $retry_args [ 'exception' ][]  =  $e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  The  FreeNetwork  component  will  call  this  function  to  distribute  this  instance ' s  activities 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  ClientExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  RedirectionExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  ServerExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  TransportExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  static  function  freeNetworkDistribute ( Actor  $sender ,  Activity  $activity ,  array  $targets ,  ? string  $reason  =  null ) :  void 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $to_addr  =  []; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        foreach  ( $targets  as  $actor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( FreeNetworkActorProtocol :: canIActor ( 'activitypub' ,  $actor -> getId ()))  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Sometimes FreeNetwork can allow us to actor even though we don't have an internal representation of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // the actor, that could for example mean that OStatus handled this actor while we were deactivated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // On next interaction this should be resolved, for now continue
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( \is_null ( $ap_target  =  DB :: findOneBy ( ActivitypubActor :: class ,  [ 'actor_id'  =>  $actor -> getId ()],  return_null :  true )))  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $to_addr [ $ap_target -> getInboxSharedUri ()  ? ?  $ap_target -> getInboxUri ()][]  =  $actor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        foreach  ( $to_addr  as  $inbox  =>  $to_actors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Queue :: enqueue ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                payload :  [ $sender ,  $activity ,  $inbox ,  $to_actors ], 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                queue :  'ActivitypubPostman' , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 14:23:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                priority :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  Internal  tool  to  sign  and  send  activities  out 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  Exception 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  static  function  postman ( Actor  $sender ,  string  $json_activity ,  string  $inbox ,  string  $method  =  'post' ) :  ResponseInterface 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Log :: debug ( 'ActivityPub Postman: Delivering '  .  $json_activity  .  ' to '  .  $inbox ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $headers  =  HTTPSignature :: sign ( $sender ,  $inbox ,  $json_activity ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 16:47:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Log :: debug ( 'ActivityPub Postman: Delivery headers were: '  .  print_r ( $headers ,  true )); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $response  =  HTTPClient :: $method ( $inbox ,  [ 'headers'  =>  $headers ,  'body'  =>  $json_activity ]); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 20:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Log :: debug ( 'ActivityPub Postman: Delivery result with status code '  .  $response -> getStatusCode ()  .  ': '  .  $response -> getContent ()); 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-29 23:58:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  $response ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 15:06:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // WebFinger Events
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  Add  activity + json  mimetype  to  WebFinger 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onEndWebFingerProfileLinks ( XML_XRD  $xrd ,  Actor  $object ) :  bool 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( $object -> isPerson ())  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $link  =  new  XML_XRD_Element_Link ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                rel :  'self' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                href :  $object -> getUri ( Router :: ABSOLUTE_URL ), //Router::url('actor_view_id', ['id' => $object->getId()], Router::ABSOLUTE_URL),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                type :  'application/activity+json' , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $xrd -> links []  =  clone  $link ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 04:14:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Event :: next ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 13:22:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  When  FreeNetwork  component  asks  us  to  help  with  identifying  Actors  from  XRDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onFreeNetworkFoundXrd ( XML_XRD  $xrd ,  ? Actor  & $actor  =  null ) :  bool 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $addr  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foreach  ( $xrd -> aliases  as  $alias )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( Discovery :: isAcct ( $alias ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $addr  =  Discovery :: normalize ( $alias ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( \is_null ( $addr ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! FreeNetworkActorProtocol :: canIAddr ( 'activitypub' ,  $addr ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 03:34:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $ap_actor  =  ActivitypubActor :: fromXrd ( $addr ,  $xrd ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            $actor     =  Actor :: getById ( $ap_actor -> getActorId ()); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 04:25:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            FreeNetworkActorProtocol :: protocolSucceeded ( 'activitypub' ,  $actor ,  $addr ); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 03:34:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( Exception  $e )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Log :: error ( 'ActivityPub Actor from URL Mention check failed: '  .  $e -> getMessage ()); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-02 03:34:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: next ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 17:00:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Discovery Events
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  When  FreeNetwork  component  asks  us  to  help  with  identifying  Actors  from  URIs 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  onFreeNetworkFindMentions ( string  $target ,  ? Actor  & $actor  =  null ) :  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( FreeNetworkActorProtocol :: canIAddr ( 'activitypub' ,  $addr  =  Discovery :: normalize ( $target )))  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $ap_actor  =  DB :: wrapInTransaction ( fn  ()  =>  ActivitypubActor :: getByAddr ( $addr )); 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 13:18:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $actor  =  Actor :: getById ( $ap_actor -> getActorId ()); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                FreeNetworkActorProtocol :: protocolSucceeded ( 'activitypub' ,  $actor -> getId (),  $addr ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Event :: stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( Exception  $e )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-20 13:59:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Log :: error ( 'ActivityPub WebFinger Mention check failed.' ,  [ $e ]); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-04 04:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Event :: next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 12:16:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ return  string  got  from  URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  static  function  getUriByObject ( mixed  $object ) :  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( $object :: class )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  Note :: class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( $object -> getIsLocal ())  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  $object -> getUrl (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Try known remote objects
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    $known_object  =  DB :: findOneBy ( ActivitypubObject :: class ,  [ 'object_type'  =>  'note' ,  'object_id'  =>  $object -> getId ()],  return_null :  true ); 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( $known_object  instanceof  ActivitypubObject )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  $known_object -> getObjectUri (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        throw  new  BugFoundException ( 'ActivityPub cannot generate an URI for a stored note.' ,  [ $object ,  $known_object ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  Actor :: class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  $object -> getUri (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  Activity :: class : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Try known remote activities
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $known_activity  =  DB :: findOneBy ( ActivitypubActivity :: class ,  [ 'activity_id'  =>  $object -> getId ()],  return_null :  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! \is_null ( $known_activity ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  $known_activity -> getActivityUri (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  Router :: url ( 'activity_view' ,  [ 'id'  =>  $object -> getId ()],  Router :: ABSOLUTE_URL ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                throw  new  InvalidArgumentException ( 'ActivityPub::getUriByObject found a limitation with: '  .  var_export ( $object ,  true )); 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-12 06:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Get  a  Note  from  ActivityPub  URI ,  if  it  doesn ' t  exist ,  attempt  to  fetch  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  This  should  only  be  necessary  internally . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  ClientExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  RedirectionExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  ServerExceptionInterface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  TransportExceptionInterface 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-24 01:58:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  @ return  null | Actor | mixed | Note  got  from  URI 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  static  function  getObjectByUri ( string  $resource ,  bool  $try_online  =  true ) :  mixed 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Try known object
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $known_object  =  DB :: findOneBy ( ActivitypubObject :: class ,  [ 'object_uri'  =>  $resource ],  return_null :  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! \is_null ( $known_object ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  $known_object -> getObject (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Try known activity
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 17:48:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        $known_activity  =  DB :: findOneBy ( ActivitypubActivity :: class ,  [ 'activity_uri'  =>  $resource ],  return_null :  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! \is_null ( $known_activity ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  $known_activity -> getActivity (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Try Actor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Explorer :: getOneFromUri ( $resource ,  try_online :  false ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( \Exception )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Ignore, this is brute forcing, it's okay not to find
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Is it a HTTP URL?
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( Common :: isValidHttpUrl ( $resource ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $resource_parts  =  parse_url ( $resource ); 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // If it is local
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 00:17:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( $resource_parts [ 'host' ]  ===  Common :: config ( 'site' ,  'server' ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Try Local Note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $local_note  =  DB :: findOneBy ( Note :: class ,  [ 'url'  =>  $resource ],  return_null :  true ); 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 17:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! \is_null ( $local_note ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  $local_note ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Try local Activity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $match           =  Router :: match ( $resource_parts [ 'path' ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $local_activity  =  DB :: findOneBy ( Activity :: class ,  [ 'id'  =>  $match [ 'id' ]],  return_null :  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! \is_null ( $local_activity ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  $local_activity ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        throw  new  InvalidArgumentException ( 'Tried to retrieve a non-existent local activity.' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  catch  ( \Exception )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Ignore, this is brute forcing, it's okay not to find
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 20:37:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                throw  new  BugFoundException ( 'ActivityPub failed to retrieve local resource: "'  .  $resource  .  '". This is a big issue.' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Then it's remote
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! $try_online )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw  new  Exception ( " Remote resource  { $resource }  not found without online resources. " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $response  =  HTTPClient :: get ( $resource ,  [ 'headers'  =>  self :: HTTP_CLIENT_HEADERS ]); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // If it was deleted
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( $response -> getStatusCode ()  ==  410 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    //$obj = Type::create('Tombstone', ['id' => $resource]);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  elseif  ( ! HTTPClient :: statusCodeIsOkay ( $response ))  {  // If it is unavailable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw  new  Exception ( 'Non Ok Status Code for given Object id.' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  Model :: jsonToType ( $response -> getContent ()); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:23:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 22:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-06 23:47:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}