Added endpoint add summit speaker assistance

POST /api/v1/summits/{id}/speakers-assistances

payload

  'speaker_id'    => 'required:integer',
  'on_site_phone' => 'sometimes|string|max:50',
  'registered'    => 'sometimes|boolean',
  'is_confirmed'  => 'sometimes|boolean',
  'checked_in'    => 'sometimes|boolean',

Change-Id: Ia9cb0a1196c1ed9adec0fc542d47d7e045bc43df
This commit is contained in:
Sebastian Marcet 2018-01-30 14:10:48 -03:00
parent 2ae0358ebf
commit ccf2f735f2
11 changed files with 223 additions and 21 deletions

View File

@ -378,7 +378,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
'email' => 'sometimes|string|max:50',
'on_site_phone' => 'sometimes|string|max:50',
'registered' => 'sometimes|boolean',
'confirmed' => 'sometimes|boolean',
'is_confirmed' => 'sometimes|boolean',
'checked_in' => 'sometimes|boolean',
'registration_code' => 'sometimes|string',
);
@ -447,7 +447,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
'email' => 'sometimes|string|max:50',
'on_site_phone' => 'sometimes|string|max:50',
'registered' => 'sometimes|boolean',
'confirmed' => 'sometimes|boolean',
'is_confirmed' => 'sometimes|boolean',
'checked_in' => 'sometimes|boolean',
'registration_code' => 'sometimes|string',
);

View File

@ -20,13 +20,14 @@ use Illuminate\Support\Facades\Validator;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\oauth2\IResourceServerContext;
use models\summit\ISpeakerRepository;
use models\summit\ISummitRepository;
use ModelSerializers\SerializerRegistry;
use services\model\ISpeakerService;
use utils\FilterParser;
use utils\OrderParser;
use utils\PagingInfo;
use Exception;
/**
* Class OAuth2SummitSpeakersAssistanceApiController
* @package App\Http\Controllers
@ -43,6 +44,11 @@ final class OAuth2SummitSpeakersAssistanceApiController extends OAuth2ProtectedC
*/
private $speakers_assistance_repository;
/**
* @var ISpeakerRepository
*/
private $speaker_repository;
/**
* @var ISpeakerService
*/
@ -53,13 +59,15 @@ final class OAuth2SummitSpeakersAssistanceApiController extends OAuth2ProtectedC
(
ISummitRepository $summit_repository,
IPresentationSpeakerSummitAssistanceConfirmationRequestRepository $speakers_assistance_repository,
ISpeakerRepository $speaker_repository,
ISpeakerService $service,
IResourceServerContext $resource_server_context
)
{
parent::__construct($resource_server_context);
$this->summit_repository = $summit_repository;
$this->service = $service;
$this->summit_repository = $summit_repository;
$this->speaker_repository = $speaker_repository;
$this->service = $service;
$this->speakers_assistance_repository = $speakers_assistance_repository;
}
@ -152,12 +160,63 @@ final class OAuth2SummitSpeakersAssistanceApiController extends OAuth2ProtectedC
}
}
/**
* @param $summit_id
* @return mixed
*/
public function addSpeakerSummitAssistance($summit_id)
{
try {
if(!Request::isJson()) return $this->error403();
$data = Input::json()->all();
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id);
if (is_null($summit)) return $this->error404();
$rules = [
'speaker_id' => 'required:integer',
'on_site_phone' => 'sometimes|string|max:50',
'registered' => 'sometimes|boolean',
'is_confirmed' => 'sometimes|boolean',
'checked_in' => 'sometimes|boolean',
];
// Creates a Validator instance and validates the data.
$validation = Validator::make($data, $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error412
(
$messages
);
}
$speaker_assistance = $this->service->addSpeakerAssistance($summit, $data);
return $this->created(SerializerRegistry::getInstance()->getSerializer($speaker_assistance)->serialize());
}
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 $summit_id
* @param $assistance_id
* @return mixed
*/
public function deleteSpeakerSummitAssistanceSummit($summit_id, $assistance_id)
public function deleteSpeakerSummitAssistance($summit_id, $assistance_id)
{
try {
@ -179,4 +238,5 @@ final class OAuth2SummitSpeakersAssistanceApiController extends OAuth2ProtectedC
}
}
}

View File

