diff --git a/app/Factories/PresentationVideoFactory.php b/app/Factories/PresentationVideoFactory.php index 54650d20..d0dae4d3 100644 --- a/app/Factories/PresentationVideoFactory.php +++ b/app/Factories/PresentationVideoFactory.php @@ -28,6 +28,7 @@ final class PresentationVideoFactory implements IPresentationVideoFactory public function build(array $data){ $video = new PresentationVideo; $utc_now = new \DateTime(); + $video->setYoutubeId(trim($data['you_tube_id'])); $video->setDateUploaded($utc_now); diff --git a/app/Http/Controllers/apis/protected/summit/OAuth2PresentationApiController.php b/app/Http/Controllers/apis/protected/summit/OAuth2PresentationApiController.php index c4d175da..13a0057b 100644 --- a/app/Http/Controllers/apis/protected/summit/OAuth2PresentationApiController.php +++ b/app/Http/Controllers/apis/protected/summit/OAuth2PresentationApiController.php @@ -82,6 +82,7 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController public function addVideo(LaravelRequest $request, $summit_id, $presentation_id){ try { + $summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -130,4 +131,83 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController return $this->error500($ex); } } + + public function updateVideo(LaravelRequest $request, $summit_id, $presentation_id, $video_id){ + try { + + $summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + if (!$request->isJson()) { + return $this->error412(array('invalid content type!')); + } + if(!Request::isJson()) return $this->error403(); + + $data = Input::json(); + + $rules = array + ( + 'you_tube_id' => 'required|alpha_dash', + 'name' => 'sometimes|required|text:512', + 'description' => 'sometimes|required|text|max:512', + 'display_on_site' => 'sometimes|required|boolean', + ); + + $data = $data->all(); + // Creates a Validator instance and validates the data. + $validation = Validator::make($data, $rules); + + if ($validation->fails()) { + $ex = new ValidationException; + $ex->setMessages($validation->messages()->toArray()); + throw $ex; + } + + $this->presentation_service->updateVideo($presentation_id, $video_id, $data); + + return $this->updated(); + } + catch (EntityNotFoundException $ex1) + { + Log::warning($ex1); + return $this->error404(); + } + catch (ValidationException $ex2) + { + Log::warning($ex2); + return $this->error412($ex2->getMessages()); + } + catch (Exception $ex) + { + Log::error($ex); + return $this->error500($ex); + } + } + + public function deleteVideo($summit_id, $presentation_id, $video_id){ + try { + + $summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $this->presentation_service->deleteVideo($presentation_id, $video_id); + + return $this->deleted(); + } + catch (EntityNotFoundException $ex1) + { + Log::warning($ex1); + return $this->error404(); + } + catch (ValidationException $ex2) + { + Log::warning($ex2); + return $this->error412($ex2->getMessages()); + } + 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 924573fa..ae650bf6 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -117,6 +117,10 @@ Route::group(array( Route::get('', 'OAuth2PresentationApiController@getPresentationVideos'); Route::get('{video_id}', 'OAuth2PresentationApiController@getPresentationVideo'); Route::post('', 'OAuth2PresentationApiController@addVideo'); + Route::group(array('prefix' => '{video_id}'), function () { + Route::put('', 'OAuth2PresentationApiController@updateVideo'); + Route::delete('', 'OAuth2PresentationApiController@deleteVideo'); + }); }); }); }); diff --git a/app/Models/Foundation/Summit/Events/Presentations/Materials/PresentationMaterial.php b/app/Models/Foundation/Summit/Events/Presentations/Materials/PresentationMaterial.php index 68432019..b952ca09 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/Materials/PresentationMaterial.php +++ b/app/Models/Foundation/Summit/Events/Presentations/Materials/PresentationMaterial.php @@ -58,6 +58,11 @@ abstract class PresentationMaterial extends SilverstripeBaseModel $this->presentation = $presentation; } + + public function unsetPresentation(){ + $this->presentation = null; + } + /** * @return int */ diff --git a/app/Models/Foundation/Summit/Events/Presentations/Presentation.php b/app/Models/Foundation/Summit/Events/Presentations/Presentation.php index fd7ed240..731e1de3 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/Presentation.php +++ b/app/Models/Foundation/Summit/Events/Presentations/Presentation.php @@ -182,6 +182,24 @@ class Presentation extends SummitEvent return count($this->getVideos()) > 0; } + /** + * @param int $video_id + * @return PresentationVideo + */ + public function getVideoBy($video_id){ + return $this->materials + ->filter(function( $element) use($video_id) { return $element instanceof PresentationVideo && $element->getId() == $video_id; }) + ->first(); + } + + /** + * @param PresentationVideo $video + */ + public function removeVideo(PresentationVideo $video){ + $this->materials->removeElement($video); + $video->unsetPresentation(); + } + /** * @return PresentationSlide[] */ @@ -302,7 +320,7 @@ class Presentation extends SummitEvent public function unsetModerator(){ - $this->moderator = nul; + $this->moderator = null; } } diff --git a/app/Models/Foundation/Summit/Factories/IPresentationVideoFactory.php b/app/Models/Foundation/Summit/Factories/IPresentationVideoFactory.php index 3c83e04d..c41641a7 100644 --- a/app/Models/Foundation/Summit/Factories/IPresentationVideoFactory.php +++ b/app/Models/Foundation/Summit/Factories/IPresentationVideoFactory.php @@ -11,6 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use models\summit\PresentationVideo; /** * Interface IPresentationVideoFactory diff --git a/app/Services/Model/IPresentationService.php b/app/Services/Model/IPresentationService.php index 69bec8b2..6eb4106c 100644 --- a/app/Services/Model/IPresentationService.php +++ b/app/Services/Model/IPresentationService.php @@ -27,4 +27,20 @@ interface IPresentationService * @return PresentationVideo */ public function addVideoTo($presentation_id, array $video_data); + + /** + * @param int $presentation_id + * @param int $video_id + * @param array $video_data + * @return PresentationVideo + */ + public function updateVideo($presentation_id, $video_id, array $video_data); + + + /** + * @param int $presentation_id + * @param int $video_id + * @return void + */ + public function deleteVideo($presentation_id, $video_id); } \ No newline at end of file diff --git a/app/Services/Model/PresentationService.php b/app/Services/Model/PresentationService.php index 3c18beda..c26a603e 100644 --- a/app/Services/Model/PresentationService.php +++ b/app/Services/Model/PresentationService.php @@ -16,6 +16,7 @@ use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; use models\summit\factories\IPresentationVideoFactory; use models\summit\ISummitEventRepository; +use models\summit\Presentation; use models\summit\PresentationVideo; use libs\utils\ITransactionService; @@ -80,4 +81,74 @@ final class PresentationService implements IPresentationService return $video; } + + /** + * @param int $presentation_id + * @param int $video_id + * @param array $video_data + * @return PresentationVideo + */ + public function updateVideo($presentation_id, $video_id, array $video_data) + { + return $this->tx_service->transaction(function() use($presentation_id, $video_id, $video_data){ + + $presentation = $this->presentation_repository->getById($presentation_id); + + if(is_null($presentation)) + throw new EntityNotFoundException('presentation not found!'); + + $video = $presentation->getVideoBy($video_id); + + if(is_null($video)) + throw new EntityNotFoundException('video not found!'); + + if(!$video instanceof PresentationVideo) + throw new EntityNotFoundException('video not found!'); + + if(isset($video_data['name'])) + $video->setName(trim($video_data['name'])); + + if(isset($video_data['you_tube_id'])) + $video->setYoutubeId(trim($video_data['you_tube_id'])); + + if(isset($video_data['description'])) + $video->setDescription(trim($video_data['description'])); + + if(isset($video_data['display_on_site'])) + $video->setDisplayOnSite((bool)$video_data['display_on_site']); + + return $video; + + }); + } + + /** + * @param int $presentation_id + * @param int $video_id + * @return void + */ + public function deleteVideo($presentation_id, $video_id) + { + $this->tx_service->transaction(function() use($presentation_id, $video_id){ + + $presentation = $this->presentation_repository->getById($presentation_id); + + if(is_null($presentation)) + throw new EntityNotFoundException('presentation not found!'); + + if(!$presentation instanceof Presentation) + throw new EntityNotFoundException('presentation not found!'); + + $video = $presentation->getVideoBy($video_id); + + if(is_null($video)) + throw new EntityNotFoundException('video not found!'); + + if(!$video instanceof PresentationVideo) + throw new EntityNotFoundException('video not found!'); + + $presentation->removeVideo($video); + + }); + } } \ No newline at end of file diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index 51786de5..034c20d1 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -561,6 +561,26 @@ class ApiEndpointsSeeder extends Seeder ) ); + ApiEndpoint::create( + array( + 'name' => 'update-presentation-video', + 'active' => true, + 'api_id' => $summit->id, + 'route' => '/api/v1/summits/{id}/presentations/{presentation_id}/videos/{video_id}', + 'http_method' => 'PUT' + ) + ); + + ApiEndpoint::create( + array( + 'name' => 'delete-presentation-video', + 'active' => true, + 'api_id' => $summit->id, + 'route' => '/api/v1/summits/{id}/presentations/{presentation_id}/videos/{video_id}', + 'http_method' => 'DELETE' + ) + ); + //members ApiEndpoint::create( @@ -575,7 +595,6 @@ class ApiEndpointsSeeder extends Seeder // notifications - ApiEndpoint::create( array( 'name' => 'get-notifications', @@ -689,9 +708,16 @@ class ApiEndpointsSeeder extends Seeder $endpoint->scopes()->attach($summit_external_order_confirm->id); //write videos + $endpoint = ApiEndpoint::where('name', '=', 'create-presentation-video')->first(); $endpoint->scopes()->attach($write_videos_scope->id); + $endpoint = ApiEndpoint::where('name', '=', 'update-presentation-video')->first(); + $endpoint->scopes()->attach($write_videos_scope->id); + + $endpoint = ApiEndpoint::where('name', '=', 'delete-presentation-video')->first(); + $endpoint->scopes()->attach($write_videos_scope->id); + } diff --git a/tests/OAuth2SummitApiTest.php b/tests/OAuth2SummitApiTest.php index eaac4a75..80ccafdf 100644 --- a/tests/OAuth2SummitApiTest.php +++ b/tests/OAuth2SummitApiTest.php @@ -1695,6 +1695,76 @@ final class OAuth2SummitApiTest extends ProtectedApiTest } + public function testUpdatePresentationVideo() + { + $params = array + ( + 'id' => 7, + 'presentation_id' => 15404, + 'video_id' => 32801 + ); + + $headers = array + ( + "HTTP_Authorization" => " Bearer " .$this->access_token, + "CONTENT_TYPE" => "application/json" + ); + + $video_data = array + ( + 'you_tube_id' => 'cpHa7kSOur0', + 'name' => 'test video update', + ); + + $response = $this->action + ( + "PUT", + "OAuth2PresentationApiController@updateVideo", + $params, + array(), + array(), + array(), + $headers, + json_encode($video_data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(204); + + } + + public function testDeletePresentationVideo() + { + $params = array + ( + 'id' => 7, + 'presentation_id' => 15404, + 'video_id' => 32800 + ); + + $headers = array + ( + "HTTP_Authorization" => " Bearer " .$this->access_token, + "CONTENT_TYPE" => "application/json" + ); + + $response = $this->action + ( + "DELETE", + "OAuth2PresentationApiController@deleteVideo", + $params, + array(), + array(), + array(), + $headers + + ); + + $content = $response->getContent(); + $this->assertResponseStatus(204); + + } + public function testGetMyMemberFromCurrentSummit(){ $params = array