Implement outbound comment syncing for not-logged-in users

Although it is possibly not working...
This commit is contained in:
Jeremy Dormitzer 2018-10-24 07:31:38 -04:00
parent 87aae44c72
commit 7b8a35d8b0
5 changed files with 104 additions and 37 deletions

View File

@ -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'] );

View File

@ -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)
"
);
}
?>

View File

@ -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 );
}
?>

View File

@ -66,24 +66,24 @@ function user_can_post_to_outbox() {
}
function register_routes() {
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)/outbox', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[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<actor>[a-zA-Z0-9-]+)/outbox', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-_]+)/outbox', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_outbox',
) );
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)/inbox', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-_]+)/inbox', array(
'methods' => 'POST',
'callback' => __NAMESPACE__ . '\post_to_inbox',
) );
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)/inbox', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-_]+)/inbox', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_inbox',
) );
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[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<actor>[a-zA-Z0-9-]+)/following', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-_]+)/following', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_following',
) );
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)/followers', array(
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-_]+)/followers', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_followers',
) );

View File

@ -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' );