@ -217,12 +217,12 @@ Route::group([
// speakers assistance
Route::group(['prefix' => 'speakers-assistances'], function () {
Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersAssistanceApiController@getBySummit']);
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersAssistanceApiController@addSpeakerSummitAssistance']);
Route::group(['prefix' => '{assistance_id}'], function () {
Route::delete('',[ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersAssistanceApiController@deleteSpeakerSummitAssistanceSummit']);
Route::delete('',[ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersAssistanceApiController@deleteSpeakerSummitAssistance']);
});
});
// events
Route::group(array('prefix' => 'events'), function () {

View File

@ -3,7 +3,7 @@
* Copyright 2016 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
* You may obtain a copy of the License atN
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@ -11,17 +11,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Libs\ModelSerializers\AbstractSerializer;
/**
* Class SilverStripeSerializer
* @package ModelSerializers
*/
class SilverStripeSerializer extends AbstractSerializer
{
protected static $array_mappings = array
(
'Id' => 'id:json_int',
);
protected static $array_mappings = [
'Id' => 'id:json_int',
'Created' => 'created:datetime_epoch',
'LastEdited' => 'last_edited:datetime_epoch',
];
}

View File

@ -100,7 +100,6 @@ class PresentationSpeaker extends SilverstripeBaseModel
*/
private $notes;
/**
* @ORM\Column(name="OrgHasCloud", type="boolean")
*/
@ -607,6 +606,14 @@ class PresentationSpeaker extends SilverstripeBaseModel
return $res === false ? null : $res;
}
/**
* @param Summit $summit
* @return bool
*/
public function hasAssistanceFor(Summit $summit){
return $this->getAssistanceFor($summit) != null;
}
/**
* @return mixed
*/
@ -635,6 +642,44 @@ class PresentationSpeaker extends SilverstripeBaseModel
return $request;
}
/**
* @param Summit $summit
* @return bool
*/
public function isSpeakerOfSummit(Summit $summit){
$query = <<<SQL
SELECT DISTINCT Summit.* FROM SummitEvent
INNER JOIN Summit ON Summit.ID = SummitEvent.SummitID
INNER JOIN Presentation ON Presentation.ID = SummitEvent.ID
WHERE
SummitEvent.Published = 1
AND (
EXISTS (
SELECT Presentation_Speakers.ID FROM Presentation_Speakers
WHERE Presentation_Speakers.PresentationID = Presentation.ID AND
Presentation_Speakers.PresentationSpeakerID = :speaker_id
) OR
Presentation.ModeratorID = :speaker_id
)
AND Summit.ID = :summit_id;
SQL;
$rsm = new ResultSetMappingBuilder($this->getEM());
$rsm->addRootEntityFromClassMetadata(\models\summit\Summit::class, 's');
// build rsm here
$native_query = $this->getEM()->createNativeQuery($query, $rsm);
$native_query->setParameter("speaker_id", $this->id);
$native_query->setParameter("summit_id", $summit->getId());
$summits = $native_query->getResult();
return count($summits) > 0;
}
/**
* @return Summit[]
*/
@ -645,7 +690,8 @@ SELECT DISTINCT Summit.* FROM Presentation_Speakers
INNER JOIN Presentation ON Presentation.ID = Presentation_Speakers.PresentationID
INNER JOIN SummitEvent ON SummitEvent.ID = Presentation.ID
INNER JOIN Summit ON Summit.ID = SummitEvent.SummitID
WHERE SummitEvent.Published = 1 AND Presentation_Speakers.PresentationSpeakerID = :speaker_id;
WHERE SummitEvent.Published = 1 AND
( Presentation_Speakers.PresentationSpeakerID = :speaker_id OR Presentation.ModeratorID = :speaker_id )
SQL;
$rsm = new ResultSetMappingBuilder($this->getEM());

View File

@ -15,6 +15,7 @@ use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\File;
use models\summit\PresentationSpeaker;
use models\summit\PresentationSpeakerSummitAssistanceConfirmationRequest;
use models\summit\SpeakerSummitRegistrationPromoCode;
use models\summit\Summit;
use Illuminate\Http\UploadedFile;
@ -91,6 +92,15 @@ interface ISpeakerService
*/
public function deleteSpeaker($speaker_id);
/**
* @param Summit $summit
* @param array $data
* @throws ValidationException
* @throws EntityNotFoundException
* @return PresentationSpeakerSummitAssistanceConfirmationRequest
*/
public function addSpeakerAssistance(Summit $summit, array $data);
/**
* @param Summit $summit
* @param int $assistance_id

View File

@ -203,7 +203,7 @@ final class SpeakerService implements ISpeakerService
$on_site_phone = isset($data['on_site_phone']) ? trim($data['on_site_phone']) : null;
$registered = isset($data['registered']) ? 1 : 0;
$checked_in = isset($data['checked_in']) ? 1 : 0;
$confirmed = isset($data['confirmed']) ? 1 : 0;
$confirmed = isset($data['is_confirmed']) ? 1 : 0;
$summit_assistance->setOnSitePhone($on_site_phone);
$summit_assistance->setRegistered($registered);
@ -710,4 +710,47 @@ final class SpeakerService implements ISpeakerService
$this->speakers_assistance_repository->delete($assistance);
});
}
/**
* @param Summit $summit
* @param array $data
* @throws ValidationException
* @throws EntityNotFoundException
* @return PresentationSpeakerSummitAssistanceConfirmationRequest
*/
public function addSpeakerAssistance(Summit $summit, array $data)
{
return $this->tx_service->transaction(function() use($data, $summit){
$speaker_id = intval($data['speaker_id']);
$speaker = $this->speaker_repository->getById($speaker_id);
if(is_null($speaker))
throw new EntityNotFoundException(trans('not_found_errors.add_speaker_assistance_speaker_not_found', ['speaker_id' => $speaker_id]));
if(!$speaker->isSpeakerOfSummit($summit)){
throw new ValidationException(trans('validation_errors.add_speaker_assistance_speaker_is_not_on_summit',
[
'speaker_id' => $speaker_id,
'summit_id' => $summit->getId()
]
));
}
if($speaker->hasAssistanceFor($summit))
throw new ValidationException(trans('validation_errors.add_speaker_assistance_speaker_already_has_assistance',
[
'speaker_id' => $speaker_id,
'summit_id' => $summit->getId()
]
));
$assistance = $speaker->buildAssistanceFor($summit);
$speaker->addSummitAssistance(
$this->updateSummitAssistance($assistance, $data)
);
return $assistance;
});
}
}

View File

@ -752,9 +752,17 @@ class ApiEndpointsSeeder extends Seeder
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
],
],
// summit speakers assistances
[
'name' => 'delete-speaker-assistance-by-id',
'name' => 'add-speaker-assistance',
'route' => '/api/v1/summits/{id}/speakers-assistances',
'http_method' => 'POST',
'scopes' => [
sprintf(SummitScopes::WriteSummitSpeakerAssistanceData, $current_realm),
sprintf(SummitScopes::WriteSummitData, $current_realm)
],
],
[
'name' => 'delete-speaker-assistance',
'route' => '/api/v1/summits/{id}/speakers-assistances/{assistance_id}',
'http_method' => 'DELETE',
'scopes' => [

View File

@ -14,4 +14,5 @@
return [
'promo_code_delete_code_not_found' => 'promo code id :promo_code_id does not belongs to summit id :summit_id.',
'promo_code_email_code_not_found' => 'promo code id :promo_code_id does not belongs to summit id :summit_id.',
'add_speaker_assistance_speaker_not_found' => 'speaker id :speaker_id not found',
];

View File

@ -18,4 +18,6 @@ return [
'promo_code_email_send_empty_email' => 'Cannot find an email address for the promocode owner.',
'promo_code_email_send_empty_name' => 'Cannot find a name for the promocode owner.',
'speaker_assistance_delete_already_confirmed' => 'Cannot delete summit assistance :assistance_id because is already confirmed by speaker :speaker_id',
'add_speaker_assistance_speaker_already_has_assistance' => 'speaker id :speaker_id already has an assistance for summit id :summit_id',
'add_speaker_assistance_speaker_is_not_on_summit' => 'speaker id :speaker_id is not related to summit id :summit_id ( is not assigned as speaker of any published presentations nor its assigned as moderator)',
];

View File

@ -133,7 +133,7 @@ class OAuth2SpeakersAssistancesApiTest extends ProtectedApiTest
$response = $this->action(
"DELETE",
"OAuth2SummitSpeakersAssistanceApiController@deleteSpeakerSummitAssistanceSummit",
"OAuth2SummitSpeakersAssistanceApiController@deleteSpeakerSummitAssistance",
$params,
[],
[],
@ -146,4 +146,36 @@ class OAuth2SpeakersAssistancesApiTest extends ProtectedApiTest
$this->assertResponseStatus(204);
}
public function testAddSummitAssistance($summit_id = 23){
$params = [
'id' => $summit_id,
];
$data = [
'speaker_id' => 1
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"POST",
"OAuth2SummitSpeakersAssistanceApiController@addSpeakerSummitAssistance",
$params,
[],
[],
[],
$headers,
json_encode($data)
);
$content = $response->getContent();
$this->assertResponseStatus(201);
$assistance = json_decode($content);
$this->assertTrue(!is_null($assistance));
return $assistance;
}
}