5

I am writing an extension which allows to upload files in the frontend and backend of a TYPO3 instance. The upload works in both views but if the admin wants to delete an upload in the backend in list view, the "physical" file, which is located on the harddisk of the webserver, will not be deleted, only the sys_file_reference record.

Is there a possibility to tell the tca that in case of a deletion of the upload record the associated file should also be deleted? I've also tried to implement a slot with the following code but nothing happens:

ext_localconf.php:

\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher')->connect(
    'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
    'afterRemoveObject',
    'Kmi\feupload\Slots\MyAfterRemoveObjectSlot',
    'myAfterRemoveObjectMethod'
);

Classes/Slots/MyAfterRemoveObjectSlot.php:

namespace Kmi\feupload\Slots;
class MyAfterRemoveObjectSlot {
    public function myAfterRemoveObjectMethod($object) {
    // do something
    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($object);
    }
}

Has anyone an idea how to solve this? There will be many uploads and if the admin deletes one, the associated file should also be deleted...

Thank you in advance for your help :)

lorenz
  • 4,538
  • 1
  • 27
  • 45
Vanessa-Joyce
  • 183
  • 3
  • 8
  • https://forge.typo3.org/issues/52631 – Zeeshan Apr 20 '15 at 13:58
  • So, do I get you right that you want to delete the underlying file if a file reference is deleted? And the file reference is a relation from your "upload" object? Please clarify, then I can help you. Your SignalSlot will not work because the backend doesn't use Extbase Persistence. But there are solutions using hooks in DataHandler. Please also specify the TYPO3 version, if it's 6.2 or 7 please add the respective tag. – lorenz Apr 20 '15 at 15:11
  • Yes, that's exactly what I want it to do. The file reference is an attribute of my upload object and the class extends \TYPO3\CMS\Extbase\Domain\Model\FileReference. I am using TYPO3 6.2. Thank you – Vanessa-Joyce Apr 20 '15 at 15:22
  • Thank you Zeeshan for your answer. Unfortunately I'm not working on the FILES object but on an upload object of my own class which has a relation to a FILES object. So I have no idea how to solve this. – Vanessa-Joyce Apr 23 '15 at 13:15

2 Answers2

2

Unfortunately I don't have time to create a complete, tested answer ATM but I'm putting together the steps needed and hope that you can work a solution and complete my answer then.

Every manipulation done through a TCEFORM is saved with the DataHandler (formerly called TCEmain). The DataHandler has numerous hooks. I assume that your model "Upload" has a property file which is of type (or extends) \TYPO3\CMS\Extbase\Domain\Model\FileReference.

File references in TCEFORM are added as IRRE elements. So when you remove the file reference and save the Upload object, the following data is (amogst others) sent to DataHandler:

cmd[sys_file_reference][15011][delete]=1

This means that the file reference with uid 15011 must be deleted. I suggest to implement the processCmdmap_deleteAction hook for this.

So you must also check the datamap to find out if the command was executed through a manipulation of an "Upload" record.

ext_localconf.php:

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['your_extension'] = 'My\\Extension\\Hook\\DataHandler';

EXT:your_extension/Classes/Hook/DataHandler.php

This code is untested!

<?php
namespace My\Extension\Hook

class DataHandler {

    /**
     * @param string $table
     * @param int $id
     * @param array $recordToDelete
     * @param $parentObject \TYPO3\CMS\Core\DataHandling\DataHandler
     */
    public function processCmdmap_deleteAction($table, $id, $recordToDelete, $parentObject) {
        if (array_key_exists('tx_myext_domain_model_upload', $parentObject->datamap)) {
            // Parent record of record to delete is of type "tx_myext_domain_model_upload"
            if ($table === 'sys_file_reference' && is_integer($id)) {
                // A file reference was requested to delete
                // Get an instance of the ResourceFactory
                /** @var $resourceFactory \TYPO3\CMS\Core\Resource\ResourceFactory */
                $resourceFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
                // We get the FileReference object for the given id
                $fileReferenceObject = $resourceFactory->getFileReferenceObject($id);
                // Delete the original file of the file reference
                $fileWasDeleted = $fileReferenceObject->getOriginalFile()->delete();
                // @TODO throw a warning if $fileWasDeleted is false                
            }
        }
    }

}

I commented the code so you know which checks are necessary for what.

Don't forget to clear the system cache after defining the hook in ext_localconf.php.

lorenz
  • 4,538
  • 1
  • 27
  • 45
  • #lorenz, you saved my day to delete FAL reference record, and also image/file deleted from respective folder. but what I see, It is delete entire row/record from sys_file_reference not mark as deleted=1. In my case I am happy with this deal ;) again Thank you Man :) – Ghanshyam Gohel Nov 22 '15 at 17:55
0
// delete video or image from sys_file table and sys_file_reference 
//  table (here videourl - sys_file_reference fieldname)
$fileRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileRepository::class);
$fileObjects = $fileRepository->findByRelation('tablename', 'videourl', $id);
foreach ($fileObjects as $fileKey => $fileValue) {
    $delete= $fileValue->getOriginalFile()->delete(); 
}
Bernd Wilke πφ
  • 10,390
  • 1
  • 19
  • 38
Meera
  • 1
  • 3