Pending/Accepted invitation endpoint

added new endpoint to get pending/accepted
invitations from my member

Change-Id: I6a673a902200dacbd3197487c14e5389e5ef14be
This commit is contained in:
Sebastian Marcet 2017-01-18 14:47:58 -03:00
parent b364505b55
commit add88d3440
10 changed files with 226 additions and 12 deletions

View File

@ -1,6 +1,6 @@
<?php namespace App\Http\Controllers;
/**
* Copyright 2016 OpenStack Foundation
* Copyright 2017 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -49,6 +49,9 @@ final class OAuth2TeamInvitationsApiController extends OAuth2ProtectedController
$this->service = $service;
}
/**
* @return mixed
*/
public function getMyInvitations(){
try {
@ -83,6 +86,80 @@ final class OAuth2TeamInvitationsApiController extends OAuth2ProtectedController
}
}
/**
* @return mixed
*/
public function getMyPendingInvitations(){
try {
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id)) return $this->error403();
$invitations = $this->repository->getPendingInvitationsByInvitee($current_member_id);
$response = new PagingResponse
(
count($invitations),
count($invitations),
1,
1,
$invitations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
}
catch (ValidationException $ex1) {
Log::warning($ex1);
return $this->error412(array($ex1->getMessage()));
}
catch(EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message'=> $ex2->getMessage()));
}
catch (\Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
/**
* @return mixed
*/
public function getMyAcceptedInvitations(){
try {
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id)) return $this->error403();
$invitations = $this->repository->getAcceptedInvitationsByInvitee($current_member_id);
$response = new PagingResponse
(
count($invitations),
count($invitations),
1,
1,
$invitations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
}
catch (ValidationException $ex1) {
Log::warning($ex1);
return $this->error412(array($ex1->getMessage()));
}
catch(EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message'=> $ex2->getMessage()));
}
catch (\Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
/**
* @param $invitation_id
* @return mixed

View File

@ -53,6 +53,8 @@ Route::group(array(
// invitations
Route::group(['prefix'=>'team-invitations'], function(){
Route::get('', 'OAuth2TeamInvitationsApiController@getMyInvitations');
Route::get('pending', 'OAuth2TeamInvitationsApiController@getMyPendingInvitations');
Route::get('accepted', 'OAuth2TeamInvitationsApiController@getMyAcceptedInvitations');
Route::group(['prefix'=>'{invitation_id}'], function() {
Route::put('', 'OAuth2TeamInvitationsApiController@acceptInvitation');
Route::delete('', 'OAuth2TeamInvitationsApiController@declineInvitation');

View File

@ -258,6 +258,18 @@ class ChatTeam extends SilverstripeBaseModel
return $this->getOwnerId() == $member->getId();
}
/**
* @param Member $member
* @return bool
*/
public function isAlreadyInvited(Member $member){
$res = $this->invitations->filter(function ($i) use($member){
return $i->getInvitee()->getId() == $member->getId() && $i->isPending();
});
return $res->count() > 0;
}
/**
* @param Member $member
* @return bool
@ -276,10 +288,19 @@ class ChatTeam extends SilverstripeBaseModel
$res = $this->members->filter(function ($e) use($member){
return $e->getMember()->getId() == $member->getId();
});
if($res->count() == 0) return;
if($res->count() == 0) return;
// remove member
$team_member = $res->first();
$this->members->removeElement($team_member);
$res2 = $this->invitations->filter(function ($i) use($member){
return $i->getInvitee()->getId() == $member->getId();
});
// remove invitation
if($res2->count() > 0) {
$this->invitations->removeElement($res2->first());
}
$team_member->setTeam(null);
}
}

View File

@ -164,6 +164,13 @@ class ChatTeamInvitation extends SilverstripeBaseModel
return $this->getIsAccepted();
}
/**
* @return bool
*/
public function isPending(){
return !$this->getIsAccepted();
}
public function accept()
{
$this->is_accepted = true;

View File

@ -23,4 +23,8 @@ interface IChatTeamInvitationRepository extends IBaseRepository
* @return ChatTeamInvitation[]
*/
function getInvitationsByInvitee($invitee_id);
function getPendingInvitationsByInvitee($invitee_id);
function getAcceptedInvitationsByInvitee($invitee_id);
}

View File

@ -37,4 +37,34 @@ final class DoctrineChatTeamInvitationRepository
->innerJoin('i.invitee', 'm', Join::WITH, " m.id = :member_id")
->setParameter('member_id', $invitee_id)->getQuery()->getResult();
}
/**
* @param int $invitee_id
* @return ChatTeamInvitation[]
*/
function getPendingInvitationsByInvitee($invitee_id)
{
return $this->getEntityManager()
->createQueryBuilder()
->select("i")
->from(\models\main\ChatTeamInvitation::class, "i")
->innerJoin('i.invitee', 'm', Join::WITH, " m.id = :member_id")
->where('i.is_accepted = false')
->setParameter('member_id', $invitee_id)->getQuery()->getResult();
}
/**
* @param int $invitee_id
* @return ChatTeamInvitation[]
*/
function getAcceptedInvitationsByInvitee($invitee_id)
{
return $this->getEntityManager()
->createQueryBuilder()
->select("i")
->from(\models\main\ChatTeamInvitation::class, "i")
->innerJoin('i.invitee', 'm', Join::WITH, " m.id = :member_id")
->where('i.is_accepted = true')
->setParameter('member_id', $invitee_id)->getQuery()->getResult();
}
}

