From 3d4a9f97b6c31d2986ed3e073536def8a7a8f93c Mon Sep 17 00:00:00 2001 From: smarcet Date: Mon, 17 Feb 2020 23:39:38 -0300 Subject: [PATCH] Updated Feedback Endpoints GET api/v1/summits/{id}/members/me/schedule/{event_id}/feedback Required Scopes REALM_URL/me/read POST api/v1/summits/{id}/members/me/schedule/{event_id}/feedback Payload 'rate' => 'required|integer|digits_between:0,5', 'note' => 'max:500', Required Scopes REALM_URL/me/summits/events/feedback/add PUT api/v1/summits/{id}/members/me/schedule/{event_id}/feedback Payload 'rate' => 'required|integer|digits_between:0,5', 'note' => 'max:500', Required Scopes REALM_URL/me/summits/events/feedback/add DELETE api/v1/summits/{id}/members/me/schedule/{event_id}/feedback Required Scopes REALM_URL/me/summits/events/feedback/delete Change-Id: I754e8bfbc15554280fba436b1168dcfbb0299f88 Signed-off-by: smarcet --- .../OAuth2SummitEventsApiController.php | 411 +++++++++--------- app/Http/routes.php | 27 +- app/Models/Foundation/Main/Member.php | 36 +- .../Summit/Events/SummitEventFeedback.php | 44 +- .../Factories/SummitEventFeedbackFactory.php | 44 ++ app/Services/Model/ISummitService.php | 38 +- app/Services/Model/SummitService.php | 158 ++++--- database/seeds/ApiEndpointsSeeder.php | 42 +- tests/OAuth2SummitEventsApiTest.php | 9 +- 9 files changed, 485 insertions(+), 324 deletions(-) create mode 100644 app/Models/Foundation/Summit/Factories/SummitEventFeedbackFactory.php diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitEventsApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitEventsApiController.php index d0995d93..eee33e63 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitEventsApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitEventsApiController.php @@ -698,10 +698,9 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController /** * @param $summit_id * @param $event_id - * @param $attendee_id * @return mixed */ - public function getEventFeedback($summit_id, $event_id, $attendee_id = null) + public function getEventFeedback($summit_id, $event_id) { try { @@ -732,18 +731,6 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } $filter = null; - if (!is_null($attendee_id)) // add filter by attendee, this case me - { - if($attendee_id !== 'me') return $this->error403(); - $current_member = $this->resource_server_context->getCurrentUser(); - if (is_null($current_member)) return $this->error403(); - - $filter = FilterParser::parse('owner_id=='.$current_member->getId(), array - ( - 'owner_id' => array('=='), - )); - } - // default values $page = 1; $per_page = 5; @@ -782,88 +769,212 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } /** - * @param LaravelRequest $request * @param $summit_id * @param $event_id - * @return mixed + * @return \Illuminate\Http\JsonResponse|mixed */ - public function addEventFeedback(LaravelRequest $request, $summit_id, $event_id) - { - try { - if (!$request->isJson()) { - return $this->error412(array('invalid content type!')); - } + public function addMyEventFeedbackReturnId($summit_id, $event_id){ + return $this->_addMyEventFeedback($summit_id, $event_id, true); + } + /** + * @param $summit_id + * @param $event_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function addMyEventFeedback($summit_id, $event_id){ + return $this->_addMyEventFeedback($summit_id, $event_id, false); + } + /** + * @param $summit_id + * @param $event_id + * @param bool $returnId + * @return \Illuminate\Http\JsonResponse|mixed + */ + private function _addMyEventFeedback($summit_id, $event_id, $returnId = false){ + try { $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); - if(!Request::isJson()) return $this->error400(); - $data = Input::json(); + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); - $rules = array - ( - 'rate' => 'required|integer|digits_between:0,10', - 'note' => 'required|max:500', - 'attendee_id' => 'required' - ); - - // Creates a Validator instance and validates the data. - $validation = Validator::make($data->all(), $rules); - - if ($validation->fails()) { - $messages = $validation->messages()->toArray(); - - return $this->error412 - ( - $messages - ); - } - - $event = $summit->getScheduleEvent(intval($event_id)); - - if (is_null($event)) { - return $this->error404(); - } - - $data = $data->all(); - $attendee_id = $data['attendee_id']; - - $attendee = CheckAttendeeStrategyFactory::build - ( - CheckAttendeeStrategyFactory::Own, - $this->resource_server_context - )->check($attendee_id, $summit); - - if (is_null($attendee)) return $this->error404(); - - $data['attendee_id'] = intval($attendee->getId()); - - $res = $this->service->addEventFeedback + $payload = $this->getJsonPayload([ + 'rate' => 'required|integer|digits_between:0,5', + 'note' => 'max:500', + ]); + + $feedback = $this->service->addMyEventFeedback ( + $current_member, $summit, - $event, - $data + $event_id, + $payload ); - return !is_null($res) ? $this->created($res->getId()) : $this->error400(); + if($returnId){ + return $this->updated($feedback->getId()); + } + + return $this->created(SerializerRegistry::getInstance()->getSerializer($feedback)->serialize + ( + Request::input('expand', '') + )); } - catch (EntityNotFoundException $ex1) { - Log::warning($ex1); + catch (EntityNotFoundException $ex) { + Log::warning($ex); 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 (ValidationException $ex) { + Log::warning($ex); + return $this->error412(array($ex->getMessage())); } catch (Exception $ex) { Log::error($ex); + return $this->error500($ex); + } + } + /** + * @param $summit_id + * @param $event_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function updateMyEventFeedbackReturnId($summit_id, $event_id){ + return $this->_updateMyEventFeedback($summit_id, $event_id, true); + } + + /** + * @param $summit_id + * @param $event_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function updateMyEventFeedback($summit_id, $event_id){ + return $this->_updateMyEventFeedback($summit_id, $event_id, false); + } + + /** + * @param $summit_id + * @param $event_id + * @param bool $returnId + * @return \Illuminate\Http\JsonResponse|mixed + */ + private function _updateMyEventFeedback($summit_id, $event_id, $returnId = false) + { + try { + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); + + $payload = $this->getJsonPayload([ + 'rate' => 'required|integer|digits_between:0,5', + 'note' => 'max:500', + ]); + + $feedback = $this->service->updateMyEventFeedback + ( + $current_member, + $summit, + $event_id, + $payload + ); + + if($returnId){ + return $this->updated($feedback->getId()); + } + + return $this->updated(SerializerRegistry::getInstance()->getSerializer($feedback)->serialize + ( + Request::input('expand', '') + )); + } + catch (EntityNotFoundException $ex) { + Log::warning($ex); + return $this->error404(); + } + catch (ValidationException $ex) { + Log::warning($ex); + return $this->error412(array($ex->getMessage())); + } + catch (Exception $ex) { + Log::error($ex); + return $this->error500($ex); + } + } + + /** + * @param $summit_id + * @param $event_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function getMyEventFeedback($summit_id, $event_id){ + try { + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); + + $feedback = $this->service->getMyEventFeedback + ( + $current_member, + $summit, + $event_id + ); + + return $this->ok(SerializerRegistry::getInstance()->getSerializer($feedback)->serialize + ( + Request::input('expand', '') + )); + } + catch (EntityNotFoundException $ex) { + Log::warning($ex); + return $this->error404(); + } + catch (ValidationException $ex) { + Log::warning($ex); + return $this->error412(array($ex->getMessage())); + } + catch (Exception $ex) { + Log::error($ex); + return $this->error500($ex); + } + } + + /** + * @param $summit_id + * @param $event_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function deleteMyEventFeedback($summit_id, $event_id){ + try { + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $current_member = $this->resource_server_context->getCurrentUser(); + if (is_null($current_member)) return $this->error403(); + + $this->service->deleteMyEventFeedback + ( + $current_member, + $summit, + $event_id + ); + + return $this->deleted(); + } + catch (EntityNotFoundException $ex) { + Log::warning($ex); + return $this->error404(); + } + catch (ValidationException $ex) { + Log::warning($ex); + return $this->error412(array($ex->getMessage())); + } + catch (Exception $ex) { + Log::error($ex); return $this->error500($ex); } } @@ -872,129 +983,8 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController * @param LaravelRequest $request * @param $summit_id * @param $event_id - * @return mixed + * @return \Illuminate\Http\JsonResponse|mixed */ - public function addEventFeedbackByMember(LaravelRequest $request, $summit_id, $event_id) - { - try { - - list($summit, $event, $data) = $this->validateAndGetFeedbackData($request, $summit_id, $event_id); - - $res = $this->service->addEventFeedback - ( - $summit, - $event, - $data - ); - - return !is_null($res) ? $this->created($res->getId()) : $this->error400(); - } - 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 LaravelRequest $request - * @param $summit_id - * @param $event_id - * @return mixed - */ - public function updateEventFeedbackByMember(LaravelRequest $request, $summit_id, $event_id) - { - try { - - list($summit, $event, $data) = $this->validateAndGetFeedbackData($request, $summit_id, $event_id); - $res = $this->service->updateEventFeedback - ( - $summit, - $event, - $data - ); - - return !is_null($res) ? $this->updated($res->getId()) : $this->error400(); - } - 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); - } - } - - private function validateAndGetFeedbackData(LaravelRequest $request, $summit_id, $event_id){ - if (!$request->isJson()) { - return $this->error412(array('invalid content type!')); - } - - $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); - if (is_null($summit)) return $this->error404(); - if(!Request::isJson()) return $this->error400(); - - $data = Input::json(); - - $rules = array - ( - 'rate' => 'required|integer|digits_between:0,5', - 'note' => 'max:500', - ); - - // Creates a Validator instance and validates the data. - $validation = Validator::make($data->all(), $rules); - - if ($validation->fails()) { - $messages = $validation->messages()->toArray(); - - return $this->error412 - ( - $messages - ); - } - - $event = $summit->getScheduleEvent(intval($event_id)); - - if (is_null($event)) { - return $this->error404(); - } - - $data = $data->all(); - $current_member = $this->resource_server_context->getCurrentUser(); - if (is_null($current_member)) return $this->error403(); - - $data['member_id'] = $current_member->getId(); - - return [$summit, $event, $data]; - } - public function addEventAttachment(LaravelRequest $request, $summit_id, $event_id){ try { @@ -1031,6 +1021,10 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } + /** + * @param $summit_id + * @return \Illuminate\Http\JsonResponse|mixed + */ public function getUnpublishedEvents($summit_id){ try @@ -1062,6 +1056,10 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } + /** + * @param $summit_id + * @return \Illuminate\Http\JsonResponse|mixed + */ public function getScheduleEmptySpots($summit_id){ try { @@ -1118,6 +1116,10 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } + /** + * @param $summit_id + * @return \Illuminate\Http\JsonResponse|mixed + */ public function unPublishEvents($summit_id){ try { $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); @@ -1163,6 +1165,10 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } + /** + * @param $summit_id + * @return \Illuminate\Http\JsonResponse|mixed + */ public function updateAndPublishEvents($summit_id){ try { $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); @@ -1208,6 +1214,10 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } + /** + * @param $summit_id + * @return \Illuminate\Http\JsonResponse|mixed + */ public function updateEvents($summit_id){ try { $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); @@ -1256,7 +1266,7 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController /** * @param $summit_id * @param $event_id - * @return mixed + * @return \Illuminate\Http\JsonResponse|mixed */ public function cloneEvent($summit_id, $event_id) { @@ -1285,5 +1295,4 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController } } - } \ No newline at end of file diff --git a/app/Http/routes.php b/app/Http/routes.php index f6456154..aace0494 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -267,9 +267,12 @@ Route::group([ Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitEventsApiController@deleteEvent' ]); Route::put('/publish', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitEventsApiController@publishEvent']); Route::delete('/publish', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitEventsApiController@unPublishEvent']); - Route::post('/feedback', 'OAuth2SummitEventsApiController@addEventFeedback'); + Route::post('/attachment', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitEventsApiController@addEventAttachment']); - Route::get('/feedback/{attendee_id?}', ['middleware' => 'cache:'.Config::get('cache_api_response.get_event_feedback_response_lifetime', 300), 'uses' => 'OAuth2SummitEventsApiController@getEventFeedback'] )->where('attendee_id', 'me|[0-9]+'); + + Route::group(['prefix' => 'feedback'], function () { + Route::get('', ['middleware' => 'cache:'.Config::get('cache_api_response.get_event_feedback_response_lifetime', 300), 'uses' => 'OAuth2SummitEventsApiController@getEventFeedback']); + }); }); Route::group(['prefix' => 'all'], function () { @@ -574,9 +577,12 @@ Route::group([ Route::get("", [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitMembersApiController@getAllBySummit']); Route::get("csv", [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitMembersApiController@getAllBySummitCSV']); Route::group(array('prefix' => '{member_id}'), function () { + Route::get('', 'OAuth2SummitMembersApiController@getMyMember')->where('member_id', 'me'); + + // favorites - Route::group(array('prefix' => 'favorites'), function () + Route::group(['prefix' => 'favorites'], function () { Route::get('', 'OAuth2SummitMembersApiController@getMemberFavoritesSummitEvents')->where('member_id', 'me'); @@ -598,12 +604,19 @@ Route::group([ Route::group(array('prefix' => '{event_id}'), function (){ - Route::group(array('prefix' => 'rsvp'), function (){ + Route::group(['prefix' => 'rsvp'], function (){ Route::post('', 'OAuth2SummitMembersApiController@addEventRSVP')->where('member_id', 'me'); Route::put('', 'OAuth2SummitMembersApiController@updateEventRSVP')->where('member_id', 'me'); Route::delete('', 'OAuth2SummitMembersApiController@deleteEventRSVP')->where('member_id', 'me'); }); + Route::group(['prefix' => 'feedback'], function (){ + Route::get('','OAuth2SummitMembersApiController@getMyEventFeedback')->where('member_id', 'me'); + Route::post('', 'OAuth2SummitMembersApiController@addMyEventFeedback')->where('member_id', 'me'); + Route::put('', 'OAuth2SummitMembersApiController@updateMyEventFeedback')->where('member_id', 'me'); + Route::delete('', 'OAuth2SummitMembersApiController@deleteMyEventFeedback')->where('member_id', 'me'); + }); + Route::post('', 'OAuth2SummitMembersApiController@addEventToMemberSchedule')->where('member_id', 'me'); Route::delete('', 'OAuth2SummitMembersApiController@removeEventFromMemberSchedule')->where('member_id', 'me'); }); @@ -859,8 +872,10 @@ Route::group([ Route::group(['prefix' => 'events'], function () { Route::group(['prefix' => '{event_id}'], function () { - Route::post('/feedback', 'OAuth2SummitEventsApiController@addEventFeedbackByMember'); - Route::put('/feedback', 'OAuth2SummitEventsApiController@updateEventFeedbackByMember'); + Route::group(['prefix' => 'feedback'], function () { + Route::post('', 'OAuth2SummitEventsApiController@addMyEventFeedbackReturnId'); + Route::put('', 'OAuth2SummitEventsApiController@updateMyEventFeedbackReturnId'); + }); }); }); }); diff --git a/app/Models/Foundation/Main/Member.php b/app/Models/Foundation/Main/Member.php index 444ac115..75265523 100644 --- a/app/Models/Foundation/Main/Member.php +++ b/app/Models/Foundation/Main/Member.php @@ -605,20 +605,32 @@ class Member extends SilverstripeBaseModel /** * @param SummitEvent $event - * @return SummitEventFeedback[] + * @return SummitEventFeedback|null */ - public function getFeedbackByEvent(SummitEvent $event) + public function getFeedbackByEvent(SummitEvent $event):?SummitEventFeedback { - return $this->createQueryBuilder() - ->select('distinct f') - ->from('models\summit\SummitEventFeedback', 'f') - ->join('f.event', 'e') - ->join('f.owner', 'o') - ->join('e.summit', 's') - ->where('e.id = :event_id and o.id = :owner_id') - ->setParameter('event_id', $event->getId()) - ->setParameter('owner_id', $this->getId()) - ->getQuery()->getResult(); + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('event', $event)); + $feedback = $this->feedback->matching($criteria)->first(); + return $feedback === false ? null : $feedback; + } + + /** + * @param SummitEventFeedback $feedback + */ + public function addFeedback(SummitEventFeedback $feedback){ + if($this->feedback->contains($feedback)) return; + $this->feedback->add($feedback); + $feedback->setOwner($this); + } + + /** + * @param SummitEventFeedback $feedback + */ + public function removeFeedback(SummitEventFeedback $feedback){ + if(!$this->feedback->contains($feedback)) return; + $this->feedback->removeElement($feedback); + $feedback->clearOwner(); } /** diff --git a/app/Models/Foundation/Summit/Events/SummitEventFeedback.php b/app/Models/Foundation/Summit/Events/SummitEventFeedback.php index 52ba2c05..9cddbedf 100644 --- a/app/Models/Foundation/Summit/Events/SummitEventFeedback.php +++ b/app/Models/Foundation/Summit/Events/SummitEventFeedback.php @@ -33,6 +33,26 @@ class SummitEventFeedback extends SilverstripeBaseModel */ private $rate; + /** + * @ORM\Column(name="note", type="string") + * @var string + */ + private $note; + + /** + * @ORM\ManyToOne(targetEntity="models\main\Member", inversedBy="feedback") + * @ORM\JoinColumn(name="OwnerID", referencedColumnName="ID", onDelete="CASCADE") + * @var Member + */ + private $owner; + + /** + * @ORM\ManyToOne(targetEntity="models\summit\SummitEvent", inversedBy="feedback", fetch="LAZY") + * @ORM\JoinColumn(name="EventID", referencedColumnName="ID", onDelete="CASCADE") + * @var SummitEvent + */ + private $event; + /** * @return int */ @@ -65,19 +85,6 @@ class SummitEventFeedback extends SilverstripeBaseModel $this->note = $note; } - /** - * @ORM\Column(name="note", type="string") - * @var string - */ - private $note; - - /** - * @ORM\ManyToOne(targetEntity="models\main\Member", inversedBy="feedback") - * @ORM\JoinColumn(name="OwnerID", referencedColumnName="ID", onDelete="CASCADE") - * @var Member - */ - private $owner; - /** * @return Member */ @@ -93,13 +100,6 @@ class SummitEventFeedback extends SilverstripeBaseModel $this->owner = $owner; } - /** - * @ORM\ManyToOne(targetEntity="models\summit\SummitEvent", inversedBy="feedback", fetch="LAZY") - * @ORM\JoinColumn(name="EventID", referencedColumnName="ID", onDelete="CASCADE") - * @var SummitEvent - */ - private $event; - /** * @return SummitEvent */ @@ -139,6 +139,10 @@ class SummitEventFeedback extends SilverstripeBaseModel } } + public function clearOwner(){ + $this->owner = null; + } + /** * @param SummitEvent $event */ diff --git a/app/Models/Foundation/Summit/Factories/SummitEventFeedbackFactory.php b/app/Models/Foundation/Summit/Factories/SummitEventFeedbackFactory.php new file mode 100644 index 00000000..185a8ac7 --- /dev/null +++ b/app/Models/Foundation/Summit/Factories/SummitEventFeedbackFactory.php @@ -0,0 +1,44 @@ +setRate(intval($data['rate'])); + + $note = isset($data['note']) ? trim($data['note']) : ""; + $feedback->setNote($note); + return $feedback; + } + +} \ No newline at end of file diff --git a/app/Services/Model/ISummitService.php b/app/Services/Model/ISummitService.php index 432ffcc3..63358a91 100644 --- a/app/Services/Model/ISummitService.php +++ b/app/Services/Model/ISummitService.php @@ -90,20 +90,46 @@ interface ISummitService public function removeEventFromMemberSchedule(Summit $summit, Member $member, $event_id, $check_rsvp = true); /** + * @param Member $member * @param Summit $summit - * @param SummitEvent $event - * @param array $feedback + * @param int $event_id + * @param array $payload * @return SummitEventFeedback + * @throws EntityNotFoundException + * @throws ValidationException */ - public function addEventFeedback(Summit $summit, SummitEvent $event, array $feedback); + public function addMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback; /** + * @param Member $member * @param Summit $summit - * @param SummitEvent $event - * @param array $feedback + * @param int $event_id + * @param array $payload * @return SummitEventFeedback + * @throws EntityNotFoundException + * @throws ValidationException */ - public function updateEventFeedback(Summit $summit, SummitEvent $event, array $feedback); + public function updateMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback; + + /** + * @param Member $member + * @param Summit $summit + * @param int $event_id + * @return SummitEventFeedback + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function getMyEventFeedback(Member $member, Summit $summit, int $event_id):SummitEventFeedback; + + /** + * @param Member $member + * @param Summit $summit + * @param int $event_id + * @return void + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function deleteMyEventFeedback(Member $member, Summit $summit, int $event_id):void; /** * @param Summit $summit diff --git a/app/Services/Model/SummitService.php b/app/Services/Model/SummitService.php index ac8c07a9..18bf8b0c 100644 --- a/app/Services/Model/SummitService.php +++ b/app/Services/Model/SummitService.php @@ -23,6 +23,7 @@ use App\Events\SummitUpdated; use App\Http\Utils\IFileUploader; use App\Mail\BookableRoomReservationCanceledEmail; use App\Mail\Schedule\ShareEventEmail; +use App\Models\Foundation\Summit\Factories\SummitEventFeedbackFactory; use App\Models\Foundation\Summit\Factories\SummitFactory; use App\Models\Foundation\Summit\Factories\SummitRSVPFactory; use App\Models\Foundation\Summit\Repositories\IDefaultSummitEventTypeRepository; @@ -380,108 +381,133 @@ final class SummitService extends AbstractService implements ISummitService } /** + * @param Member $member * @param Summit $summit - * @param SummitEvent $event - * @param array $data + * @param int $event_id + * @param array $payload * @return SummitEventFeedback + * @throws Exception */ - public function addEventFeedback(Summit $summit, SummitEvent $event, array $data) + public function addMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback { + return $this->tx_service->transaction(function () use ($member, $summit, $event_id, $payload) { - return $this->tx_service->transaction(function () use ($summit, $event, $data) { - - if (!$event->isAllowFeedback()) - throw new ValidationException(sprintf("event id %s does not allow feedback", $event->getIdentifier())); - - $member = null; - - // check for attendee - $attendee_id = isset($data['attendee_id']) ? intval($data['attendee_id']) : null; - $member_id = isset($data['member_id']) ? intval($data['member_id']) : null; - if (!is_null($attendee_id)) { - $attendee = $summit->getAttendeeById($attendee_id); - if (!$attendee) throw new EntityNotFoundException(); - $member = $attendee->getMember(); - } - - // check by member - if (!is_null($member_id)) { - $member = $this->member_repository->getById($member_id); - } - - if (is_null($member)) - throw new EntityNotFoundException('member not found!.'); + $event = $summit->getScheduleEvent($event_id); + if(is_null($event)) + throw new EntityNotFoundException("Event not found."); if (!Summit::allowToSee($event, $member)) - throw new EntityNotFoundException('event not found on summit!.'); + throw new EntityNotFoundException("Event not found."); + + if (!$event->isAllowFeedback()) + throw new ValidationException(sprintf("Event id %s does not allow feedback.", $event->getIdentifier())); // check older feedback - $older_feedback = $member->getFeedbackByEvent($event); + $former_feedback = $member->getFeedbackByEvent($event); - if (count($older_feedback) > 0) - throw new ValidationException(sprintf("you already sent feedback for event id %s!.", $event->getIdentifier())); + if (!is_null($former_feedback)) + throw new ValidationException(sprintf("You already sent feedback for event id %s!.", $event->getIdentifier())); - $newFeedback = new SummitEventFeedback(); - $newFeedback->setRate(intval($data['rate'])); - $note = isset($data['note']) ? trim($data['note']) : ""; - $newFeedback->setNote($note); + $newFeedback = SummitEventFeedbackFactory::build($payload); $newFeedback->setOwner($member); $event->addFeedBack($newFeedback); - return $newFeedback; }); } /** + * @param Member $member * @param Summit $summit - * @param SummitEvent $event - * @param array $data + * @param int $event_id + * @param array $payload * @return SummitEventFeedback - * @internal param array $feedback + * @throws Exception */ - public function updateEventFeedback(Summit $summit, SummitEvent $event, array $data) + public function updateMyEventFeedback(Member $member, Summit $summit, int $event_id, array $payload):SummitEventFeedback { - return $this->tx_service->transaction(function () use ($summit, $event, $data) { + return $this->tx_service->transaction(function () use ($member, $summit, $event_id, $payload) { - if (!$event->isAllowFeedback()) - throw new ValidationException(sprintf("event id %s does not allow feedback", $event->getIdentifier())); + $event = $summit->getScheduleEvent($event_id); - $member = null; - - // check for attendee - $attendee_id = isset($data['attendee_id']) ? intval($data['attendee_id']) : null; - $member_id = isset($data['member_id']) ? intval($data['member_id']) : null; - if (!is_null($attendee_id)) { - $attendee = $summit->getAttendeeById($attendee_id); - if (!$attendee) throw new EntityNotFoundException(); - $member = $attendee->getMember(); - } - - // check by member - if (!is_null($member_id)) { - $member = $this->member_repository->getById($member_id); - } - - if (is_null($member)) - throw new EntityNotFoundException('member not found!.'); + if(is_null($event)) + throw new EntityNotFoundException("Event not found."); if (!Summit::allowToSee($event, $member)) - throw new EntityNotFoundException('event not found on summit!.'); + throw new EntityNotFoundException("Event not found."); + + if (!$event->isAllowFeedback()) + throw new ValidationException(sprintf("Event id %s does not allow feedback.", $event->getIdentifier())); // check older feedback $feedback = $member->getFeedbackByEvent($event); - if (count($feedback) == 0) + if (is_null($feedback)) + throw new ValidationException(sprintf("you dont have feedback for event id %s!.", $event->getIdentifier())); + + return SummitEventFeedbackFactory::populate($feedback, $payload); + }); + } + + /** + * @param Member $member + * @param Summit $summit + * @param int $event_id + * @return SummitEventFeedback + * @throws Exception + */ + public function getMyEventFeedback(Member $member, Summit $summit, int $event_id):SummitEventFeedback + { + return $this->tx_service->transaction(function () use ($member, $summit, $event_id) { + + $event = $summit->getScheduleEvent($event_id); + + if(is_null($event)) + throw new EntityNotFoundException("Event not found."); + + if (!Summit::allowToSee($event, $member)) + throw new EntityNotFoundException("Event not found."); + + if (!$event->isAllowFeedback()) + throw new ValidationException(sprintf("Event id %s does not allow feedback.", $event->getIdentifier())); + + // check older feedback + $feedback = $member->getFeedbackByEvent($event); + + if (is_null($feedback)) throw new ValidationException(sprintf("you dont have feedback for event id %s!.", $event->getIdentifier())); - $feedback = $feedback[0]; - $feedback->setRate(intval($data['rate'])); - $note = isset($data['note']) ? trim($data['note']) : ""; - $feedback->setNote($note); return $feedback; }); } + /** + * @param Member $member + * @param Summit $summit + * @param int $event_id + * @throws Exception + */ + public function deleteMyEventFeedback(Member $member, Summit $summit, int $event_id):void + { + $this->tx_service->transaction(function () use ($member, $summit, $event_id) { + + $event = $summit->getScheduleEvent($event_id); + if(is_null($event)) + throw new EntityNotFoundException("Event not found."); + + if (!Summit::allowToSee($event, $member)) + throw new EntityNotFoundException("Event not found."); + + if (!$event->isAllowFeedback()) + throw new ValidationException(sprintf("Event id %s does not allow feedback.", $event->getIdentifier())); + + // check older feedback + $feedback = $member->getFeedbackByEvent($event); + + $member->removeFeedback($feedback); + + }); + } + /** * @param Summit $summit * @param null|int $member_id diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index 8c160616..ac22d761 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -2195,12 +2195,6 @@ class ApiEndpointsSeeder extends Seeder IGroup::SummitRegistrationAdmins, ] ], - [ - 'name' => 'add-event-feedback', - 'route' => '/api/v1/summits/{id}/events/{event_id}/feedback', - 'http_method' => 'POST', - 'scopes' => [sprintf(SummitScopes::WriteSummitData, $current_realm)], - ], [ 'name' => 'add-event-attachment', 'route' => '/api/v1/summits/{id}/events/{event_id}/attachment', @@ -2213,6 +2207,38 @@ class ApiEndpointsSeeder extends Seeder IGroup::SummitRegistrationAdmins, ] ], + [ + 'name' => 'add-event-feedback', + 'route' => ' api/v1/summits/{id}/members/{member_id}/schedule/{event_id}/feedback', + 'http_method' => 'POST', + 'scopes' => [ + sprintf(SummitScopes::AddMyEventFeedback, $current_realm), + ], + ], + [ + 'name' => 'update-event-feedback', + 'route' => ' api/v1/summits/{id}/members/{member_id}/schedule/{event_id}/feedback', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::AddMyEventFeedback, $current_realm), + ], + ], + [ + 'name' => 'delete-event-feedback', + 'route' => ' api/v1/summits/{id}/members/{member_id}/schedule/{event_id}/feedback', + 'http_method' => 'DELETE', + 'scopes' => [ + sprintf(SummitScopes::DeleteMyEventFeedback, $current_realm), + ], + ], + [ + 'name' => 'get-event-feedback-by-member', + 'route' => ' api/v1/summits/{id}/members/{member_id}/schedule/{event_id}/feedback', + 'http_method' => 'GET', + 'scopes' => [ + sprintf(SummitScopes::MeRead, $current_realm), + ], + ], [ 'name' => 'add-event-feedback-v2', 'route' => '/api/v2/summits/{id}/events/{event_id}/feedback', @@ -2233,11 +2259,11 @@ class ApiEndpointsSeeder extends Seeder ], [ 'name' => 'get-event-feedback', - 'route' => '/api/v1/summits/{id}/events/{event_id}/feedback/{attendee_id?}', + 'route' => '/api/v1/summits/{id}/events/{event_id}/feedback', 'http_method' => 'GET', 'scopes' => [ + sprintf(SummitScopes::ReadAllSummitData, $current_realm), sprintf(SummitScopes::ReadSummitData, $current_realm), - sprintf(SummitScopes::ReadAllSummitData, $current_realm) ], ], [ diff --git a/tests/OAuth2SummitEventsApiTest.php b/tests/OAuth2SummitEventsApiTest.php index 8f45d6a7..3b0e41f6 100644 --- a/tests/OAuth2SummitEventsApiTest.php +++ b/tests/OAuth2SummitEventsApiTest.php @@ -1426,7 +1426,7 @@ final class OAuth2SummitEventsApiTest extends ProtectedApiTest $this->assertTrue(!is_null($feedback)); } - public function testUpdateFeedback2EventByMember($summit_id = 22, $event_id = 17683) + public function testUpdateFeedback2EventByMember($summit_id = 27, $event_id = 24340) { //$this->testAddFeedback2EventByMember($summit_id, $event_id); $params = array @@ -1450,7 +1450,7 @@ final class OAuth2SummitEventsApiTest extends ProtectedApiTest $response = $this->action ( "PUT", - "OAuth2SummitEventsApiController@updateEventFeedbackByMember", + "OAuth2SummitEventsApiController@updateMyEventFeedbackReturnId", $params, array(), array(), @@ -1502,7 +1502,7 @@ final class OAuth2SummitEventsApiTest extends ProtectedApiTest } - public function testAddFeedback2EventByMember($summit_id = 22, $event_id = 17683) + public function testAddFeedback2EventByMember($summit_id = 27, $event_id = 24340) { $params = array ( @@ -1524,7 +1524,7 @@ final class OAuth2SummitEventsApiTest extends ProtectedApiTest $response = $this->action ( "POST", - "OAuth2SummitEventsApiController@addEventFeedbackByMember", + "OAuth2SummitEventsApiController@addMyEventFeedbackReturnId", $params, array(), array(), @@ -1535,7 +1535,6 @@ final class OAuth2SummitEventsApiTest extends ProtectedApiTest $content = $response->getContent(); $this->assertResponseStatus(204); - } public function testCloneEvent($summit_id = 25, $event_id= 22943)