Added new endpoint to delete location by summit

DELETE /api/v1/summits/{id}/locations/{location_id}

Change-Id: I7a5eaa7d23d1e2c5057e04eff04073c01983c466
This commit is contained in:
Sebastian Marcet 2018-03-02 14:42:46 -03:00
parent a4e3d7128e
commit e3ea12ff97
31 changed files with 936 additions and 126 deletions

View File

@ -1,6 +1,4 @@
<?php namespace App\EntityPersisters;
use models\summit\CalendarSync\WorkQueue\AdminSummitEventActionSyncWorkRequest;
/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
@ -13,7 +11,12 @@ use models\summit\CalendarSync\WorkQueue\AdminSummitEventActionSyncWorkRequest;
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\summit\CalendarSync\WorkQueue\AdminSummitEventActionSyncWorkRequest;
/**
* Class AdminSummitEventActionSyncWorkRequestPersister
* @package App\EntityPersisters
*/
class AdminSummitEventActionSyncWorkRequestPersister extends BasePersister
{
public static function persist(AdminSummitEventActionSyncWorkRequest $request){

View File

@ -0,0 +1,51 @@
<?php namespace App\EntityPersisters;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\summit\CalendarSync\WorkQueue\AdminSummitLocationActionSyncWorkRequest;
/**
* Class AdminSummitLocationActionSyncWorkRequestPersister
* @package App\EntityPersisters
*/
final class AdminSummitLocationActionSyncWorkRequestPersister extends BasePersister
{
/**
* @param AdminSummitLocationActionSyncWorkRequest $request
*/
public static function persist(AdminSummitLocationActionSyncWorkRequest $request){
$sql = <<<SQL
INSERT INTO AbstractCalendarSyncWorkRequest
(`Type`, IsProcessed, ProcessedDate, Created, LastEdited, ClassName)
VALUES (:Type, 0, NULL, NOW(), NOW(), 'AdminSummitLocationActionSyncWorkRequest');
INSERT INTO AdminScheduleSummitActionSyncWorkRequest (ID, CreatedByID) VALUES (LAST_INSERT_ID(), :CreatedByID)
INSERT INTO AdminSummitLocationActionSyncWorkRequest (ID, LocationID) VALUES (LAST_INSERT_ID(), :LocationID);
SQL;
$bindings = [
'Type' => $request->getType(),
'CreatedByID' => $request->getCreatedById(),
'LocationID' => $request->getLocationId(),
];
$types = [
'Type' => 'string',
'CreatedByID' => 'integer',
'LocationID' => 'integer',
];
self::insert($sql, $bindings, $types);
}
}

View File

@ -0,0 +1,95 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Illuminate\Queue\SerializesModels;
/**
* Class LocationAction
* @package App\Events
*/
class LocationAction
{
use SerializesModels;
/**
* @var int
*/
private $location_id;
/**
* @var int
*/
private $summit_id;
/**
* @var string
*/
private $location_class_name;
/**
* @var int[]
*/
private $related_event_ids;
/**
* LocationUpdated constructor.
* @param int $summit_id
* @param int $location_id
* @param string $location_class_name
* @param int[] $related_event_ids
*/
public function __construct
(
$summit_id,
$location_id,
$location_class_name,
array $related_event_ids = []
)
{
$this->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;
}
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class LocationDeleted
* @package App\Events
*/
final class LocationDeleted extends LocationAction
{
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class LocationInserted
* @package App\Events
*/
final class LocationInserted extends LocationAction
{
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class LocationUpdated
* @package App\Events
*/
final class LocationUpdated extends LocationAction
{
}

View File

@ -0,0 +1,59 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Illuminate\Queue\SerializesModels;
/**
* Class TrackAction
* @package App\Events
*/
class TrackAction
{
use SerializesModels;
/**
* @var int
*/
private $track_id;
/**
* @var int
*/
private $summit_id;
/**
* TrackAction constructor.
* @param int $summit_id
* @param int $track_id
*/
public function __construct($summit_id, $track_id)
{
$this->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;
}
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class TrackDeleted
* @package App\Events
*/
final class TrackDeleted extends TrackAction
{
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class TrackInserted
* @package App\Events
*/
final class TrackInserted extends TrackAction
{
}

View File

@ -11,35 +11,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Illuminate\Queue\SerializesModels;
use models\summit\PresentationCategory;
/**
* Class TrackUpdated
* @package App\Events
*/
final class TrackUpdated extends Event
{
use SerializesModels;
final class TrackUpdated extends TrackAction {
/**
* @var PresentationCategory
*/
private $track;
/**
* TrackUpdated constructor.
* @param PresentationCategory $track
*/
public function __construct(PresentationCategory $track)
{
$this->track = $track;
}
/**
* @return PresentationCategory
*/
public function getTrack()
{
return $this->track;
}
}

View File

@ -0,0 +1,49 @@
<?php namespace App\Factories\CalendarAdminActionSyncWorkRequest;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Events\LocationAction;
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
use Illuminate\Support\Facades\App;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\CalendarSync\WorkQueue\AdminSummitLocationActionSyncWorkRequest;
/**
* Class AdminSummitLocationActionSyncWorkRequestFactory
* @package App\Factories\CalendarAdminActionSyncWorkRequest
*/
final class AdminSummitLocationActionSyncWorkRequestFactory
{
/**
* @param LocationAction $event
* @return AdminSummitLocationActionSyncWorkRequest
*/
public static function build(LocationAction $event, $type){
$resource_server_context = App::make(IResourceServerContext::class);
$member_repository = App::make(IMemberRepository::class);
$location_repository = App::make(ISummitLocationRepository::class);
$owner_id = $resource_server_context->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;
}
}

View File

@ -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);

View File

@ -0,0 +1,55 @@
<?php namespace App\Factories\EntityEvents;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Events\LocationAction;
use Illuminate\Support\Facades\App;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\ISummitRepository;
use models\summit\SummitEntityEvent;
/**
* Class LocationActionEntityEventFactory
* @package App\Factories\EntityEvents
*/
final class LocationActionEntityEventFactory
{
/**
* @param LocationAction $event
* @param string $type
* @return SummitEntityEvent
*/
public static function build(LocationAction $event, $type = 'UPDATE')
{
$resource_server_context = App::make(IResourceServerContext::class);
$member_repository = App::make(IMemberRepository::class);
$summit_repository = App::make(ISummitRepository::class);
$summit = $summit_repository->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;
}
}

View File

@ -0,0 +1,59 @@
<?php namespace App\Factories\EntityEvents;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Events\TrackAction;
use Illuminate\Support\Facades\App;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\ISummitRepository;
use models\summit\PresentationCategory;
use models\summit\SummitEntityEvent;
/**
* Class TrackActionEntityEventFactory
* @package App\Factories\EntityEvents
*/
final class TrackActionEntityEventFactory
{
/**
* @param TrackAction $event
* @param string $type
* @return SummitEntityEvent
*/
public static function build(TrackAction $event, $type = 'UPDATE')
{
$resource_server_context = App::make(IResourceServerContext::class);
$member_repository = App::make(IMemberRepository::class);
$summit_repository = App::make(ISummitRepository::class);
$summit = $summit_repository->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;
}
}

View File

@ -1,55 +0,0 @@
<?php namespace App\Factories\EntityEvents;
/**
* Copyright 2018 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
* 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,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Events\TrackUpdated;
use Illuminate\Support\Facades\App;
use models\summit\SummitEntityEvent;
/**
* Class TrackUpdatedEntityEventFactory
* @package App\Factories\EntityEvents
*/
final class TrackUpdatedEntityEventFactory
{
/**
* @param TrackUpdated $event
* @return SummitEntityEvent[]
*/
public static function build(TrackUpdated $event){
$list = [];
$resource_server_context = App::make(\models\oauth2\IResourceServerContext::class);
$member_repository = App::make(\models\main\IMemberRepository::class);
$owner_id = $resource_server_context->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;
}
}

View File

@ -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);
}
}
}

View File

@ -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]+');
});

