我遇到了许多TYPO3扩展的问题,Uid的订购查询结果来自后端的flexform插件设置。我尝试创建一个查询,它以相同的顺序给出了结果uid,就像flexform来自插件设置一样。就像我选择data.uid 5 7和3,我的查询结果按顺序给我这些。
例如:
SITEINFO:
从Controller调用此函数。
$partners = $this->partnerRepository->findByUids($this->settings['showMainSponsor']);
$ this-> settings ['showMainSponsor'] 中的是值=“3,4,1”。
这些是TYPO3插件设置中所选区域的Uid。
存储库函数“ findByUids ”看起来像这样。
public function findByUids($uids){
if(!isset($uids) || empty($uids)){
return NULL;
}
$uidListString = $uids;
if(!is_array($uids)){
$uidListString = explode(',', $uids);
}
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);
//here i set the orderings
$orderings = $this->orderByField('uid', $uidListString);
$query->setOrderings($orderings);
$query->matching(
$query->logicalAnd(
$query->in('uid', $uidListString)
)
);
return $query->execute();
}
这里调用一个名为“ orderByField ”的函数来设置所有的排序。
/**
* @param string $field
* @param array $values
*
* @return array
*/
protected function orderByField($field, $values) {
$orderings = array();
foreach ($values as $value) {
$orderings["$field={$value}"] = \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING;
}
return $orderings;
}
这些按Flexform中给定uid列表排序queryresult的方法适用于TYPO3 6.2 和 7.6 。现在我尝试将此扩展附加到TYPO3 8.6项目,但此方法不再起作用。我试着调试它并在查询中查找。在那里我发现了什么打破了这个问题不起作用的查询如下所示:
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
我在我的DBMS上试过这个但是失败了。原因是最后3个陈述。
`tx_partner_domain_model_partner`.`uid=3` DESC, `tx_partner_domain_model_partner`.`uid=4` DESC, `tx_partner_domain_model_partner`.`uid=1` DESC
TYPO3用``喜欢
逃脱了uid `tx_partner_domain_model_partner`.`uid=4` DESC
如果我们这样做这样的调用没有这些``arround the uid = 3 ..
`tx_partner_domain_model_partner`.uid=3 DESC, `tx_partner_domain_model_partner`.uid=4 DESC, `tx_brapartner_domain_model_partner`.uid=1 DESC
它工作正常。也许有一个安全原因,为什么TYPO3在他的最新版本上做到这一点,但我没有找到任何其他良好的解决方案,这个基本情况。 目前我得到了一个foreach,我通过findByUid查询他自己的每个uid,但这在我看来并不像是一种“最佳实践”方式。对于这种从数据库获取数据的情况,有没有人更清楚?或者这可能是一个Bug?
我希望有人可以帮助我。
最好的问候
Fanor
答案 0 :(得分:1)
我认为问题出在\TYPO3\CMS\Core\Database\Query\QueryBuilder::orderBy
,其中引用了fieldName。您可以覆盖此类并将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;
}
答案 1 :(得分:1)
不覆盖:
清除默认订单:
$query->setOrderings(array());
将您的QueryBuilder转换为新的教义QB:
/** @var Typo3DbQueryParser $queryParser */
$queryParser = $this->objectManager->get(Typo3DbQueryParser::class);
/** @var QueryBuilder $doctrineQueryBuilder */
$doctrineQueryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
通过concreteQb添加UID
$concreteQb = $doctrineQueryBuilder->getConcreteQueryBuilder();
foreach ($uidList as $uid) {
$concreteQb->addOrderBy("$key={$uid}", QueryInterface::ORDER_DESCENDING);
}
获取映射结果:
/** @var DataMapper $dataMapper */
$dataMapper = $this->objectManager->get(DataMapper::class);
return $dataMapper->map(YourDataClass::class, $$doctrineQueryBuilder->execute()->fetchAll());
答案 2 :(得分:0)
控制器的替代方案:
Base::vf
这是一种肮脏的方式,因为这个逻辑位于错误的地方,但它有效:)
此外,它也不像您的解决方案那样高效。 您的解决方案在7.6原因中运行良好。但我不知道为什么它在版本8中有所突破。也许在这个TYPO3的订购系统中“修复安全问题”。