Added endpoints to add/remove speakers

from my presentations

DELETE /api/v1/speakers/me/presentations/{presentation_id}/speakers/{speaker_id}
PUT /api/v1/speakers/me/presentations/{presentation_id}/speakers/{speaker_id}

Required Scopes
* /summits/write
* /speakers/write
* /speakers/write/me

Change-Id: I1a262445b3b4342a983b169add63f3c9731e960b
This commit is contained in:
Sebastian Marcet 2018-08-13 18:39:15 -03:00
parent abfb97dbd0
commit ff8a664d95
6 changed files with 214 additions and 1 deletions

View File

@ -13,7 +13,6 @@
* limitations under the License.
**/
use App\Models\Foundation\Summit\Repositories\ISelectionPlanRepository;
use App\Services\Model\ISummitSelectionPlanService;
use Exception;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
@ -32,6 +31,7 @@ use models\summit\PresentationSpeaker;
use ModelSerializers\ISerializerTypeSelector;
use ModelSerializers\SerializerRegistry;
use services\model\ISpeakerService;
use services\model\ISummitService;
use utils\FilterParser;
use utils\OrderParser;
use utils\PagingInfo;
@ -80,6 +80,12 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
*/
private $selection_plan_repository;
/**
* @var ISummitService
*/
private $summit_service;
/**
* OAuth2SummitSpeakersApiController constructor.
* @param ISummitRepository $summit_repository
@ -89,6 +95,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
* @param IMemberRepository $member_repository
* @param ISelectionPlanRepository $selection_plan_repository
* @param ISpeakerService $service
* @param ISummitService $summit_service
* @param ISerializerTypeSelector $serializer_type_selector
* @param IResourceServerContext $resource_server_context
*/
@ -101,6 +108,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
IMemberRepository $member_repository,
ISelectionPlanRepository $selection_plan_repository,
ISpeakerService $service,
ISummitService $summit_service,
ISerializerTypeSelector $serializer_type_selector,
IResourceServerContext $resource_server_context
)
@ -113,6 +121,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
$this->event_feedback_repository = $event_feedback_repository;
$this->selection_plan_repository = $selection_plan_repository;
$this->service = $service;
$this->summit_service = $summit_service;
$this->serializer_type_selector = $serializer_type_selector;
}
@ -829,4 +838,57 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
}
}
/**
* @param $presentation_id
* @param $speaker_id
* @return mixed
*/
public function addSpeakerToMyPresentation($presentation_id, $speaker_id){
try {
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id))
return $this->error403();
$this->summit_service->addSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id);
return $this->updated();
} 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 $presentation_id
* @param $speaker_id
* @return mixed
*/
public function removeSpeakerToMyPresentation($presentation_id, $speaker_id){
try {
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id))
return $this->error403();
$this->summit_service->removeSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id);
return $this->deleted();
} 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);
}
}
}

View File

