Fixed error on file upload when folder does not exists
Change-Id: Ic3e503178115f8f6939ae4850d3a240e2f4dda64
This commit is contained in:
parent
6abd51f8dc
commit
23a16de81d
@ -12,12 +12,12 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\Events\FileCreated;
|
||||
use App\Services\Model\IFolderService;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use models\main\File;
|
||||
use models\main\IFolderRepository;
|
||||
|
||||
/**
|
||||
* Class FileUploader
|
||||
* @package App\Http\Utils
|
||||
@ -25,12 +25,16 @@ use models\main\IFolderRepository;
|
||||
final class FileUploader
|
||||
{
|
||||
/**
|
||||
* @var IFolderRepository
|
||||
* @var IFolderService
|
||||
*/
|
||||
private $folder_repository;
|
||||
private $folder_service;
|
||||
|
||||
public function __construct(IFolderRepository $folder_repository){
|
||||
$this->folder_repository = $folder_repository;
|
||||
/**
|
||||
* FileUploader constructor.
|
||||
* @param IFolderService $folder_service
|
||||
*/
|
||||
public function __construct(IFolderService $folder_service){
|
||||
$this->folder_service = $folder_service;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +46,8 @@ final class FileUploader
|
||||
public function build(UploadedFile $file, $folder_name, $is_image = false){
|
||||
$attachment = new File();
|
||||
$local_path = Storage::putFileAs(sprintf('/public/%s', $folder_name), $file, $file->getClientOriginalName());
|
||||
$folder = $this->folder_repository->getFolderByName($folder_name);
|
||||
$folder = $this->folder_service->findOrMake($folder_name);
|
||||
|
||||
$attachment->setParent($folder);
|
||||
$attachment->setName($file->getClientOriginalName());
|
||||
$attachment->setFilename(sprintf("assets/%s/%s",$folder_name, $file->getClientOriginalName()));
|
||||
|
@ -181,10 +181,16 @@ class File extends SilverstripeBaseModel
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->class_name = 'File';
|
||||
$this->class_name = 'File';
|
||||
$this->show_in_search = true;
|
||||
}
|
||||
|
||||
public function setImage(){
|
||||
$this->class_name = 'Image';
|
||||
}
|
||||
|
||||
public function setFolder(){
|
||||
$this->class_name = 'Folder';
|
||||
}
|
||||
|
||||
}
|
@ -23,4 +23,18 @@ interface IFolderRepository extends IBaseRepository
|
||||
* @return File
|
||||
*/
|
||||
public function getFolderByName($folder_name);
|
||||
|
||||
/**
|
||||
* @param string $file_name
|
||||
* @return File
|
||||
*/
|
||||
public function getFolderByFileName($file_name);
|
||||
|
||||
/**
|
||||
* @param string $folder_name
|
||||
* @param File $parent
|
||||
* @return File
|
||||
*/
|
||||
public function getFolderByNameAndParent($folder_name, File $parent);
|
||||
|
||||
}
|
@ -45,6 +45,27 @@ SQL;
|
||||
return $native_query->getOneOrNullResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file_name
|
||||
* @return File
|
||||
*/
|
||||
public function getFolderByFileName($file_name)
|
||||
{
|
||||
|
||||
$query = <<<SQL
|
||||
select * from File where ClassName = 'Folder' AND
|
||||
FileName = :file_name
|
||||
SQL;
|
||||
// build rsm here
|
||||
$rsm = new ResultSetMappingBuilder($this->_em);
|
||||
$rsm->addRootEntityFromClassMetadata(\models\main\File::class, 'f');
|
||||
$native_query = $this->_em->createNativeQuery($query, $rsm);
|
||||
|
||||
$native_query->setParameter("file_name", $file_name);
|
||||
|
||||
return $native_query->getOneOrNullResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -52,4 +73,26 @@ SQL;
|
||||
{
|
||||
return File::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $folder_name
|
||||
* @param File $parent
|
||||
* @return File
|
||||
*/
|
||||
public function getFolderByNameAndParent($folder_name, File $parent)
|
||||
{
|
||||
$query = <<<SQL
|
||||
select * from File where ClassName = 'Folder' AND
|
||||
Name = :folder_name and ParentID = :parent_id
|
||||
SQL;
|
||||
// build rsm here
|
||||
$rsm = new ResultSetMappingBuilder($this->_em);
|
||||
$rsm->addRootEntityFromClassMetadata(\models\main\File::class, 'f');
|
||||
$native_query = $this->_em->createNativeQuery($query, $rsm);
|
||||
|
||||
$native_query->setParameter("folder_name", $folder_name);
|
||||
$native_query->setParameter("parent_id", $parent->getId());
|
||||
|
||||
return $native_query->getOneOrNullResult();
|
||||
}
|
||||
}
|
91
app/Services/Model/FolderService.php
Normal file
91
app/Services/Model/FolderService.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php namespace App\Services\Model;
|
||||
/**
|
||||
* Copyright 2018 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use libs\utils\ITransactionService;
|
||||
use models\main\File;
|
||||
use models\main\IFolderRepository;
|
||||
/**
|
||||
* Class FolderService
|
||||
* @package App\Services\Model
|
||||
*/
|
||||
final class FolderService implements IFolderService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var IFolderRepository
|
||||
*/
|
||||
private $folder_repository;
|
||||
|
||||
/**
|
||||
* @var ITransactionService
|
||||
*/
|
||||
private $tx_service;
|
||||
|
||||
/**
|
||||
* FolderService constructor.
|
||||
* @param IFolderRepository $folder_repository
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
public function __construct(IFolderRepository $folder_repository, ITransactionService $tx_service)
|
||||
{
|
||||
$this->folder_repository = $folder_repository;
|
||||
$this->tx_service = $tx_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $folder_name
|
||||
* @return File
|
||||
*/
|
||||
public function findOrMake($folder_name)
|
||||
{
|
||||
return $this->tx_service->transaction(function() use($folder_name){
|
||||
|
||||
$folder = $this->folder_repository->getFolderByFileName($folder_name);
|
||||
if(!is_null($folder)) return $folder;
|
||||
|
||||
// create it
|
||||
$folder_path = preg_replace('/^\/?(.*)\/?$/', '$1', $folder_name);
|
||||
$parts = explode("/", $folder_path);
|
||||
$parent = null;
|
||||
$item = null;
|
||||
$file_name = null;
|
||||
foreach($parts as $part) {
|
||||
if(!$part) continue; // happens for paths with a trailing slash
|
||||
if(!empty($file_name))
|
||||
$file_name .= '/';
|
||||
$file_name .= $part;
|
||||
$item = is_null($parent) ?
|
||||
$this->folder_repository->getFolderByName($part) :
|
||||
$this->folder_repository->getFolderByNameAndParent($part, $parent);
|
||||
|
||||
if(!$item) {
|
||||
$item = new File();
|
||||
if(!is_null($parent)){
|
||||
$item->setParent($parent);
|
||||
}
|
||||
else{
|
||||
$file_name = 'assets/'.$file_name;
|
||||
}
|
||||
$item->setFolder();
|
||||
$item->setName($part);
|
||||
$item->setTitle($part);
|
||||
$item->setFilename($file_name);
|
||||
$this->folder_repository->add($item);
|
||||
}
|
||||
$parent = $item;
|
||||
}
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
}
|
26
app/Services/Model/IFolderService.php
Normal file
26
app/Services/Model/IFolderService.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php namespace App\Services\Model;
|
||||
/**
|
||||
* Copyright 2018 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use models\main\File;
|
||||
/**
|
||||
* Interface IFolderService
|
||||
* @package App\Services\Model
|
||||
*/
|
||||
interface IFolderService
|
||||
{
|
||||
/**
|
||||
* @param $string $folder_name
|
||||
* @return File
|
||||
*/
|
||||
public function findOrMake($folder_name);
|
||||
}
|
@ -29,14 +29,12 @@ use App\Models\Foundation\Summit\Factories\SummitLocationBannerFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitLocationFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitLocationImageFactory;
|
||||
use App\Models\Foundation\Summit\Factories\SummitVenueFloorFactory;
|
||||
use App\Models\Foundation\Summit\Locations\Banners\ScheduledSummitLocationBanner;
|
||||
use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner;
|
||||
use App\Models\Foundation\Summit\Repositories\ISummitLocationRepository;
|
||||
use App\Services\Apis\GeoCodingApiException;
|
||||
use App\Services\Apis\IGeoCodingAPI;
|
||||
use App\Services\Model\Strategies\GeoLocation\GeoLocationStrategyFactory;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use libs\utils\ITransactionService;
|
||||
@ -45,10 +43,7 @@ use models\exceptions\ValidationException;
|
||||
use models\main\IFolderRepository;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitAbstractLocation;
|
||||
use models\summit\SummitAirport;
|
||||
use models\summit\SummitExternalLocation;
|
||||
use models\summit\SummitGeoLocatedLocation;
|
||||
use models\summit\SummitHotel;
|
||||
use models\summit\SummitLocationImage;
|
||||
use models\summit\SummitVenue;
|
||||
use models\summit\SummitVenueFloor;
|
||||
@ -64,11 +59,6 @@ final class LocationService implements ILocationService
|
||||
*/
|
||||
private $location_repository;
|
||||
|
||||
/**
|
||||
* @var IFolderRepository
|
||||
*/
|
||||
private $folder_repository;
|
||||
|
||||
/**
|
||||
* @var ITransactionService
|
||||
*/
|
||||
@ -79,25 +69,30 @@ final class LocationService implements ILocationService
|
||||
*/
|
||||
private $geo_coding_api;
|
||||
|
||||
/**
|
||||
* @var IFolderService
|
||||
*/
|
||||
private $folder_service;
|
||||
|
||||
/**
|
||||
* LocationService constructor.
|
||||
* @param ISummitLocationRepository $location_repository
|
||||
* @param IFolderRepository $folder_repository
|
||||
* @param IGeoCodingAPI $geo_coding_api
|
||||
* @param IFolderService $folder_service
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
public function __construct
|
||||
(
|
||||
ISummitLocationRepository $location_repository,
|
||||
IFolderRepository $folder_repository,
|
||||
IGeoCodingAPI $geo_coding_api,
|
||||
IFolderService $folder_service,
|
||||
ITransactionService $tx_service
|
||||
)
|
||||
{
|
||||
$this->location_repository = $location_repository;
|
||||
$this->geo_coding_api = $geo_coding_api;
|
||||
$this->folder_service = $folder_service;
|
||||
$this->tx_service = $tx_service;
|
||||
$this->folder_repository = $folder_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1176,7 +1171,7 @@ final class LocationService implements ILocationService
|
||||
);
|
||||
}
|
||||
|
||||
$uploader = new FileUploader($this->folder_repository);
|
||||
$uploader = new FileUploader($this->folder_service);
|
||||
$pic = $uploader->build($file, sprintf('summits/%s/locations/%s/maps/', $location->getSummitId(), $location->getId()), true);
|
||||
$map = SummitLocationImageFactory::buildMap($metadata);
|
||||
$map->setPicture($pic);
|
||||
@ -1280,7 +1275,7 @@ final class LocationService implements ILocationService
|
||||
);
|
||||
}
|
||||
|
||||
$uploader = new FileUploader($this->folder_repository);
|
||||
$uploader = new FileUploader($this->folder_service);
|
||||
$pic = $uploader->build($file, sprintf('summits/%s/locations/%s/maps/', $location->getSummitId(), $location->getId()), true);
|
||||
$map->setPicture($pic);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
**/
|
||||
use App\Models\Foundation\Summit\Factories\PresentationSpeakerSummitAssistanceConfirmationRequestFactory;
|
||||
use App\Models\Foundation\Summit\Repositories\IPresentationSpeakerSummitAssistanceConfirmationRequestRepository;
|
||||
use App\Services\Model\IFolderService;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use libs\utils\ITransactionService;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
@ -20,7 +21,6 @@ use models\exceptions\ValidationException;
|
||||
use models\main\EmailCreationRequest;
|
||||
use models\main\File;
|
||||
use models\main\IEmailCreationRequestRepository;
|
||||
use models\main\IFolderRepository;
|
||||
use models\main\IMemberRepository;
|
||||
use models\main\MemberPromoCodeEmailCreationRequest;
|
||||
use models\main\SpeakerCreationEmailCreationRequest;
|
||||
@ -52,9 +52,9 @@ final class SpeakerService implements ISpeakerService
|
||||
private $member_repository;
|
||||
|
||||
/**
|
||||
* @var IFolderRepository
|
||||
* @var IFolderService
|
||||
*/
|
||||
private $folder_repository;
|
||||
private $folder_service;
|
||||
|
||||
/**
|
||||
* @var ISpeakerRegistrationRequestRepository
|
||||
@ -89,7 +89,7 @@ final class SpeakerService implements ISpeakerService
|
||||
* @param ISpeakerRegistrationRequestRepository $speaker_registration_request_repository
|
||||
* @param ISpeakerSummitRegistrationPromoCodeRepository $registration_code_repository
|
||||
* @param IEmailCreationRequestRepository $email_creation_request_repository
|
||||
* @param IFolderRepository $folder_repository
|
||||
* @param IFolderService $folder_service
|
||||
* @param IPresentationSpeakerSummitAssistanceConfirmationRequestRepository $speakers_assistance_repository
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
@ -100,14 +100,14 @@ final class SpeakerService implements ISpeakerService
|
||||
ISpeakerRegistrationRequestRepository $speaker_registration_request_repository,
|
||||
ISpeakerSummitRegistrationPromoCodeRepository $registration_code_repository,
|
||||
IEmailCreationRequestRepository $email_creation_request_repository,
|
||||
IFolderRepository $folder_repository,
|
||||
IFolderService $folder_service,
|
||||
IPresentationSpeakerSummitAssistanceConfirmationRequestRepository $speakers_assistance_repository,
|
||||
ITransactionService $tx_service
|
||||
)
|
||||
{
|
||||
$this->speaker_repository = $speaker_repository;
|
||||
$this->member_repository = $member_repository;
|
||||
$this->folder_repository = $folder_repository;
|
||||
$this->folder_service = $folder_service;
|
||||
$this->speaker_registration_request_repository = $speaker_registration_request_repository;
|
||||
$this->registration_code_repository = $registration_code_repository;
|
||||
$this->email_creation_request_repository = $email_creation_request_repository;
|
||||
@ -397,7 +397,7 @@ final class SpeakerService implements ISpeakerService
|
||||
throw new ValidationException(sprintf( "file exceeds max_file_size (%s MB).", ($max_file_size/1024)/1024));
|
||||
}
|
||||
|
||||
$uploader = new FileUploader($this->folder_repository);
|
||||
$uploader = new FileUploader($this->folder_service);
|
||||
$photo = $uploader->build($file, 'profile-images', true);
|
||||
$speaker->setPhoto($photo);
|
||||
|
||||
|
@ -17,6 +17,7 @@ use App\Events\MyScheduleAdd;
|
||||
use App\Events\MyScheduleRemove;
|
||||
use App\Http\Utils\FileUploader;
|
||||
use App\Models\Utils\IntervalParser;
|
||||
use App\Services\Model\IFolderService;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
@ -25,7 +26,6 @@ use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\File;
|
||||
use models\main\ICompanyRepository;
|
||||
use models\main\IFolderRepository;
|
||||
use models\main\IGroupRepository;
|
||||
use models\main\IMemberRepository;
|
||||
use models\main\ITagRepository;
|
||||
@ -135,9 +135,9 @@ final class SummitService implements ISummitService
|
||||
private $calendar_sync_work_request_repository;
|
||||
|
||||
/**
|
||||
* @var IFolderRepository
|
||||
* @var IFolderService
|
||||
*/
|
||||
private $folder_repository;
|
||||
private $folder_service;
|
||||
|
||||
/**
|
||||
* @var ICompanyRepository
|
||||
@ -161,7 +161,7 @@ final class SummitService implements ISummitService
|
||||
* @param IRSVPRepository $rsvp_repository
|
||||
* @param IAbstractCalendarSyncWorkRequestRepository $calendar_sync_work_request_repository
|
||||
* @param IEventbriteAPI $eventbrite_api
|
||||
* @param IFolderRepository $folder_repository
|
||||
* @param IFolderService $folder_service
|
||||
* @param ICompanyRepository $company_repository
|
||||
* @param IGroupRepository $group_repository,
|
||||
* @param ITransactionService $tx_service
|
||||
@ -178,7 +178,7 @@ final class SummitService implements ISummitService
|
||||
IRSVPRepository $rsvp_repository,
|
||||
IAbstractCalendarSyncWorkRequestRepository $calendar_sync_work_request_repository,
|
||||
IEventbriteAPI $eventbrite_api,
|
||||
IFolderRepository $folder_repository,
|
||||
IFolderService $folder_service,
|
||||
ICompanyRepository $company_repository,
|
||||
IGroupRepository $group_repository,
|
||||
ITransactionService $tx_service
|
||||
@ -194,9 +194,9 @@ final class SummitService implements ISummitService
|
||||
$this->rsvp_repository = $rsvp_repository;
|
||||
$this->calendar_sync_work_request_repository = $calendar_sync_work_request_repository;
|
||||
$this->eventbrite_api = $eventbrite_api;
|
||||
$this->folder_repository = $folder_repository;
|
||||
$this->folder_service = $folder_service;
|
||||
$this->company_repository = $company_repository;
|
||||
$this->group_repository = $group_repository;
|
||||
$this->group_repository = $group_repository;
|
||||
$this->tx_service = $tx_service;
|
||||
}
|
||||
|
||||
@ -1230,7 +1230,7 @@ final class SummitService implements ISummitService
|
||||
throw new ValidationException(sprintf( "file exceeds max_file_size (%s MB).", ($max_file_size/1024)/1024));
|
||||
}
|
||||
|
||||
$uploader = new FileUploader($this->folder_repository);
|
||||
$uploader = new FileUploader($this->folder_service);
|
||||
$attachment = $uploader->build($file, 'summit-event-attachments', true);
|
||||
$event->setAttachment($attachment);
|
||||
|
||||
|
@ -14,7 +14,9 @@
|
||||
use App\Services\Apis\GoogleGeoCodingAPI;
|
||||
use App\Services\Apis\IGeoCodingAPI;
|
||||
use App\Services\Model\AttendeeService;
|
||||
use App\Services\Model\FolderService;
|
||||
use App\Services\Model\IAttendeeService;
|
||||
use App\Services\Model\IFolderService;
|
||||
use App\Services\Model\ILocationService;
|
||||
use App\Services\Model\IMemberService;
|
||||
use App\Services\Model\ISummitEventTypeService;
|
||||
@ -173,6 +175,12 @@ final class ServicesProvider extends ServiceProvider
|
||||
LocationService::class
|
||||
);
|
||||
|
||||
App::singleton
|
||||
(
|
||||
IFolderService::class,
|
||||
FolderService::class
|
||||
);
|
||||
|
||||
App::singleton(IGeoCodingAPI::class, function(){
|
||||
return new GoogleGeoCodingAPI
|
||||
(
|
||||
|
@ -17,6 +17,11 @@
|
||||
*/
|
||||
final class OAuth2SummitLocationsApiTest extends ProtectedApiTest
|
||||
{
|
||||
public function testGetFolder(){
|
||||
$service = \Illuminate\Support\Facades\App::make(\App\Services\Model\IFolderService::class);
|
||||
$folder = $service->findOrMake('summits/1/locations/292/maps');
|
||||
}
|
||||
|
||||
public function testGetCurrentSummitLocations($summit_id = 23)
|
||||
{
|
||||
$params = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user