View File

@ -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
*/

View File

@ -314,4 +314,27 @@ SQL;
return $res;
}
/**
* @return int[]
*/
public function getRelatedPublishedSummitEventsIds(){
$query = <<<SQL
SELECT e.id
FROM models\summit\SummitEvent e
WHERE
e.published = 1
AND e.summit = :summit
AND e.category = :track
SQL;
$native_query = $this->getEM()->createQuery($query);
$native_query->setParameter("summit", $this->summit);
$native_query->setParameter("track", $this);
$res = $native_query->getResult();
return $res;
}
}

View File

@ -235,4 +235,50 @@ class SummitEventType extends SilverstripeBaseModel
$this->is_private = $is_private;
}
/**
* @return SummitEvent[]
*/
public function getRelatedPublishedSummitEvents(){
$query = <<<SQL
SELECT e
FROM models\summit\SummitEvent e
WHERE
e.published = 1
AND e.summit = :summit
AND e.type = :type
SQL;
$native_query = $this->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 = <<<SQL
SELECT e.id
FROM models\summit\SummitEvent e
WHERE
e.published = 1
AND e.summit = :summit
AND e.type = :type
SQL;
$native_query = $this->getEM()->createQuery($query);
$native_query->setParameter("summit", $this->summit);
$native_query->setParameter("type", $this);
$res = $native_query->getResult();
return $res;
}
}

View File

@ -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;
}

View File

@ -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',

View File

@ -1707,4 +1707,38 @@ SQL;
}
}
/**
* @param SummitAbstractLocation $location
* @return int[]
*/
public function getScheduleEventsIdsPerLocation(SummitAbstractLocation $location){
$query = <<<SQL
SELECT e.id
FROM models\summit\SummitEvent e
WHERE
e.published = 1
AND e.summit = :summit
AND e.location = :location
SQL;
$native_query = $this->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;
}
}

View File

@ -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')
);
}
});
}

View File

@ -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);
}

View File

@ -1,4 +1,5 @@
<?php namespace App\Services\Model;
/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
@ -11,13 +12,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Events\LocationDeleted;
use App\Events\LocationInserted;
use App\Events\LocationUpdated;
use App\Models\Foundation\Summit\Factories\SummitLocationFactory;
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
use App\Services\Apis\AddressInfo;
use App\Services\Apis\GeoCodingApiException;
use App\Services\Apis\GeoCoordinatesInfo;
use App\Services\Apis\IGeoCodingAPI;
use App\Services\Model\Strategies\GeoLocation\GeoLocationStrategyFactory;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException;
@ -25,7 +28,7 @@ use models\exceptions\ValidationException;
use models\summit\Summit;
use models\summit\SummitAbstractLocation;
use models\summit\SummitGeoLocatedLocation;
use models\summit\SummitVenue;
/**
* Class LocationService
* @package App\Services\Model
@ -61,8 +64,8 @@ final class LocationService implements ILocationService
)
{
$this->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);
});
}
}

View File

@ -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);
});

View File

@ -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);
});
}

View File

@ -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',

View File

@ -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',
];

View File

@ -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);
}
}