I would like to execute some individual code when one of my Extbase domain objects is deleted from the list view in TYPO3 backend.
Thought that it could / would work by overwriting the remove( $o )
method in the according repository like
public function remove( $object ) {
parent::__remove( $object );
do_something_i_want();
}
, but that won't work I guess. Looks like the repository-methods are only called / used by actions of my extension (e.g. if I had some delete-action in a FE- or BE-plugin) but not when the object is just deleted from list view in the backend? I don't use (up to now) any FE/BE-plugin / -actions - only the simple add/edit/delete functions in the backends list view of my storage folder.
Background: I have e.g. two models with some 1:n relation (let's say singer
and song
), where one object includes some uploaded file (album_cover
> pointing to the file's URL in /uploads/myext/
folder); using @cascade
works fine for deleting every song
belonging to a singer
that is deleted, but it won't touch the file uploaded (only) for song.album_cover
- leading to quite some waste over time. So I would love to do some sort of onDeletionOfSinger() { deleteAllFilesForHisSongs(); }
-thing.
(Same thing would apply on deletion of let's say a single song
and it's album_cover
-file.)
Sounds quite easy & common, but I just don't get behind it and found nothing useful - would love some hint / pointing to the right direction :-).
List view uses TCEmain hooks during its operations, so you can use one of them to intersect delete action, i.e.: processCmdmap_deleteAction
Register your hooks class in typo3conf/ext/your_ext/ext_tables.php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][] = 'VENDORNAME\\YourExt\\Hooks\\ProcessCmdmap';
Create a class with valid namespace and path (according to previous step)
file: typo3conf/ext/your_ext/Classes/Hooks/ProcessCmdmap.php
<?php
namespace VENDORNAME\YourExt\Hooks;
class ProcessCmdmap {
/**
* hook that is called when an element shall get deleted
*
* @param string $table the table of the record
* @param integer $id the ID of the record
* @param array $record The accordant database record
* @param boolean $recordWasDeleted can be set so that other hooks or
* @param DataHandler $tcemainObj reference to the main tcemain object
* @return void
*/
function processCmdmap_postProcess($command, $table, $id, $value, $dataHandler) {
if ($command == 'delete' && $table == 'tx_yourext_domain_model_something') {
// Perform something before real delete
// You don't need to delete the record here it will be deleted by CMD after the hook
}
}
}
Don't forget to clear system cache after registering new hook's class
In addition to biesiors answer I want to point out, that there is also a signalSlot for this. So you can rather register on that signal than hooking into tcemain.
in your ext_localconf.php
put:
$signalSlotDispatcher =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterRemoveObject',
'Vendor\MxExtension\Slots\MyAfterRemoveObjectSlot',
'myAfterRemoveObjectMethod'
);
So in your Slot you have this PHP file:
namespace Vendor\MxExtension\Slots;
class MyAfterRemoveObjectSlot {
public function myAfterRemoveObjectMethod($object) {
// do something
}
}
Note thet $object
will be the $object that was just removed from the DB.
For more information, see https://usetypo3.com/signals-and-hooks-in-typo3.html