diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php index 2248b0f4..a20bff07 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitLocationsApiController.php @@ -2235,6 +2235,108 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController } } + + /** + * @param LaravelRequest $request + * @param $room_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function addVenueRoomImage(LaravelRequest $request, $summit_id, $venue_id, $room_id){ + try { + + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $venue = $summit->getLocation($venue_id); + + if (is_null($venue)) { + return $this->error404(); + } + + if (!$venue instanceof SummitVenue) { + return $this->error404(); + } + + $room = $venue->getRoom($room_id); + + if (is_null($room)) { + return $this->error404(); + } + + $file = $request->file('file'); + if (is_null($file)) { + return $this->error412(array('file param not set!')); + } + + $photo = $this->location_service->addRoomImage($summit, $venue_id, $room_id, $file); + + return $this->created(SerializerRegistry::getInstance()->getSerializer($photo)->serialize()); + + } catch (EntityNotFoundException $ex1) { + Log::warning($ex1); + return $this->error404(); + } catch (ValidationException $ex2) { + Log::warning($ex2); + return $this->error412(array($ex2->getMessage())); + } catch (\HTTP401UnauthorizedException $ex3) { + Log::warning($ex3); + return $this->error401(); + } catch (Exception $ex) { + Log::error($ex); + return $this->error500($ex); + } + } + + /** + * @param $summit_id + * @param $venue_id + * @param $room_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function removeVenueRoomImage($summit_id, $venue_id, $room_id){ + try { + + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $venue = $summit->getLocation($venue_id); + + if (is_null($venue)) { + return $this->error404(); + } + + if (!$venue instanceof SummitVenue) { + return $this->error404(); + } + + $room = $venue->getRoom($room_id); + + if (is_null($room)) { + return $this->error404(); + } + + $room = $this->location_service->removeRoomImage($summit, $venue_id, $room_id); + + return $this->updated(SerializerRegistry::getInstance()->getSerializer($room)->serialize()); + + } catch (EntityNotFoundException $ex1) { + Log::warning($ex1); + return $this->error404(); + } catch (ValidationException $ex2) { + Log::warning($ex2); + return $this->error412(array($ex2->getMessage())); + } catch (\HTTP401UnauthorizedException $ex3) { + Log::warning($ex3); + return $this->error401(); + } catch (Exception $ex) { + Log::error($ex); + return $this->error500($ex); + } + } // bookable rooms use SummitBookableVenueRoomApi; diff --git a/app/Http/routes.php b/app/Http/routes.php index 0297e76a..4d093822 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -379,6 +379,10 @@ Route::group([ Route::get('', 'OAuth2SummitLocationsApiController@getVenueRoom'); Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@updateVenueRoom']); Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@deleteVenueRoom']); + Route::group(['prefix' => 'image'], function () { + Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@addVenueRoomImage']); + Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitLocationsApiController@removeVenueRoomImage']); + }); }); }); diff --git a/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php b/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php index fbe90f73..f9482fa3 100644 --- a/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php +++ b/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php @@ -58,7 +58,7 @@ class SummitVenueRoom extends SummitAbstractLocation implements IOrderable private $metrics; /** - * @ORM\ManyToOne(targetEntity="models\main\File", fetch="EAGER", cascade={"persist"}) + * @ORM\ManyToOne(targetEntity="models\main\File", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\JoinColumn(name="ImageID", referencedColumnName="ID", onDelete="CASCADE") * @var File */ @@ -91,6 +91,10 @@ class SummitVenueRoom extends SummitAbstractLocation implements IOrderable } } + public function clearImage(){ + $this->image = null; + } + /** * @param File $image */ diff --git a/app/Services/Model/ILocationService.php b/app/Services/Model/ILocationService.php index b02c5728..81a5800d 100644 --- a/app/Services/Model/ILocationService.php +++ b/app/Services/Model/ILocationService.php @@ -12,6 +12,7 @@ * limitations under the License. **/ use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner; +use models\main\File; use models\main\Member; use models\summit\SummitBookableVenueRoom; use models\summit\SummitLocationImage; @@ -306,4 +307,26 @@ interface ILocationService * @throws ValidationException */ public function deleteVenueBookableRoomAttribute(Summit $summit, int $venue_id, int $room_id, int $attribute_id):SummitBookableVenueRoom; + + + /** + * @param Summit $summit + * @param UploadedFile $venue_id + * @param int $room_id + * @param UploadedFile $file + * @param int $max_file_size + * @return mixed|File + * @throws \Exception + */ + public function addRoomImage(Summit $summit, $venue_id, $room_id, UploadedFile $file, $max_file_size = 10485760); + + /** + * @param Summit $summit + * @param int $venue_id + * @param int $room_id + * @throws EntityNotFoundException + * @throws ValidationException + * @return SummitVenueRoom + */ + public function removeRoomImage(Summit $summit, int $venue_id, int $room_id):SummitVenueRoom; } \ No newline at end of file diff --git a/app/Services/Model/SummitLocationService.php b/app/Services/Model/SummitLocationService.php index 2864d174..edb2f83a 100644 --- a/app/Services/Model/SummitLocationService.php +++ b/app/Services/Model/SummitLocationService.php @@ -43,6 +43,7 @@ use Illuminate\Support\Facades\Log; use libs\utils\ITransactionService; use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; +use models\main\File; use models\main\IMemberRepository; use models\main\Member; use models\summit\Summit; @@ -2255,4 +2256,86 @@ final class SummitLocationService return $room; }); } + + /** + * @param Summit $summit + * @param UploadedFile $venue_id + * @param int $room_id + * @param UploadedFile $file + * @param int $max_file_size + * @return mixed|File + * @throws \Exception + */ + public function addRoomImage(Summit $summit, $venue_id, $room_id, UploadedFile $file, $max_file_size = 10485760) + { + return $this->tx_service->transaction(function () use ($summit, $venue_id, $room_id, $file, $max_file_size) { + + $allowed_extensions = ['png', 'jpg', 'jpeg', 'gif', 'pdf']; + + $room = $summit->getLocation($room_id); + if (is_null($room)) { + throw new EntityNotFoundException + ( + 'room not found' + ); + } + + if (!$room instanceof SummitVenueRoom) { + throw new EntityNotFoundException + ( + 'room not found' + ); + } + + if (!in_array($file->extension(), $allowed_extensions)) { + throw new ValidationException("file does not has a valid extension ('png','jpg','jpeg','gif','pdf')."); + } + + if ($file->getSize() > $max_file_size) { + throw new ValidationException(sprintf("file exceeds max_file_size (%s MB).", ($max_file_size / 1024) / 1024)); + } + + $image = $this->file_uploader->build($file, sprintf('summits/%s/locations/%s/rooms', $summit->getId(), $venue_id ), true); + $room->setImage($image); + + return $image; + }); + } + + /** + * @param Summit $summit + * @param int $venue_id + * @param int $room_id + * @throws EntityNotFoundException + * @throws ValidationException + * @return SummitVenueRoom + */ + public function removeRoomImage(Summit $summit, int $venue_id, int $room_id): SummitVenueRoom + { + return $this->tx_service->transaction(function () use ($summit, $venue_id, $room_id) { + + + $room = $summit->getLocation($room_id); + if (is_null($room)) { + throw new EntityNotFoundException + ( + 'room not found' + ); + } + + if (!$room instanceof SummitVenueRoom) { + throw new EntityNotFoundException + ( + 'room not found' + ); + } + + if(!$room->hasImage()) + throw new ValidationException("room has no image set"); + + $room->clearImage(); + + return $room; + }); + } } \ No newline at end of file diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index fce3825f..ab8c328c 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -1094,6 +1094,24 @@ class ApiEndpointsSeeder extends Seeder sprintf(SummitScopes::WriteLocationsData, $current_realm) ], ], + [ + 'name' => 'add-venue-room-image', + 'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/rooms/{room_id}/image', + 'http_method' => 'POST', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm), + sprintf(SummitScopes::WriteLocationsData, $current_realm) + ], + ], + [ + 'name' => 'remove-venue-room-image', + 'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/rooms/{room_id}/image', + 'http_method' => 'DELETE', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm), + sprintf(SummitScopes::WriteLocationsData, $current_realm) + ], + ], [ 'name' => 'update-venue-room', 'route' => '/api/v1/summits/{id}/locations/venues/{venue_id}/rooms/{room_id}',