diff --git a/includes/client/comments.php b/includes/client/comments.php index f014948..082a306 100644 --- a/includes/client/comments.php +++ b/includes/client/comments.php @@ -7,22 +7,20 @@ require_once plugin_dir_path( __FILE__ ) . '../server/activities/delete.php'; require_once plugin_dir_path( __FILE__ ) . '../server/objects.php'; function handle_comment_post( $comment_id, $comment_approved ) { - xdebug_break(); if ( $comment_approved ) { $comment = \get_comment( $comment_id ); - handle_transition_comment_status( 'approve', 'nonexistent', $comment ); + handle_transition_comment_status( 'approved', 'nonexistent', $comment ); } } function handle_edit_comment( $comment_id ) { $comment = \get_comment( $comment_id ); if ( $comment->comment_approved ) { - handle_transition_comment_status( 'approve', 'approve', $comment ); + handle_transition_comment_status( 'approved', 'approved', $comment ); } } function handle_transition_comment_status( $new_status, $old_status, $comment ) { - xdebug_break(); // This creates a new commenter actor if necessary $actor_slug = get_comment_actor_slug( $comment ); $actor_outbox = get_rest_url( @@ -30,10 +28,10 @@ function handle_transition_comment_status( $new_status, $old_status, $comment ) ); $comment_object = comment_to_object( $comment, $actor_slug ); $activity = null; - if ( $new_status == 'approve' && $old_status != 'approve' ) { + if ( $new_status == 'approved' && $old_status != 'approved' ) { // Create $activity = \pterotype\activities\create\make_create( $actor_slug, $comment_object ); - } else if ( $new_status == 'approve' && $old_status == 'approve' ) { + } else if ( $new_status == 'approved' && $old_status == 'approved' ) { // Update $activity = \pterotype\activities\update\make_update( $actor_slug, $comment_object ); } else if ( $new_status == 'trash' && $old_status != 'trash' ) { @@ -53,10 +51,10 @@ function handle_transition_comment_status( $new_status, $old_status, $comment ) } function get_comment_actor_slug( $comment ) { - if ( $comment->user_id !== 0 ) { + if ( $comment->user_id !== '0' ) { return get_comment_user_actor_slug( $comment->user_id ); } else { - return get_comment_email_actor_slug( $comment->comment_author_email ); + return get_comment_email_actor_slug( $comment ); } } @@ -69,8 +67,23 @@ function get_comment_user_actor_slug( $user_id ) { } } -function get_comment_email_actor_slug( $email_address ) { - $slug = \pterotype\actors\upsert_commenter_actor( $email_address ); +function get_comment_email_actor_slug( $comment ) { + $email_address = $comment->comment_author_email; + $url = $comment->comment_author_url; + if ( empty( $url ) ) { + $url = null; + } + $name = $comment->comment_author; + if ( empty( $name ) ) { + $name = null; + } + $icon = \get_avatar_url( $email_address ); + if ( ! $icon ) { + $icon = null; + } + $slug = \pterotype\actors\upsert_commenter_actor( + $email_address, $url, $name, $icon + ); return $slug; } @@ -124,7 +137,7 @@ function traverse_reply_chain_helper( $object, $depth, $acc ) { if ( $depth === 50 ) { return $acc; } - if ( array_key_exists( 'inReplyTo', $object ) ) { + if ( ! array_key_exists( 'inReplyTo', $object ) ) { return $acc; } $parent = \pterotype\util\dereference_object( $object['inReplyTo'] ); diff --git a/includes/schema.php b/includes/schema.php index 4365df5..8969178 100644 --- a/includes/schema.php +++ b/includes/schema.php @@ -16,6 +16,7 @@ function run_migrations() { } apply_migration( '0.0.1', 'migration_0_0_1' ); apply_migration( '1.1.0', 'migration_1_1_0' ); + apply_migration( '1.1.1', 'migration_1_1_1' ); update_option( 'pterotype_previously_migrated_version', PTEROTYPE_VERSION ); } @@ -196,4 +197,17 @@ function migration_1_1_0() { " ); } + +function migration_1_1_1() { + global $wpdb; + $wpdb->query( + " + ALTER TABLE {$wpdb->prefix}pterotype_actors + ADD email VARCHAR(255), + ADD url VARCHAR(255), + ADD name VARCHAR(255), + ADD icon VARCHAR(255) + " + ); +} ?> diff --git a/includes/server/actors.php b/includes/server/actors.php index 277e7e1..3ba2f3d 100644 --- a/includes/server/actors.php +++ b/includes/server/actors.php @@ -40,13 +40,14 @@ function get_actor_from_row( $row ) { $user = get_user_by( 'slug', $row->slug ); return get_user_actor( $user ); case 'commenter': - return get_commenter_actor( $row->slug ); + return get_commenter_actor( $row ); } } -function get_commenter_actor( $slug ) { +function get_commenter_actor( $row ) { + $slug = $row->slug; $actor_id = get_actor_id( $slug ); - $email_address = str_replace( '[AT]', '@', $slug ); + $email_address = $row->email; $actor = array( '@context' => array( 'https://www.w3.org/ns/activitystreams', @@ -71,9 +72,7 @@ function get_commenter_actor( $slug ) { 'outbox' => get_rest_url( null, sprintf( '/pterotype/v1/actor/%s/outbox', $slug ) ), - 'name' => $email_address, - // TODO in the future, make this configurable, both here and in the Webfinger handler - 'preferredUsername' => $email_address, + 'preferredUsername' => $slug, 'publicKey' => array( 'id' => get_rest_url( null, sprintf( '/pterotype/v1/actor/%s#publicKey', $slug ) @@ -84,7 +83,17 @@ function get_commenter_actor( $slug ) { 'publicKeyPem' => \pterotype\pgp\get_public_key( $actor_id ), ), ); - // TODO retrieve commenter name, url, and icon + if ( ! empty( $row->name ) ) { + $actor['name'] = $row->name; + } else { + $actor['name'] = $row->email; + } + if ( ! empty( $row->url ) ) { + $actor['url'] = $row->url; + } + if ( ! empty( $row->icon ) ) { + $actor['icon'] = $row->icon; + } return $actor; } @@ -196,14 +205,9 @@ function initialize_actors() { } } -function create_actor( $slug, $type ) { +function create_actor( $slug, $type, $email = null, $url = null, $name = null, $icon = null ) { global $wpdb; - $res = $wpdb->query( $wpdb->prepare( - "INSERT IGNORE INTO {$wpdb->prefix}pterotype_actors(slug, type) - VALUES(%s, %s)", - $slug, - $type - ) ); + $res = $wpdb->query( get_create_actor_query( $slug, $type, $email, $url, $name, $icon ) ); if ( $res === false ) { return new \WP_Error( 'db_error', @@ -218,9 +222,35 @@ function create_actor( $slug, $type ) { return $res->object; } -function upsert_commenter_actor( $email_address ) { +function get_create_actor_query( $slug, $type, $email = null, $url = null, $name = null, $icon = ull ) { global $wpdb; - $slug = str_replace( '@', '[AT]', $email_address ); + $query = "INSERT IGNORE INTO {$wpdb->prefix}pterotype_actors(slug, type"; + $args = array( $slug, $type ); + if ( $email ) { + $query = $query . ", email"; + $args[] = $email; + } + if ( $url ) { + $query = $query . ", url"; + $args[] = $url; + } + if ( $name ) { + $query = $query . ", name"; + $args[] = $name; + } + if ( $icon ) { + $query = $query . ", icon"; + $args[] = $icon; + } + $query = $query . ") VALUES ("; + $placeholders = join( ',', array_map( function( $el ) { return '%s'; }, $args ) ); + $query = $query . $placeholders . ")"; + return $wpdb->prepare( $query, $args ); +} + +function upsert_commenter_actor( $email_address, $url = null, $name = null, $icon = null ) { + global $wpdb; + $slug = email_address_to_slug( $email_address ); $existing = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}pterotype_actors WHERE slug = %s", $slug @@ -228,13 +258,23 @@ function upsert_commenter_actor( $email_address ) { if ( $existing !== null ) { return $slug; } - create_actor( $slug, 'commenter' ); + create_actor( $slug, 'commenter', $email_address, $url, $name, $icon ); $actor_id = get_actor_id( $slug ); $keys_created = \pterotype\pgp\get_public_key( $actor_id ); if ( ! $keys_created ) { $keys = \pterotype\pgp\gen_key( $slug ); \pterotype\pgp\persist_key( $actor_id, $keys['publickey'], $keys['privatekey'] ); } + $actor = get_actor_by_slug( $slug ); + $res = \pterotype\objects\upsert_object( $actor ); + if ( is_wp_error( $res ) ) { + return $res; + } return $slug; } + +function email_address_to_slug( $email_address ) { + $slug = str_replace( array( '@', '.'), '_', $email_address ); + return preg_replace( '/[^a-zA-Z0-9-_]/', '', $slug ); +} ?> diff --git a/includes/server/api.php b/includes/server/api.php index cc7b8aa..eea7753 100644 --- a/includes/server/api.php +++ b/includes/server/api.php @@ -66,24 +66,24 @@ function user_can_post_to_outbox() { } function register_routes() { - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/outbox', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/outbox', array( 'methods' => 'POST', 'callback' => __NAMESPACE__ . '\post_to_outbox', 'permission_callback' => __NAMESPACE__ . '\user_can_post_to_outbox', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/outbox', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/outbox', array( 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_outbox', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/inbox', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/inbox', array( 'methods' => 'POST', 'callback' => __NAMESPACE__ . '\post_to_inbox', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/inbox', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/inbox', array( 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_inbox', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)', array( 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_actor', ) ); @@ -91,11 +91,11 @@ function register_routes() { 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_object', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/following', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/following', array( 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_following', ) ); - register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-]+)/followers', array( + register_rest_route( 'pterotype/v1', '/actor/(?P[a-zA-Z0-9-_]+)/followers', array( 'methods' => 'GET', 'callback' => __NAMESPACE__ . '\get_followers', ) ); diff --git a/pterotype.php b/pterotype.php index 5e1a45c..6a6786f 100644 --- a/pterotype.php +++ b/pterotype.php @@ -3,7 +3,7 @@ Plugin Name: Pterotype Plugin URI: https://getpterotype.com Description: Pterotype expands your audience by giving your blog an ActivityPub stream, making it a part of the Fediverse. -Version: 1.1.0 +Version: 1.1.1 Author: Jeremy Dormitzer Author URI: https://jeremydormitzer.com License: MIT @@ -12,7 +12,7 @@ License URI: https://github.com/jdormit/blob/master/LICENSE require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php'; require_once plugin_dir_path( __FILE__ ) . 'includes/init.php'; -define( 'PTEROTYPE_VERSION', '1.1.0' ); +define( 'PTEROTYPE_VERSION', '1.1.1' ); define( 'PTEROTYPE_BLOG_ACTOR_SLUG', '-blog' ); define( 'PTEROTYPE_BLOG_ACTOR_USERNAME', 'blog' );