Skip to content
Advertisement

Updating data after backend action TYPO3 11.5

Working on Typo3 11.5.13

I’m trying to update some data on my pages table after a be_user changed something. I read something about setting hooks for that purpose but I can’t seem to find a good explanation as to how hooks actually function within Typo3 and how to configure one, especially for my purpose.

As far as I can see, this problem I have should be quickly solved but the complexity of the typo3 doc is hindering my progress again. Maybe you can explain how I can accomplish my goal.

Simply put: A backend user is supposed to choose a date in a datepicker and some dateinterval in the settings of a page. After saving(Or even after picking both values) I would like to update the “Next time happening” field the user can see but not change to be updated to the given date plus the dateinterval chosen.

If you have some sort of idea please share it with me.

Advertisement

Answer

Generally hooks are not that good documented. Modern Events are easier to find and better commented. However, if I get your use case right, using DataHandler Hooks are they way to go. That mean, every place which are using the DataHandler to save data are then covered. The backend form engine are using DataHandler.

Basic information about hooks in the core documentation:

How to identify or find hooks, events, signalslots (depending on TYPO3 version):

Introduction or “DataHandler” explained:

Basicly, DataHandler has two main kind of processings:

  • Data manipulations -> process_datamap()
  • Actions (move,delete, copy, translate) -> process_cmdmap()

For DataHandler, you register a class only for datamap and/or processmap, not for a concrete hook itself.

// <your-ext>/Classes/Hooks/MyDataHandlerHooks.php
namespace <Vendor><YourExt>Hooks;
class MyDataHandlerHooks {}

// <your-ext>/ext_localconf.php
// -> for cmdmap hooks
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['yourextname']
  = VendorYourExtHooksMyDataHandlerHooks::class;
// -> for datamap hooks
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['yourextname']
  = VendorYourExtHooksMyDataHandlerHooks::class;

You need to register your class only for these kind of hooks you want to consume. And you do not have to implement all hooks.

Hooks can be looked up in TYPO3CMSCoreDataHandlingDataHandler (as hooks are normally searched.

Next step would be to find the proper hook for your use case, and simply add that hook method to your class. Naming the hooks are not chooseable for DataHandler hooks.

TYPO3 Core tests contains a test fixture class for DataHandler hooks – which is not complete, but contains at least the most common ones (along with the needed method signatures) since 8.x:

So you may have to look into the version for your core version to get a feeling how the signature should look for that core version.

Generally I would guess one of these two:

  • processDatamap_postProcessFieldArray(): Hook with prepared field array, and you can simple add your new stuff to write or update it and it will be saved. Good if you need to change the record directly.
  • processDatamap_afterDatabaseOperations(): Hook after record has been changed. This is a good startpoint if you need to do other things after saving a record.

Given your usecase, I would tip on the first one, so here a example implementation (in the class and registering as datamap hook as explained above):

// <your-ext>/Classes/Hooks/MyDataHandlerHooks.php
namespace <Vendor><YourExt>Hooks;
class MyDataHandlerHooks {

    /**
     * @param string|int $id
     */
    public function processDatamap_postProcessFieldArray(
        string $status,           // Status of the current operation, 'new' or 'update'
        string $table,            // The table currently processing data for 
        $id,                      // The record uid currently processing data for, 
                                  // [integer] or [string] (like 'NEW...') 
        array &$fieldArray,        // The field array of a record, cleaned to only
                                  // 'to-be-changed' values. Needs to be &$fieldArray to be considered reference.
        DataHandler $dataHandler
    ): void
    {
        // $fieldArray may be stripped down to only the real fields which
        // needs to be updated, mainly for $status === 'update'. So if you
        // need to be sure to have correct data you may have to retrieve
        // the record to get the current value, if not provided as with new
        // value.

        if ($table === 'be_users'
            && $status === 'update'
            && array_key_exists('target_field_name', $fieldArray)
        ) {
            $valueToReactTo = $fieldArray['target_field_name'];
            if ($valueToReactTo === 'some-check-value') {
              // needs not to be there
              $fieldArray['update-field'] = 'my-custom-value';
            }
        }
    }

}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement