处理打字错误中的空 dataWrap

Handle empty dataWrap in typoscript

我有 'inherited' 以下打字错误片段,当在 tx_extension_domain_model_item 记录中引用时,它应该会生成呈现的 tt_content 记录:

lib.recordBasedHighlight = CONTENT
lib.recordBasedHighlight {
    table = tt_content
    select.orderBy = sorting
    select.languageField = sys_language_uid 

    select.andWhere.stdWrap.cObject = TEXT
    select.andWhere.stdWrap.cObject {
        dataWrap = DB:tx_extension_domain_model_item:{GP:tx_extension_pi1|item}:referenced_content
        wrap3 = uid IN ({|})
        insertData = 1
    }
    select.pidInList.stdWrap.cObject = TEXT
    select.pidInList.stdWrap.cObject {
        dataWrap = DB:tx_extension_domain_model_item:{GP:tx_extension_pi1|item}:pid
        wrap3 = {|}
        insertData = 1
    }

    renderObj < tt_content
    renderObj.list.10 >
}

referenced_content 字段引用了一些实际内容时(该值将是 tt_content uid),这会很好地工作。如果不是这种情况,wrap3 语句会导致 uid IN (),正如预期的那样,会引发 SQL 错误。

我尝试将 required = 1 添加到 .select.andWhere.stdWrap.cObject 配置中,这导致在未引用任何内容时从 pidInList 中的 pid 获取所有内容,因为 andWhere 子句在该字段为空时被清空。

应如何更改上述脚本片段,以便呈现正确的 tt_content 记录,而当 referenced_content 为空时不呈现任何记录?

ifEmpty 做点什么似乎很明显,但我就是做不对。直到我试图从根本上改变一些事情。以下对我有用:

lib.recordBasedHighlight = CONTENT
lib.recordBasedHighlight {
    table = tt_content
    select.orderBy = sorting
    select.languageField = sys_language_uid 

    select.andWhere.stdWrap.cObject = TEXT
    select.andWhere.stdWrap.cObject {
        stdWrap {
            cObject = TEXT
            cObject {
                # NOT SAFE: GET/POST parameter is passed on to the database without sanitation
                dataWrap = DB:tx_extension_domain_model_item:{GP:tx_extension_pi1|item}:referenced_content
                wrap3 = {|}
                insertData = 1
            }
            ifEmpty.cObject = TEXT
            ifEmpty.cObject.value = 0
        }
        wrap = uid IN (|)
    }
    select.pidInList.stdWrap.cObject = TEXT
    select.pidInList.stdWrap.cObject {
        # NOT SAFE: GET/POST parameter is passed on to the database without sanitation
        dataWrap = DB:tx_extension_domain_model_item:{GP:tx_extension_pi1|item}:pid
        wrap3 = {|}
        insertData = 1
    }

    renderObj < tt_content
    renderObj.list.10 >
}

referenced_content 字段为空时,这会导致 andWhere 变为 uid IN (0)。这导致没有 tt_content 记录被呈现,这正是我所追求的。

我知道这个片段会产生一个 SQL 查询,事先已知该查询不会 return 任何结果,但另一种方法是编写更好的错字(不是我的强项)或将其全部重写为 userFunc。在任何情况下,它都会做更多的工作,并且 TYPO3 是相当资源密集型的,单个查询更多不会受到伤害。所以我对解决方案很满意。

编辑

正如 Thomas Löffler 在对原始问题的第一条评论中正确指出的那样,代码片段中存在重大安全遗漏:使用的 GET 参数在传递到数据库之前未经过清理。我没有花时间重写代码片段以包括建议的安全措施,尽管在使用代码片段的项目中这不是那么相关(请参阅我的评论以获得更详细的解释)。这并不意味着代码片段在所有情况下都是安全的,这让我在这个答案中包含一个警告:代码片段本身并不安全!请自行决定使用此代码段!