You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TCA字段foreign_table_where遵循Extbase storage pid配置?

问题描述

我开发了一款支持多语言、多域名的Extbase扩展,遇到了TCA字段相关问题。控制器与仓储可根据各根页面定义的persistence.storagePid常量获取结果,但selectMultipleSideBySide类型的TCA字段无法实现该效果,当前配置如下:

'config' => [
 'type' => 'select',
 'renderType' => 'selectMultipleSideBySide',
 'MM' => 'tx_lmyext_domain_model_model1_mm',
 'foreign_table' => 'tx_myext_domain_model_model1',
 'foreign_table_where' => ' AND tx_myext_domain_model_model1.sys_language_uid IN (-1,###REC_FIELD_sys_language_uid###) ORDER BY tx_locationslist_domain_model_model1.title',
 'maxitems' => 1,
],

持久化设置对该查询无作用,选择字段右侧显示了数据库中所有对象,示例如下:

多选左列多选右列
来自PID 200的对象
来自PID 200的对象
来自PID 90的对象 <- 不应在此处

选中“来自PID 90的对象”后,前端因仓储查询设置不会显示,但编辑器仍可在TCA字段中选择它。

请问是否有办法仅显示指定PID的条目,类似已移除的###STORAGE-PID###标签的效果(如AND tx_myext_domain_model_model1.pid IN (###STORAGE-PID###))?

目前我用AND tx_myext_domain_model_model1.pid IN (###SITEROOT###)实现了近似效果,但这要求所有对象存于各域名的根页面,而我希望将其存于文件夹中。
由于PID会随页面树中选中的页面变化,无法直接在查询中写死PID。
我尝试过PAGE_TSCONFIG_ID标签,效果尚可,但希望仅通过TypoScript常量完成各域名的配置。
也曾尝试使用group元素,但需逐个选择条目,且仍能选中错误PID的对象。
在仓储中通过initializeObject()设置storage pid,也未改变TCA中的可选条目。

解决方案

方法1:通过TypoScript常量传递存储PID到TCA

可以读取扩展配置中对应的存储PID,动态注入到TCA的查询条件中。在扩展的Configuration/TCA/Overrides/目标表.php中添加代码:

// 读取TypoScript中配置的存储PID
$storagePids = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class)
    ->get('你的扩展密钥', 'storagePid');

// 拼接查询条件到TCA配置
if ($storagePids) {
    $GLOBALS['TCA']['目标表']['columns']['关联字段名']['config']['foreign_table_where'] .= ' AND tx_myext_domain_model_model1.pid IN (' . $storagePids . ')';
}

多域名场景下,确保每个根页面的TypoScript常量正确覆盖plugin.tx_你的扩展.persistence.storagePid,并同步到扩展配置中。

方法2:结合站点配置动态获取存储PID

在站点配置中添加自定义字段存储模型文件夹PID,然后在TCA中根据当前编辑页面的站点读取对应值:

$currentPageId = (int)$_GET['id'] ?? 0;
$site = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Site\SiteFinder::class)
    ->getSiteByPageUid($currentPageId);
$storagePid = $site->getConfiguration()['你的扩展']['storagePid'] ?? '';

if ($storagePid) {
    $GLOBALS['TCA']['目标表']['columns']['关联字段名']['config']['foreign_table_where'] .= ' AND tx_myext_domain_model_model1.pid IN (' . $storagePid . ')';
}

这种方式支持多站点独立配置存储PID,无需硬编码值,适配不同域名的文件夹存储需求。

方法3:使用userFunc生成动态查询条件

如果需要更灵活的逻辑(比如根据当前编辑页面的根页面匹配对应存储PID),可以自定义userFunc来扩展查询条件:
首先修改TCA配置:

'config' => [
    // 原有配置...
    'foreign_table_where' => 'AND tx_myext_domain_model_model1.sys_language_uid IN (-1,###REC_FIELD_sys_language_uid###) ORDER BY tx_locationslist_domain_model_model1.title',
    'userFunc' => \你的命名空间\Tca\ForeignTableWhereHandler::class . '->addStoragePidCondition',
],

然后创建对应的处理类:

<?php
namespace 你的命名空间\Tca;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Site\SiteFinder;

class ForeignTableWhereHandler
{
    public function addStoragePidCondition(&$parameters)
    {
        $currentPageId = (int)$_GET['id'] ?? 0;
        $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageUid($currentPageId);
        // 从站点配置或TypoScript读取存储PID
        $storagePid = $site->getConfiguration()['plugin.tx_你的扩展.persistence.storagePid'] ?? '';
        
        if ($storagePid) {
            $parameters['additionalWhereClause'] .= ' AND tx_myext_domain_model_model1.pid IN (' . $storagePid . ')';
        }
    }
}

这种方式完全自定义逻辑,适配复杂的多站点、多存储PID场景。

注意事项

  • 已移除的###STORAGE-PID###标签无法再使用,不要在静态TCA中尝试。
  • 多个存储PID用逗号分隔,例如200,201。
  • 修改TCA后必须清理TYPO3缓存才能生效。

内容的提问来源于stack exchange,提问作者Birne125

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:08:24