Added new endpoints update and delete speaker

PUT /api/v1/speakers/{speaker_id}
DELETE /api/v1/speakers/{speaker_id}

Change-Id: I38b01e5f14df0437d09c3f72908734654618dfd1
This commit is contained in:
Sebastian Marcet
2018-01-26 17:53:00 -03:00
parent 234dc17bae
commit 26c12abc80
8 changed files with 268 additions and 17 deletions

View File

@@ -19,7 +19,6 @@ use Illuminate\Support\Facades\Validator;
use libs\utils\HTMLCleaner;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\Group;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\IEventFeedbackRepository;
@@ -29,9 +28,7 @@ use models\summit\ISummitRepository;
use ModelSerializers\ISerializerTypeSelector;
use ModelSerializers\SerializerRegistry;
use services\model\ISpeakerService;
use services\model\ISummitService;
use utils\FilterParser;
use utils\FilterParserException;
use utils\OrderParser;
use utils\PagingInfo;
use Illuminate\Http\Request as LaravelRequest;
@@ -472,9 +469,9 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
'bio',
];
$speaker = $this->service->updateSpeaker($summit, $speaker, HTMLCleaner::cleanData($data->all(), $fields));
$speaker = $this->service->updateSpeakerBySummit($summit, $speaker, HTMLCleaner::cleanData($data->all(), $fields));
return $this->created(SerializerRegistry::getInstance()->getSerializer($speaker)->serialize());
return $this->updated(SerializerRegistry::getInstance()->getSerializer($speaker)->serialize());
}
catch (ValidationException $ex1) {
Log::warning($ex1);
@@ -491,6 +488,11 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
}
}
/**
* @param LaravelRequest $request
* @param $speaker_id
* @return mixed
*/
public function addSpeakerPhoto(LaravelRequest $request, $speaker_id){
try {
@@ -620,4 +622,98 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController
}
}
/**
* @param $speaker_id
* @return mixed
*/
public function updateSpeaker($speaker_id){
try {
if(!Request::isJson()) return $this->error403();
$data = Input::json();
$speaker = $this->speaker_repository->getById($speaker_id);
if (is_null($speaker)) return $this->error404();
$rules = array
(
'title' => 'sometimes|string|max:100',
'first_name' => 'sometimes|string|max:100',
'last_name' => 'sometimes|string|max:100',
'bio' => 'sometimes|string',
'notes' => 'sometimes|string',
'irc' => 'sometimes|string|max:50',
'twitter' => 'sometimes|string|max:50',
'member_id' => 'sometimes|integer',
'email' => 'sometimes|string|max:50',
'available_for_bureau' => 'sometimes|boolean',
'funded_travel' => 'sometimes|boolean',
'willing_to_travel' => 'sometimes|boolean',
'willing_to_present_video' => 'sometimes|boolean',
);
// Creates a Validator instance and validates the data.
$validation = Validator::make($data->all(), $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error412
(
$messages
);
}
$fields = [
'title',
'bio',
'notes',
];
$speaker = $this->service->updateSpeaker($speaker, HTMLCleaner::cleanData($data->all(), $fields));
return $this->updated(SerializerRegistry::getInstance()->getSerializer($speaker, SerializerRegistry::SerializerType_Private)->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 $speaker_id
* @return mixed
*/
public function deleteSpeaker($speaker_id){
try {
$speaker = $this->speaker_repository->getById($speaker_id);
if (is_null($speaker)) return $this->error404();
$this->service->deleteSpeaker($speaker_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

@@ -60,9 +60,9 @@ abstract class JsonController extends Controller
return $res;
}
protected function updated($data = 'ok')
protected function updated($data = 'ok', $has_content = true)
{
$res = Response::json($data, 204);
$res = Response::json($data, $has_content ? 201 : 204);
//jsonp
if (Input::has('callback')) {
$res->setCallback(Input::get('callback'));

View File

@@ -352,6 +352,8 @@ Route::group([
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@addSpeaker']);
Route::put('merge/{speaker_from_id}/{speaker_to_id}', 'OAuth2SummitSpeakersApiController@merge');
Route::group(['prefix' => '{speaker_id}'], function () {
Route::put('',[ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@updateSpeaker'])->where('speaker_id', 'me|[0-9]+');
Route::delete('',[ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@deleteSpeaker'])->where('speaker_id', 'me|[0-9]+');
Route::get('', 'OAuth2SummitSpeakersApiController@getSpeaker');
Route::post('/photo', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@addSpeakerPhoto']);
});

View File

@@ -107,20 +107,20 @@ class PresentationSpeaker extends SilverstripeBaseModel
private $org_has_cloud;
/**
* @ORM\ManyToOne(targetEntity="SpeakerRegistrationRequest", cascade={"persist"})
* @ORM\ManyToOne(targetEntity="SpeakerRegistrationRequest", cascade={"persist"}), orphanRemoval=true
* @ORM\JoinColumn(name="RegistrationRequestID", referencedColumnName="ID")
* @var SpeakerRegistrationRequest
*/
private $registration_request;
/**
* @ORM\OneToMany(targetEntity="PresentationSpeakerSummitAssistanceConfirmationRequest", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="PresentationSpeakerSummitAssistanceConfirmationRequest", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var PresentationSpeakerSummitAssistanceConfirmationRequest[]
*/
private $summit_assistances;
/**
* @ORM\OneToMany(targetEntity="SpeakerSummitRegistrationPromoCode", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="SpeakerSummitRegistrationPromoCode", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var SpeakerSummitRegistrationPromoCode[]
*/
private $promo_codes;
@@ -152,25 +152,25 @@ class PresentationSpeaker extends SilverstripeBaseModel
private $member;
/**
* @ORM\OneToMany(targetEntity="SpeakerExpertise", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="SpeakerExpertise", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var SpeakerExpertise[]
*/
private $areas_of_expertise;
/**
* @ORM\OneToMany(targetEntity="SpeakerPresentationLink", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="SpeakerPresentationLink", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var SpeakerPresentationLink[]
*/
private $other_presentation_links;
/**
* @ORM\OneToMany(targetEntity="SpeakerTravelPreference", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="SpeakerTravelPreference", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var SpeakerTravelPreference[]
*/
private $travel_preferences;
/**
* @ORM\OneToMany(targetEntity="SpeakerLanguage", mappedBy="speaker", cascade={"persist"})
* @ORM\OneToMany(targetEntity="SpeakerLanguage", mappedBy="speaker", cascade={"persist"}, orphanRemoval=true)
* @var SpeakerLanguage[]
*/
private $languages;

View File

@@ -46,7 +46,15 @@ interface ISpeakerService
* @return PresentationSpeaker
* @throws ValidationException
*/
public function updateSpeaker(Summit $summit, PresentationSpeaker $speaker, array $data);
public function updateSpeakerBySummit(Summit $summit, PresentationSpeaker $speaker, array $data);
/**
* @param array $data
* @param PresentationSpeaker $speaker
* @return PresentationSpeaker
* @throws ValidationException
*/
public function updateSpeaker(PresentationSpeaker $speaker, array $data);
/**
* @param PresentationSpeaker $speaker
@@ -74,4 +82,12 @@ interface ISpeakerService
* @return void
*/
public function merge(PresentationSpeaker $speaker_from, PresentationSpeaker $speaker_to, array $data);
/**
* @param int $speaker_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function deleteSpeaker($speaker_id);
}

View File

@@ -327,7 +327,7 @@ final class SpeakerService implements ISpeakerService
* @throws ValidationException
* @throws EntityNotFoundException
*/
public function updateSpeaker(Summit $summit, PresentationSpeaker $speaker, array $data)
public function updateSpeakerBySummit(Summit $summit, PresentationSpeaker $speaker, array $data)
{
return $this->tx_service->transaction(function() use ($summit, $speaker, $data){
$member_id = isset($data['member_id']) ? intval($data['member_id']) : null;
@@ -618,4 +618,58 @@ final class SpeakerService implements ISpeakerService
});
}
/**
* @param array $data
* @param PresentationSpeaker $speaker
* @return PresentationSpeaker
* @throws ValidationException
*/
public function updateSpeaker(PresentationSpeaker $speaker, array $data)
{
return $this->tx_service->transaction(function() use ($speaker, $data){
$member_id = isset($data['member_id']) ? intval($data['member_id']) : null;
if($member_id > 0)
{
$member = $this->member_repository->getById($member_id);
if(is_null($member))
throw new EntityNotFoundException;
$existent_speaker = $this->speaker_repository->getByMember($member);
if($existent_speaker && $existent_speaker->getId() !== $speaker->getId())
throw new ValidationException
(
sprintf
(
"member_id %s already has assigned another speaker id (%s)",
$member_id,
$existent_speaker->getId()
)
);
$speaker->setMember($member);
}
$this->updateSpeakerMainData($speaker, $data);
return $speaker;
});
}
/**
* @param int $speaker_id
* @throws ValidationException
* @throws EntityNotFoundException
* @return void
*/
public function deleteSpeaker($speaker_id)
{
return $this->tx_service->transaction(function() use($speaker_id){
$speaker = $this->speaker_repository->getById($speaker_id);
if(is_null($speaker))
throw new EntityNotFoundException;
$this->speaker_repository->delete($speaker);
});
}
}

View File

@@ -215,7 +215,7 @@ class ApiEndpointsSeeder extends Seeder
],
),
array(
'name' => 'update-speaker',
'name' => 'update-speaker-by-summit',
'route' => '/api/v1/summits/{id}/speakers/{speaker_id}',
'http_method' => 'PUT',
'scopes' => [
@@ -238,6 +238,22 @@ class ApiEndpointsSeeder extends Seeder
sprintf(SummitScopes::WriteSpeakersData, $current_realm),
],
),
array(
'name' => 'update-speaker',
'route' => '/api/v1/speakers/{speaker_id}',
'http_method' => 'PUT',
'scopes' => [
sprintf(SummitScopes::WriteSpeakersData, $current_realm),
],
),
array(
'name' => 'delete-speaker',
'route' => '/api/v1/speakers/{speaker_id}',
'http_method' => 'DELETE',
'scopes' => [
sprintf(SummitScopes::WriteSpeakersData, $current_realm),
],
),
array(
'name' => 'get-all-speakers',
'route' => '/api/v1/speakers',

View File

@@ -91,6 +91,73 @@ final class OAuth2SpeakersApiTest extends ProtectedApiTest
return $speaker;
}
public function testUpdateSpeaker()
{
$speaker = $this->testPostSpeaker();
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$data = [
'title' => 'Developer update!',
'first_name' => 'Sebastian update',
'last_name' => 'Marcet update',
'notes' => 'test update',
'willing_to_present_video' => false,
];
$response = $this->action
(
"PUT",
"OAuth2SummitSpeakersApiController@updateSpeaker",
[
'speaker_id' => $speaker->id
],
[],
[],
[],
$headers,
json_encode($data)
);
$this->assertResponseStatus(201);
$content = $response->getContent();
$speaker = json_decode($content);
$this->assertTrue($speaker->id > 0);
$this->assertTrue($speaker->notes == "test update");
$this->assertTrue($speaker->willing_to_present_video == false);
return $speaker;
}
public function testDeleteSpeaker()
{
$speaker = $this->testPostSpeaker();
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action
(
"DELETE",
"OAuth2SummitSpeakersApiController@deleteSpeaker",
[
'speaker_id' => $speaker->id
],
[],
[],
[],
$headers
);
$this->assertResponseStatus(204);
$content = $response->getContent();
}
public function testPostSpeakerRegCodeBySummit($summit_id = 23)
{
$params = [