2017-04-22 66 views
0

我試圖調整我的查詢,使用TYPO3存儲庫中的比較字段,並沒有真正弄清楚它。任何人都知道如何正確調試這個? 我正在使用TYPO3 8.x CMS。 (準確的說是8.4)TYPO3 8.x在CustomRepository中比較DateTime(查詢,約束)

<?php 
public function findActiveProducts() { 

    $query = $this->createQuery(); 
    $constraints = array(); 

    $date = new \DateTime(midnight); 
    // $date = new \DateTime(); // i tried to use the precise time to compare 
    $today = $date->format('Y-m-d H:i:s'); 
    // $today = $date->format('Y-m-d'); // 1st try (the field value in db) 
    // $today = $date->getTimestamp(); // 2nd try (the type in the modal 

    $constraints[] = $query->lessThanOrEqual('entrydate', $today); 
    $constraints[] = $query->equals('deleted', 0, false); 


     ->matching(
       $query->logicalAnd($constraints) 
      ) 
      ->setLimit(10) 
      ->setOrderings(array(
        'entrydate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING 
       ) 
      ); 

    // Some debug's to find out more. sadly didn't work 
    \TYPO3\CMS\Core\Utility\DebugUtility::debug($today , 'today value'); 
    \TYPO3\CMS\Core\Utility\DebugUtility::debug($query, 'my query'); 
    \TYPO3\CMS\Core\Utility\DebugUtility::debug($constraints, 'constraints'); 

    $result = $query->execute(); 




?> 

所以:有沒有人有一個很好的建議如何調試呢? stackoverflow上的一個人在另一個主題中寫了一個條目解釋我們只需要打開TYPO3中的sql錯誤,並在查詢中鍵入一個錯誤的值來輸出sql錯誤。這將工作,但錯誤信息不會持續到我嘗試比較的字段。所以我會很高興,如果s.b.會幫助我擺脫這種痛苦。

oldschool調試不再在8.x中工作,否則這不會有什麼大不了的。

<?php 
      $parser =  \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser'); 
      $parser->convertQueryToDoctrineQueryBuilder($query); 
      $queryParts = $parser->parseQuery($query); 
      \TYPO3\CMS\Core\Utility\DebugUtility::debug($queryParts, 'Query'); 
    ?> 

通過模型的方式......適用於所有的部分罰款,我使用它,除非是在倉庫裏的自定義查詢。

/** 
    * entrydate 
    * 
    * @var \DateTime 
    */ 
    protected $entrydate = null; 

我也搜索過stackoverflow,但沒有找到合適的解決方案。 - 對我來說,這一個不工作: How to compare DateTime in Extbase repository - 我不會讓我的查詢與這一個:How to debug a query in extbase? - 也沒有這樣的:Extbase - get created sql from query

+0

你找到一個辦法?我被困在同一點。從SQLLogger獲得調試信息,但看起來,prepareStatement佔位符未填寫日期時間:SELECT'tx_my_domain_model_event'。* FROM'tx_my_domain_model_event'' tx_my_domain_model_event' WHERE('tx_my_domain_model_event'.'startdate'>:dcValue1)AND(' tx_my_domain_model_event'.'sys_language_uid' IN(0,-1))AND('tx_my_domain_model_event'.'pid' IN(10,11,12,13,17,19,20,26))AND ... so日期時間比較是針對:dcValue1 –

回答

2

根據這樣的事實,即TYPO3使用原則作爲其從TYPO3 v8開始,你可以使用Doctrine SQLLogger來調試你的查詢,這是一個非常簡單的任務。

/** 
* Description of EntityRepository 
* 
* @author Kevin Ditscheid <[email protected]> 
*/ 
class EntityRepository extends \TYPO3\CMS\Extbase\Persistence\Repository{ 
    /** 
    * Find entities by a given DateTime object 
    * 
    * @param \DateTime $date The DateTime to filter by 
    * 
    * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface 
    */ 
    public function findByDate(\DateTime $date): \TYPO3\CMS\Extbase\Persistence\QueryResultInterface{ 
     $query = $this->createQuery(); 
     $queryResult = $query->matching($query->greaterThan('timestampDate', $date))->execute(); 

     // create a new logger for the database queries to log 
     $logger = new \Doctrine\DBAL\Logging\EchoSQLLogger(); 
     // get the Docrine Connection configuration object 
     $connectionConfiguration = $this->getConnectionPool()->getConnectionForTable('tx_sqldebug_domain_model_entity')->getConfiguration(); 
     // backup the current logger 
     $loggerBackup = $connectionConfiguration->getSQLLogger(); 
     // set our logger as the active logger object of the Doctrine connection 
     $connectionConfiguration->setSQLLogger($logger); 
     // we need to fetch our results here, to enable doctrine to fetch the results 
     $entities = $queryResult->toArray(); 
     // restore the old logger 
     $connectionConfiguration->setSQLLogger($loggerBackup); 
     return $queryResult; 
    } 
    /** 
    * Get the ConnectionPool object 
    * 
    * @return \TYPO3\CMS\Core\Database\ConnectionPool 
    */ 
    protected function getConnectionPool(): \TYPO3\CMS\Core\Database\ConnectionPool{ 
     return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ConnectionPool::class); 
    } 
} 

此示例獲取TYPO3連接池對象,其存儲數據庫連接TYPO3正在與。然後,它爲我們想要處理的表獲取特定的Connection對象,並獲取其Configuration對象,該對象本身是類\Doctrine\DBAL\Configuration的一個實例。現在它可以將一個自己的SQLLogger實例附加到配置對象。它使用簡單var_dumps查詢的Doctrine \Doctrine\DBAL\Logging\EchoSQLLogger。它備份和恢復配置的Logger對象,只是爲了保存沒有丟失,後來的查詢不會被var_dumped和洪水輸出不必要的聲音。 您現在應該可以看到您使用extbase查詢對象創建的查詢。

我創建了TYPO3 8在這裏一個小例子擴展:https://github.com/the-coding-owl/sql_debug

+0

多麼偉大的擴展!凱文那真是太棒了!感謝您的快速和正確的答覆! –

0

根據https://docs.typo3.org/typo3cms/TCAReference/ColumnsConfig/Type/Input.html#id25您Typo3的datetime對象動態轉換爲Unix的時間戳。

因此,在生成的SQL請求中,WHERE子句將比較一個Unix時間戳和一個Date對象......這就像比較蘋果和香蕉並導致什麼都沒有。

我沒有找到如何將Date對象存儲在數據庫中並將它們與自定義存儲庫進行比較的原因,因爲'eval'參數是必需的,並將所有內容都轉換爲時間戳。

解決方案是將日期信息作爲時間戳存儲在數據庫中。

1

爲了處理自定義datatabse查詢datetime對象,你應該把它作爲一個字符串:

$query->lessThan('modified_on', $date->format('Y-m-d H:i:s') 

這是爲我工作在TYPO3 v8.7.7這個固定的錯誤: https://forge.typo3.org/issues/81056