4

在我们的例子中,我们有一个表 A,其中包含使用表 B 的 IRRE 记录。在后端模块中,我们导入一个 XML 文件来为表 B 导入这些记录。

表 A 的所有记录/数据均可用。表 B 的所有数据都可用,新的 uids/标识符除外。

基于https://docs.typo3.org/typo3cms/CoreApiReference/6.2/ApiOverview/Typo3CoreEngine/Database/我必须NEWxxxx为所有新创建的记录设置标识符。

我一次导入大量记录。我可以在循环中生成这些标识符并一次处理所有记录,还是必须按记录运行整个数据映射处理记录?

除了标识符之外,我是否必须在包含 IRRE 记录的父记录上设置任何字段?

不涉及翻译/工作区/其他关系。

谢谢你的帮助。

4

1 回答 1

8

TYPO3 中的 DataHandler 使用以下数组结构来创建新记录或更新现有记录 - 这在 TYPO3 CMS 8 之前有效并包括在内:

$dataMap = ['<table-name>' => [
    '<record-uid>' => ['<field-name>' => '<field-value>']
];

现有记录使用记录字段的整数值uid,例如123,新记录使用一些以 为前缀的随机但唯一标识符NEW,例如NEWa2b3c4f8uniqid('NEW', true)- 创建,因为 TYPO3 CMS 7StringUtility::getUniqueId('NEW')可以而且应该用于此。

通用示例

假设应创建以下记录:

  • 表格中的新内容元素tt_content
  • sys_file_reference字段表的两个新内联文件引用tt_content.image
    • sys_file使用 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,NEWdef123,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 = 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'];

笔记

在上面的示例中直接为 field 定义引用tt_content.image,它可以包含NEW...id 以及现有的整数 id。TYPO3 中所有引用类型的行为都是相同的:

  • TCA 类型inline,适用于所有变体(普通foreign_field、、、MM
  • TCA 类型select, 适用于所有变体 (plain, MM)
  • TCA 类型group, 适用于所有变体 (plain, MM)

传递数据DataHandler可确保创建日志条目,并且在大多数情况下,可以使用 TYPO3 的历史/回滚模块恢复修改。

除此之外,还可以执行批量操作 - 的调用DataHandler不仅限于聚合(tt_content上面示例中的记录)。但是,NEW...id 必须是唯一的,并且在大规模执行期间不得重复使用以避免副作用。

转换为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 核心$id = StringUtility::getUniqueId('NEW')用于创建这些唯一标识符。但是,这也可以通过使用来实现$id = 'NEW' . bin2hex(random_bytes(10);- 标识符对于这个特定的过程必须是唯一的。

于 2017-03-24T12:06:47.267 回答