diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 38cc699..adaab03 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -213,6 +213,8 @@ sub startup { $api->post('/topic/add')->to('api-topic#create'); $api->post('/topics')->to('api-topic#get_all'); + $api->post('/topics/subscriptions')->to('api-topic#get_all_and_subscriptions'); + $api->post('/topics/update')->to('api-topic#update_subscriptions'); $api->post('/send-message')->to('api-sendmessage#post_message'); diff --git a/lib/Pear/LocalLoop/Command/dev_data.pm b/lib/Pear/LocalLoop/Command/dev_data.pm index 759a539..f8ff78c 100644 --- a/lib/Pear/LocalLoop/Command/dev_data.pm +++ b/lib/Pear/LocalLoop/Command/dev_data.pm @@ -25,7 +25,13 @@ sub run { } my $schema = $self->app->schema; - + + $c->schema->resultset('Topic')->create( + { + name => 'default' + } + ); + $schema->resultset('User')->create( { email => 'test@example.com', @@ -91,12 +97,6 @@ sub run { } ); - $c->schema->resultset('DeviceToken')->create( - { - name => 'default' - } - ); - return 1; } diff --git a/lib/Pear/LocalLoop/Controller/Api/Devices.pm b/lib/Pear/LocalLoop/Controller/Api/Devices.pm index c483b1f..90ae67b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Devices.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Devices.pm @@ -89,18 +89,6 @@ sub create { my $response = $ua->request($request); if ( $response->is_success ) { - my $deviceToken = - $c->schema->resultset('DeviceToken')->find( { 'token' => $token } ); - my $topic = - $c->schema->resultset('Topic')->find( { 'name' => 'default' } ); - - $deviceToken->create_related( - 'device_subscriptions', - { - topic => $topic - } - ); - return $c->render( json => { success => Mojo::JSON->true, diff --git a/lib/Pear/LocalLoop/Controller/Api/Topic.pm b/lib/Pear/LocalLoop/Controller/Api/Topic.pm index 9bf7201..d38ed94 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Topic.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Topic.pm @@ -6,12 +6,21 @@ use JSON::Parse 'parse_json'; use Mojo::JWT; use Mojo::File; use Carp; +use Data::Dumper; has error_messages => sub { return { topic => { required => { message => 'Topic is required', status => 400 }, not_in_resultset => { message => 'Topic already exists', status => 400 }, + }, + token => { + required => { message => 'Device token is required', status => 400 }, + in_resultset => { message => 'Device token doesn\'t exist', status => 400 }, + }, + topicSubscriptions => { + required => { message => 'Set of topic subscriptions is required', status => 400 }, + in_resultset => { message => 'Topic doesn\'t exist', status => 400 }, } }; }; @@ -62,7 +71,7 @@ sub get_all { id => $_->id, name => $_->name, numberOfSubscribers => - $_->search_related( 'device_subscriptions', + $_->search_related( 'user_topic_subscriptions', { 'topic_id' => $_->id } )->count, } } $topic_rs->all @@ -75,4 +84,73 @@ sub get_all { } ); } + +sub get_all_and_subscriptions { + my $c = shift; + + my $user = $c->stash->{api_user}; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + my $topic_rs = $c->schema->resultset('Topic'); + + my @topics = ( + map { + { + id => $_->id, + name => $_->name, + isSubscribed => $_->search_related( 'user_topic_subscriptions', + { 'topic_id' => $_->id, 'user_id' => $user->id })->count + } + } $topic_rs->all + ); + + return $c->render( + json => { + success => Mojo::JSON->true, + topics => \@topics, + } + ); +} + +sub update_subscriptions { + my $c = shift; + + my $user = $c->stash->{api_user}; + my $topic_rs = $c->schema->resultset('Topic'); + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->required('topicSubscriptions'); + + foreach my $sub ( @{ $validation->every_param('topicSubscriptions') } ) { + my $subscription = $user->find_related( 'user_topic_subscriptions', + { 'topic_id' => $sub->{id} } + ); + + if ( $sub->{isSubscribed} && !$subscription ) { + $user->create_related( + 'user_topic_subscriptions', + { + topic_id => $sub->{id}, + } + ); + } elsif ( !$sub->{isSubscribed} && $subscription ) { + $user->delete_related( + 'user_topic_subscriptions', + { + topic_id => $sub->{id}, + } + ); + } + } + + return $c->render( + json => { + success => Mojo::JSON->true, + message => 'Topic subscriptions updated successfully!', + } + ); +} + 1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 17cb9cf..7c78743 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 34; +our $VERSION = 35; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/DeviceToken.pm b/lib/Pear/LocalLoop/Schema/Result/DeviceToken.pm index e97e87e..427ac38 100644 --- a/lib/Pear/LocalLoop/Schema/Result/DeviceToken.pm +++ b/lib/Pear/LocalLoop/Schema/Result/DeviceToken.pm @@ -46,13 +46,4 @@ __PACKAGE__->belongs_to( { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); -__PACKAGE__->has_many( - "device_subscriptions", - "Pear::LocalLoop::Schema::Result::DeviceSubscription", - { "foreign.device_token_id" => "self.id" }, - { cascade_copy => 0, cascade_delete => 0 }, -); - -__PACKAGE__->many_to_many( 'topics' => 'device_subscriptions', 'topic' ); - 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Topic.pm b/lib/Pear/LocalLoop/Schema/Result/Topic.pm index 434ae62..b5615d5 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Topic.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Topic.pm @@ -43,15 +43,17 @@ __PACKAGE__->belongs_to( ); __PACKAGE__->has_many( - "device_subscriptions", - "Pear::LocalLoop::Schema::Result::DeviceSubscription", + "user_topic_subscriptions", + "Pear::LocalLoop::Schema::Result::UserTopicSubscription", { "foreign.topic_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); __PACKAGE__->many_to_many( - 'device_tokens' => 'device_subscriptions', - 'device_token' + 'users' => 'user_topic_subscriptions', + 'user' ); +__PACKAGE__->many_to_many( 'topics' => 'user_topic_subscriptions', 'topic' ); + 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/User.pm b/lib/Pear/LocalLoop/Schema/Result/User.pm index 0ac7615..01dd8a7 100644 --- a/lib/Pear/LocalLoop/Schema/Result/User.pm +++ b/lib/Pear/LocalLoop/Schema/Result/User.pm @@ -84,6 +84,14 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +__PACKAGE__->has_many( + "user_topic_subscriptions", + "Pear::LocalLoop::Schema::Result::UserTopicSubscription", + { "foreign.user_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + + __PACKAGE__->filter_column( is_admin => { filter_to_storage => 'to_bool', diff --git a/lib/Pear/LocalLoop/Schema/Result/DeviceSubscription.pm b/lib/Pear/LocalLoop/Schema/Result/UserTopicSubscription.pm similarity index 77% rename from lib/Pear/LocalLoop/Schema/Result/DeviceSubscription.pm rename to lib/Pear/LocalLoop/Schema/Result/UserTopicSubscription.pm index 594eeba..6517c1d 100644 --- a/lib/Pear/LocalLoop/Schema/Result/DeviceSubscription.pm +++ b/lib/Pear/LocalLoop/Schema/Result/UserTopicSubscription.pm @@ -1,11 +1,11 @@ -package Pear::LocalLoop::Schema::Result::DeviceSubscription; +package Pear::LocalLoop::Schema::Result::UserTopicSubscription; use strict; use warnings; use base 'DBIx::Class::Core'; -__PACKAGE__->table("device_subscriptions"); +__PACKAGE__->table("user_topic_subscriptions"); __PACKAGE__->add_columns( "id" => { @@ -13,7 +13,7 @@ __PACKAGE__->add_columns( is_auto_increment => 1, is_nullable => 0, }, - "device_token_id" => { + "user_id" => { data_type => "integer", is_foreign_key => 1, is_nullable => 0, @@ -28,9 +28,9 @@ __PACKAGE__->add_columns( __PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to( - "device_token", - "Pear::LocalLoop::Schema::Result::DeviceToken", - "device_token_id", + "user", + "Pear::LocalLoop::Schema::Result::User", + "user_id", { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, );