Implement likes and shares collection for objects

This commit is contained in:
Jeremy Dormitzer 2018-09-24 08:39:54 -04:00
parent 4393c41426
commit 1f871c53df
8 changed files with 192 additions and 12 deletions

View File

@ -9,17 +9,81 @@ function handle_outbox( $actor, $activity ) {
if ( !array_key_exists( 'object', $activity ) ) {
return new \WP_Error(
'invalid_activity',
__( 'Expected an object', 'activitypub' ),
__( 'Expected an object', 'pterotype' ),
array( 'status' => 400 )
);
}
$object = $activity['object'];
if ( !array_key_exists( 'id', $object ) ) {
return new \WP_Error(
'invalid_object',
__( 'Expected an id', 'pterotype' ),
array( 'status' => 400 )
);
}
$object_row = \objects\upsert_object( $object );
$actor_id = \actors\get_actor_id( $actor );
$res = \likes\create_like( $actor_id, $object_row->id );
$res = \likes\create_local_actor_like( $actor_id, $object_row->id );
if ( is_wp_error( $res ) ) {
return $res;
}
if ( \objects\is_local_object( $object ) ) {
$activity_id = \activities\get_activity_id( $activity['id'] );
if ( !$activity_id ) {
return new \WP_Error(
'not_found',
__( 'Activity not found', 'pterotype' ),
array( 'status' => 404 )
);
}
$object_id = $object_row->id;
\likes\record_like( $object_id, $activity_id );
}
return $activity;
}
function handle_inbox( $actor, $activity ) {
if ( !array_key_exists( 'id', $activity ) ) {
return new \WP_Error(
'invalid_activity',
__( 'Expected an id', 'pterotype' ),
array( 'status' => 400 )
);
}
if ( !array_key_exists( 'object', $activity ) ) {
return new \WP_Error(
'invalid_activity',
__( 'Expected an object', 'pterotype' ),
array( 'status' => 400 )
);
}
$object = $activity['object'];
if ( !array_key_exists( 'id', $object ) ) {
return new \WP_Error(
'invalid_object',
__( 'Expected an id', 'pterotype' ),
array( 'status' => 400 )
);
}
if ( \objects\is_local_object( $object ) ) {
$activity_id = \activities\get_activity_id( $activity['id'] );
if ( !$activity_id ) {
return new \WP_Error(
'not_found',
__( 'Activity not found', 'pterotype' ),
array( 'status' => 404 )
);
}
$object_id = \objects\get_object_id( $object['id'] );
if ( !$object_id ) {
return new \WP_Error(
'not_found',
__( 'Object not found', 'pterotype' ),
array( 'status' => 404 )
);
}
\likes\record_like( $object_id, $activity_id );
}
return $activity;
}
?>

View File

@ -6,6 +6,8 @@ require_once plugin_dir_path( __FILE__ ) . '/outbox.php';
require_once plugin_dir_path( __FILE__ ) . '/objects.php';
require_once plugin_dir_path( __FILE__ ) . '/activities.php';
require_once plugin_dir_path( __FILE__ ) . '/following.php';
require_once plugin_dir_path( __FILE__ ) . '/likes.php';
require_once plugin_dir_path( __FILE__ ) . '/shares.php';
function get_actor( $request ) {
$actor = $request['actor'];
@ -38,6 +40,16 @@ function get_following( $request ) {
return \following\get_following_collection( $actor_slug );
}
function get_likes( $request ) {
$object_id = $request['object'];
return \likes\get_likes_collection( $object_id );
}
function get_shares( $request ) {
$object_id = $request['object'];
return \shares\get_shares_collection( $object_id );
}
function register_routes() {
register_rest_route( 'pterotype/v1', '/actor/(?P<actor>[a-zA-Z0-9-]+)/outbox', array(
'methods' => 'POST',
@ -59,9 +71,17 @@ function register_routes() {
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_activity',
) );
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-]+)/following', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_following',
) );
register_rest_route( 'pterotype/v1', '/object/(?P<object>[0-9]+)/likes', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_likes',
) );
register_rest_route( 'pterotype/v1', '/object/(?P<object>[0-9]+)/shares', array(
'methods' => 'GET',
'callback' => __NAMESPACE__ . '\get_shares',
) );
}
?>

View File

