TYPO3 8.7 使用 Flexform uid 进行查询排序

Fan*_*nor 5 php doctrine typo3 extbase

我遇到了许多 TYPO3 扩展的问题,这些扩展通过 Uid\xc2\xb4s 排序查询结果,这些结果来自后端的 Flexform 插件设置。我尝试创建一个查询,以与插件设置中的 Flexform 相同的顺序给出结果 uid\xc2\xb4s 。就像我选择 data.uid 5 7 和 3 一样,我的查询结果按这个顺序给我这些。

\n\n

例如:

\n\n

网站信息:

\n\n
    \n
  • PHP 7.0
  • \n
  • 错别字3 8.7
  • \n
  • 玛丽亚数据库:10.1
  • \n
  • Debian服务器
  • \n
\n\n

该函数由控制器调用。

\n\n
$partners = $this->partnerRepository->findByUids($this->settings[\'showMainSponsor\']);\n
Run Code Online (Sandbox Code Playgroud)\n\n

$this->settings[\'showMainSponsor\']中的值为 ="3, 4 ,1"。

\n\n

这些是 TYPO3 插件设置中选定区域的 Uid\xc2\xb4s。

\n\n

存储库函数“ findByUids ”看起来像这样。

\n\n
public function findByUids($uids){\n\n    if(!isset($uids) || empty($uids)){\n        return NULL;\n    }\n\n    $uidListString = $uids;\n    if(!is_array($uids)){\n        $uidListString = explode(\',\', $uids);\n    }\n\n    $query = $this->createQuery();\n    $query->getQuerySettings()->setRespectStoragePage(FALSE);\n\n    //here i set the orderings\n    $orderings = $this->orderByField(\'uid\', $uidListString);\n    $query->setOrderings($orderings);\n\n    $query->matching(\n        $query->logicalAnd(\n            $query->in(\'uid\', $uidListString)\n        )\n    );\n\n\n\n    return $query->execute();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里调用一个名为“ orderByField ”的函数来设置所有的排序。

\n\n
/**\n * @param string $field\n * @param array $values\n *\n * @return array\n */\nprotected function orderByField($field, $values) {\n    $orderings = array();\n    foreach ($values as $value) {\n        $orderings["$field={$value}"] =  \\TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface::ORDER_DESCENDING;\n    }\n    return $orderings;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这些通过来自 Flexform 的给定 uid 列表对查询结果进行排序的方法适用于 TYPO3 6.27.6。现在我尝试将此扩展附加到 TYPO3 8.6 项目,但此方法不再起作用。我尝试调试它并在查询中查找。在那里我发现是什么打破了这个查询。不起作用的查询如下所示:

\n\n
SELECT `tx_partner_domain_model_partner`.* FROM `tx_partner_domain_model_partner` `tx_partner_domain_model_partner` WHERE (`tx_partner_domain_model_partner`.`uid` IN (3, 4, 1)) AND (`tx_partner_domain_model_partner`.`sys_language_uid` IN (0, -1)) AND ((`tx_partner_domain_model_partner`.`deleted` = 0) AND (`tx_partner_domain_model_partner`.`t3ver_state` <= 0) AND (`tx_partner_domain_model_partner`.`pid` <> -1) AND (`tx_partner_domain_model_partner`.`hidden` = 0) AND (`tx_partner_domain_model_partner`.`starttime` <= 1506603780) AND ((`tx_partner_domain_model_partner`.`endtime` = 0) OR (`tx_partner_domain_model_partner`.`endtime` > 1506603780))) ORDER BY `tx_partner_domain_model_partner`.`uid=3` DESC, `tx_partner_domain_model_partner`.`uid=4` DESC, `tx_partner_domain_model_partner`.`uid=1` DESC\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在我的 DBMS 上尝试了这个,但失败了。原因是最后3个陈述。

\n\n
`tx_partner_domain_model_partner`.`uid=3` DESC, `tx_partner_domain_model_partner`.`uid=4` DESC, `tx_partner_domain_model_partner`.`uid=1` DESC\n
Run Code Online (Sandbox Code Playgroud)\n\n

TYPO3 用 `` like 转义了 uid

\n\n
 `tx_partner_domain_model_partner`.`uid=4` DESC\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我们像这样进行调用而没有这些 `` 围绕 uid=3 ..

\n\n
`tx_partner_domain_model_partner`.uid=3 DESC, `tx_partner_domain_model_partner`.uid=4 DESC, `tx_brapartner_domain_model_partner`.uid=1 DESC\n
Run Code Online (Sandbox Code Playgroud)\n\n

效果很好。也许是出于安全原因,TYPO3 在他的最新版本上这样做,但我没有找到任何其他好的解决方案来解决这个基本情况。\n目前我有一个 foreach,我通过 findByUid 查询每个 uid,但这对我来说似乎不是“最佳实践”方式。对于这种从数据库获取数据的情况,有人有更干净的方法吗?或者也许这是一个错误?

\n\n

我希望有一个人可以帮助我。

\n\n

此致

\n\n

法诺

\n

Wol*_*ang 2

我认为问题在于\TYPO3\CMS\Core\Database\Query\QueryBuilder::orderByfieldName 被引用的位置。您可以覆盖此类并通过 = 分割 fieldName 并构建带引号的字符串和 intval() 剩余的字符串,如下所示:

public function orderBy(string $fieldName, string $order = null): QueryBuilder
{
    if (strpos($fieldName, '=') !== false) {
        list($field, $value) = GeneralUtility::trimExplode('=', $fieldName);
        $field = $this->connection->quoteIdentifier($field);
        $value = intval($value);
        $fieldName = $field . $value;
    }
    else {
        $fieldName = $this->connection->quoteIdentifier($fieldName);
    }
    $this->concreteQueryBuilder->orderBy($fieldName, $order);

    return $this;
}
Run Code Online (Sandbox Code Playgroud)