TYPO3 DataHandler:复制记录并将其与其自身关联 --> 进入循环

问题描述 投票:0回答:2

我正在开发一个具有重复日期的活动扩展。因此,我有一个重复的日期模式并复制每个日期的记录。所以记录与其自身有关系: - 主要活动 -- N 个子事件

目前,我使用DataHandler方法copyRecord,效果非常好。但这只是复制记录,而不映射关系。 - 主要事件 --> 数据库中应该有子项的计数 -- N 个子事件 --> 应该与其父主事件有关系

数据库应如下所示: 赛事 1(主赛事)| uid: 1 |事件: 0 | recurring_children: 3 (计数) 活动副本1 | uid: 2 |事件: 1 |重复儿童:0 活动副本2 | uid: 3 |事件: 1 |重复儿童:0 活动副本3 | uid: 4 |事件: 1 |循环子代:0

我尝试了多种方法,但没有一个没有问题。

以下尝试在数据库中设置关系,但创建更多事件(我猜,这个循环,我必须构建一个条件以避免用重复项填充数据映射):

    public function processDatamap_afterDatabaseOperations(
    $status,
    $table,
    $recordUid,
    array $fields,
    \TYPO3\CMS\Core\DataHandling\DataHandler $parentObject){

    $event = BackendUtility::getRecord($table, $recordUid);
    if ($status === 'update') {
        /** @var \TYPO3\CMS\Core\DataHandling\DataHandler $tce */
        $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
        $tce->start(array(), array());
        $overrides = [
            'is_recurring_parent' => 0,
            'is_recurring_child' => 1,
            'recurring_weekdays' => '',
            'recurring_period_end' => '0000-00-00',
            'event' => $recordUid,
            'title' => 'FOOBAR'
        ];

        if ($event['is_recurring_parent']) {
            $foobar = $tce->copyRecord('tx_technoseumevents_domain_model_event', $event['uid'], $event['pid'], false, $overrides);
        }

T3版本8.7

抱歉,我第一次使用数据处理程序来执行复杂的任务。也许有人给我提示...

typo3 typo3-8.x typo3-extensions
2个回答
1
投票

首先发生的递归性表明您的架构存在问题,可能值得在此问题之前解决,因为它可以从根本上解决问题,而不是治疗症状。通常,记录不应与其自身相关 - 但也就是说,递归可能以其他方式发生,并且在您的用例中可能无法避免。

解决问题的建议:

  • 考虑添加一个条件,以防止在您需要操作的表以外的表上调用您的代码。仅此一点实际上可能就是您的副本递归的原因,因此这是第一个需要处理的问题。
  • 如果可能,并且您不担心短路问题,例如更改记录的标题 TCA 字段以在前面加上“副本”,或导致副本被隐藏,则可以切换到
    copyRecord_raw
    。它需要稍微不同的参数(与调用
    copyRecord
    相比,您可能需要重构以将一些参数作为覆盖数组的一部分传递)。这样做可以防止对您复制的子项调用钩子。
  • 您正在使用嵌套的 DataHandler 实例 - 最好在示例中的
    $dataHandler
    实例上调用该方法。 DataHandler 维护一个复制堆栈,但是(部分)它仅在您在同一实例中执行操作且仅针对某些特定挂钩(即预类型和非全局挂钩)时才起作用。
  • 最后,存在一个运行时缓存条目,其中包含已复制的记录数组。尽管访问和存储此缓存条目中的条目的实用程序方法不可公开访问 - 因此您无法从挂钩类中调用它们 - 您可以读取条目数组,对其进行操作并将其放回以防止对同一记录进行递归处理。请参阅 DataHandler 中的 isNestedElementCallRegistered 方法 (https://github.com/TYPO3/TYPO3.CMS/blob/v8.7.17/typo3/sysext/core/Classes/DataHandling/DataHandler.php#L9034)。

最后一点:数据库操作后的钩子有时可能会在您不期望的时候被调用。例如,如果您复制一条记录并移动它(例如:副本来自 UI,而不是以编程方式),您在

$fieldArray
中收到的数组可能不是最终的数组(例如,
pid
可能是一个意想不到的价值)。不了解这一点和上述特性也可能会增加无意中导致递归操作的危险。

编辑:如果您在 TCA 中使用双向关系,那么删除一侧也可能会改善情况。例如,每个“日期”不一定必须知道它与哪个事件相关联。需要考虑的事情。


0
投票

我收到以下错误

(1/1) 错误

在 null 上调用成员函数 backendCheckLogin()

© www.soinside.com 2019 - 2024. All rights reserved.