Project

General

Profile

Actions

Bug #94549

closed

Flexform section change order when deleting item

Added by Paul Kamma almost 3 years ago. Updated 6 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Backend API
Target version:
-
Start date:
2021-07-13
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
10
PHP Version:
7.4
Tags:
flexform asort section order save
Complexity:
Is Regression:
Sprint Focus:

Description

I've discoverd an odd behaviour with FlexForms in combination with sections. When a section contains at least 17 Items and (After a save) a item is removed and then saved then the order is changed of the items.

I tried to find the root of this behaviour and ended in the DataHandler

https://github.com/TYPO3/TYPO3.CMS/blob/10.4/typo3/sysext/core/Classes/DataHandling/DataHandler.php#L2336

The asort cause the isse but I don't know why. I made some independent tests with the data which gets passed to the method and noticed something.

$data = [
   "60ed404104921816320239" => "",
   "60ed524b3b735029561451" => "",
   "60ed56d915a2d143366883" => "",
   "60ed550b0146a452956314" => "",
   "60ed523e70373667109521" => "",
   "60ed5241903ef623057117" => "",
   "60ed5243d6b64443066657" => "",
   "60ed5246a244d957906702" => "",
   "60ed5248d9115418847870" => "",
   "60ed404526917612536689" => "",
   "60ed52531e488403102629" => "",
   "60ed525043157609282528" => "",
   "60ed52551e75e407845160" => "",
   "60ed525714df1794924549" => "",
   "60ed52591c447113268801" => "",
   "60ed525ad7160719857266" => "DELETE",
];

asort($data);
print_r($data);

//Output
Array
(
    [60ed404104921816320239] => 
    [60ed524b3b735029561451] => 
    [60ed56d915a2d143366883] => 
    [60ed550b0146a452956314] => 
    [60ed523e70373667109521] => 
    [60ed5241903ef623057117] => 
    [60ed5243d6b64443066657] => 
    [60ed5246a244d957906702] => 
    [60ed5248d9115418847870] => 
    [60ed404526917612536689] => 
    [60ed52531e488403102629] => 
    [60ed525043157609282528] => 
    [60ed52551e75e407845160] => 
    [60ed525714df1794924549] => 
    [60ed52591c447113268801] => 
    [60ed525ad7160719857266] => DELETE
)

The Order is correct, now lets try the same with one item more:

$data2 = [
   "60ed404104921816320239" => "",
   "60ed524b3b735029561451" => "",
   "60ed56d915a2d143366883" => "",
   "60ed550b0146a452956314" => "",
   "60ed523e70373667109521" => "",
   "60ed5241903ef623057117" => "",
   "60ed5243d6b64443066657" => "",
   "60ed5246a244d957906702" => "",
   "60ed5248d9115418847870" => "",
   "60ed404526917612536689" => "",
   "60ed52531e488403102629" => "",
   "60ed525043157609282528" => "",
   "60ed52551e75e407845160" => "",
   "60ed525714df1794924549" => "",
   "60ed52591c447113268801" => "",
   "60ed57dcde329615532849" => "",
   "60ed57e02d30b476661246" => "DELETE",
];

asort($data2);
print_r($data2);

//Output
Array
(
    [60ed404104921816320239] => 
    [60ed404526917612536689] => 
    [60ed57dcde329615532849] => 
    [60ed52591c447113268801] => 
    [60ed525714df1794924549] => 
    [60ed52551e75e407845160] => 
    [60ed525043157609282528] => 
    [60ed52531e488403102629] => 
    [60ed5248d9115418847870] => 
    [60ed524b3b735029561451] => 
    [60ed5246a244d957906702] => 
    [60ed5243d6b64443066657] => 
    [60ed5241903ef623057117] => 
    [60ed523e70373667109521] => 
    [60ed550b0146a452956314] => 
    [60ed56d915a2d143366883] => 
    [60ed57e02d30b476661246] => DELETE
)

You notice that many items are not in the correct order as the input.

Wo why did this happen? Is the asort event required?


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Task #99952: Avoid GU::_GP() in DataHandlerClosed2023-02-14

Actions
Actions #1

Updated by Jonas Eberle almost 3 years ago

PHP asort() is has not been a stable sorting algorithm (Note: on https://www.php.net/manual/en/function.asort.php).
It is implemented in PHP 8.0+ https://github.com/php/php-src/pull/5236 (https://wiki.php.net/rfc/stable_sorting). I haven't found a polyfill but could be solved with uasort().

Actions #2

Updated by Paul Kamma almost 3 years ago

Ok that's intresting.

I found this library
https://github.com/vanderlee/PHP-stable-sort-functions

The asort with this works but I bet that someone have a better solution then using an external library.

Actions #3

Updated by Robert Wolle about 2 years ago

  • Tags changed from flexform asort to flexform asort section order save

In general it has to be addressed for PHP 7.4 and the function asort needs to be replaced.

I added a mehtod asort in the DataHandler-Class:

public function asort(array &$array, $sort_flags = SORT_REGULAR){
    $index = 0;
    foreach ($array as &$item) {
        $item = array($index++, $item);
    }

    $result = uasort($array, function($a, $b) use($sort_flags) {
        if ($a[1] == $b[1]) {
            return $a[0] - $b[0];
        }

        $set = array(-1 => $a[1], 1 => $b[1]);
        asort($set, $sort_flags);
        reset($set);
        return key($set);
    });

    foreach ($array as &$item) {
        $item = $item[1];
    }

    return $result;
}

and replaced

asort($actionCMDs[$key]);

with
$this->asort($actionCMDs[$key]);

in the method _ACTION_FLEX_FORMdata.

Actions #4

Updated by Christian Kuhn 6 months ago

Hey.

I'm pretty confident we can close here:

  • There was a rewrite of DataHandler->_ACTION_FLEX_FORMdata() with #99952 for v12, which may or may not have fixed the issue.
  • More importantly: v12 requires PHP ^8.1. asort() has been made stable with PHP 8.0, it no longer mixes the order when the value is identical.
  • We will no longer fix this issue in v11, since it's not 'critical' or security related. If you really need this in v11 projects, we'd recommend a DataHandler patch for the affected project.
Actions #5

Updated by Christian Kuhn 6 months ago

  • Related to Task #99952: Avoid GU::_GP() in DataHandler added
Actions #6

Updated by Christian Kuhn 6 months ago

  • Status changed from New to Closed
Actions #7

Updated by Christian Kuhn 6 months ago

Note Jonas: Thanks for the 'stable' information. This helped a lot to understand what is going on.

Actions

Also available in: Atom PDF