I am using the DataHandler to create and move pages like in this snippet. While new pages are created fine, existing subpages are not moved into their newly created parents.
$data = [
'pages' => [
'NEW_IT' => [
'pid' => 1,
'hidden' => false,
'title' => 'IT',
],
591 => [
// this is not set
'pid' => 'NEW_IT',
// but this is set
'title' => 'I am a child of IT',
],
]
];
I tried ['pages'][591]['move'] = 'NEW_IT'
but also to no avail.
I also tried '591'
instead of 591
, dataHandler->reverseOrder = true
and dataHandler->copyTree = true
.
dataHandler->errorLog
is empty.
$data = [
'pages' => [
'NEW_IT' => [
'pid' => 1,
'hidden' => false,
'title' => 'IT',
],
'NEW_IT_SUB' => [
'pid' => 'NEW_IT',
],
]
];
Also I wonder which IDs (NEW<any string>
vs. NEW<base64>
etc.) are acceptable as I did not find anything in the documentation and the examples use different styles. The "must be unique" is obvious. But I don't get why some people generate UUIDs there.
EDIT: I opened a forge ticket: https://forge.typo3.org/issues/90939
I have checked the code / DataHandler in v8/v9 and master. The corresponding logic in the DataHandler has not changed for that.
I have created a test case and xdebugged through it, also i was pretty sure after looking into the code, what happens. But have done this to validate that "it is working the way i think the code tells" - although it is not the way you expected. And I'm too. Remembering that I had such an issue last year through a migration script, but did not digged deeper into it (because of time), i changed it and made this as loops.
Creating page => retrieving the replaced id => using it for the other data commands.
The datahandler loops through each record for a table in the provided dataset array.
foreach ($this->datamap[$table] as $id => $incomingFieldArray) { ... }
First it prepares some stuff, and calling registered processDatamap_preProcessFieldArray
hooks, it checks the given $id
// Is it a new record? (Then Id is a string)
if (!MathUtility::canBeInterpretedAsInteger($id)) { ... } else { ... }
If the id is not an integer or an integer string, it executed the true-branch, otherwise the false-branch. So long, so good.
The TRUE-Branch handles creating a new record (page, tt_content, ...), adding the replacement for the provided NEWxxx as substituion and so on.
It also checks, if a 'pid' field is in the record, and if it contains with NEW. If it is so, it replaces NEWxxx with the uid of the previously created record.
On the otherhand, if $id is not a integer or a integer string, it assumes it is an existing record. (FALSE-Branch). On this branch there is no checking for 'pid', if it contains NEW and looking up for replacement.
But .. why is there no error ? If it did not replace it, it should crash or someting like that ? - Yes, that is what we would assume - at least for that.
'pid' is always ignored in appling to the record ( see method fillInFieldArray()
)
switch ($field) {
case 'uid':
case 'pid':
// Nothing happens, already set
break;
...
}
and so .. as long as you do not provide further fields/values in the second page array ( that with the integer id and the pid with NEW from the initial), it has nothing to do. Nothing to do is not an error - and so, it do nothing and even do not notify anything about it.
Is it a bug ? Don't know, personally I would say yes. But maybe this should be created as an issue, and eventually discussed with the core developer/other contributers.
Maybe there were/are reasons WHY it only do this one run.
Either the documentation should be changed to make clear, that 'pid' replacement only works, id $id => [] is also a new / playholder id .. or you have to do it in 2 rounds.
Or .. put as as feature/bug to the issue tracker, and let's discuss it. And maybe giv it a try to implement it in the FALSE/existing record branch too. But let's heare some other opionons about it.
If others thing this should be also be done for the existing records in the same round, I would take the time tommorrow/at the weekend to provide an patch for it / the issue. (Would be fun to fight with the datahandler ).