1

我正在尝试使用 TYPO3 存储库中的比较字段来调整我的查询,但并没有真正弄清楚。有人知道如何正确调试吗?我正在使用 TYPO3 8.x CMS。(准确地说是8.4)

<?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 错误。这会起作用,但错误消息不会持续到我尝试比较的字段。因此,如果某人能帮助我摆脱这种痛苦,我将非常高兴。

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,但没有找到合适的解决方案。- 对我来说,这个不起作用: 如何比较 Extbase 存储库中的 DateTime - 我不会用这个得到我的查询:如何在 extbase 中调试查询? - 这也没有:Extbase - 从查询中获取创建的 sql

4

3 回答 3

3

事实上,TYPO3 从 TYPO3 v8 开始使用 Doctrine 作为其连接,您可以使用 Doctrine SQLLoggers 来调试您的查询,这是一个非常简单的任务。

/**
 * Description of EntityRepository
 *
 * @author Kevin Ditscheid <kevinditscheid@gmail.com>
 */
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 ConnectionPool 对象,该对象存储 TYPO3 正在使用的数据库连接。然后它为我们想要处理的表获取特定的 Connection 对象,并获取它的 Configuration 对象,它本身就是 class 的一个实例\Doctrine\DBAL\Configuration。现在它可以将自己的 SQLLogger 实例附加到配置对象。\Doctrine\DBAL\Logging\EchoSQLLogger它使用简单地对查询进行 var_dumps 的Doctrine 。它备份和恢复配置的 Logger 对象,只是为了保存,不会丢失任何东西,以后的查询不会被 var_dumped 并用不必要的声音淹没输出。您现在应该看到您使用 extbase 查询对象创建的查询。

我在这里为 TYPO3 8 创建了一个小示例扩展:https ://github.com/the-coding-owl/sql_debug

于 2017-04-22T16:13:24.273 回答
1

要在自定义数据表查询中处理 DateTime 对象,您应该将其用作字符串:

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

这在 TYPO3 v8.7.7 中为我工作,并修复了这个错误: https ://forge.typo3.org/issues/81056

于 2017-10-06T09:47:18.143 回答
0

根据https://docs.typo3.org/typo3cms/TCAReference/ColumnsConfig/Type/Input.html#id25 Typo3 动态地将您的 DateTime 对象转换为 Unix 时间戳。

因此,在生成的 SQL 请求中,WHERE 子句会将 Unix 时间戳与日期对象进行比较……这就像将苹果与香蕉进行比较,结果一无所获。

我没有找到如何将日期对象存储在数据库中并将它们与自定义存储库进行比较的方法,因为需要“eval”参数并将所有内容转换为时间戳。

解决方案是将您的日期信息也作为时间戳存储在数据库中。

于 2017-05-05T12:59:20.213 回答