Skip to content

Instantly share code, notes, and snippets.

@marble
Forked from ghanshyamgohel/FalUpload.php
Created April 9, 2021 09:04
Show Gist options
  • Save marble/f3db19ec3130d0f616db2f16a9cb2ce2 to your computer and use it in GitHub Desktop.
Save marble/f3db19ec3130d0f616db2f16a9cb2ce2 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
# 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'
);
# 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
}
}
}
}
}
}
<?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);
}
}
<?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();
// remove file reference
$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) {
$storageRepository = $this->objectManager->get(\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 = $this->objectManager->get(\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()));
}
}
<?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;
}
}
<?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();
}
/**
* Gets the uidLocal
*
* @return int uidLocal
*/
public function getUidLocal(){
return $this->originalFileIdentifier;
}
}
<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