From d2a9492239f9b09e4eda72ef4b97417727c28faa Mon Sep 17 00:00:00 2001 From: Sebastian Marcet Date: Wed, 21 Mar 2018 13:56:22 -0300 Subject: [PATCH] Added endpoint to delete RSVP Question Value DELETE /api/v1/summits/{id}/rsvp-templates/{template_id}/questions/{question_id}/values/{value_id} Change-Id: Icb1a8d10735549fedce9f7f920594d293b5c1031 --- ...OAuth2SummitRSVPTemplatesApiController.php | 32 ++++++++ app/Http/routes.php | 1 + .../Summit/Locations/SummitVenue.php | 34 +------- .../Summit/Locations/SummitVenueFloor.php | 36 ++------- .../Summit/Locations/SummitVenueRoom.php | 5 +- app/Services/Model/IRSVPTemplateService.php | 12 ++- app/Services/Model/RSVPTemplateService.php | 80 +++++++++++++++++++ resources/lang/en/not_found_errors.php | 3 + tests/OAuth2SummitRSVPTemplateApiTest.php | 31 +++++++ 9 files changed, 169 insertions(+), 65 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitRSVPTemplatesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitRSVPTemplatesApiController.php index c81899fb..bc2d3a35 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitRSVPTemplatesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitRSVPTemplatesApiController.php @@ -536,4 +536,36 @@ final class OAuth2SummitRSVPTemplatesApiController extends OAuth2ProtectedContro return $this->error500($ex); } } + + /** + * @param $summit_id + * @param $template_id + * @param $question_id + * @param $value_id + * @return mixed + */ + public function deleteRSVPTemplateQuestionValue($summit_id, $template_id, $question_id, $value_id){ + try { + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $this->rsvp_template_service->deleteQuestionValue($summit, $template_id, $question_id, $value_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 10d8f3cb..b90f2b06 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -182,6 +182,7 @@ Route::group([ Route::group(['prefix' => '{value_id}'], function () { Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitRSVPTemplatesApiController@getRSVPTemplateQuestionValue']); Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitRSVPTemplatesApiController@updateRSVPTemplateQuestionValue']); + Route::delete('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitRSVPTemplatesApiController@deleteRSVPTemplateQuestionValue']); }); }); }); diff --git a/app/Models/Foundation/Summit/Locations/SummitVenue.php b/app/Models/Foundation/Summit/Locations/SummitVenue.php index 4d2dbfdf..bbd4c414 100644 --- a/app/Models/Foundation/Summit/Locations/SummitVenue.php +++ b/app/Models/Foundation/Summit/Locations/SummitVenue.php @@ -11,6 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Models\Foundation\Main\OrderableChilds; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping AS ORM; use Doctrine\Common\Collections\ArrayCollection; @@ -70,42 +71,15 @@ class SummitVenue extends SummitGeoLocatedLocation $room->setVenue($this); } + use OrderableChilds; + /** * @param SummitVenueRoom $room * @param int $new_order * @throws ValidationException */ public function recalculateRoomsOrder(SummitVenueRoom $room, $new_order){ - - $criteria = Criteria::create(); - $criteria->orderBy(['order'=> 'ASC']); - $rooms = $this->rooms->matching($criteria)->toArray(); - $rooms = array_slice($rooms,0, count($rooms), false); - $max_order = count($rooms); - $former_order = 1; - foreach ($rooms as $r){ - if($r->getId() == $room->getId()) break; - $former_order++; - } - - if($new_order > $max_order) - throw new ValidationException(sprintf("max order is %s", $max_order)); - - unset($rooms[$former_order - 1]); - - $rooms = array_merge - ( - array_slice($rooms, 0, $new_order -1 , true) , - [$room] , - array_slice($rooms, $new_order -1 , count($rooms), true) - ); - - $order = 1; - foreach($rooms as $r){ - $r->setOrder($order); - $order++; - } - + self::recalculateOrderFor($this->rooms, $room, $new_order); } /** diff --git a/app/Models/Foundation/Summit/Locations/SummitVenueFloor.php b/app/Models/Foundation/Summit/Locations/SummitVenueFloor.php index 430a877d..1bd53c3a 100644 --- a/app/Models/Foundation/Summit/Locations/SummitVenueFloor.php +++ b/app/Models/Foundation/Summit/Locations/SummitVenueFloor.php @@ -11,10 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Models\Foundation\Main\OrderableChilds; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping AS ORM; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Query; +use Doctrine\Common\Collections\ArrayCollection; use models\exceptions\ValidationException; use models\main\File; use models\utils\SilverstripeBaseModel; @@ -205,42 +206,15 @@ class SummitVenueFloor extends SilverstripeBaseModel $room->clearFloor(); } + use OrderableChilds; + /** * @param SummitVenueRoom $room * @param int $new_order * @throws ValidationException */ public function recalculateRoomsOrder(SummitVenueRoom $room, $new_order){ - - $criteria = Criteria::create(); - $criteria->orderBy(['order'=> 'ASC']); - $rooms = $this->rooms->matching($criteria)->toArray(); - $rooms = array_slice($rooms,0, count($rooms), false); - $max_order = count($rooms); - $former_order = 1; - foreach ($rooms as $r){ - if($r->getId() == $room->getId()) break; - $former_order++; - } - - if($new_order > $max_order) - throw new ValidationException(sprintf("max order is %s", $max_order)); - - unset($rooms[$former_order - 1]); - - $rooms = array_merge - ( - array_slice($rooms, 0, $new_order -1 , true) , - [$room] , - array_slice($rooms, $new_order -1 , count($rooms), true) - ); - - $order = 1; - foreach($rooms as $r){ - $r->setOrder($order); - $order++; - } - + self::recalculateOrderFor($this->rooms, $room, $new_order); } } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php b/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php index bff5fc6c..bb08805d 100644 --- a/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php +++ b/app/Models/Foundation/Summit/Locations/SummitVenueRoom.php @@ -12,18 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - +use App\Models\Foundation\Main\IOrderable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping AS ORM; - /** * @ORM\Entity * @ORM\Table(name="SummitVenueRoom") * Class SummitVenueRoom * @package models\summit */ -class SummitVenueRoom extends SummitAbstractLocation +class SummitVenueRoom extends SummitAbstractLocation implements IOrderable { /** * @ORM\ManyToOne(targetEntity="models\summit\SummitVenue", inversedBy="rooms") diff --git a/app/Services/Model/IRSVPTemplateService.php b/app/Services/Model/IRSVPTemplateService.php index 127825dc..da2a97fb 100644 --- a/app/Services/Model/IRSVPTemplateService.php +++ b/app/Services/Model/IRSVPTemplateService.php @@ -73,7 +73,6 @@ interface IRSVPTemplateService */ public function addQuestionValue($summit, $template_id, $question_id, $payload); - /** * @param Summit $summit * @param int $template_id @@ -86,4 +85,15 @@ interface IRSVPTemplateService */ public function updateQuestionValue($summit, $template_id, $question_id, $value_id, $payload); + /** + * @param Summit $summit + * @param int $template_id + * @param int $question_id + * @param int $value_id + * @return void + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function deleteQuestionValue($summit, $template_id, $question_id, $value_id); + } \ No newline at end of file diff --git a/app/Services/Model/RSVPTemplateService.php b/app/Services/Model/RSVPTemplateService.php index 7aac4f8b..f85daf2a 100644 --- a/app/Services/Model/RSVPTemplateService.php +++ b/app/Services/Model/RSVPTemplateService.php @@ -431,4 +431,84 @@ final class RSVPTemplateService implements IRSVPTemplateService return $value; }); } + + /** + * @param Summit $summit + * @param int $template_id + * @param int $question_id + * @param int $value_id + * @return void + * @throws EntityNotFoundException + * @throws ValidationException + */ + public function deleteQuestionValue($summit, $template_id, $question_id, $value_id) + { + return $this->tx_service->transaction(function() use($summit, $template_id, $question_id, $value_id){ + + $template = $summit->getRSVPTemplateById($template_id); + + if(is_null($template)) + throw new EntityNotFoundException + ( + trans + ( + 'not_found_errors.RSVPTemplateService.deleteQuestionValue.TemplateNotFound', + [ + 'summit_id' => $summit->getId(), + 'template_id' => $template_id, + ] + ) + ); + + $question = $template->getQuestionById($question_id); + if(is_null($question)) + throw new EntityNotFoundException + ( + trans + ( + 'not_found_errors.RSVPTemplateService.deleteQuestionValue.QuestionNotFound', + [ + 'summit_id' => $summit->getId(), + 'template_id' => $template_id, + 'question_id' => $question_id, + ] + ) + ); + + if(!$question instanceof RSVPMultiValueQuestionTemplate) + throw new EntityNotFoundException + ( + trans + ( + 'not_found_errors.RSVPTemplateService.deleteQuestionValue.QuestionNotFound', + [ + 'summit_id' => $summit->getId(), + 'template_id' => $template_id, + 'question_id' => $question_id, + ] + ) + ); + + $value = $question->getValueById($value_id); + + if(is_null($value)){ + throw new EntityNotFoundException + ( + trans + ( + 'not_found_errors.RSVPTemplateService.deleteQuestionValue.ValueNotFound', + [ + 'summit_id' => $summit->getId(), + 'template_id' => $template_id, + 'question_id' => $question_id, + 'value_id' => $value_id + ] + ) + ); + } + + $question->removeValue($value); + + }); + } } \ No newline at end of file diff --git a/resources/lang/en/not_found_errors.php b/resources/lang/en/not_found_errors.php index 161431e8..2f543175 100644 --- a/resources/lang/en/not_found_errors.php +++ b/resources/lang/en/not_found_errors.php @@ -50,4 +50,7 @@ return [ 'RSVPTemplateService.deleteQuestion.QuestionNotFound' => 'question :question_id not found on template :template_id', 'RSVPTemplateService.addQuestionValue.TemplateNotFound' => 'template :template_id not found on summit :summit_id', 'RSVPTemplateService.addQuestionValue.QuestionNotFound' => 'question :question_id not found on template :template_id', + 'RSVPTemplateService.deleteQuestionValue.TemplateNotFound' => 'template :template_id not found on summit :summit_id', + 'RSVPTemplateService.deleteQuestionValue.QuestionNotFound' => 'question :question_id not found on template :template_id', + 'RSVPTemplateService.deleteQuestionValue.ValueNotFound' => 'value :value_id not found on question :question_id', ]; \ No newline at end of file diff --git a/tests/OAuth2SummitRSVPTemplateApiTest.php b/tests/OAuth2SummitRSVPTemplateApiTest.php index cbb1f313..a6972774 100644 --- a/tests/OAuth2SummitRSVPTemplateApiTest.php +++ b/tests/OAuth2SummitRSVPTemplateApiTest.php @@ -347,4 +347,35 @@ final class OAuth2SummitRSVPTemplateApiTest extends ProtectedApiTest $this->assertTrue($value->order == 3); return $value; } + + public function testDeleteRSVPQuestionValue($summit_id = 24, $template_id = 13, $question_id = 86){ + + $value = $this->testAddRSVPQuestionValue($summit_id, $template_id, $question_id); + + $params = [ + 'id' => $summit_id, + 'template_id' => $template_id, + 'question_id' => $question_id, + 'value_id' => $value->id + ]; + + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "DELETE", + "OAuth2SummitRSVPTemplatesApiController@deleteRSVPTemplateQuestionValue", + $params, + [], + [], + [], + $headers + ); + + $content = $response->getContent(); + $this->assertResponseStatus(204); + } } \ No newline at end of file