diff --git a/app/EntityPersisters/AdminSummitEventActionSyncWorkRequestPersister.php b/app/EntityPersisters/AdminSummitEventActionSyncWorkRequestPersister.php index 25355cdc..d3c32bdd 100644 --- a/app/EntityPersisters/AdminSummitEventActionSyncWorkRequestPersister.php +++ b/app/EntityPersisters/AdminSummitEventActionSyncWorkRequestPersister.php @@ -1,6 +1,4 @@ $request->getType(), + 'CreatedByID' => $request->getCreatedById(), + 'LocationID' => $request->getLocationId(), + ]; + + $types = [ + 'Type' => 'string', + 'CreatedByID' => 'integer', + 'LocationID' => 'integer', + ]; + + self::insert($sql, $bindings, $types); + } +} \ No newline at end of file diff --git a/app/Events/LocationAction.php b/app/Events/LocationAction.php new file mode 100644 index 00000000..22491571 --- /dev/null +++ b/app/Events/LocationAction.php @@ -0,0 +1,95 @@ +summit_id = $summit_id; + $this->location_id = $location_id; + $this->location_class_name = $location_class_name; + $this->related_event_ids = $related_event_ids; + } + + /** + * @return int + */ + public function getLocationId() + { + return $this->location_id; + } + + /** + * @return int[] + */ + public function getRelatedEventIds() + { + return $this->related_event_ids; + } + + /** + * @return string + */ + public function getLocationClassName() + { + return $this->location_class_name; + } + + /** + * @return int + */ + public function getSummitId() + { + return $this->summit_id; + } +} \ No newline at end of file diff --git a/app/Events/LocationDeleted.php b/app/Events/LocationDeleted.php new file mode 100644 index 00000000..f512720d --- /dev/null +++ b/app/Events/LocationDeleted.php @@ -0,0 +1,22 @@ +summit_id = $summit_id; + $this->track_id = $track_id; + } + + /** + * @return int + */ + public function getTrackId() + { + return $this->track_id; + } + + /** + * @return int + */ + public function getSummitId() + { + return $this->summit_id; + } +} \ No newline at end of file diff --git a/app/Events/TrackDeleted.php b/app/Events/TrackDeleted.php new file mode 100644 index 00000000..8c94d935 --- /dev/null +++ b/app/Events/TrackDeleted.php @@ -0,0 +1,22 @@ +track = $track; - } - - /** - * @return PresentationCategory - */ - public function getTrack() - { - return $this->track; - } } \ No newline at end of file diff --git a/app/Factories/CalendarAdminActionSyncWorkRequest/AdminSummitLocationActionSyncWorkRequestFactory.php b/app/Factories/CalendarAdminActionSyncWorkRequest/AdminSummitLocationActionSyncWorkRequestFactory.php new file mode 100644 index 00000000..a718080c --- /dev/null +++ b/app/Factories/CalendarAdminActionSyncWorkRequest/AdminSummitLocationActionSyncWorkRequestFactory.php @@ -0,0 +1,49 @@ +getCurrentUserExternalId(); + if(is_null($owner_id)) $owner_id = 0; + + $request = new AdminSummitLocationActionSyncWorkRequest(); + $location = $location_repository->getById($event->getLocationId()); + $request->setLocationId($location); + + $request->Type = $type; + if($owner_id > 0){ + $member = $member_repository->getById($owner_id); + $request->setCreatedBy($member); + } + + return $request; + } +} \ No newline at end of file diff --git a/app/Factories/CalendarAdminActionSyncWorkRequest/SummitEventDeletedCalendarSyncWorkRequestFactory.php b/app/Factories/CalendarAdminActionSyncWorkRequest/SummitEventDeletedCalendarSyncWorkRequestFactory.php index 20e012c9..6ab38624 100644 --- a/app/Factories/CalendarAdminActionSyncWorkRequest/SummitEventDeletedCalendarSyncWorkRequestFactory.php +++ b/app/Factories/CalendarAdminActionSyncWorkRequest/SummitEventDeletedCalendarSyncWorkRequestFactory.php @@ -13,6 +13,8 @@ **/ use App\Events\SummitEventDeleted; +use models\main\IMemberRepository; +use models\oauth2\IResourceServerContext; use models\summit\CalendarSync\WorkQueue\AbstractCalendarSyncWorkRequest; use models\summit\CalendarSync\WorkQueue\AdminSummitEventActionSyncWorkRequest; use Illuminate\Support\Facades\App; @@ -30,8 +32,8 @@ final class SummitEventDeletedCalendarSyncWorkRequestFactory public static function build(SummitEventDeleted $event){ $args = $event->getArgs(); $params = $args->getParams(); - $resource_server_context = App::make(\models\oauth2\IResourceServerContext::class); - $member_repository = App::make(\models\main\IMemberRepository::class); + $resource_server_context = App::make(IResourceServerContext::class); + $member_repository = App::make(IMemberRepository::class); $owner_id = $resource_server_context->getCurrentUserExternalId(); if($owner_id > 0){ $member = $member_repository->getById($owner_id); diff --git a/app/Factories/EntityEvents/LocationActionEntityEventFactory.php b/app/Factories/EntityEvents/LocationActionEntityEventFactory.php new file mode 100644 index 00000000..e24acc1f --- /dev/null +++ b/app/Factories/EntityEvents/LocationActionEntityEventFactory.php @@ -0,0 +1,55 @@ +getById($event->getSummitId()); + $owner_id = $resource_server_context->getCurrentUserExternalId(); + + if (is_null($owner_id)) $owner_id = 0; + + $entity_event = new SummitEntityEvent; + $entity_event->setEntityClassName($event->getLocationClassName()); + $entity_event->setEntityId($event->getLocationId()); + $entity_event->setType($type); + + if ($owner_id > 0) { + $member = $member_repository->getById($owner_id); + $entity_event->setOwner($member); + } + + $entity_event->setSummit($summit); + $entity_event->setMetadata(''); + return $entity_event; + } +} \ No newline at end of file diff --git a/app/Factories/EntityEvents/TrackActionEntityEventFactory.php b/app/Factories/EntityEvents/TrackActionEntityEventFactory.php new file mode 100644 index 00000000..5556be2d --- /dev/null +++ b/app/Factories/EntityEvents/TrackActionEntityEventFactory.php @@ -0,0 +1,59 @@ +getById($event->getSummitId()); + + $owner_id = $resource_server_context->getCurrentUserExternalId(); + if (is_null($owner_id)) $owner_id = 0; + + + $entity_event = new SummitEntityEvent; + $entity_event->setEntityClassName(PresentationCategory::class); + $entity_event->setEntityId($event->getTrackId()); + $entity_event->setType($type); + + if ($owner_id > 0) { + $member = $member_repository->getById($owner_id); + $entity_event->setOwner($member); + } + + $entity_event->setSummit($summit); + $entity_event->setMetadata(''); + + return $entity_event; + } +} \ No newline at end of file diff --git a/app/Factories/EntityEvents/TrackUpdatedEntityEventFactory.php b/app/Factories/EntityEvents/TrackUpdatedEntityEventFactory.php deleted file mode 100644 index 08d3328c..00000000 --- a/app/Factories/EntityEvents/TrackUpdatedEntityEventFactory.php +++ /dev/null @@ -1,55 +0,0 @@ -getCurrentUserExternalId(); - if(is_null($owner_id)) $owner_id = 0; - - foreach($event->getTrack()->getRelatedPublishedSummitEvents() as $summit_event) { - - $entity_event = new SummitEntityEvent; - $entity_event->setEntityClassName($summit_event->getClassName()); - $entity_event->setEntityId($summit_event->getId()); - $entity_event->setType('UPDATE'); - - if ($owner_id > 0) { - $member = $member_repository->getById($owner_id); - $entity_event->setOwner($member); - } - - $entity_event->setSummit($summit_event->getSummit()); - $entity_event->setMetadata(''); - - $list[] = $entity_event; - } - - return $list; - } -} \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php index 0f0f99fa..b4ad2cc9 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php @@ -581,6 +581,16 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController ); } + if(!in_array($payload["class_name"], SummitLocationConstants::$valid_class_names) ){ + throw new ValidationException( + sprintf + ( + "class_name has an invalid value ( valid values are %s", + implode(", ", SummitLocationConstants::$valid_class_names) + ) + ); + } + $location = $this->location_service->addLocation($summit, $payload); return $this->created(SerializerRegistry::getInstance()->getSerializer($location)->serialize()); @@ -803,6 +813,16 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController ); } + if(!in_array($payload["class_name"], SummitLocationConstants::$valid_class_names) ){ + throw new ValidationException( + sprintf + ( + "class_name has an invalid value ( valid values are %s", + implode(", ", SummitLocationConstants::$valid_class_names) + ) + ); + } + $location = $this->location_service->updateLocation($summit, $location_id, $payload); return $this->updated(SerializerRegistry::getInstance()->getSerializer($location)->serialize()); @@ -1005,4 +1025,38 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController return $this->error500($ex); } } + + /** + * Delete Location Endpoints + */ + + /** + * @param $summit_id + * @param $location_id + * @return mixed + */ + public function deleteLocation($summit_id, $location_id){ + try { + + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $this->location_service->deleteLocation($summit, $location_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); + } + } } \ No newline at end of file diff --git a/app/Http/routes.php b/app/Http/routes.php index 788aab39..3d3f66b8 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -320,6 +320,7 @@ Route::group([ Route::group(['prefix' => '{location_id}'], function () { Route::get('', 'OAuth2SummitLocationsApiController@getLocation'); Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@updateLocation']); + Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@deleteLocation']); Route::get('/events/published','OAuth2SummitLocationsApiController@getLocationPublishedEvents')->where('location_id', 'tbd|[0-9]+'); Route::get('/events','OAuth2SummitLocationsApiController@getLocationEvents')->where('location_id', 'tbd|[0-9]+'); }); diff --git a/app/Models/Foundation/Summit/CalendarSync/WorkQueue/AdminSummitLocationActionSyncWorkRequest.php b/app/Models/Foundation/Summit/CalendarSync/WorkQueue/AdminSummitLocationActionSyncWorkRequest.php index eab1e4d5..289b78ff 100644 --- a/app/Models/Foundation/Summit/CalendarSync/WorkQueue/AdminSummitLocationActionSyncWorkRequest.php +++ b/app/Models/Foundation/Summit/CalendarSync/WorkQueue/AdminSummitLocationActionSyncWorkRequest.php @@ -38,6 +38,19 @@ extends AdminScheduleSummitActionSyncWorkRequest return $this->location; } + /** + * @return int + */ + public function getLocationId() + { + try{ + return is_null($this->location) ? 0 : $this->location->getId(); + } + catch (\Exception $ex){ + return 0; + } + } + /** * @param SummitAbstractLocation $location */ diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.php index 3e4cb947..3bd5777c 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.php @@ -314,4 +314,27 @@ SQL; return $res; } + + /** + * @return int[] + */ + public function getRelatedPublishedSummitEventsIds(){ + $query = <<getEM()->createQuery($query); + + $native_query->setParameter("summit", $this->summit); + $native_query->setParameter("track", $this); + + $res = $native_query->getResult(); + + return $res; + } } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Events/SummitEventType.php b/app/Models/Foundation/Summit/Events/SummitEventType.php index 9fa8f26c..9ff318fe 100644 --- a/app/Models/Foundation/Summit/Events/SummitEventType.php +++ b/app/Models/Foundation/Summit/Events/SummitEventType.php @@ -235,4 +235,50 @@ class SummitEventType extends SilverstripeBaseModel $this->is_private = $is_private; } + /** + * @return SummitEvent[] + */ + public function getRelatedPublishedSummitEvents(){ + $query = <<getEM()->createQuery($query); + + $native_query->setParameter("summit", $this->summit); + $native_query->setParameter("type", $this); + + $res = $native_query->getResult(); + + return $res; + } + + /** + * @return int[] + */ + public function getRelatedPublishedSummitEventsIds(){ + $query = <<getEM()->createQuery($query); + + $native_query->setParameter("summit", $this->summit); + $native_query->setParameter("type", $this); + + $res = $native_query->getResult(); + + return $res; + } + } diff --git a/app/Models/Foundation/Summit/Factories/PresentationCategoryFactory.php b/app/Models/Foundation/Summit/Factories/PresentationCategoryFactory.php index 1031a1c8..29a89f10 100644 --- a/app/Models/Foundation/Summit/Factories/PresentationCategoryFactory.php +++ b/app/Models/Foundation/Summit/Factories/PresentationCategoryFactory.php @@ -27,7 +27,6 @@ final class PresentationCategoryFactory public static function build(Summit $summit, array $data){ $track = new PresentationCategory(); self::populate($track, $data); - $summit->addPresentationCategory($track); return $track; } diff --git a/app/Models/Foundation/Summit/Locations/SummitGeoLocatedLocation.php b/app/Models/Foundation/Summit/Locations/SummitGeoLocatedLocation.php index 85778dfa..2a8832ea 100644 --- a/app/Models/Foundation/Summit/Locations/SummitGeoLocatedLocation.php +++ b/app/Models/Foundation/Summit/Locations/SummitGeoLocatedLocation.php @@ -11,12 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use Doctrine\DBAL\Query\Expression\ExpressionBuilder; use Doctrine\ORM\Mapping AS ORM; - /** * @ORM\Entity * @ORM\Table(name="SummitGeoLocatedLocation") @@ -99,8 +97,8 @@ class SummitGeoLocatedLocation extends SummitAbstractLocation protected $images; public static $metadata = [ - 'address1' => 'string', - 'address2' => 'string', + 'address_1' => 'string', + 'address_2' => 'string', 'zip_code' => 'string', 'city' => 'string', 'state' => 'string', diff --git a/app/Models/Foundation/Summit/Summit.php b/app/Models/Foundation/Summit/Summit.php index d44f43b1..8d172cbd 100644 --- a/app/Models/Foundation/Summit/Summit.php +++ b/app/Models/Foundation/Summit/Summit.php @@ -1707,4 +1707,38 @@ SQL; } } + + /** + * @param SummitAbstractLocation $location + * @return int[] + */ + public function getScheduleEventsIdsPerLocation(SummitAbstractLocation $location){ + $query = <<getEM()->createQuery($query); + + $native_query->setParameter("summit", $this); + $native_query->setParameter("location", $location); + + $res = $native_query->getResult(); + + return $res; + } + + /** + * @param SummitAbstractLocation $location + * @return $this + */ + public function removeLocation(SummitAbstractLocation $location){ + $this->locations->removeElement($location); + $location->setSummit(null); + return $this; + } } \ No newline at end of file diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index f2aed2db..ef0661e5 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -12,11 +12,14 @@ * limitations under the License. **/ use App\EntityPersisters\AdminSummitEventActionSyncWorkRequestPersister; +use App\EntityPersisters\AdminSummitLocationActionSyncWorkRequestPersister; use App\EntityPersisters\AssetSyncRequestPersister; use App\EntityPersisters\EntityEventPersister; use App\Factories\AssetsSyncRequest\FileCreatedAssetSyncRequestFactory; +use App\Factories\CalendarAdminActionSyncWorkRequest\AdminSummitLocationActionSyncWorkRequestFactory; use App\Factories\CalendarAdminActionSyncWorkRequest\SummitEventDeletedCalendarSyncWorkRequestFactory; use App\Factories\CalendarAdminActionSyncWorkRequest\SummitEventUpdatedCalendarSyncWorkRequestFactory; +use App\Factories\EntityEvents\LocationActionEntityEventFactory; use App\Factories\EntityEvents\MyFavoritesAddEntityEventFactory; use App\Factories\EntityEvents\MyFavoritesRemoveEntityEventFactory; use App\Factories\EntityEvents\MyScheduleAddEntityEventFactory; @@ -30,7 +33,7 @@ use App\Factories\EntityEvents\PresentationSpeakerUpdatedEntityEventFactory; use App\Factories\EntityEvents\SummitEventCreatedEntityEventFactory; use App\Factories\EntityEvents\SummitEventDeletedEntityEventFactory; use App\Factories\EntityEvents\SummitEventUpdatedEntityEventFactory; -use App\Factories\EntityEvents\TrackUpdatedEntityEventFactory; +use App\Factories\EntityEvents\TrackActionEntityEventFactory; use App\Services\Utils\SCPFileUploader; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Event; @@ -135,9 +138,52 @@ final class EventServiceProvider extends ServiceProvider EntityEventPersister::persist_list(PresentationSpeakerDeletedEntityEventFactory::build($event)); }); + // tracks + + Event::listen(\App\Events\TrackInserted::class, function($event) + { + EntityEventPersister::persist(TrackActionEntityEventFactory::build($event, 'INSERT')); + }); + Event::listen(\App\Events\TrackUpdated::class, function($event) { - EntityEventPersister::persist_list(TrackUpdatedEntityEventFactory::build($event)); + EntityEventPersister::persist(TrackActionEntityEventFactory::build($event, 'UPDATE')); + }); + + Event::listen(\App\Events\TrackDeleted::class, function($event) + { + EntityEventPersister::persist(TrackActionEntityEventFactory::build($event, 'DELETE')); + }); + + // locations events + + Event::listen(\App\Events\LocationInserted::class, function($event) + { + EntityEventPersister::persist(LocationActionEntityEventFactory::build($event, 'INSERT')); + }); + + Event::listen(\App\Events\LocationUpdated::class, function($event) + { + EntityEventPersister::persist(LocationActionEntityEventFactory::build($event, 'UPDATE')); + $published_events = $event->getRelatedEventIds(); + if(count($published_events) > 0){ + AdminSummitLocationActionSyncWorkRequestPersister::persist + ( + AdminSummitLocationActionSyncWorkRequestFactory::build($event, 'UPDATE') + ); + } + }); + + Event::listen(\App\Events\LocationDeleted::class, function($event) + { + EntityEventPersister::persist(LocationActionEntityEventFactory::build($event, 'DELETE')); + $published_events = $event->getRelatedEventIds(); + if(count($published_events) > 0){ + AdminSummitLocationActionSyncWorkRequestPersister::persist + ( + AdminSummitLocationActionSyncWorkRequestFactory::build($event, 'REMOVE') + ); + } }); } diff --git a/app/Services/Model/ILocationService.php b/app/Services/Model/ILocationService.php index 4f3fffa0..456cb2a3 100644 --- a/app/Services/Model/ILocationService.php +++ b/app/Services/Model/ILocationService.php @@ -40,4 +40,13 @@ interface ILocationService * @throws ValidationException */ public function updateLocation(Summit $summit, $location_id, array $data); + + /** + * @param Summit $summit + * @param int $location_id + * @return SummitAbstractLocation + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function deleteLocation(Summit $summit, $location_id); } \ No newline at end of file diff --git a/app/Services/Model/LocationService.php b/app/Services/Model/LocationService.php index 6c3569f7..fbf936cd 100644 --- a/app/Services/Model/LocationService.php +++ b/app/Services/Model/LocationService.php @@ -1,4 +1,5 @@ location_repository = $location_repository; - $this->geo_coding_api = $geo_coding_api; - $this->tx_service = $tx_service; + $this->geo_coding_api = $geo_coding_api; + $this->tx_service = $tx_service; } /** @@ -74,11 +77,11 @@ final class LocationService implements ILocationService */ public function addLocation(Summit $summit, array $data) { - return $this->tx_service->transaction(function() use($summit, $data){ + $location = $this->tx_service->transaction(function () use ($summit, $data) { - $old_location = $summit->getLocationByName(trim($data['name'])); + $old_location = $summit->getLocationByName(trim($data['name'])); - if(!is_null($old_location)){ + if (!is_null($old_location)) { throw new ValidationException ( trans @@ -93,7 +96,7 @@ final class LocationService implements ILocationService $location = SummitLocationFactory::build($data); - if(is_null($location)){ + if (is_null($location)) { throw new ValidationException ( trans @@ -103,35 +106,46 @@ final class LocationService implements ILocationService ); } - if($location instanceof SummitGeoLocatedLocation) { + if ($location instanceof SummitGeoLocatedLocation) { try { $geo_location_strategy = GeoLocationStrategyFactory::build($location); $geo_location_strategy->doGeoLocation($location, $this->geo_coding_api); - } - catch (GeoCodingApiException $ex1){ + } catch (GeoCodingApiException $ex1) { Log::warning($ex1->getMessage()); $validation_msg = trans('validation_errors.LocationService.addLocation.geoCodingGenericError'); - switch ($ex1->getStatus()){ + switch ($ex1->getStatus()) { case IGeoCodingAPI::ResponseStatusZeroResults: { $validation_msg = trans('validation_errors.LocationService.addLocation.InvalidAddressOrCoordinates'); } - break; + break; case IGeoCodingAPI::ResponseStatusOverQueryLimit: { $validation_msg = trans('validation_errors.LocationService.addLocation.OverQuotaLimit'); } - break; + break; } throw new ValidationException($validation_msg); - } - catch(\Exception $ex){ + } catch (\Exception $ex) { Log::warning($ex->getMessage()); throw $ex; } } $summit->addLocation($location); + return $location; - }); + }); + + Event::fire + ( + new LocationInserted + ( + $location->getSummitId(), + $location->getId(), + $location->getClassName() + ) + ); + + return $location; } /** @@ -144,9 +158,9 @@ final class LocationService implements ILocationService */ public function updateLocation(Summit $summit, $location_id, array $data) { - return $this->tx_service->transaction(function() use($summit, $location_id, $data){ + return $this->tx_service->transaction(function () use ($summit, $location_id, $data) { - if(isset($data['name'])) { + if (isset($data['name'])) { $old_location = $summit->getLocationByName(trim($data['name'])); if (!is_null($old_location) && $old_location->getId() != $location_id) { @@ -164,14 +178,29 @@ final class LocationService implements ILocationService } $location = $summit->getLocation($location_id); - if(is_null($location)){ + + if (is_null($location)) { throw new EntityNotFoundException( trans ( 'validation_errors.LocationService.updateLocation.LocationNotFoundOnSummit', + [ + 'summit_id' => $summit->getId(), + 'location_id' => $location_id, + ] + ) + ); + } + + if ($location->getClassName() != $data['class_name']) { + throw new EntityNotFoundException( + trans + ( + 'validation_errors.LocationService.updateLocation.ClassNameMissMatch', [ 'summit_id' => $summit->getId(), 'location_id' => $location_id, + 'class_name' => $data['class_name'] ] ) ); @@ -179,15 +208,14 @@ final class LocationService implements ILocationService $location = SummitLocationFactory::populate($location, $data); - if($location instanceof SummitGeoLocatedLocation && (isset($data['address_1']) || isset($data['lat']))) { + if ($location instanceof SummitGeoLocatedLocation && $this->hasGeoLocationData2Update($data)) { try { $geo_location_strategy = GeoLocationStrategyFactory::build($location); $geo_location_strategy->doGeoLocation($location, $this->geo_coding_api); - } - catch (GeoCodingApiException $ex1){ + } catch (GeoCodingApiException $ex1) { Log::warning($ex1->getMessage()); $validation_msg = trans('validation_errors.LocationService.addLocation.geoCodingGenericError'); - switch ($ex1->getStatus()){ + switch ($ex1->getStatus()) { case IGeoCodingAPI::ResponseStatusZeroResults: { $validation_msg = trans('validation_errors.LocationService.addLocation.InvalidAddressOrCoordinates'); } @@ -198,19 +226,75 @@ final class LocationService implements ILocationService break; } throw new ValidationException($validation_msg); - } - catch(\Exception $ex){ + } catch (\Exception $ex) { Log::warning($ex->getMessage()); throw $ex; } } - if(isset($data['order']) && intval($data['order']) != $location->getOrder()){ + if (isset($data['order']) && intval($data['order']) != $location->getOrder()) { // request to update order $summit->recalculateLocationOrder($location, intval($data['order'])); } + Event::fire + ( + new LocationUpdated + ( + $location->getSummitId(), + $location->getId(), + $location->getClassName(), + $summit->getScheduleEventsIdsPerLocation($location) + ) + ); + return $location; }); } + + /** + * @param array $data + * @return bool + */ + private function hasGeoLocationData2Update(array $data){ + return isset($data['address_1']) || isset($data['lat']); + } + + /** + * @param Summit $summit + * @param int $location_id + * @return SummitAbstractLocation + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function deleteLocation(Summit $summit, $location_id) + { + return $this->tx_service->transaction(function () use ($summit, $location_id) { + + $location = $summit->getLocation($location_id); + + if (is_null($location)) { + throw new EntityNotFoundException( + trans + ( + 'validation_errors.LocationService.deleteLocation.LocationNotFoundOnSummit', + [ + 'summit_id' => $summit->getId(), + 'location_id' => $location_id, + ] + ) + ); + } + + Event::fire(new LocationDeleted + ( + $location->getSummitId(), + $location->getId(), + $location->getClassName(), + $summit->getScheduleEventsIdsPerLocation($location)) + ); + + $summit->removeLocation($location); + }); + } } \ No newline at end of file diff --git a/app/Services/Model/SummitEventTypeService.php b/app/Services/Model/SummitEventTypeService.php index 16bdb86f..a1b0051d 100644 --- a/app/Services/Model/SummitEventTypeService.php +++ b/app/Services/Model/SummitEventTypeService.php @@ -145,6 +145,15 @@ final class SummitEventTypeService implements ISummitEventTypeService sprintf("event type id %s is a default one and is not allowed to be deleted", $event_type_id) ); + $summit_events = $event_type->getRelatedPublishedSummitEventsIds(); + + if(count($summit_events) > 0){ + throw new ValidationException + ( + sprintf("event type id %s could not be deleted bc its assigned to published events on summit id %s", $event_type_id, $summit->getId()) + ); + } + $summit->removeEventType($event_type); }); diff --git a/app/Services/Model/SummitTrackService.php b/app/Services/Model/SummitTrackService.php index 2a4c5711..1efe8829 100644 --- a/app/Services/Model/SummitTrackService.php +++ b/app/Services/Model/SummitTrackService.php @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Events\TrackDeleted; +use App\Events\TrackInserted; use App\Events\TrackUpdated; use App\Models\Foundation\Summit\Factories\PresentationCategoryFactory; use App\Models\Foundation\Summit\Repositories\ISummitTrackRepository; @@ -21,7 +23,6 @@ use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; use models\summit\PresentationCategory; use models\summit\Summit; - /** * Class SummitTrackService * @package App\Services\Model @@ -58,7 +59,7 @@ final class SummitTrackService implements ISummitTrackService */ public function addTrack(Summit $summit, array $data) { - return $this->tx_service->transaction(function () use ($summit, $data) { + $track = $this->tx_service->transaction(function () use ($summit, $data) { if (!empty($data['code'])) { $former_track = $summit->getPresentationCategoryByCode(trim($data['code'])); @@ -72,9 +73,13 @@ final class SummitTrackService implements ISummitTrackService $track = PresentationCategoryFactory::build($summit, $data); - return $track; + $summit->addPresentationCategory($track); }); + + Event::fire(new TrackInserted($track->getSummitId(), $track->getId())); + + return $track; } /** @@ -109,9 +114,12 @@ final class SummitTrackService implements ISummitTrackService throw new ValidationException(sprintf("track id %s already has title %s assigned on summit id %s", $former_track->getId(), $data['title'], $summit->getId())); } - return PresentationCategoryFactory::populate($track, $data); - Event::fire(new TrackUpdated($track)); + $track = PresentationCategoryFactory::populate($track, $data); + + Event::fire(new TrackUpdated($track->getSummitId(), $track->getId())); + + return $track; }); } @@ -135,7 +143,7 @@ final class SummitTrackService implements ISummitTrackService sprintf("track id %s does not belong to summit id %s", $track_id, $summit->getId()) ); - $summit_events = $track->getRelatedPublishedSummitEvents(); + $summit_events = $track->getRelatedPublishedSummitEventsIds(); if(count($summit_events) > 0){ throw new ValidationException @@ -144,6 +152,8 @@ final class SummitTrackService implements ISummitTrackService ); } + Event::fire(new TrackDeleted($track->getSummitId(), $track->getId())); + $this->repository->delete($track); }); } diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index 25c48912..7f19eaef 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -491,6 +491,15 @@ class ApiEndpointsSeeder extends Seeder sprintf(SummitScopes::WriteLocationsData, $current_realm) ], ], + [ + 'name' => 'delete-location', + 'route' => '/api/v1/summits/{id}/locations/{location_id}', + 'http_method' => 'DELETE', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm), + sprintf(SummitScopes::WriteLocationsData, $current_realm) + ], + ], [ 'name' => 'get-locations-metadata', 'route' => '/api/v1/summits/{id}/locations/metadata', diff --git a/resources/lang/en/validation_errors.php b/resources/lang/en/validation_errors.php index 588096da..a8fc13fb 100644 --- a/resources/lang/en/validation_errors.php +++ b/resources/lang/en/validation_errors.php @@ -33,4 +33,5 @@ return [ 'LocationService.addLocation.geoCodingGenericError' => 'geocode api generic error', 'LocationService.updateLocation.LocationNameAlreadyExists' => 'there is already another location with same name for summit :summit_id', 'LocationService.updateLocation.LocationNotFoundOnSummit' => 'location :location_id not found on summit :summit_id', + 'LocationService.updateLocation.ClassNameMissMatch' => 'location :location_id on summit :summit_id does not belongs to class name :class_name', ]; \ No newline at end of file diff --git a/tests/OAuth2SummitLocationsApiTest.php b/tests/OAuth2SummitLocationsApiTest.php index 980ecb97..f6b213ab 100644 --- a/tests/OAuth2SummitLocationsApiTest.php +++ b/tests/OAuth2SummitLocationsApiTest.php @@ -620,4 +620,75 @@ final class OAuth2SummitLocationsApiTest extends ProtectedApiTest $this->assertTrue($location->order == $new_order); return $location; } + + /** + * @param int $summit_id + * @return mixed + */ + public function testUpdateExistentLocation($summit_id = 23){ + + $params = [ + 'id' => $summit_id, + 'location_id' => 292 + ]; + + $data = [ + 'class_name' => \models\summit\SummitVenue::ClassName, + 'name' => 'Sydney Convention and Exhibition Centre Update!' + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "PUT", + "OAuth2SummitLocationsApiController@updateLocation", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $location = json_decode($content); + $this->assertTrue(!is_null($location)); + $this->assertTrue($location->order == $new_order); + return $location; + } + + /** + * @param int $summit_id + */ + public function testDeleteNewlyCreatedHotel($summit_id = 24){ + + $hotel = $this->testAddLocationHotelAddress($summit_id); + $params = [ + 'id' => $summit_id, + 'location_id' => $hotel->id + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "DELETE", + "OAuth2SummitLocationsApiController@deleteLocation", + $params, + [], + [], + [], + $headers + ); + + $content = $response->getContent(); + $this->assertResponseStatus(204); + } + } \ No newline at end of file