TYPO3 8.7 使用弹性表单 uid 进行查询排序



我遇到了许多typo3扩展程序的问题,并通过UID订购查询结果,这些结果来自后端的FlexForm插件设置。我尝试创建一个查询,是什么使我以插件设置的flexform的顺序为uid的结果。就像我选择data.uid 5 7和3一样,我的查询结果给了我以下顺序。

例如:

siteinfo:

  • php 7.0
  • typo3 8.7
  • Mariadb:10.1
  • Debian Server

从控制器调用此功能。

$partners = $this->partnerRepository->findByUids($this->settings['showMainSponsor']);

in $ $ 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}"] =  TYPO3CMSExtbasePersistenceQueryInterface::ORDER_DESCENDING;
    }
    return $orderings;
}

这些方法是通过flexform从flexform works中订购查询的方法。现在,我试图将此扩展程序附加到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用``像

 `tx_partner_domain_model_partner`.`uid=4` DESC

如果我们这样打电话,没有这些```````''

`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,但在我看来,这似乎并不像"最佳练习"方式。有人从DB获取数据的情况下是否有更干净的方式?也许这是一个错误?

我希望有人可以帮助我。

最好的问候

fanor

没有覆盖:

清晰默认订购:

$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());

我认为问题在TYPO3CMSCoreDatabaseQueryQueryBuilder::orderBy中引用了字段名称。您可以覆盖此类并将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;
}
public function findByUidList($uidList)
{
    $uids = GeneralUtility::intExplode(',', $uidList, true);
    if ($uidList === '' || count($uids) === 0) {
        return [];
    }
    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->getTableName());
    $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
    $records = $queryBuilder
        ->select('*')
        ->from($this->getTableName())
        ->where($queryBuilder->expr()->in('uid', $uids))
        ->add('orderBy', 'FIELD('.$this->getTableName().'.uid,' . implode(',', $uids) . ')')
        ->execute()
        ->fetchAll();
    $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
    $dataMapper = $objectManager->get(DataMapper::class);
    $result = $dataMapper->map($this->objectType, $records);
    return $result;
}
/**
 * Return the current table name
 *
 * @return string
 */
protected function getTableName()
{
    $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
    $dataMapper = $objectManager->get(DataMapper::class);
    $tableName = $dataMapper->getDataMap($this->objectType)->getTableName();
    return $tableName;
}

这与Typo3 v10.4一起使用!:)