Added Track Icon endpoints
POST /api/v1/summits/{id}/tracks/{track_id}/icon param file Scopes %s/summits/write DELETE /api/v1/summits/{id}/tracks/{track_id}/icon Scopes %s/summits/write Change-Id: Iefc9570a7b2f3b06174445b2f661c080c0e91699 Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
parent
7b27b05d72
commit
4addbe0c94
@ -16,6 +16,7 @@ use App\Http\Utils\EpochCellFormatter;
|
||||
use App\Http\Utils\PagingConstants;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitTrackRepository;
|
||||
use App\Services\Model\ISummitTrackService;
|
||||
use Illuminate\Http\Request as LaravelRequest;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@ -608,4 +609,59 @@ final class OAuth2SummitTracksApiController extends OAuth2ProtectedController
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function addTrackIcon(LaravelRequest $request, $summit_id, $track_id){
|
||||
try {
|
||||
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id);
|
||||
if (is_null($summit)) return $this->error404();
|
||||
|
||||
$file = $request->file('file');
|
||||
if (is_null($file)) {
|
||||
return $this->error412(array('file param not set!'));
|
||||
}
|
||||
|
||||
$image = $this->track_service->addTrackIcon($summit, $track_id, $file);
|
||||
|
||||
return $this->created(SerializerRegistry::getInstance()->getSerializer($image)->serialize());
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteTrackIcon($summit_id, $track_id) {
|
||||
try {
|
||||
$summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id);
|
||||
if (is_null($summit)) return $this->error404();
|
||||
$this->track_service->removeTrackIcon($summit, $track_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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -989,10 +989,16 @@ Route::group([
|
||||
Route::get('', 'OAuth2SummitTracksApiController@getTrackBySummit');
|
||||
Route::put('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitTracksApiController@updateTrackBySummit']);
|
||||
Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitTracksApiController@deleteTrackBySummit']);
|
||||
|
||||
Route::group(['prefix' => 'allowed-tags'], function () {
|
||||
Route::get('', 'OAuth2SummitTracksApiController@getTrackAllowedTagsBySummit');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'icon'], function () {
|
||||
Route::post('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitTracksApiController@addTrackIcon']);
|
||||
Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitTracksApiController@deleteTrackIcon']);
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'extra-questions'], function () {
|
||||
Route::get('', 'OAuth2SummitTracksApiController@getTrackExtraQuestionsBySummit');
|
||||
Route::group(['prefix' => '{question_id}'], function () {
|
||||
|
@ -34,6 +34,7 @@ final class PresentationCategorySerializer extends SilverStripeSerializer
|
||||
'ChairVisible' => 'chair_visible:json_boolean',
|
||||
'SummitId' => 'summit_id:json_int',
|
||||
'Color' => 'color:json_color',
|
||||
'IconUrl' => 'icon_url:json_url',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@ use Doctrine\ORM\Event\PreUpdateEventArgs;
|
||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||
use App\Models\Foundation\Summit\Events\Presentations\TrackQuestions\TrackQuestionTemplate;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use models\main\File;
|
||||
use models\main\Tag;
|
||||
use models\utils\SilverstripeBaseModel;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
@ -177,6 +178,12 @@ class PresentationCategory extends SilverstripeBaseModel
|
||||
*/
|
||||
protected $extra_questions;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="models\main\File", cascade={"persist","remove"})
|
||||
* @ORM\JoinColumn(name="IconID", referencedColumnName="ID")
|
||||
* @var File
|
||||
*/
|
||||
protected $icon;
|
||||
|
||||
/**
|
||||
* @return TrackQuestionTemplate[]|ArrayCollection
|
||||
@ -504,4 +511,57 @@ SQL;
|
||||
{
|
||||
$this->color = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return File|null
|
||||
*/
|
||||
public function getIcon(): ?File
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param File $icon
|
||||
*/
|
||||
public function setIcon(File $icon): void
|
||||
{
|
||||
$this->icon = $icon;
|
||||
}
|
||||
|
||||
public function clearIcon():void{
|
||||
$this->icon = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIcon(){
|
||||
return $this->getIconId() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getIconId()
|
||||
{
|
||||
try{
|
||||
if(is_null($this->icon)) return 0;
|
||||
return $this->icon->getId();
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getIconUrl():?string{
|
||||
$photoUrl = null;
|
||||
if($this->hasIcon() && $photo = $this->getIcon()){
|
||||
$photoUrl = $photo->getUrl();
|
||||
}
|
||||
return $photoUrl;
|
||||
}
|
||||
|
||||
}
|
@ -11,10 +11,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\summit\PresentationCategory;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitEvent;
|
||||
|
||||
/**
|
||||
* Interface ISummitTrackService
|
||||
* @package App\Services\Model
|
||||
@ -77,4 +81,24 @@ interface ISummitTrackService
|
||||
*/
|
||||
public function removeTrackExtraQuestion($track_id, $question_id);
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $track_id
|
||||
* @param UploadedFile $file
|
||||
* @param int $max_file_size
|
||||
* @throws ValidationException
|
||||
* @throws EntityNotFoundException
|
||||
* @return SummitEvent
|
||||
*/
|
||||
public function addTrackIcon(Summit $summit, $track_id, UploadedFile $file, $max_file_size = 10485760);
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param int $track_id
|
||||
* @throws ValidationException
|
||||
* @throws EntityNotFoundException
|
||||
* @return void
|
||||
*/
|
||||
public function removeTrackIcon(Summit $summit, $track_id):void;
|
||||
|
||||
}
|
@ -15,9 +15,11 @@
|
||||
use App\Events\TrackDeleted;
|
||||
use App\Events\TrackInserted;
|
||||
use App\Events\TrackUpdated;
|
||||
use App\Http\Utils\IFileUploader;
|
||||
use App\Models\Foundation\Summit\Factories\PresentationCategoryFactory;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitTrackRepository;
|
||||
use App\Models\Foundation\Summit\Repositories\ITrackQuestionTemplateRepository;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use libs\utils\ITransactionService;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
@ -25,6 +27,8 @@ use models\exceptions\ValidationException;
|
||||
use models\main\ITagRepository;
|
||||
use models\summit\PresentationCategory;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitEvent;
|
||||
|
||||
/**
|
||||
* Class SummitTrackService
|
||||
* @package App\Services\Model
|
||||
@ -48,11 +52,17 @@ final class SummitTrackService
|
||||
*/
|
||||
private $track_question_template_repository;
|
||||
|
||||
/**
|
||||
* @var IFileUploader
|
||||
*/
|
||||
private $file_uploader;
|
||||
|
||||
/**
|
||||
* SummitTrackService constructor.
|
||||
* @param ISummitTrackRepository $track_repository
|
||||
* @param ITagRepository $tag_repository
|
||||
* @param ITrackQuestionTemplateRepository $track_question_template_repository
|
||||
* @param IFileUploader $file_uploader
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
public function __construct
|
||||
@ -60,6 +70,7 @@ final class SummitTrackService
|
||||
ISummitTrackRepository $track_repository,
|
||||
ITagRepository $tag_repository,
|
||||
ITrackQuestionTemplateRepository $track_question_template_repository,
|
||||
IFileUploader $file_uploader,
|
||||
ITransactionService $tx_service
|
||||
)
|
||||
{
|
||||
@ -67,6 +78,7 @@ final class SummitTrackService
|
||||
$this->tag_repository = $tag_repository;
|
||||
$this->track_repository = $track_repository;
|
||||
$this->track_question_template_repository = $track_question_template_repository;
|
||||
$this->file_uploader = $file_uploader;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,4 +341,50 @@ final class SummitTrackService
|
||||
$track->removeExtraQuestion($track_question_template);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addTrackIcon(Summit $summit, $track_id, UploadedFile $file, $max_file_size = 10485760)
|
||||
{
|
||||
return $this->tx_service->transaction(function () use ($summit, $track_id, $file, $max_file_size) {
|
||||
|
||||
$allowed_extensions = ['png', 'jpg', 'jpeg', 'gif'];
|
||||
|
||||
$track = $summit->getPresentationCategory($track_id);
|
||||
|
||||
if (is_null($track) || !$track instanceof PresentationCategory) {
|
||||
throw new EntityNotFoundException('track not found on summit!');
|
||||
}
|
||||
|
||||
if (!in_array($file->extension(), $allowed_extensions)) {
|
||||
throw new ValidationException("file does not has a valid extension ('png','jpg','jpeg','gif').");
|
||||
}
|
||||
|
||||
if ($file->getSize() > $max_file_size) {
|
||||
throw new ValidationException(sprintf("file exceeds max_file_size (%s MB).", ($max_file_size / 1024) / 1024));
|
||||
}
|
||||
|
||||
$file = $this->file_uploader->build($file, 'summit-track-icon', true);
|
||||
$track->setIcon($file);
|
||||
|
||||
return $file;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function removeTrackIcon(Summit $summit, $track_id): void
|
||||
{
|
||||
$this->tx_service->transaction(function () use ($summit, $track_id) {
|
||||
|
||||
$track = $summit->getPresentationCategory($track_id);
|
||||
|
||||
if (is_null($track) || !$track instanceof PresentationCategory) {
|
||||
throw new EntityNotFoundException('track not found on summit!');
|
||||
}
|
||||
$track->clearIcon();
|
||||
});
|
||||
}
|
||||
}
|
43
database/migrations/model/Version20201022181641.php
Normal file
43
database/migrations/model/Version20201022181641.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Migrations\Model;
|
||||
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
|
||||
class Version20201022181641 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
|
||||
if($schema->hasTable("PresentationCategory") && !$builder->hasColumn("PresentationCategory", "IconID")) {
|
||||
$builder->table('PresentationCategory', function (Table $table) {
|
||||
|
||||
$table->integer("IconID", false, false)->setNotnull(false)->setDefault('NULL');
|
||||
$table->index("IconID", "IconID");
|
||||
$table->foreign("File", "IconID", "ID", ["onDelete" => "CASCADE"]);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
|
||||
if($schema->hasTable("PresentationCategory") && $builder->hasColumn("PresentationCategory", "IconID")) {
|
||||
$builder->table('PresentationCategory', function (Table $table) {
|
||||
$table->dropColumn("IconID");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -3766,6 +3766,34 @@ class ApiEndpointsSeeder extends Seeder
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'add-track-icon',
|
||||
'route' => '/api/v1/summits/{id}/tracks/{track_id}/icon',
|
||||
'http_method' => 'POST',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteTracksData, $current_realm),
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm)
|
||||
],
|
||||
'authz_groups' => [
|
||||
IGroup::SuperAdmins,
|
||||
IGroup::Administrators,
|
||||
IGroup::SummitAdministrators,
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'remove-track-icon',
|
||||
'route' => '/api/v1/summits/{id}/tracks/{track_id}/icon',
|
||||
'http_method' => 'DELETE',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::WriteTracksData, $current_realm),
|
||||
sprintf(SummitScopes::WriteSummitData, $current_realm)
|
||||
],
|
||||
'authz_groups' => [
|
||||
IGroup::SuperAdmins,
|
||||
IGroup::Administrators,
|
||||
IGroup::SummitAdministrators,
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'add-track-extra-questions',
|
||||
'route' => '/api/v1/summits/{id}/tracks/{track_id}/extra-questions/{question_id}',
|
||||
|
@ -11,7 +11,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
use LaravelDoctrine\ORM\Facades\EntityManager;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
/**
|
||||
* Class OAuth2TracksApiTest
|
||||
*/
|
||||
@ -360,4 +361,82 @@ final class OAuth2TracksApiTest extends ProtectedApiTest
|
||||
$added_tracks = json_decode($content);
|
||||
$this->assertTrue(!is_null($added_tracks));
|
||||
}
|
||||
|
||||
public function testAddTrackIcon($summit_id=25){
|
||||
|
||||
$repo = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $repo->getById($summit_id);
|
||||
if(!$summit instanceof \models\summit\Summit)
|
||||
throw new Exception();
|
||||
$track = $summit->getPresentationCategories()[0];
|
||||
$params = array
|
||||
(
|
||||
'id' => $summit_id,
|
||||
'track_id' => $track->getId(),
|
||||
);
|
||||
|
||||
$headers = array
|
||||
(
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
// "CONTENT_TYPE" => "multipart/form-data; boundary=----WebKitFormBoundaryBkSYnzBIiFtZu4pb"
|
||||
);
|
||||
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"POST",
|
||||
"OAuth2SummitTracksApiController@addTrackIcon",
|
||||
$params,
|
||||
array(),
|
||||
array(),
|
||||
[
|
||||
'file' => UploadedFile::fake()->image('icon.jpg')
|
||||
],
|
||||
$headers,
|
||||
[]
|
||||
);
|
||||
|
||||
$video_id = $response->getContent();
|
||||
$this->assertResponseStatus(201);
|
||||
return intval($video_id);
|
||||
}
|
||||
|
||||
public function testRemoveTrackIcon($summit_id=25){
|
||||
|
||||
$repo = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $repo->getById($summit_id);
|
||||
if(!$summit instanceof \models\summit\Summit)
|
||||
throw new Exception();
|
||||
$track = $summit->getPresentationCategories()[0];
|
||||
$params = array
|
||||
(
|
||||
'id' => $summit_id,
|
||||
'track_id' => $track->getId(),
|
||||
);
|
||||
|
||||
$headers = array
|
||||
(
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
// "CONTENT_TYPE" => "multipart/form-data; boundary=----WebKitFormBoundaryBkSYnzBIiFtZu4pb"
|
||||
);
|
||||
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"DELETE",
|
||||
"OAuth2SummitTracksApiController@deleteTrackIcon",
|
||||
$params,
|
||||
array(),
|
||||
array(),
|
||||
[
|
||||
|
||||
],
|
||||
$headers,
|
||||
[]
|
||||
);
|
||||
|
||||
$video_id = $response->getContent();
|
||||
$this->assertResponseStatus(204);
|
||||
return intval($video_id);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user