2017-09-28 31 views
3

我遇到了很多TYPO3擴展的問題,UID的排序查詢結果來自後端的flexform插件設置。我嘗試創建一個查詢,它以相同的順序爲我提供了結果uid,就像Flexform從插件設置中那樣。就像我選擇data.uid 5 7和3,並且我的查詢結果以這種順序給我。TYPO3 8.7查詢使用Flexform進行排序uid's

例如:

SITEINFO:

  • PHP 7.0
  • TYPO3 8.7
  • MariaDB的:10.1
  • 的Debian服務器

此功能從控制器中調用。

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

$這 - >設置[ '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; 
} 

從柔性成型給定的UID列表訂購QueryResult中的這些方法適用於TYPO3 6.27.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 

如果我們做這樣的呼籲沒有這些``角落找尋的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,但這對我來說似乎並不像「最佳實踐」的方式。有沒有人從這個從db獲取數據的情況下得到了一個更清晰的方法?或者,也許這是一個錯誤?

我希望有人能幫助我。

問候

Fanor

回答

0

的控制器替代:

$ids = explode(',',$this->settings['showMainSponsor']) 
foreach($ids as $key => $id){ 
    $partners[$id] = $this->partnerRepository->findByUid($id); 
} 

It's小骯髒的方式,因爲這種邏輯是錯誤的地方,但它的工作原理:)

此外,它也不是高性能的,就像您的解決方案。 您的解決方案在7.6原因中正常工作。但我不知道爲什麼它在版本8中突破。也許在這個TYPO3的訂購系統中「解決安全問題」。

+0

他已經提到了他的問題,這個解決方案。 – Wolfgang

+0

是的,沒錯,可能是因爲這個方法來自我的問題,我們的學徒只是在這裏僱用的。 – episch

1

我認爲問題出在\TYPO3\CMS\Core\Database\Query\QueryBuilder::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; 
}