diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php index e8014a85..ac2e31e3 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php @@ -514,4 +514,39 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController return $this->error500($ex); } } + + /** + * @param $speaker_from_id + * @param $speaker_to_id + * @return mixed + */ + public function merge($speaker_from_id, $speaker_to_id){ + try { + if(!Request::isJson()) return $this->error403(); + $data = Input::json(); + + $speaker_from = $this->speaker_repository->getById($speaker_from_id); + if (is_null($speaker_from)) return $this->error404(); + + $speaker_to = $this->speaker_repository->getById($speaker_to_id); + if (is_null($speaker_to)) return $this->error404(); + + $this->service->merge($speaker_from, $speaker_to, $data->all()); + + 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); + } + } } \ No newline at end of file diff --git a/app/Http/routes.php b/app/Http/routes.php index 7205d1b0..8e9ac856 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -312,7 +312,7 @@ Route::group([ // speakers Route::group(array('prefix' => 'speakers'), function () { Route::get('', 'OAuth2SummitSpeakersApiController@getAll'); - + Route::put('merge/{speaker_from_id}/{speaker_to_id}', 'OAuth2SummitSpeakersApiController@merge'); Route::group(['prefix' => '{speaker_id}'], function () { Route::get('', 'OAuth2SummitSpeakersApiController@getSpeaker'); Route::post('/photo', [ 'middleware' => 'auth.user:administrators', 'uses' => 'OAuth2SummitSpeakersApiController@addSpeakerPhoto']); diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php index c512ff9e..556ea325 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php @@ -655,7 +655,7 @@ SQL; $summits = $native_query->getResult(); if(count($summits) == 0){ $assistance = $this->getLatestAssistance(); - if(is_null($assistance)) return []; + if(!$assistance) return []; return [ $assistance->getSummit() ]; } return $summits; @@ -881,6 +881,14 @@ SQL; return $this->areas_of_expertise; } + /** + * @param SpeakerExpertise $area_of_expertise + */ + public function addAreaOfExpertise(SpeakerExpertise $area_of_expertise){ + $this->areas_of_expertise->add($area_of_expertise); + $area_of_expertise->setSpeaker($this); + } + /** * @return SpeakerPresentationLink[] */ @@ -889,6 +897,14 @@ SQL; return $this->other_presentation_links; } + /** + * @param SpeakerPresentationLink $link + */ + public function addOtherPresentationLink(SpeakerPresentationLink $link){ + $this->other_presentation_links->add($link); + $link->setSpeaker($this); + } + /** * @return SpeakerTravelPreference[] */ @@ -897,6 +913,14 @@ SQL; return $this->travel_preferences; } + /** + * @param SpeakerTravelPreference $travel_preference + */ + public function addTravelPreference(SpeakerTravelPreference $travel_preference){ + $this->travel_preferences->add($travel_preference); + $travel_preference->setSpeaker($this); + } + /** * @return SpeakerLanguage[] */ @@ -905,6 +929,14 @@ SQL; return $this->languages; } + /** + * @param SpeakerLanguage $language + */ + public function addLanguage(SpeakerLanguage $language){ + $this->languages->add($language); + $language->setSpeaker($this); + } + /** * @return SpeakerOrganizationalRole[] */ @@ -913,6 +945,14 @@ SQL; return $this->organizational_roles; } + public function clearOrganizationalRoles(){ + $this->organizational_roles->clear(); + } + + public function addOrganizationalRole(SpeakerOrganizationalRole $role){ + $this->organizational_roles->add($role); + } + /** * @return SpeakerActiveInvolvement[] */ @@ -921,4 +961,23 @@ SQL; return $this->active_involvements; } + public function clearActiveInvolvements(){ + $this->active_involvements->clear(); + } + + /** + * @param SpeakerActiveInvolvement $active_involvement + */ + public function addActiveInvolvement(SpeakerActiveInvolvement $active_involvement){ + $this->active_involvements->add($active_involvement); + } + + /** + * @param Presentation $presentation + */ + public function addModeratedPresentation(Presentation $presentation){ + $this->moderated_presentations->add($presentation); + $presentation->setModerator($this); + } + } \ No newline at end of file diff --git a/app/Services/Model/ISpeakerService.php b/app/Services/Model/ISpeakerService.php index 3374e5ae..a6b00b16 100644 --- a/app/Services/Model/ISpeakerService.php +++ b/app/Services/Model/ISpeakerService.php @@ -59,4 +59,12 @@ interface ISpeakerService * @return File */ public function addSpeakerPhoto($speaker_id, UploadedFile $file, $max_file_size = 10485760); + + /** + * @param PresentationSpeaker $speaker_from + * @param PresentationSpeaker $speaker_to + * @param array $data + * @return void + */ + public function merge(PresentationSpeaker $speaker_from, PresentationSpeaker $speaker_to, array $data); } \ No newline at end of file diff --git a/app/Services/Model/SpeakerService.php b/app/Services/Model/SpeakerService.php index ccaee086..51e2be75 100644 --- a/app/Services/Model/SpeakerService.php +++ b/app/Services/Model/SpeakerService.php @@ -395,4 +395,135 @@ final class SpeakerService implements ISpeakerService return $photo; }); } + + /** + * @param PresentationSpeaker $speaker_from + * @param PresentationSpeaker $speaker_to + * @param array $data + * @return void + */ + public function merge(PresentationSpeaker $speaker_from, PresentationSpeaker $speaker_to, array $data) + { + return $this->tx_service->transaction(function () use ($speaker_from, $speaker_to, $data) { + // bio + if (!isset($data['bio'])) throw new ValidationException("bio field is required"); + $speaker_id = intval($data['bio']); + $speaker_to->setBio($speaker_id == $speaker_from->getId() ? $speaker_from->getBio() : $speaker_to->getBio()); + + // first_name + if (!isset($data['first_name'])) throw new ValidationException("first_name field is required"); + $speaker_id = intval($data['first_name']); + $speaker_to->setFirstName($speaker_id == $speaker_from->getId() ? $speaker_from->getFirstName() : $speaker_to->getFirstName()); + + // last_name + if (!isset($data['last_name'])) throw new ValidationException("last_name field is required"); + $speaker_id = intval($data['last_name']); + $speaker_to->setLastName($speaker_id == $speaker_from->getId() ? $speaker_from->getLastName() : $speaker_to->getLastName()); + + // title + if (!isset($data['title'])) throw new ValidationException("title field is required"); + $speaker_id = intval($data['title']); + $speaker_to->setTitle($speaker_id == $speaker_from->getId() ? $speaker_from->getTitle() : $speaker_to->getTitle()); + + // irc + if (!isset($data['irc'])) throw new ValidationException("irc field is required"); + $speaker_id = intval($data['irc']); + $speaker_to->setIrcHandle($speaker_id == $speaker_from->getId() ? $speaker_from->getIrcHandle() : $speaker_to->getIrcHandle()); + + // twitter + if (!isset($data['twitter'])) throw new ValidationException("twitter field is required"); + $speaker_id = intval($data['twitter']); + $speaker_to->setTwitterName($speaker_id == $speaker_from->getId() ? $speaker_from->getTwitterName() : $speaker_to->getTwitterName()); + + // pic + try { + if (!isset($data['pic'])) throw new ValidationException("pic field is required"); + $speaker_id = intval($data['pic']); + $speaker_to->setPhoto($speaker_id == $speaker_from->getId() ? $speaker_from->getPhoto() : $speaker_to->getPhoto()); + } + catch (\Exception $ex){ + + } + // registration_request + try { + if (!isset($data['registration_request'])) throw new ValidationException("registration_request field is required"); + $speaker_id = intval($data['registration_request']); + $speaker_to->setRegistrationRequest($speaker_id == $speaker_from->getId() ? $speaker_from->getRegistrationRequest() : $speaker_to->getRegistrationRequest()); + } + catch (\Exception $ex){ + + } + // member + try { + if (!isset($data['member'])) throw new ValidationException("member field is required"); + $speaker_id = intval($data['member']); + $speaker_to->setMember($speaker_id == $speaker_from->getId() ? $speaker_from->getMember() : $speaker_to->getMember()); + } + catch (\Exception $ex){ + + } + // presentations + + foreach ($speaker_from->getAllPresentations(false) as $presentation){ + $speaker_to->addPresentation($presentation); + } + + foreach ($speaker_from->getAllModeratedPresentations(false) as $presentation){ + $speaker_to->addModeratedPresentation($presentation); + } + + // languages + + foreach($speaker_from->getLanguages() as $language){ + $speaker_to->addLanguage($language); + } + + // promo codes + + foreach($speaker_from->getPromoCodes() as $code){ + $speaker_to->addPromoCode($code); + } + + // summit assistances + + foreach($speaker_from->getSummitAssistances() as $assistance){ + $speaker_to->addSummitAssistance($assistance); + } + + // presentation links + + foreach($speaker_from->getOtherPresentationLinks() as $link){ + $speaker_to->addOtherPresentationLink($link); + } + + // travel preferences + + foreach ($speaker_from->getTravelPreferences() as $travel_preference){ + $speaker_to->addTravelPreference($travel_preference); + } + + // areas of expertise + + foreach ($speaker_from->getAreasOfExpertise() as $areas_of_expertise){ + $speaker_to->addAreaOfExpertise($areas_of_expertise); + } + + // roles + + foreach ($speaker_from->getOrganizationalRoles() as $role){ + $speaker_to->addOrganizationalRole($role); + } + $speaker_from->clearOrganizationalRoles(); + + // involvements + + foreach ($speaker_from->getActiveInvolvements() as $involvement){ + $speaker_to->addActiveInvolvement($involvement); + } + + $speaker_from->clearActiveInvolvements(); + + $this->speaker_repository->delete($speaker_from); + }); + } } \ No newline at end of file diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index d5c4b2de..485a9f18 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -199,6 +199,14 @@ class ApiEndpointsSeeder extends Seeder sprintf(SummitScopes::ReadAllSummitData, $current_realm) ], ), + array( + 'name' => 'merge-speakers', + 'route' => '/api/v1/speakers/merge/{speaker_from_id}/{speaker_to_id}', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::WriteSpeakersData, $current_realm), + ], + ), array( 'name' => 'get-speaker-by-summit', 'route' => '/api/v1/summits/{id}/speakers/{speaker_id}', diff --git a/tests/OAuth2SpeakersApiTest.php b/tests/OAuth2SpeakersApiTest.php index 72e253a3..67b324db 100644 --- a/tests/OAuth2SpeakersApiTest.php +++ b/tests/OAuth2SpeakersApiTest.php @@ -65,7 +65,6 @@ class OAuth2SpeakersApiTest extends ProtectedApiTest ]; $data = [ - 'title' => 'Developer!', 'first_name' => 'Sebastian', 'last_name' => 'Marcet', @@ -315,4 +314,45 @@ class OAuth2SpeakersApiTest extends ProtectedApiTest $this->assertTrue(!is_null($speaker)); } + public function testMergeSpeakers(){ + + $params = [ + 'speaker_from_id' => 3643, + 'speaker_to_id' => 1 + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $data = [ + 'title' => 1, + 'bio' => 1, + 'first_name' => 1, + 'last_name' => 1, + 'irc' => 1, + 'twitter' => 1, + 'pic' => 1, + 'registration_request' => 1, + 'member' => 1, + ]; + + $response = $this->action( + "PUT", + "OAuth2SummitSpeakersApiController@merge", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(204); + $speaker = json_decode($content); + $this->assertTrue(!is_null($speaker)); + } + } \ No newline at end of file