diff --git a/inc/activities.php b/inc/activities.php index b786973..63f440c 100644 --- a/inc/activities.php +++ b/inc/activities.php @@ -92,9 +92,10 @@ function create_activities_table() { " CREATE TABLE IF NOT EXISTS activitypub_activities ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - activitypub_id TEXT UNIQUE NOT NULL, + activitypub_id VARCHAR(255) UNIQUE NOT NULL, activity TEXT NOT NULL - ); + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); $wpdb->query( diff --git a/inc/activities/follow.php b/inc/activities/follow.php index 85047c0..f4b0cab 100644 --- a/inc/activities/follow.php +++ b/inc/activities/follow.php @@ -3,6 +3,7 @@ namespace activities\follow; require_once plugin_dir_path( __FILE__ ) . '/../following.php'; require_once plugin_dir_path( __FILE__ ) . '/../actors.php'; +require_once plugin_dir_path( __FILE__ ) . '/../objects.php'; function handle_outbox( $actor, $activity ) { if ( !array_key_exists( 'object', $activity ) ) { @@ -13,8 +14,9 @@ function handle_outbox( $actor, $activity ) { ); } $object = $activity['object']; + $object_row = \objects\upsert_object( $object ); $actor_id = \actors\get_actor_id( $actor ); - $res = \following\request_follow( $actor_id, $object ); + $res = \following\request_follow( $actor_id, $object_row->id ); if ( is_wp_error( $res ) ) { return $res; } diff --git a/inc/activities/like.php b/inc/activities/like.php index c1c461a..0aedccc 100644 --- a/inc/activities/like.php +++ b/inc/activities/like.php @@ -3,6 +3,7 @@ namespace activities\like; require_once plugin_dir_path( __FILE__ ) . '/../likes.php'; require_once plugin_dir_path( __FILE__ ) . '/../actors.php'; +require_once plugin_dir_path( __FILE__ ) . '/../objects.php'; function handle_outbox( $actor, $activity ) { if ( !array_key_exists( 'object', $activity ) ) { @@ -13,16 +14,9 @@ function handle_outbox( $actor, $activity ) { ); } $object = $activity['object']; - if ( !array_key_exists( 'id', $object ) ) { - return new \WP_Error( - 'invalid_object', - __( 'Expected an object id', 'activitypub' ), - array( 'status' => 400 ) - ); - } - $object_id = $object['id']; + $object_row = \objects\upsert_object( $object ); $actor_id = \actors\get_actor_id( $actor ); - $res = \likes\create_like( $actor_id, $object_id ); + $res = \likes\create_like( $actor_id, $object_row->id ); if ( is_wp_error( $res ) ) { return $res; } diff --git a/inc/actors.php b/inc/actors.php index 4ddd956..c9ece48 100644 --- a/inc/actors.php +++ b/inc/actors.php @@ -69,7 +69,8 @@ function create_actors_table() { id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(64) UNIQUE NOT NULL, type VARCHAR(64) NOT NULL - ); + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); } diff --git a/inc/blocks.php b/inc/blocks.php index 5bbb4d7..65b2052 100644 --- a/inc/blocks.php +++ b/inc/blocks.php @@ -25,9 +25,10 @@ function create_blocks_table() { CREATE TABLE IF NOT EXISTS activitypub_blocks( actor_id INT UNSIGNED NOT NULL, blocked_actor_url TEXT NOT NULL, - FOREIGN KEY actor_fk(actor_id) - REFERENCES activitypub_actors(id) - ); + FOREIGN KEY blocks_actor_fk(actor_id) + REFERENCES activitypub_actors(id) + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); } diff --git a/inc/following.php b/inc/following.php index 6c0e734..f558ceb 100644 --- a/inc/following.php +++ b/inc/following.php @@ -4,12 +4,12 @@ namespace following; $PENDING = 'PENDING'; $FOLLOWING = 'FOLLOWING'; -function request_follow( $actor_id, $object ) { +function request_follow( $actor_id, $object_id ) { global $wpdb; return $wpdb->insert( 'activitypub_following', array( 'actor_id' => $actor_id, - 'object' => wp_json_encode( $object ), + 'object_id' => wp_json_encode( $object ), 'state' => $PENDING ) ); @@ -21,11 +21,15 @@ function create_following_table() { " CREATE TABLE IF NOT EXISTS activitypub_following( actor_id INT UNSIGNED NOT NULL, - object TEXT NOT NULL, + object_id INT UNSIGNED NOT NULL, state VARCHAR(64) NOT NULL, - FOREIGN KEY actor_fk(actor_id) - REFERENCES activitypub_actors(id) - ); + PRIMARY KEY (actor_id, object_id), + FOREIGN KEY following_actor_fk(actor_id) + REFERENCES activitypub_actors(id), + FOREIGN KEY following_object_fk(object_id) + REFERENCES activitypub_objects(id) + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); } diff --git a/inc/inbox.php b/inc/inbox.php index d1f76e7..5645de0 100644 --- a/inc/inbox.php +++ b/inc/inbox.php @@ -69,9 +69,10 @@ function create_inbox_table() { id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, actor_id UNSIGNED INT NOT NULL, activity_id INT UNSIGNED NOT NULL, - FOREIGN KEY activity_fk(activity_id) - REFERENCES activitypub_activities(id), - ); + FOREIGN KEY inbox_activity_fk(activity_id) + REFERENCES activitypub_activities(id) + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); } diff --git a/inc/init.php b/inc/init.php index 5283d97..50516d5 100644 --- a/inc/init.php +++ b/inc/init.php @@ -8,6 +8,7 @@ require_once plugin_dir_path( __FILE__ ) . '/activities.php'; require_once plugin_dir_path( __FILE__ ) . '/actors.php'; require_once plugin_dir_path( __FILE__ ) . '/likes.php'; require_once plugin_dir_path( __FILE__ ) . '/following.php'; +require_once plugin_dir_path( __FILE__ ) . '/blocks.php'; add_action( 'rest_api_init', function() { \api\register_routes(); @@ -26,5 +27,6 @@ add_action( 'activitypub_init', function() { \actors\initialize_user_actors(); \likes\create_likes_table(); \following\create_following_table(); + \blocks\create_blocks_table(); } ); ?> diff --git a/inc/likes.php b/inc/likes.php index ceeb752..25884f6 100644 --- a/inc/likes.php +++ b/inc/likes.php @@ -4,7 +4,7 @@ namespace likes; function create_like( $actor_id, $object_id ) { global $wpdb; return $wpdb->insert( - 'activitypub_likes', array( 'actor_id' => $actor_id, 'object_url' => $object_id ) + 'activitypub_likes', array( 'actor_id' => $actor_id, 'object_id' => $object_id ) ); } @@ -13,11 +13,15 @@ function create_likes_table() { $wpdb->query( " CREATE TABLE IF NOT EXISTS activitypub_likes ( - actor_id INT NOT NULL, - object_url TEXT NOT NULL, - FOREIGN KEY actor_fk(actor_id) - REFERENCES activitypub_actors(id) - ); + actor_id INT UNSIGNED NOT NULL, + object_id INT UNSIGNED NOT NULL, + PRIMARY KEY (actor_id, object_id), + FOREIGN KEY likes_actor_fk(actor_id) + REFERENCES activitypub_actors(id), + FOREIGN KEY likes_object_fk(object_id) + REFERENCES activitypub_objects(id) + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); } diff --git a/inc/objects.php b/inc/objects.php index f2e7fb1..637002f 100644 --- a/inc/objects.php +++ b/inc/objects.php @@ -34,6 +34,49 @@ function create_local_object( $object ) { return $object; } +function upsert_object( $object ) { + global $wpdb; + if ( !array_key_exists( 'id', $object ) ) { + return new \WP_Error( + 'invalid_object', + __( 'Objects must have an "id" field', 'activitypub' ), + array( 'status' => 400 ) + ); + } + $row = $wpdb->get_row( $wpdb->prepare( + 'SELECT * FROM activitypub_objects WHERE activitypub_url = %s', $object['id'] + ) ); + $res = true; + if ( $row === null ) { + $res = $wpdb->insert( + 'activitypub_objects', + array( + 'activitypub_id' => $object['id'], + 'object' => wp_json_encode( $object ) + ) + ); + } else { + $res = $wpdb->replace( + 'activitypub_objects', + array( + 'id' => $row->id, + 'activitypub_id' => $object['id'], + 'object' => wp_json_encode( $object ) + ), + array( '%d', '%s', '%s' ) + ); + $row = new stdClass(); + $row->id = $wpdb->insert_id; + } + if ( !$res ) { + return new \WP_Error( + 'db_error', __( 'Failed to upsert object row', 'activitypub' ) + ); + } + $row->object = $object; + return $row; +} + function update_object( $object ) { global $wpdb; if ( !array_key_exists( 'id', $object ) ) { @@ -106,9 +149,10 @@ function create_object_table() { " CREATE TABLE IF NOT EXISTS activitypub_objects ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - activitypub_id TEXT UNIQUE NOT NULL, + activitypub_id VARCHAR(255) UNIQUE NOT NULL, object TEXT NOT NULL - ); + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); $wpdb->query( diff --git a/inc/outbox.php b/inc/outbox.php index 1cbf8b9..3481ba8 100644 --- a/inc/outbox.php +++ b/inc/outbox.php @@ -150,11 +150,12 @@ function create_outbox_table() { " CREATE TABLE IF NOT EXISTS activitypub_outbox ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - actor_id UNSIGNED INT NOT NULL, + actor_id INT UNSIGNED NOT NULL, activity_id INT UNSIGNED NOT NULL, - FOREIGN KEY activity_fk(activity_id) - REFERENCES activitypub_activities(id), - ); + FOREIGN KEY outbox_activity_fk(activity_id) + REFERENCES activitypub_activities(id) + ) + ENGINE=InnoDB DEFAULT CHARSET=utf8; " ); }