DataHandler в TYPO3 использует следующую структуру массива для создания новых или обновления существующих записей - это действительно до TYPO3 CMS 8 включительно:
$dataMap = ['<table-name>' => [
'<record-uid>' => ['<field-name>' => '<field-value>']
];
Существующие записи используют целочисленное значение поля записи uid
, например 123
, новые записи используют некоторый случайный, но уникальный идентификатор с префиксом NEW
, например NEWa2b3c4f8
создано uniqid('NEW', true)
- поскольку для этого можно и нужно использовать TYPO3 CMS 7 StringUtility::getUniqueId('NEW')
.
Общий пример
Предположим, будут созданы следующие записи:
- новый элемент содержимого в таблице
tt_content
- two new inline file references for table
sys_file_reference
for field tt_content.image
- referencing to existing
sys_file
record with uid 123
- ссылка на существующую
sys_file
запись с uid 234
// generating unique identifiers for records to be created
$ttContentId = 'NEW58d5079c8741c822627844'; // StringUtility::getUniqueId('NEW')
$fileRefId1st = 'NEW58d506f3cd0c4159344142'; // StringUtility::getUniqueId('NEW')
$fileRefId2nd = 'NEW58d50714c1226092562338'; // StringUtility::getUniqueId('NEW')
Подготовка карты данных
Если внимательно присмотреться к tt_content.image
, это фактически определение (новых) встроенных ссылок, определенных разделенными запятыми значениями новых или существующих записей - это может быть NEWabc,NEWdef
, 123,234,345
или NEWabc,123,NEWdef
, смешивая новые и существующие ссылки на записи.
$dataMap = [
'tt_content' => [
'NEW58d5079c8741c822627844' => [
'title' => 'My new content element',
'bodytext' => 'Look at the following images...',
'CType' => 'textpic',
// $fileRefId1st & $fileRefId2nd, the sorting order is defined by this as well
'image' => 'NEW58d506f3cd0c4159344142,NEW58d50714c1226092562338',
],
],
'sys_file_reference' => [
'NEW58d506f3cd0c4159344142' => [
'uid_local' => 123,
'title' => 'Image #123',
],
'NEW58d50714c1226092562338' => [
'uid_local' => 234,
'title' => 'Image #234',
],
]
];
Подготовка команд-карты
// the command-maps is similar to the data-map to copy, localize, move records
// however, it's not required in this scenario and thus stays empty
$commandMap = [];
Выполнение DataHandler
$dataHandler = new \TYPO3\CMS\Core\DataHandling\DataHandler();
$dataHandler->start($dataMap, $commandMap);
$dataHandler->process_datamap();
// $dataHandler->process_cmdmap(); // if $commandMap should be processed as well
Если вам нужны uid
созданных записей, это можно решить с помощью внутреннего сопоставления записей DataHandler. Например, следующий код разрешает новый uid
созданной записи tt_content
:
// fetching the actual record ID, e.g. results in 333
$ttContentId = $dataHandler->substNEWwithIDs['NEW58d5079c8741c822627844'];
Примечания
Определение ссылок происходит в приведенном выше примере непосредственно для поля tt_content.image
, которое может содержать NEW...
идентификаторов, а также существующие целочисленные идентификаторы. Поведение для всех типов ссылок в TYPO3 одинаково:
- Тип TCA
inline
, для всех вариантов (простой, foreign_field
, MM
)
- Тип TCA
select
, для всех вариантов (простой, MM
)
- Тип TCA
group
, для всех вариантов (простой, MM
)
Передача данных через DataHandler
гарантирует создание записей журнала, и в большинстве случаев модификации можно отменить с помощью модуля истории / отката TYPO3.
Кроме того, можно выполнять массовые действия - вызов DataHandler
не ограничивается только агрегатом (запись tt_content
в приведенном выше примере). Однако NEW...
идентификаторы должны быть уникальными и не должны повторно использоваться во время массового выполнения, чтобы избежать побочных эффектов.
Преобразован в сценарий table_a
& table_b
Если преобразовать это в сценарий table_a
и table_b
исходного вопроса, $dataMap
может выглядеть следующим образом. Конечно, вы должны определить, какие ссылки на table_b
привязаны к table_a
.
$dataMap = [
// existing records of table_a, thus using the real ids
'table_a' => [
'11' => [ 'reference_field' => 'NEWb1,NEWb2' ],
'22' => [ 'reference_field' => 'NEWb3,NEWb4' ],
'33' => [ 'reference_field' => 'NEWb5,NEWb6' ],
],
// new records to be references for table_b, thus using NEW... ids
'table_b' => [
'NEWb1' => [ ... field values of this particular table_b record ... ],
'NEWb2' => [ ... field values of this particular table_b record ... ],
'NEWb3' => [ ... field values of this particular table_b record ... ],
'NEWb4' => [ ... field values of this particular table_b record ... ],
'NEWb5' => [ ... field values of this particular table_b record ... ],
'NEWb6' => [ ... field values of this particular table_b record ... ],
],
];
Примечания к идентификаторам
Идентификаторы вроде NEWb1
намеренно сохранены простыми - обычно эти идентификаторы состоят из префикса NEW
и (псевдо) случайной шестнадцатеричной строки abdc...
.
Ядро TYPO3 использует _ 51_, чтобы создать эти уникальные идентификаторы. Однако этого также можно добиться с помощью $id = 'NEW' . bin2hex(random_bytes(10);
- идентификаторы просто должны быть уникальными для этого конкретного процесса.
person
Oliver Hader
schedule
24.03.2017
NEW...
идентификаторы уникальны и не используются повторно для разных данных записи. - person Oliver Hader   schedule 24.03.2017