@ -56,7 +56,7 @@ function get_following_collection( $actor_slug ) {
),
ARRAY_A
);
if ( !$object ) {
if ( !$objects ) {
$objects = array();
}
$collection = \collections\make_ordered_collection( $objects );

View File

@ -1,13 +1,49 @@
<?php
namespace likes;
// TODO implement a 'likes' collection for objects -
// implemented similar to/same as 'shares' collection
require_once plugin_dir_path( __FILE__ ) . '/collections.php';
function create_like( $actor_id, $object_id ) {
function create_local_actor_like( $actor_id, $object_id ) {
global $wpdb;
return $wpdb->insert(
'pterotype_likes', array( 'actor_id' => $actor_id, 'object_id' => $object_id )
'pterotype_actor_likes',
array( 'actor_id' => $actor_id, 'object_id' => $object_id ),
'%d'
);
}
function record_like ( $object_id, $like_id ) {
global $wpdb;
return $wpdb->insert(
'pterotype_object_likes',
array(
'object_id' => $object_id,
'like_id' => $like_id
),
'%d'
);
}
function get_likes_collection( $object_id ) {
global $wpdb;
$likes = $wpdb->get_results(
$wpdb->prepare(
'
SELECT activity FROM pterotype_object_likes
JOIN pterotype_activities ON like_id = pterotype_activities.id
WHERE object_id = %d
',
$object_id
),
ARRAY_A
);
if ( !$likes ) {
$likes = array();
}
$collection = \collections\make_ordered_collection( $likes );
$collection['id'] = get_rest_url( null, sprintf(
'/pterotype/v1/object/%d/likes', $object_id
) );
return $collection;
}
?>

View File

@ -23,6 +23,7 @@ function run_migrations() {
apply_migration( '0.0.1', 'migration_0_0_1' );
apply_migration( '0.0.2', 'migration_0_0_2' );
apply_migration( '0.0.3', 'migration_0_0_3' );
apply_migration( '0.0.4', 'migration_0_0_4' );
update_option( 'pterotype_previously_migrated_version', PTEROTYPE_VERSION );
}
@ -185,7 +186,36 @@ function migration_0_0_3() {
PRIMARY KEY (object_id, shared_by),
FOREIGN KEY shares_object_fk(object_id)
REFERENCES pterotype_objects(id),
FOREIGN KEY shares_activity_fk(object_id)
FOREIGN KEY shares_activity_fk(announce_id)
REFERENCES pterotype_activities(id)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
"
);
}
function migration_0_0_4() {
global $wpdb;
/*
pterotype_actor_likes stores things that local actors have liked
*/
$wpdb->query(
"
ALTER TABLE pterotype_likes RENAME pterotype_actor_likes;
"
);
/*
pterotype_object_likes stores likes about local objects
*/
$wpdb->query(
"
CREATE TABLE pterotype_object_likes(
object_id INT UNSIGNED NOT NULL,
like_id INT UNSIGNED NOT NULL,
PRIMARY KEY (object_id, like_id),
FOREIGN KEY o_likes_object_fk(object_id)
REFERENCES pterotype_objects(id),
FOREIGN KEY o_likes_activity_fk(like_id)
REFERENCES pterotype_activities(id)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -31,6 +31,10 @@ function handle_activity( $actor_slug, $activity ) {
array( 'status' => 400 )
);
}
$res = persist_activity( $actor_slug, $activity );
if ( is_wp_error( $res ) ) {
return $res;
}
switch ( $activity['type'] ) {
case 'Create':
$activity = \activities\create\handle_outbox( $actor_slug, $activity );
@ -102,8 +106,8 @@ function handle_activity( $actor_slug, $activity ) {
if ( is_wp_error( $activity ) ) {
return $activity;
}
$activity = deliver_activity( $activity );
return persist_activity( $actor_slug, $activity );
deliver_activity( $activity );
return $res;
}
function get_outbox( $actor_slug ) {
@ -137,6 +141,7 @@ function deliver_activity( $activity ) {
function persist_activity( $actor_slug, $activity ) {
global $wpdb;
$activity = \activities\strip_private_fields( $activity );
$activity = \activities\create_local_activity( $activity );
$activity_id = $wpdb->insert_id;
$actor_id = \actors\get_actor_id( $actor_slug );

View File

@ -1,6 +1,8 @@
<?php
namespace shares;
require_once plugin_dir_path( __FILE__ ) . '/collections.php';
function add_share( $object_id, $activity_id ) {
global $wpdb;
return $wpdb->insert(
@ -12,4 +14,27 @@ function add_share( $object_id, $activity_id ) {
'%d'
);
}
function get_shares_collection( $object_id ) {
global $wpdb;
$shares = $wpdb->get_results(
$wpdb->prepare(
'
SELECT activity FROM pterotype_shares
JOIN pterotype_activities ON announce_id = pterotype_activities.id
WHERE object_id = %d
',
$object_id
),
ARRAY_A
);
if ( !$shares ) {
$shares = array();
}
$collection = \collections\make_ordered_collection( $shares );
$collection['id'] = get_rest_url( null, sprintf(
'/pterotype/v1/object/%d/shares', $object_id
) );
return $collection;
}
?>

View File

@ -4,7 +4,7 @@ Plugin Name: Pterotype
*/
require_once plugin_dir_path( __FILE__ ) . 'inc/init.php';
define( 'PTEROTYPE_VERSION', '0.0.3' );
define( 'PTEROTYPE_VERSION', '0.0.4' );
function pterotype_init() {
do_action( 'pterotype_init' );