Last active
June 12, 2023 14:40
-
-
Save ghanshyamgohel/43993b657797876fcee23752af87f31e to your computer and use it in GitHub Desktop.
TYPO3 extBase easy upload example for FAL image. Key: FAL upload single image, FAL upload multiple images, FAL delete single image, FAL delete multiple images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Location: your_ext/ext_tables.sql | |
# | |
# Table structure for table 'tx_yourext_domain_model_falupload' | |
# | |
CREATE TABLE tx_yourext_domain_model_falupload ( | |
teaser_image int(11) unsigned NOT NULL default '0', | |
gallery int(11) unsigned NOT NULL default '0' | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Location: your_ext/ext_typoscript_setup.txt | |
config.tx_extbase{ | |
persistence{ | |
classes{ | |
VENDOR\YourExt\Domain\Model\FileReference{ | |
mapping{ | |
tableName = sys_file_reference | |
columns{ | |
uid_local.mapOnProperty = originalFileIdentifier | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Location: your_ext/Classes/Domain/Model/FalUpload.php | |
namespace VENDOR\YourExt\Domain\Model; | |
class FalUpload extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity | |
{ | |
/** | |
* teaserImage | |
* | |
* @var \VENDOR\YourExt\Domain\Model\FileReference | |
*/ | |
protected $teaserImage = null; | |
/** | |
* gallery | |
* | |
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\VENDOR\YourExt\Domain\Model\FileReference> | |
*/ | |
protected $gallery = 0; | |
protected function initStorageObjects() | |
{ | |
$this->gallery = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); | |
} | |
/* teaserImage get,set */ | |
/** | |
* Returns the teaserImage | |
* | |
* @return \VENDOR\YourExt\Domain\Model\FileReference $teaserImage | |
*/ | |
public function getTeaserImage() | |
{ | |
return $this->teaserImage; | |
} | |
/** | |
* Sets the teaserImage | |
* | |
* @param \VENDOR\YourExt\Domain\Model\FileReference $teaserImage | |
* @return void | |
*/ | |
public function setTeaserImage(\VENDOR\YourExt\Domain\Model\FileReference $teaserImage) | |
{ | |
$this->teaserImage = $teaserImage; | |
} | |
/* gallery get,set,add,remove */ | |
/** | |
* Returns the gallery | |
* | |
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage | |
*/ | |
public function getGallery() | |
{ | |
return $this->gallery; | |
} | |
/** | |
* Sets the gallery | |
* | |
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $gallery | |
* @return void | |
*/ | |
public function setGallery($gallery) | |
{ | |
$this->gallery = $gallery; | |
} | |
/** | |
* Sets the gallery | |
* | |
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> | |
* @return void | |
*/ | |
public function addGallery(\TYPO3\CMS\Extbase\Domain\Model\FileReference $file) | |
{ | |
$this->gallery->attach($file); | |
} | |
/** | |
* Removes an gallery from the Gallery | |
* | |
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $imageToRemove The gallery to be removed | |
* @return void | |
*/ | |
public function removeGalleryImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $imageToRemove) | |
{ | |
$this->gallery->detach($imageToRemove); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Location: your_ext/Classes/Controller/FalUploadController.php | |
namespace VENDOR\YourExt\Controller; | |
use TYPO3\CMS\Core\Utility\GeneralUtility; | |
class FalUploadController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController | |
{ | |
/** | |
* action editAction | |
* | |
* @param \VENDOR\YourExt\Domain\Model\FalUpload $falUpload | |
* @return void | |
*/ | |
public function editAction(\VENDOR\YourExt\Domain\Model\FalUpload $falUpload){ | |
$this->view->assign('falUpload', $falUpload); | |
} | |
/** | |
* action updateMediaAction | |
* | |
* @param \VENDOR\YourExt\Domain\Model\FalUpload $falUpload | |
* @return void | |
*/ | |
public function updateMediaAction(\VENDOR\YourExt\Domain\Model\FalUpload $falUpload){ | |
$resourceFactory = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class); | |
$objectStorage = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage; | |
if($this->request->hasArgument('teaserImage')){ | |
$teaserImage = $this->request->getArgument('teaserImage'); | |
if($falUpload->getTeaserImage()){ | |
$fileReferenceUid = $falUpload->getTeaserImage()->getUid(); | |
// remove old file | |
$fileReferenceObject = $resourceFactory->getFileReferenceObject($fileReferenceUid); | |
$fileReferenceObject->getOriginalFile()->delete(); | |
} | |
// image upload and fileReference process | |
$fileReferenceResult = $this->uploadFalFile($teaserImage); | |
// set new uploaded image | |
$falUpload->setTeaserImage($fileReferenceResult); | |
} | |
if($this->request->hasArgument('gallery')){ | |
$gallery = $this->request->getArgument('gallery'); | |
foreach($gallery as $key=>$galleryfileDataArray){ | |
$fileReferenceResultGallery = $this->uploadFalFile($galleryfileDataArray); | |
// set multi uploaded images | |
$falUpload->addGallery($fileReferenceResultGallery); | |
} | |
} | |
// bulk delete images(gallery) by checked checkbox | |
if($this->request->hasArgument('media')){ | |
$media = $this->request->getArgument('media'); | |
$mediaArr = GeneralUtility::intExplode(',',implode(',',$media)); // array of selected images to be deleted | |
$galleryImages = $falUpload->getGallery(); | |
if($galleryImages){ | |
$galleryRemoveReference = []; | |
foreach($galleryImages as $key=>$imageSingle){ | |
$galleryFileReferenceUid = (int)$imageSingle->getUid(); | |
if(in_array($galleryFileReferenceUid,$mediaArr)){ | |
// remove file | |
$galleryFileReferenceObject = $resourceFactory->getFileReferenceObject($galleryFileReferenceUid); | |
$galleryFileReferenceObject->getOriginalFile()->delete(); | |
// collect file reference which will delete later | |
$objectStorage->attach($imageSingle); | |
$galleryRemoveReference[] = $imageSingle; | |
} | |
} | |
// remove images | |
$falUpload->getGallery()->removeAll($objectStorage); | |
// remove file reference from DB | |
if($galleryRemoveReference){ | |
foreach($galleryRemoveReference as $key=>$mediaReference){ | |
$this->falUploadRepository->removeGalleryReference($mediaReference); | |
} | |
} | |
} | |
} | |
// add tstamp for last modified record | |
$falUpload->setTstamp(new \DateTime); | |
// update model | |
$this->falUploadRepository->update($falUpload); | |
// add flash message | |
$this->addFlashMessage('The record successfully updated.', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::OK); | |
$this->redirect('list'); | |
} | |
/** | |
* | |
* @var array $fileData | |
* @return \VENDOR\YourExt\Domain\Model\FileReference | |
*/ | |
private function uploadFalFile($fileData) { | |
// `objectManager->get` deprecated | |
$storageRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\StorageRepository::class); | |
// Upload images in your folder | |
$uploadDir = GeneralUtility::getFileAbsFileName('fileadmin/faluploads/'); | |
if(!is_dir($uploadDir)){ | |
mkdir($uploadDir, 0777, true); | |
} | |
$newFileReference = GeneralUtility::makeInstance(\VENDOR\YourExt\Domain\Model\FileReference::class); | |
if(!empty($fileData['name'])){ | |
$storage = $storageRepository->findByUid(1); // fileadmin = 1 | |
$saveFolder = $storage->getFolder('faluploads'); | |
// save data | |
$fileObject = $storage->addFile($fileData['tmp_name'], $saveFolder, $fileData['name']); | |
$newFileReference->setFile($fileObject); | |
} | |
return $newFileReference; | |
} | |
/** | |
* action deleteMedia | |
* | |
* @param \VENDOR\YourExt\Domain\Model\FalUpload $falUpload | |
* @param \VENDOR\YourExt\Domain\Model\FileReference $media | |
* @param string $fieldName | |
* @return void | |
*/ | |
public function deleteMediaAction( | |
\VENDOR\YourExt\Domain\Model\FalUpload $falUpload, | |
\VENDOR\YourExt\Domain\Model\FileReference $media,$fieldName = '') | |
{ | |
$falUploadUid = $falUpload->getUid(); | |
if(!empty($media)){ | |
switch ($fieldName) { | |
case 'teaserImage': | |
// Important note for single image delete: | |
// 'detach' method only works with ObjectStorage | |
// so for single image deletion, I have created function in repository | |
$fieldName = 'teaser_image'; | |
$this->falUploadRepository->removeMedia($media, $falUploadUid, $fieldName); | |
break; | |
case 'gallery': | |
// remove file | |
$resourceFactory = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class); | |
$fileReferenceObject = $resourceFactory->getFileReferenceObject($media->getUid()); | |
$fileReferenceObject->getOriginalFile()->delete(); | |
// remove reference | |
$falUpload->removeGalleryImage($media); | |
// remove file reference from DB | |
$this->falUploadRepository->removeGalleryReference($media); | |
break; | |
} | |
// add tstamp for last modified record | |
$falUpload->setTstamp(new \DateTime); | |
// update model | |
$this->falUploadRepository->update($falUpload); | |
// add flash message | |
$this->addFlashMessage('The image has been deleted.', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::OK); | |
} | |
// redirect | |
$this->redirect('edit','FalUpload',NULL,array('falUpload'=>$falUpload->getUid())); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Location: your_ext/Classes/Domain/Repository/FalUploadRepository.php | |
namespace VENDOR\YourExt\Domain\Repository; | |
use TYPO3\CMS\Core\Utility\GeneralUtility; | |
use TYPO3\CMS\Core\Database\ConnectionPool; | |
class FalUploadRepository extends \TYPO3\CMS\Extbase\Persistence\Repository | |
{ | |
/** | |
* The function can be use for single image delete | |
* remove fileReference from DB and file source | |
*/ | |
public function removeMedia($media, $fieldUid, $fieldName){ | |
$fileUid = $media->getUidLocal(); | |
$fileReferenceUid = $media->getUid(); | |
// remove file source | |
$resourceFactory = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class); | |
$fileReferenceObject = $resourceFactory->getFileReferenceObject($fileReferenceUid); | |
$fileWasDeleted = $fileReferenceObject->getOriginalFile()->delete(); | |
// remove sys_file record | |
$queryBuilderSysFile = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file'); | |
$queryBuilderSysFile->delete('sys_file') | |
->where( | |
$queryBuilderSysFile->expr()->eq('uid', $fileUid) | |
)->execute(); | |
// remove sys_file_reference record | |
$queryBuilderFileReference = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference'); | |
$queryBuilderFileReference->delete('sys_file_reference') | |
->where( | |
$queryBuilderFileReference->expr()->eq('uid', $fileReferenceUid) | |
)->execute(); | |
//update your table field | |
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_yourext_domain_model_falupload'); | |
$queryBuilder->update('tx_yourext_domain_model_falupload') | |
->where( | |
$queryBuilder->expr()->eq('uid', $fieldUid) | |
)->set($fieldName, 0)->execute(); | |
return $fileWasDeleted; | |
} | |
/** | |
* The function can be use for delete reference record from sys_file_reference table | |
* `detach` method only delete sys_file and update sys_file_reference 0 so for that, | |
* we will have many garbage/unused records in sys_file_reference. | |
* This function will delete those fileReference when gallery images will be delete | |
* | |
* remove fileReference from DB and file source | |
*/ | |
public function removeGalleryReference($media){ | |
if($media){ | |
$fileReferenceUid = $media->getUid(); | |
// remove sys_file_reference record | |
$queryBuilderFileReference = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference'); | |
$queryBuilderFileReference->delete('sys_file_reference') | |
->where( | |
$queryBuilderFileReference->expr()->eq('uid', $fileReferenceUid) | |
)->execute(); | |
return true; | |
} | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Location: your_ext/Classes/Domain/Model/FileReference.php | |
namespace VENDOR\YourExt\Domain\Model; | |
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference { | |
/** | |
* Uid of a sys_file | |
* | |
* @var integer | |
*/ | |
protected $originalFileIdentifier; | |
/** | |
* @param \TYPO3\CMS\Core\Resource\FileReference $originalResource | |
*/ | |
public function setOriginalResource(\TYPO3\CMS\Core\Resource\FileReference $originalResource) { | |
$this->originalResource = $originalResource; | |
$this->originalFileIdentifier = (int)$originalResource->getOriginalFile()->getUid(); | |
} | |
/** | |
* setFile | |
* | |
* @param \TYPO3\CMS\Core\Resource\File $falFile | |
* @return void | |
*/ | |
public function setFile(\TYPO3\CMS\Core\Resource\File $falFile) { | |
$this->originalFileIdentifier = (int)$falFile->getUid(); | |
$this->uidLocal = (int)$falFile->getUid(); | |
} | |
/** | |
* Gets the uidLocal | |
* | |
* @return int uidLocal | |
*/ | |
public function getUidLocal(){ | |
return $this->originalFileIdentifier; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<f:comment>Location: your_ext/Resources/Private/Templates/FalUpload/Edit.html</f:comment> | |
<f:form action="updateMedia" object="{falUpload}" objectName="falUpload" novalidate="novalidate" enctype="multipart/form-data" id="uploadmedia"> | |
<f:comment> SINGLE IMAGE upload/delete/download </f:comment> | |
<f:form.upload name="teaserImage" id="uploadsingle" /> | |
<div class="row"> | |
<f:if condition="{falUpload.teaserImage}"> | |
<div class="col-sm-12 col-md-4 col-lg-4"> | |
<div class="thumbnail"> | |
<div class="thumb-preview"> | |
<a class="thumb-image" href="{falUpload.teaserImage.originalResource.publicUrl}"> | |
<f:image src="{falUpload.teaserImage.originalResource.publicUrl}" width="340c" height="309" class="img-responsive" /> | |
</a> | |
<div class="thumb-options"> | |
<a href="{falUpload.teaserImage.originalResource.publicUrl}" class="download-file" download><i class="fa fa-download"></i></a> | |
<f:link.action action="deleteMedia" arguments="{falUpload:falUpload,media:falUpload.teaserImage,fieldName:'teaserImage'}" class="delete"><i class="fa fa-trash-o"></i></f:link.action> | |
</div> | |
</div> | |
</div> | |
</div> | |
</f:if> | |
</div> | |
<f:comment> MULTIPLE IMAGE upload/delete/download/checkbox to delete multiple </f:comment> | |
<f:form.upload name="gallery" id="uploadmulti" multiple="1" /> | |
<div class="row"> | |
<f:if condition="{falUpload.gallery}"> | |
<f:for each="{falUpload.gallery}" as="galleryList" iteration="iterator"> | |
<div class="col-sm-12 col-md-4 col-lg-4"> | |
<div class="thumbnail"> | |
<div class="thumb-preview"> | |
<a class="thumb-image" href="{galleryList.originalResource.publicUrl}"> | |
<f:image src="{galleryList.originalResource.publicUrl}" width="340c" height="309" class="img-responsive" /> | |
</a> | |
<div class="thumb-options"> | |
<div class="mg-option checkbox-custom checkbox-inline"> | |
<f:form.checkbox id="gallery_{iterator.cycle}" name="media[]" value="{galleryList.uid}" /> | |
<label for="gallery_{iterator.cycle}"> </label> | |
</div> | |
<div class="mg-group pull-right"> | |
<a href="{galleryList.originalResource.publicUrl}" class="download-file" download><i class="fa fa-download"></i></a> | |
<f:link.action action="deleteMedia" arguments="{falUpload:falUpload,media:galleryList,fieldName:'gallery'}" class="delete"><i class="fa fa-trash-o"></i></f:link.action> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</f:for> | |
</f:if> | |
</div> | |
</f:form> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment