Bug #82784

DataHandler: copyRecords doesn't set sorting correctly for negative $destPid

Added by Sebastian Michaelsen over 3 years ago. Updated over 3 years ago.

Should have
DataHandler aka TCEmain
Target version:
Start date:
Due date:
% Done:


Estimated time:
TYPO3 Version:
PHP Version:
Is Regression:
Sprint Focus:


In DataHandler->copyRecord() accepts a $destPid which (according to the phpDoc) can either contain a page id or (indicated by a negative number) a content uid after which the source record is copied to. This "convention" is also used in DataHandler->moveRecord().

However DataHandler->copyRecord() does not implement the functionality. Only DataHandler->moveRecord() does.

How to reproduce:

            $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
            $data = [
                'tt_content' => [
                    $sourceContentUid=> [
                        'copy' => ($targetContentUid * -1),
            $dataHandler->start([], $data);

The copied element will just receive the sorting value of the source element instead of being sorted after the target content element.


Updated by Coders.Care Extension Team over 3 years ago

AFAICS sorting is done in process_datamap, which is called by process_cmdmap in case of 'copy' but not in case of 'move', since usually there is no data to be processed, when moving a record.

So sorting should be handled at lines 1058 to 1082 of \TYPO3\CMS\Core\DataHandling\DataHandler

// The $pid_value is now the numerical pid at this point
if ($OK) {
    $sortRow = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
    // Points to a page on which to insert the element, possibly in the top of the page
    if ($pid_value >= 0) {
        // If this table is sorted we better find the top sorting number
        if ($sortRow) {
            $fieldArray[$sortRow] = $this->getSortNumber($table, 0, $pid_value);
        // The numerical pid is inserted in the data array
        $fieldArray['pid'] = $pid_value;
    } else {
        // points to another record before ifself
        // If this table is sorted we better find the top sorting number
        if ($sortRow) {
            // Because $pid_value is < 0, getSortNumber returns an array
            $tempArray = $this->getSortNumber($table, 0, $pid_value);
            $fieldArray['pid'] = $tempArray['pid'];
            $fieldArray[$sortRow] = $tempArray['sortNumber'];
        } else {
            // Here we fetch the PID of the record that we point to...
            $tempdata = $this->recordInfo($table, abs($pid_value), 'pid');
            $fieldArray['pid'] = $tempdata['pid'];

Updated by Oliver Hader over 3 years ago

  • Status changed from New to Accepted

Should be verified with an additional DataHandler functional test using negative PID values

Also available in: Atom PDF