View File

@ -45,7 +45,7 @@ final class DoctrineChatTeamRepository extends SilverStripeDoctrineRepository im
{
$result = $this
->getEntityManager()
->createQuery("select t.id from \models\main\ChatTeam t join t.messages m where exists (select m2.id from \models\main\ChatTeamPushNotificationMessage m2 where m2.id = m.id and m2.is_sent = 0 )")
->createQuery("select distinct t.id from \models\main\ChatTeam t join t.messages m where exists (select m2.id from \models\main\ChatTeamPushNotificationMessage m2 where m2.id = m.id and m2.is_sent = 0 )")
->getScalarResult();
$ids = array_map('current', $result);
return $ids;

View File

@ -1,6 +1,6 @@
<?php namespace services\model;
/**
* Copyright 2016 OpenStack Foundation
* Copyright 2017 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -172,6 +172,7 @@ final class ChatTeamService implements IChatTeamService
function addMember2Team($team_id, $invitee_id, $permission = ChatTeamPermission::Read)
{
return $this->tx_service->transaction(function() use($team_id, $invitee_id, $permission){
$team = $this->repository->getById($team_id);
if(is_null($team)) throw new EntityNotFoundException();
@ -182,15 +183,16 @@ final class ChatTeamService implements IChatTeamService
if (is_null($inviter)) throw new EntityNotFoundException();
$invitee = $this->member_repository->getById($invitee_id);
if(is_null($invitee))
throw new EntityNotFoundException();
if(is_null($invitee)) throw new EntityNotFoundException();
if(!$team->isAdmin($inviter))
throw new EntityNotFoundException();
if(!$team->isAdmin($inviter)) throw new EntityNotFoundException();
if($team->isMember($invitee))
throw new ValidationException(sprintf('member id %s already is a member of team id %s', $invitee_id, $team_id));
if($team->isAlreadyInvited($invitee))
throw new ValidationException(sprintf('member id %s has a pending invitation on team id %s', $invitee_id, $team_id));
$invitation = $team->createInvitation($inviter, $invitee, $permission);
$team->addInvitation($invitation);
@ -343,17 +345,21 @@ final class ChatTeamService implements IChatTeamService
function sendMessages($batch_size = 1000)
{
return $this->tx_service->transaction(function() use($batch_size){
echo(sprintf('calling ChatTeamService.sendMessages(%s)', $batch_size)).PHP_EOL;
$teams_ids = $this->repository->getAllTeamsIdsWithPendingMessages2Sent();
$qty = 0;
foreach($teams_ids as $team_id) {
echo(sprintf('processing messages for team id %s', $team_id)).PHP_EOL;
$messages = $this->chat_message_repository->getAllNotSentByTeamPaginated
(
$team_id,
new PagingInfo(1, $batch_size)
);
echo(sprintf('found %s messages for team id %s, send them...', $team_id, $messages->getTotal())).PHP_EOL;
$team_messages_counter = 0;
foreach ($messages->getItems() as $message){
$data = [
@ -369,7 +375,10 @@ final class ChatTeamService implements IChatTeamService
$this->push_sender_service->sendPush([sprintf('team_%s', $team_id)], $data);
$message->markSent();
++$qty;
++$team_messages_counter;
}
echo(sprintf('sent %s messages for team id %s', $team_messages_counter, $team_id)).PHP_EOL;
}
return $qty;
});

View File

@ -552,6 +552,18 @@ class ApiEndpointsSeeder extends Seeder
'http_method' => 'GET',
'scopes' => [sprintf('%s/members/invitations/read', $current_realm)],
),
array(
'name' => 'get-pending-invitations',
'route' => '/api/v1/members/me/team-invitations/pending',
'http_method' => 'GET',
'scopes' => [sprintf('%s/members/invitations/read', $current_realm)],
),
array(
'name' => 'get-accepted-invitations',
'route' => '/api/v1/members/me/team-invitations/accepted',
'http_method' => 'GET',
'scopes' => [sprintf('%s/members/invitations/read', $current_realm)],
),
array(
'name' => 'accept-invitation',
'route' => '/api/v1/members/me/team-invitations/{invitation_id}',

View File

@ -329,9 +329,61 @@ final class OAuth2ChatTeamApiTest extends ProtectedApiTest
);
$content = $response->getContent();
$messages = json_decode($content);
$this->assertTrue(!is_null($messages));
$invitations = json_decode($content);
$this->assertTrue(!is_null($invitations));
$this->assertResponseStatus(200);
return $messages;
return $invitations;
}
public function testGetMyPendingInvitations(){
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
];
$params = [
];
$response = $this->action(
"GET",
"OAuth2TeamInvitationsApiController@getMyPendingInvitations",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$invitations = json_decode($content);
$this->assertTrue(!is_null($invitations));
$this->assertResponseStatus(200);
return $invitations;
}
public function testGetMyAcceptedInvitations(){
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
];
$params = [
];
$response = $this->action(
"GET",
"OAuth2TeamInvitationsApiController@getMyAcceptedInvitations",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$invitations = json_decode($content);
$this->assertTrue(!is_null($invitations));
$this->assertResponseStatus(200);
return $invitations;
}
}