@ -533,6 +533,16 @@ Route::group([
Route::get('', 'OAuth2SummitSpeakersApiController@getMySpeaker');
Route::post('', 'OAuth2SummitSpeakersApiController@createMySpeaker');
Route::group(['prefix' => 'presentations'], function(){
Route::group(['prefix' => '{presentation_id}'], function(){
Route::group(['prefix' => 'speakers'], function(){
Route::put('{speaker_id}', 'OAuth2SummitSpeakersApiController@addSpeakerToMyPresentation');
Route::delete('{speaker_id}', 'OAuth2SummitSpeakersApiController@removeSpeakerToMyPresentation');
});
Route::group(['prefix' => 'moderators'], function(){
});
});
Route::group(['prefix' => '{role}'], function(){
Route::group(['prefix' => 'selection-plans'], function(){
Route::group(['prefix' => '{selection_plan_id}'], function(){

View File

@ -345,9 +345,18 @@ class Presentation extends SummitEvent
* @param PresentationSpeaker $speaker
*/
public function removeSpeaker(PresentationSpeaker $speaker){
if(!$this->speakers->contains($speaker)) return;
$this->speakers->removeElement($speaker);
}
/**
* @param PresentationSpeaker $speaker
* @return bool
*/
public function isSpeaker(PresentationSpeaker $speaker){
return $this->speakers->contains($speaker);
}
/**
* @return PresentationSlide[]
*/
@ -677,4 +686,15 @@ class Presentation extends SummitEvent
}
}
/**
* @param PresentationSpeaker $speaker
* @return bool
*/
public function canEdit(PresentationSpeaker $speaker){
if($this->getCreatorId() == $speaker->getId()) return true;
if($this->getModeratorId() == $speaker->getId()) return true;
if($this->isSpeaker($speaker)) return true;
return false;
}
}

View File

@ -222,4 +222,24 @@ interface ISummitService
* @return void
*/
public function deleteSummit($summit_id);
/**
* @param int $current_member_id
* @param int $speaker_id
* @param int $presentation_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function addSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id);
/**
* @param int $current_member_id
* @param int $speaker_id
* @param int $presentation_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function removeSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id);
}

View File

@ -1653,4 +1653,85 @@ final class SummitService extends AbstractService implements ISummitService
});
}
/**
* @param int $current_member_id
* @param int $speaker_id
* @param int $presentation_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function addSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id)
{
return $this->tx_service->transaction(function () use ($current_member_id, $speaker_id, $presentation_id) {
$current_member = $this->member_repository->getById($current_member_id);
if(is_null($current_member))
throw new EntityNotFoundException(sprintf("member %s not found", $current_member_id));
$current_speaker = $this->speaker_repository->getByMember($current_member);
if(is_null($current_speaker))
throw new EntityNotFoundException(sprintf("member %s does not has a speaker profile", $current_member_id));
$presentation = $this->event_repository->getById($presentation_id);
if(is_null($presentation))
throw new EntityNotFoundException(sprintf("presentation %s not found", $presentation_id));
if(!$presentation instanceof Presentation)
throw new EntityNotFoundException(sprintf("presentation %s not found", $presentation_id));
if(!$presentation->canEdit($current_speaker))
throw new ValidationException(sprintf("member %s can not edit presentation %s",
$current_member_id,
$presentation_id
));
$speaker = $this->speaker_repository->getById(intval($speaker_id));
if (is_null($speaker))
throw new EntityNotFoundException(sprintf('speaker %s not found', $speaker_id));
$presentation->addSpeaker($speaker);
});
}
/**
* @param int $current_member_id
* @param int $speaker_id
* @param int $presentation_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function removeSpeaker2Presentation($current_member_id, $speaker_id, $presentation_id)
{
return $this->tx_service->transaction(function () use ($current_member_id, $speaker_id, $presentation_id) {
$current_member = $this->member_repository->getById($current_member_id);
if(is_null($current_member))
throw new EntityNotFoundException(sprintf("member %s not found", $current_member_id));
$current_speaker = $this->speaker_repository->getByMember($current_member);
if(is_null($current_speaker))
throw new EntityNotFoundException(sprintf("member %s does not has a speaker profile", $current_member_id));
$presentation = $this->event_repository->getById($presentation_id);
if(is_null($presentation))
throw new EntityNotFoundException(sprintf("presentation %s not found", $presentation_id));
if(!$presentation instanceof Presentation)
throw new EntityNotFoundException(sprintf("presentation %s not found", $presentation_id));
if(!$presentation->canEdit($current_speaker))
throw new ValidationException(sprintf("member %s can not edit presentation %s",
$current_member_id,
$presentation_id
));
$speaker = $this->speaker_repository->getById(intval($speaker_id));
if (is_null($speaker))
throw new EntityNotFoundException(sprintf('speaker %s not found', $speaker_id));
$presentation->removeSpeaker($speaker);
});
}
}

View File

@ -329,6 +329,26 @@ class ApiEndpointsSeeder extends Seeder
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
],
),
[
'name' => 'add-speaker-2-my-presentation',
'route' => '/api/v1/speakers/me/presentations/{presentation_id}/speakers/{speaker_id}',
'http_method' => 'PUT',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteSpeakersData, $current_realm),
sprintf(SummitScopes::WriteMySpeakersData, $current_realm)
],
],
[
'name' => 'remove-speaker-2-my-presentation',
'route' => '/api/v1/speakers/me/presentations/{presentation_id}/speakers/{speaker_id}',
'http_method' => 'DELETE',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteSpeakersData, $current_realm),
sprintf(SummitScopes::WriteMySpeakersData, $current_realm)
],
],
array(
'name' => 'create-my-speaker',
'route' => '/api/v1/speakers/me',