diff --git a/inc/activities/create.php b/inc/activities/create.php index d5920ae..7a8e415 100644 --- a/inc/activities/create.php +++ b/inc/activities/create.php @@ -12,45 +12,48 @@ to the object and vice-versa. Returns either the modified $activity or a WP_Error. */ function handle( $actor, $activity ) { - if ( !(array_key_exists( "type", $activity ) && $activity["type"] === "Create") ) { - return new WP_Error( + if ( !(array_key_exists( 'type', $activity ) && $activity['type'] === 'Create') ) { + return new \WP_Error( 'invalid_activity', __( 'Expecting a Create activity', 'activitypub' ) ); } - if ( !array_key_exists( "object", $activity ) ) { - return new WP_Error( + if ( !array_key_exists( 'object', $activity ) ) { + return new \WP_Error( 'invalid_object', __( 'Expecting an object', 'activitypub' ) ); } - if ( !array_key_exists( "actor", $activity ) ) { - // TODO validate that $activity["actor"] is the URL of the $actor - return new WP_Error( + if ( !array_key_exists( 'actor', $activity ) ) { + // TODO validate that $activity['actor'] is the URL of the $actor + return new \WP_Error( 'invalid_actor', __( 'Expecting a valid actor', 'activitypub' ) ); } - $object = $activity["object"]; - $actor_id = $activity["actor"]; - $object["attributedTo"] = $actor_id; + $object = $activity['object']; + $actor_id = $activity['actor']; + $object['attributedTo'] = $actor_id; reconcile_receivers( $object, $activity ); scrub_object( $object ); - $object = \objects\persist_object( $object ); - $activity["object"] = $object; + $object = \objects\create_object( $object ); + if ( is_wp_error( $object ) ) { + return $object; + } + $activity['object'] = $object; return $activity; } function reconcile_receivers( &$object, &$activity ) { - copy_field_value( "audience", $object, $activity ); - copy_field_value( "audience", $activity, $object ); + copy_field_value( 'audience', $object, $activity ); + copy_field_value( 'audience', $activity, $object ); - copy_field_value( "to", $object, $activity ); - copy_field_value( "to", $activity, $object ); + copy_field_value( 'to', $object, $activity ); + copy_field_value( 'to', $activity, $object ); - copy_field_value( "cc", $object, $activity ); - copy_field_value( "cc", $activity, $object ); + copy_field_value( 'cc', $object, $activity ); + copy_field_value( 'cc', $activity, $object ); // copy bcc and bto to activity for delivery but not to object - copy_field_value( "bcc", $object, $activity ); - copy_field_value( "bto", $object, $activity ); + copy_field_value( 'bcc', $object, $activity ); + copy_field_value( 'bto', $object, $activity ); } function copy_field_value( $field, $from, &$to ) { @@ -66,7 +69,7 @@ function copy_field_value( $field, $from, &$to ) { } function scrub_object( &$object ) { - unset( $object["bcc"] ); - unset( $object["bto"] ); + unset( $object['bcc'] ); + unset( $object['bto'] ); } ?> diff --git a/inc/activities/update.php b/inc/activities/update.php index 54f82ef..a92cc39 100644 --- a/inc/activities/update.php +++ b/inc/activities/update.php @@ -1,7 +1,40 @@ 400 ) + ); + } + if ( !array_key_exists( 'object', $activity ) ) { + return new \WP_Error( + 'invalid_activity', + __( 'Expecting an object', 'activitypub' ) + array( 'status' => 400 ) + ); + } + $update_object = $activity['object']; + if ( !array_key_exists( 'id', $update_object ) ) { + return new \WP_Error( + 'invalid_object', + __( 'Object must have an "id" parameter', 'activitypub' ) + array( 'status' => 400 ) + ); + } + $existing_object = \objects\get_object_from_url( $update_object['id'] ); + if ( is_wp_error( $existing_object ) ) { + return $existing_object; + } + $updated_object = array_merge( $existing_object, $update_object ); + $updated_object = \objects\update_object( $updated_object ); + if ( is_wp_error( $updated_object ) ) { + return $updated_object; + } + return $activity; } ?> diff --git a/inc/objects.php b/inc/objects.php index 81ab117..120f58c 100644 --- a/inc/objects.php +++ b/inc/objects.php @@ -1,13 +1,44 @@ insert( 'activitypub_objects', array( 'object' => wp_json_encode( $object ) ) ); + $res = $wpdb->insert( + 'activitypub_objects', array( 'object' => wp_json_encode( $object ) ) + ); + if ( !$res ) { + return new \WP_Error( + 'db_error', __( 'Failed to insert object row', 'activitypub' ) + ); + } $object['id'] = get_object_url( $wpdb->insert_id ); return $object; } +function update_object( $object ) { + global $wpdb; + if ( !array_key_exists( 'id', $object ) ) { + return new \WP_Error( + 'invalid_object', + __( 'Object must have an "id" parameter', 'activitypub' ), + array( 'status' => 400 ) + ); + } + $id = get_id_from_url( $object['id'] ); + $object_json = wp_json_encode( $object ); + $res = $wpdb->update( + 'activitypub_object', + array( 'object' => $object_json ), + array( 'id' => $id ), + '%s', '%d' ); + if ( !$res ) { + return new \WP_Error( + 'db_error', __( 'Failed to update object row', 'activitypub' ) + ); + } + return $object; +} + function get_object( $id ) { global $wpdb; $object_json = $wpdb->get_var( sprintf( @@ -15,7 +46,7 @@ function get_object( $id ) { ) ); if ( is_null( $object_json ) ) { return new \WP_Error( - 404, __( 'Object not found', 'activitypub' ), array ( 'status' => 404 ) + 'not_found', __( 'Object not found', 'activitypub' ), array ( 'status' => 404 ) ); } $object = json_decode( $object_json, true ); @@ -23,6 +54,26 @@ function get_object( $id ) { return $object; } +function get_id_from_url( $url ) { + global $wpdb; + $matches = array(); + $found = preg_match( + get_rest_url( null, '/activitypub/v1/object/(.+)' ), $url, $matches ); + if ( $found === 0 || count( $matches ) != 2 ) { + return new \WP_Error( + 'invalid_url', + sprintf( '%s %s', $url, __( 'is not a valid object url', 'activitypub' ) ), + array( 'status' => 400 ) + ); + } + $id = $matches[1]; + return $id; +} + +function get_object_from_url( $url ) { + return get_object( get_id_from_url( $url ) ); +} + function get_object_url( $id ) { return get_rest_url( null, sprintf( '/activitypub/v1/object/%d', $id ) ); }