2018-08-21 13:17:07 +00:00
|
|
|
<?php
|
2018-08-22 12:33:21 +00:00
|
|
|
/*
|
|
|
|
When an Activity is received (i.e. POSTed) to an Actor's inbox, the server must:
|
2018-08-21 13:17:07 +00:00
|
|
|
|
2018-08-22 12:33:21 +00:00
|
|
|
1. Forward the Activity as necessary
|
|
|
|
See (https://www.w3.org/TR/activitypub/#x7-1-2-forwarding-from-inbox).
|
|
|
|
2. Perform the side effects of receiving the Activity
|
2018-09-15 21:47:13 +00:00
|
|
|
3. Persist the activity in the actor's inbox (and the attached object, if necessary)
|
2018-08-22 12:33:21 +00:00
|
|
|
*/
|
2018-09-15 21:47:13 +00:00
|
|
|
namespace inbox;
|
|
|
|
|
2018-09-19 22:08:16 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities.php';
|
2018-09-24 21:36:30 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/objects.php';
|
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/deliver.php';
|
2018-09-19 22:08:16 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/create.php';
|
2018-09-20 22:48:40 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/update.php';
|
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/delete.php';
|
2018-09-20 23:10:15 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/follow.php';
|
2018-09-24 00:30:31 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/accept.php';
|
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/reject.php';
|
2018-09-24 02:22:30 +00:00
|
|
|
require_once plugin_dir_path( __FILE__ ) . '/activities/announce.php';
|
2018-09-19 22:08:16 +00:00
|
|
|
|
|
|
|
function handle_activity( $actor_slug, $activity ) {
|
2018-09-15 21:47:13 +00:00
|
|
|
if ( !array_key_exists( 'type', $activity ) ) {
|
|
|
|
return new \WP_Error(
|
|
|
|
'invalid_activity',
|
2018-09-19 15:16:41 +00:00
|
|
|
__( 'Activity must have a type', 'pterotype' ),
|
2018-09-15 21:47:13 +00:00
|
|
|
array( 'status' => 400 )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
forward_activity( $activity );
|
2018-09-24 02:22:30 +00:00
|
|
|
$res = persist_activity( $actor_slug, $activity );
|
|
|
|
if ( is_wp_error( $res ) ) {
|
|
|
|
return $res;
|
|
|
|
}
|
2018-09-15 21:47:13 +00:00
|
|
|
switch ( $activity['type'] ) {
|
|
|
|
case 'Create':
|
2018-09-20 23:10:15 +00:00
|
|
|
$activity = \activities\create\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Update':
|
2018-09-20 23:10:15 +00:00
|
|
|
$activity = \activities\update\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Delete':
|
2018-09-20 23:10:15 +00:00
|
|
|
$activity = \activities\delete\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Follow':
|
2018-09-20 23:10:15 +00:00
|
|
|
$activity = \activities\follow\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Accept':
|
2018-09-22 13:25:35 +00:00
|
|
|
$activity = \activities\accept\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Reject':
|
2018-09-24 00:30:31 +00:00
|
|
|
$activity = \activities\reject\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Add':
|
2018-09-24 21:36:30 +00:00
|
|
|
// TODO not yet implemented
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Remove':
|
2018-09-24 21:36:30 +00:00
|
|
|
// TODO not yet implemented
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Announce':
|
2018-09-24 02:22:30 +00:00
|
|
|
$activity = \activities\announce\handle_inbox( $actor_slug, $activity );
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
case 'Undo':
|
2018-09-24 00:30:31 +00:00
|
|
|
// TODO
|
2018-09-15 21:47:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( is_wp_error( $activity ) ) {
|
|
|
|
return $activity;
|
|
|
|
}
|
2018-09-24 02:22:30 +00:00
|
|
|
return $res;
|
2018-09-15 21:47:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function forward_activity( $activity ) {
|
2018-09-24 21:36:30 +00:00
|
|
|
if ( !array_key_exists( 'id', $activity ) ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$seen_before = \activities\get_activity_id( $activity['id'] );
|
|
|
|
if ( $seen_before ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( !references_local_object( $activity, 0 ) ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$collections = array_intersect_key(
|
|
|
|
$activity,
|
|
|
|
array_flip( array( 'to', 'cc', 'audience' ) )
|
|
|
|
);
|
|
|
|
if ( count( $collections ) === 0 ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
\deliver\deliver_activity( $activity );
|
|
|
|
}
|
|
|
|
|
|
|
|
function references_local_object( $object, $depth ) {
|
|
|
|
if ( $depth === 12 ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( \objects\is_local_object( $object ) ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
$fields = array_intersect_key(
|
|
|
|
$object,
|
|
|
|
array_flip( array( 'inReplyTo', 'object', 'target', 'tag' ) )
|
|
|
|
);
|
|
|
|
if ( count( $fields ) === 0 ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$result = false;
|
|
|
|
foreach ( $fields as $field_value ) {
|
|
|
|
if ( $result ) {
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
// $field_value is either a url, a Link, or an object
|
|
|
|
if ( is_array( $field_value ) ) {
|
|
|
|
if ( array_key_exists( 'id', $field_value ) ) {
|
|
|
|
return \objects\is_local_object( $field_value );
|
|
|
|
} else if ( array_key_exists( 'href', $field_value ) ) {
|
|
|
|
$response = wp_remote_get( $field_value['href'] );
|
|
|
|
if ( is_wp_error( $response ) ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$body = wp_remote_retrieve_body( $response );
|
|
|
|
if ( empty( $body ) ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$body_array = json_decode( $body, true );
|
|
|
|
return $body_array && references_local_object( $body_array, $depth + 1 );
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$response = wp_remote_get( $field_value );
|
|
|
|
if ( is_wp_error( $response ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$body = wp_remote_retrieve_body( $response );
|
|
|
|
if ( empty( $body ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$body_array = json_decode( $body, true );
|
|
|
|
$result = $body_array && references_local_object( $body_array, $depth + 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2018-09-15 21:47:13 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 22:08:16 +00:00
|
|
|
function persist_activity( $actory_slug, $activity ) {
|
2018-09-15 21:47:13 +00:00
|
|
|
global $wpdb;
|
2018-09-19 22:08:16 +00:00
|
|
|
$activity = \activities\persist_activity( $activity );
|
|
|
|
if ( is_wp_error( $activity ) ) {
|
|
|
|
return $activity;
|
|
|
|
}
|
|
|
|
$activity_id = $wpdb->insert_id;
|
|
|
|
$actor_id = \actors\get_actor_id( $actor_slug );
|
|
|
|
$wpdb->insert( 'pterotype_inbox', array(
|
|
|
|
'actor_id' => $actor_id,
|
|
|
|
'activity_id' => $activity_id,
|
|
|
|
) );
|
|
|
|
$response = new \WP_Rest_Response();
|
|
|
|
return $response;
|
2018-09-15 21:47:13 +00:00
|
|
|
}
|
2018-08-21 13:17:07 +00:00
|
|
|
?>
|